s3:param: Ensure that the service pointers are not used directly.
[Samba.git] / source3 / param / loadparm.c
blobdd56419bf45ac9787818bf5efcb04e98aab2e322
1 /*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12 Copyright (C) Michael Adam 2008
13 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14 Copyright (C) Andrew Bartlett 2011
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 3 of the License, or
19 (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
31 * Load parameters.
33 * This module provides suitable callback functions for the params
34 * module. It builds the internal table of service details which is
35 * then used by the rest of the server.
37 * To add a parameter:
39 * 1) add it to the global or service structure definition
40 * 2) add it to the parm_table
41 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42 * 4) If it's a global then initialise it in init_globals. If a local
43 * (ie. service) parameter then initialise it in the sDefault structure
46 * Notes:
47 * The configuration file is processed sequentially for speed. It is NOT
48 * accessed randomly as happens in 'real' Windows. For this reason, there
49 * is a fair bit of sequence-dependent code here - ie., code which assumes
50 * that certain things happen before others. In particular, the code which
51 * happens at the boundary between sections is delicately poised, so be
52 * careful!
56 #include "includes.h"
57 #include "system/filesys.h"
58 #include "util_tdb.h"
59 #include "lib/param/loadparm.h"
60 #include "lib/param/param.h"
61 #include "printing.h"
62 #include "lib/smbconf/smbconf.h"
63 #include "lib/smbconf/smbconf_init.h"
65 #include "ads.h"
66 #include "../librpc/gen_ndr/svcctl.h"
67 #include "intl.h"
68 #include "../libcli/smb/smb_signing.h"
69 #include "dbwrap/dbwrap.h"
70 #include "dbwrap/dbwrap_rbt.h"
71 #include "../lib/util/bitmap.h"
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
75 #endif
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
79 #endif
81 bool bLoaded = false;
83 extern userdom_struct current_user_info;
85 /* the special value for the include parameter
86 * to be interpreted not as a file name but to
87 * trigger loading of the global smb.conf options
88 * from registry. */
89 #ifndef INCLUDE_REGISTRY_NAME
90 #define INCLUDE_REGISTRY_NAME "registry"
91 #endif
93 static bool in_client = false; /* Not in the client by default */
94 static struct smbconf_csn conf_last_csn;
96 static int config_backend = CONFIG_BACKEND_FILE;
98 /* some helpful bits */
99 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
100 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
102 #define USERSHARE_VALID 1
103 #define USERSHARE_PENDING_DELETE 2
105 static bool defaults_saved = false;
107 #include "lib/param/param_global.h"
109 static struct loadparm_global Globals;
111 /* This is a default service used to prime a services structure */
112 static struct loadparm_service sDefault =
114 .valid = true,
115 .autoloaded = false,
116 .usershare = 0,
117 .usershare_last_mod = {0, 0},
118 .szService = NULL,
119 .path = NULL,
120 .username = NULL,
121 .invalid_users = NULL,
122 .valid_users = NULL,
123 .admin_users = NULL,
124 .szCopy = NULL,
125 .szInclude = NULL,
126 .preexec = NULL,
127 .postexec = NULL,
128 .root_preexec = NULL,
129 .root_postexec = NULL,
130 .cups_options = NULL,
131 .print_command = NULL,
132 .lpq_command = NULL,
133 .lprm_command = NULL,
134 .lppause_command = NULL,
135 .lpresume_command = NULL,
136 .queuepause_command = NULL,
137 .queueresume_command = NULL,
138 ._printername = NULL,
139 .printjob_username = NULL,
140 .dont_descend = NULL,
141 .hosts_allow = NULL,
142 .hosts_deny = NULL,
143 .magic_script = NULL,
144 .magic_output = NULL,
145 .veto_files = NULL,
146 .hide_files = NULL,
147 .veto_oplock_files = NULL,
148 .comment = NULL,
149 .force_user = NULL,
150 .force_group = NULL,
151 .read_list = NULL,
152 .write_list = NULL,
153 .volume = NULL,
154 .fstype = NULL,
155 .vfs_objects = NULL,
156 .msdfs_proxy = NULL,
157 .aio_write_behind = NULL,
158 .dfree_command = NULL,
159 .min_print_space = 0,
160 .iMaxPrintJobs = 1000,
161 .max_reported_print_jobs = 0,
162 .write_cache_size = 0,
163 .create_mask = 0744,
164 .force_create_mode = 0,
165 .directory_mask = 0755,
166 .force_directory_mode = 0,
167 .max_connections = 0,
168 .default_case = CASE_LOWER,
169 .printing = DEFAULT_PRINTING,
170 .oplock_contention_limit = 2,
171 .csc_policy = 0,
172 .block_size = 1024,
173 .dfree_cache_time = 0,
174 .preexec_close = false,
175 .root_preexec_close = false,
176 .case_sensitive = Auto,
177 .preserve_case = true,
178 .short_preserve_case = true,
179 .hide_dot_files = true,
180 .hide_special_files = false,
181 .hide_unreadable = false,
182 .hide_unwriteable_files = false,
183 .browseable = true,
184 .access_based_share_enum = false,
185 .bAvailable = true,
186 .read_only = true,
187 .guest_only = false,
188 .administrative_share = false,
189 .guest_ok = false,
190 .printable = false,
191 .print_notify_backchannel = false,
192 .map_system = false,
193 .map_hidden = false,
194 .map_archive = true,
195 .store_dos_attributes = false,
196 .dmapi_support = false,
197 .locking = true,
198 .strict_locking = Auto,
199 .posix_locking = true,
200 .oplocks = true,
201 .kernel_oplocks = false,
202 .level2_oplocks = true,
203 .only_user = false,
204 .mangled_names = true,
205 .bWidelinks = false,
206 .follow_symlinks = true,
207 .sync_always = false,
208 .strict_allocate = false,
209 .strict_sync = false,
210 .mangling_char = '~',
211 .copymap = NULL,
212 .delete_readonly = false,
213 .fake_oplocks = false,
214 .delete_veto_files = false,
215 .dos_filemode = false,
216 .dos_filetimes = true,
217 .dos_filetime_resolution = false,
218 .fake_directory_create_times = false,
219 .blocking_locks = true,
220 .inherit_permissions = false,
221 .inherit_acls = false,
222 .inherit_owner = false,
223 .msdfs_root = false,
224 .use_client_driver = false,
225 .default_devmode = true,
226 .force_printername = false,
227 .nt_acl_support = true,
228 .force_unknown_acl_user = false,
229 ._use_sendfile = false,
230 .profile_acls = false,
231 .map_acl_inherit = false,
232 .afs_share = false,
233 .ea_support = false,
234 .acl_check_permissions = true,
235 .acl_map_full_control = true,
236 .acl_group_control = false,
237 .acl_allow_execute_always = false,
238 .change_notify = true,
239 .kernel_change_notify = true,
240 .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
241 .aio_read_size = 0,
242 .aio_write_size = 0,
243 .map_readonly = MAP_READONLY_YES,
244 .directory_name_cache_size = 100,
245 .smb_encrypt = SMB_SIGNING_DEFAULT,
246 .kernel_share_modes = true,
247 .durable_handles = true,
248 .param_opt = NULL,
249 .dummy = ""
252 /* local variables */
253 static struct loadparm_service **ServicePtrs = NULL;
254 static int iNumServices = 0;
255 static int iServiceIndex = 0;
256 static struct db_context *ServiceHash;
257 static bool bInGlobalSection = true;
258 static bool bGlobalOnly = false;
259 static struct file_lists *file_lists = NULL;
260 static unsigned int *flags_list = NULL;
262 static void set_allowed_client_auth(void);
264 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
265 static void free_param_opts(struct parmlist_entry **popts);
267 /* this is used to prevent lots of mallocs of size 1 */
268 static const char null_string[] = "";
271 Free a string value.
274 static void string_free(char **s)
276 if (!s || !(*s))
277 return;
278 if (*s == null_string)
279 *s = NULL;
280 TALLOC_FREE(*s);
284 Set a string value, deallocating any existing space, and allocing the space
285 for the string
288 static bool string_set(TALLOC_CTX *mem_ctx, char **dest,const char *src)
290 string_free(dest);
292 if (!src) {
293 src = "";
296 (*dest) = talloc_strdup(mem_ctx, src);
297 if ((*dest) == NULL) {
298 DEBUG(0,("Out of memory in string_init\n"));
299 return false;
302 return true;
305 bool lp_string_set(char **dest, const char *src) {
306 return string_set(Globals.ctx, dest, src);
310 * Function to return the default value for the maximum number of open
311 * file descriptors permitted. This function tries to consult the
312 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
313 * the smaller of those.
315 static int max_open_files(void)
317 int sysctl_max = MAX_OPEN_FILES;
318 int rlimit_max = MAX_OPEN_FILES;
320 #ifdef HAVE_SYSCTLBYNAME
322 size_t size = sizeof(sysctl_max);
323 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
326 #endif
328 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
330 struct rlimit rl;
332 ZERO_STRUCT(rl);
334 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
335 rlimit_max = rl.rlim_cur;
337 #if defined(RLIM_INFINITY)
338 if(rl.rlim_cur == RLIM_INFINITY)
339 rlimit_max = MAX_OPEN_FILES;
340 #endif
342 #endif
344 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
345 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
346 "minimum Windows limit (%d)\n",
347 sysctl_max,
348 MIN_OPEN_FILES_WINDOWS));
349 sysctl_max = MIN_OPEN_FILES_WINDOWS;
352 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
353 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
354 "minimum Windows limit (%d)\n",
355 rlimit_max,
356 MIN_OPEN_FILES_WINDOWS));
357 rlimit_max = MIN_OPEN_FILES_WINDOWS;
360 return MIN(sysctl_max, rlimit_max);
364 * Common part of freeing allocated data for one parameter.
366 static void free_one_parameter_common(void *parm_ptr,
367 struct parm_struct parm)
369 if ((parm.type == P_STRING) ||
370 (parm.type == P_USTRING))
372 string_free((char**)parm_ptr);
373 } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
374 TALLOC_FREE(*((char***)parm_ptr));
379 * Free the allocated data for one parameter for a share
380 * given as a service struct.
382 static void free_one_parameter(struct loadparm_service *service,
383 struct parm_struct parm)
385 void *parm_ptr;
387 if (parm.p_class != P_LOCAL) {
388 return;
391 parm_ptr = lp_parm_ptr(service, &parm);
393 free_one_parameter_common(parm_ptr, parm);
397 * Free the allocated parameter data of a share given
398 * as a service struct.
400 static void free_parameters(struct loadparm_service *service)
402 uint32_t i;
404 for (i=0; parm_table[i].label; i++) {
405 free_one_parameter(service, parm_table[i]);
410 * Free the allocated data for one parameter for a given share
411 * specified by an snum.
413 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
415 void *parm_ptr;
417 if (snum < 0) {
418 parm_ptr = lp_parm_ptr(NULL, &parm);
419 } else if (parm.p_class != P_LOCAL) {
420 return;
421 } else {
422 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
425 free_one_parameter_common(parm_ptr, parm);
429 * Free the allocated parameter data for a share specified
430 * by an snum.
432 static void free_parameters_by_snum(int snum)
434 uint32_t i;
436 for (i=0; parm_table[i].label; i++) {
437 free_one_parameter_by_snum(snum, parm_table[i]);
442 * Free the allocated global parameters.
444 static void free_global_parameters(void)
446 free_param_opts(&Globals.param_opt);
447 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
448 TALLOC_FREE(Globals.ctx);
451 struct lp_stored_option {
452 struct lp_stored_option *prev, *next;
453 const char *label;
454 const char *value;
457 static struct lp_stored_option *stored_options;
460 save options set by lp_set_cmdline() into a list. This list is
461 re-applied when we do a globals reset, so that cmdline set options
462 are sticky across reloads of smb.conf
464 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
466 struct lp_stored_option *entry, *entry_next;
467 for (entry = stored_options; entry != NULL; entry = entry_next) {
468 entry_next = entry->next;
469 if (strcmp(pszParmName, entry->label) == 0) {
470 DLIST_REMOVE(stored_options, entry);
471 talloc_free(entry);
472 break;
476 entry = talloc(NULL, struct lp_stored_option);
477 if (!entry) {
478 return false;
481 entry->label = talloc_strdup(entry, pszParmName);
482 if (!entry->label) {
483 talloc_free(entry);
484 return false;
487 entry->value = talloc_strdup(entry, pszParmValue);
488 if (!entry->value) {
489 talloc_free(entry);
490 return false;
493 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
495 return true;
498 static bool apply_lp_set_cmdline(void)
500 struct lp_stored_option *entry = NULL;
501 for (entry = stored_options; entry != NULL; entry = entry->next) {
502 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
503 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
504 entry->label, entry->value));
505 return false;
508 return true;
511 /***************************************************************************
512 Initialise the global parameter structure.
513 ***************************************************************************/
515 static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
517 static bool done_init = false;
518 char *s = NULL;
519 int i;
521 /* If requested to initialize only once and we've already done it... */
522 if (!reinit_globals && done_init) {
523 /* ... then we have nothing more to do */
524 return;
527 if (!done_init) {
528 /* The logfile can be set before this is invoked. Free it if so. */
529 if (Globals.logfile != NULL) {
530 string_free(&Globals.logfile);
531 Globals.logfile = NULL;
533 done_init = true;
534 } else {
535 free_global_parameters();
538 /* This memset and the free_global_parameters() above will
539 * wipe out smb.conf options set with lp_set_cmdline(). The
540 * apply_lp_set_cmdline() call puts these values back in the
541 * table once the defaults are set */
542 ZERO_STRUCT(Globals);
544 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
546 /* Initialize the flags list if necessary */
547 if (flags_list == NULL) {
548 get_flags();
551 for (i = 0; parm_table[i].label; i++) {
552 if ((parm_table[i].type == P_STRING ||
553 parm_table[i].type == P_USTRING))
555 string_set(Globals.ctx, (char **)lp_parm_ptr(NULL, &parm_table[i]), "");
560 string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
561 string_set(Globals.ctx, &sDefault.printjob_username, "%U");
563 init_printer_values(lp_ctx, Globals.ctx, &sDefault);
565 sDefault.ntvfs_handler = (const char **)str_list_make_v3(NULL, "unixuid default", NULL);
567 DEBUG(3, ("Initialising global parameters\n"));
569 /* Must manually force to upper case here, as this does not go via the handler */
570 string_set(Globals.ctx, &Globals.netbios_name, myhostname_upper());
572 string_set(Globals.ctx, &Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
573 string_set(Globals.ctx, &Globals.private_dir, get_dyn_PRIVATE_DIR());
575 /* use the new 'hash2' method by default, with a prefix of 1 */
576 string_set(Globals.ctx, &Globals.mangling_method, "hash2");
577 Globals.mangle_prefix = 1;
579 string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
581 /* using UTF8 by default allows us to support all chars */
582 string_set(Globals.ctx, &Globals.unix_charset, DEFAULT_UNIX_CHARSET);
584 /* Use codepage 850 as a default for the dos character set */
585 string_set(Globals.ctx, &Globals.dos_charset, DEFAULT_DOS_CHARSET);
588 * Allow the default PASSWD_CHAT to be overridden in local.h.
590 string_set(Globals.ctx, &Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
592 string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
594 string_set(Globals.ctx, &Globals.passwd_program, "");
595 string_set(Globals.ctx, &Globals.lock_directory, get_dyn_LOCKDIR());
596 string_set(Globals.ctx, &Globals.state_directory, get_dyn_STATEDIR());
597 string_set(Globals.ctx, &Globals.cache_directory, get_dyn_CACHEDIR());
598 string_set(Globals.ctx, &Globals.pid_directory, get_dyn_PIDDIR());
599 string_set(Globals.ctx, &Globals.nbt_client_socket_address, "0.0.0.0");
601 * By default support explicit binding to broadcast
602 * addresses.
604 Globals.nmbd_bind_explicit_broadcast = true;
606 s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
607 if (s == NULL) {
608 smb_panic("init_globals: ENOMEM");
610 string_set(Globals.ctx, &Globals.server_string, s);
611 TALLOC_FREE(s);
612 #ifdef DEVELOPER
613 string_set(Globals.ctx, &Globals.panic_action, "/bin/sleep 999999999");
614 #endif
616 string_set(Globals.ctx, &Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
618 string_set(Globals.ctx, &Globals.logon_drive, "");
619 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
620 string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
621 string_set(Globals.ctx, &Globals.logon_path, "\\\\%N\\%U\\profile");
623 Globals.name_resolve_order = (const char **)str_list_make_v3(NULL, "lmhosts wins host bcast", NULL);
624 string_set(Globals.ctx, &Globals.password_server, "*");
626 Globals.algorithmic_rid_base = BASE_RID;
628 Globals.load_printers = true;
629 Globals.printcap_cache_time = 750; /* 12.5 minutes */
631 Globals.config_backend = config_backend;
632 Globals._server_role = ROLE_AUTO;
634 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
635 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
636 Globals.max_xmit = 0x4104;
637 Globals.max_mux = 50; /* This is *needed* for profile support. */
638 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
639 Globals._disable_spoolss = false;
640 Globals.max_smbd_processes = 0;/* no limit specified */
641 Globals.username_level = 0;
642 Globals.deadtime = 0;
643 Globals.getwd_cache = true;
644 Globals.large_readwrite = true;
645 Globals.max_log_size = 5000;
646 Globals.max_open_files = max_open_files();
647 Globals.server_max_protocol = PROTOCOL_SMB3_00;
648 Globals.server_min_protocol = PROTOCOL_LANMAN1;
649 Globals.client_max_protocol = PROTOCOL_NT1;
650 Globals.client_min_protocol = PROTOCOL_CORE;
651 Globals._security = SEC_AUTO;
652 Globals.encrypt_passwords = true;
653 Globals.client_schannel = Auto;
654 Globals.winbind_sealed_pipes = true;
655 Globals.require_strong_key = true;
656 Globals.server_schannel = Auto;
657 Globals.read_raw = true;
658 Globals.write_raw = true;
659 Globals.null_passwords = false;
660 Globals.old_password_allowed_period = 60;
661 Globals.obey_pam_restrictions = false;
662 Globals.syslog = 1;
663 Globals.syslog_only = false;
664 Globals.timestamp_logs = true;
665 string_set(Globals.ctx, &Globals.log_level, "0");
666 Globals.debug_prefix_timestamp = false;
667 Globals.debug_hires_timestamp = true;
668 Globals.debug_pid = false;
669 Globals.debug_uid = false;
670 Globals.debug_class = false;
671 Globals.enable_core_files = true;
672 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
673 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
674 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
675 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
676 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
677 Globals.lm_interval = 60;
678 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
679 Globals.nis_homedir = false;
680 #ifdef WITH_NISPLUS_HOME
681 string_set(Globals.ctx, &Globals.homedir_map, "auto_home.org_dir");
682 #else
683 string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
684 #endif
685 #endif
686 Globals.time_server = false;
687 Globals.bind_interfaces_only = false;
688 Globals.unix_password_sync = false;
689 Globals.pam_password_change = false;
690 Globals.passwd_chat_debug = false;
691 Globals.passwd_chat_timeout = 2; /* 2 second default. */
692 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
693 Globals.nt_status_support = true; /* Use NT status by default. */
694 Globals.stat_cache = true; /* use stat cache by default */
695 Globals.max_stat_cache_size = 256; /* 256k by default */
696 Globals.restrict_anonymous = 0;
697 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
698 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
699 Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
700 Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
701 Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
702 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
704 Globals.map_to_guest = 0; /* By Default, "Never" */
705 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
706 Globals.enhanced_browsing = true;
707 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
708 #ifdef MMAP_BLACKLIST
709 Globals.use_mmap = false;
710 #else
711 Globals.use_mmap = true;
712 #endif
713 Globals.unicode = true;
714 Globals.unix_extensions = true;
715 Globals.reset_on_zero_vc = false;
716 Globals.log_writeable_files_on_exit = false;
717 Globals.create_krb5_conf = true;
718 Globals.winbindMaxDomainConnections = 1;
720 /* hostname lookups can be very expensive and are broken on
721 a large number of sites (tridge) */
722 Globals.hostname_lookups = false;
724 string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
725 string_set(Globals.ctx, &Globals.ldap_suffix, "");
726 string_set(Globals.ctx, &Globals.szLdapMachineSuffix, "");
727 string_set(Globals.ctx, &Globals.szLdapUserSuffix, "");
728 string_set(Globals.ctx, &Globals.szLdapGroupSuffix, "");
729 string_set(Globals.ctx, &Globals.szLdapIdmapSuffix, "");
731 string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
732 Globals.ldap_ssl = LDAP_SSL_START_TLS;
733 Globals.ldap_ssl_ads = false;
734 Globals.ldap_deref = -1;
735 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
736 Globals.ldap_delete_dn = false;
737 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
738 Globals.ldap_follow_referral = Auto;
739 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
740 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
741 Globals.ldap_page_size = LDAP_PAGE_SIZE;
743 Globals.ldap_debug_level = 0;
744 Globals.ldap_debug_threshold = 10;
746 /* This is what we tell the afs client. in reality we set the token
747 * to never expire, though, when this runs out the afs client will
748 * forget the token. Set to 0 to get NEVERDATE.*/
749 Globals.afs_token_lifetime = 604800;
750 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
752 /* these parameters are set to defaults that are more appropriate
753 for the increasing samba install base:
755 as a member of the workgroup, that will possibly become a
756 _local_ master browser (lm = true). this is opposed to a forced
757 local master browser startup (pm = true).
759 doesn't provide WINS server service by default (wsupp = false),
760 and doesn't provide domain master browser services by default, either.
764 Globals.show_add_printer_wizard = true;
765 Globals.os_level = 20;
766 Globals.local_master = true;
767 Globals._domain_master = Auto; /* depending on _domain_logons */
768 Globals._domain_logons = false;
769 Globals.browse_list = true;
770 Globals.we_are_a_wins_server = false;
771 Globals.wins_proxy = false;
773 TALLOC_FREE(Globals.init_logon_delayed_hosts);
774 Globals.init_logon_delay = 100; /* 100 ms default delay */
776 Globals.wins_dns_proxy = true;
778 Globals.allow_trusted_domains = true;
779 string_set(Globals.ctx, &Globals.szIdmapBackend, "tdb");
781 string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
782 string_set(Globals.ctx, &Globals.template_homedir, "/home/%D/%U");
783 string_set(Globals.ctx, &Globals.winbind_separator, "\\");
784 string_set(Globals.ctx, &Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
786 string_set(Globals.ctx, &Globals.cups_server, "");
787 string_set(Globals.ctx, &Globals.iprint_server, "");
789 string_set(Globals.ctx, &Globals._ctdbd_socket, "");
791 Globals.cluster_addresses = NULL;
792 Globals.clustering = false;
793 Globals.ctdb_timeout = 0;
794 Globals.ctdb_locktime_warn_threshold = 0;
796 Globals.winbind_cache_time = 300; /* 5 minutes */
797 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
798 Globals.winbind_request_timeout = 60; /* 60 seconds */
799 Globals.winbind_max_clients = 200;
800 Globals.winbind_enum_users = false;
801 Globals.winbind_enum_groups = false;
802 Globals.winbind_use_default_domain = false;
803 Globals.winbind_trusted_domains_only = false;
804 Globals.winbind_nested_groups = true;
805 Globals.winbind_expand_groups = 1;
806 Globals.winbind_nss_info = (const char **)str_list_make_v3(NULL, "template", NULL);
807 Globals.winbind_refresh_tickets = false;
808 Globals.winbind_offline_logon = false;
810 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
811 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
813 Globals.passdb_expand_explicit = false;
815 Globals.name_cache_timeout = 660; /* In seconds */
817 Globals.use_spnego = true;
818 Globals.client_use_spnego = true;
820 Globals.client_signing = SMB_SIGNING_DEFAULT;
821 Globals.server_signing = SMB_SIGNING_DEFAULT;
823 Globals.defer_sharing_violations = true;
824 Globals.smb_ports = (const char **)str_list_make_v3(NULL, SMB_PORTS, NULL);
826 Globals.enable_privileges = true;
827 Globals.host_msdfs = true;
828 Globals.enable_asu_support = false;
830 /* User defined shares. */
831 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
832 if (s == NULL) {
833 smb_panic("init_globals: ENOMEM");
835 string_set(Globals.ctx, &Globals.usershare_path, s);
836 TALLOC_FREE(s);
837 string_set(Globals.ctx, &Globals.usershare_template_share, "");
838 Globals.usershare_max_shares = 0;
839 /* By default disallow sharing of directories not owned by the sharer. */
840 Globals.usershare_owner_only = true;
841 /* By default disallow guest access to usershares. */
842 Globals.usershare_allow_guests = false;
844 Globals.keepalive = DEFAULT_KEEPALIVE;
846 /* By default no shares out of the registry */
847 Globals.registry_shares = false;
849 Globals.iminreceivefile = 0;
851 Globals.map_untrusted_to_domain = false;
852 Globals.multicast_dns_register = true;
854 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
855 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
856 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
857 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
859 string_set(Globals.ctx, &Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
861 Globals.server_services = (const char **)str_list_make_v3(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
863 Globals.dcerpc_endpoint_servers = (const char **)str_list_make_v3(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
865 Globals.tls_enabled = true;
867 string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
868 string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
869 string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
871 string_set(Globals.ctx, &Globals.share_backend, "classic");
873 Globals.iPreferredMaster = Auto;
875 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
877 string_set(Globals.ctx, &Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
879 string_set(Globals.ctx, &Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
881 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
882 if (s == NULL) {
883 smb_panic("init_globals: ENOMEM");
885 Globals.samba_kcc_command = (const char **)str_list_make_v3(NULL, s, NULL);
886 TALLOC_FREE(s);
888 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
889 if (s == NULL) {
890 smb_panic("init_globals: ENOMEM");
892 Globals.dns_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
893 TALLOC_FREE(s);
895 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
896 if (s == NULL) {
897 smb_panic("init_globals: ENOMEM");
899 Globals.spn_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
900 TALLOC_FREE(s);
902 Globals.nsupdate_command = (const char **)str_list_make_v3(NULL, "/usr/bin/nsupdate -g", NULL);
904 Globals.rndc_command = (const char **)str_list_make_v3(NULL, "/usr/sbin/rndc", NULL);
906 Globals.cldap_port = 389;
908 Globals.dgram_port = 138;
910 Globals.nbt_port = 137;
912 Globals.krb5_port = 88;
914 Globals.kpasswd_port = 464;
916 Globals.web_port = 901;
918 /* Now put back the settings that were set with lp_set_cmdline() */
919 apply_lp_set_cmdline();
922 /*******************************************************************
923 Convenience routine to grab string parameters into talloced memory
924 and run standard_sub_basic on them. The buffers can be written to by
925 callers without affecting the source string.
926 ********************************************************************/
928 char *lp_string(TALLOC_CTX *ctx, const char *s)
930 char *ret;
932 /* The follow debug is useful for tracking down memory problems
933 especially if you have an inner loop that is calling a lp_*()
934 function that returns a string. Perhaps this debug should be
935 present all the time? */
937 #if 0
938 DEBUG(10, ("lp_string(%s)\n", s));
939 #endif
940 if (!s) {
941 return NULL;
944 ret = talloc_sub_basic(ctx,
945 get_current_username(),
946 current_user_info.domain,
948 if (trim_char(ret, '\"', '\"')) {
949 if (strchr(ret,'\"') != NULL) {
950 TALLOC_FREE(ret);
951 ret = talloc_sub_basic(ctx,
952 get_current_username(),
953 current_user_info.domain,
957 return ret;
961 In this section all the functions that are used to access the
962 parameters from the rest of the program are defined
965 #define FN_GLOBAL_STRING(fn_name,ptr) \
966 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
967 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
968 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
969 #define FN_GLOBAL_LIST(fn_name,ptr) \
970 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
971 #define FN_GLOBAL_BOOL(fn_name,ptr) \
972 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
973 #define FN_GLOBAL_CHAR(fn_name,ptr) \
974 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
975 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
976 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
978 #define FN_LOCAL_STRING(fn_name,val) \
979 char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
980 #define FN_LOCAL_CONST_STRING(fn_name,val) \
981 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
982 #define FN_LOCAL_LIST(fn_name,val) \
983 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
984 #define FN_LOCAL_BOOL(fn_name,val) \
985 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
986 #define FN_LOCAL_INTEGER(fn_name,val) \
987 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
989 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
990 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
991 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
992 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
993 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
994 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
996 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
997 winbindMaxDomainConnections)
999 int lp_winbind_max_domain_connections(void)
1001 if (lp_winbind_offline_logon() &&
1002 lp_winbind_max_domain_connections_int() > 1) {
1003 DEBUG(1, ("offline logons active, restricting max domain "
1004 "connections to 1\n"));
1005 return 1;
1007 return MAX(1, lp_winbind_max_domain_connections_int());
1010 int lp_smb2_max_credits(void)
1012 if (Globals.ismb2_max_credits == 0) {
1013 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1015 return Globals.ismb2_max_credits;
1017 int lp_cups_encrypt(void)
1019 int result = 0;
1020 #ifdef HAVE_HTTPCONNECTENCRYPT
1021 switch (Globals.CupsEncrypt) {
1022 case Auto:
1023 result = HTTP_ENCRYPT_REQUIRED;
1024 break;
1025 case true:
1026 result = HTTP_ENCRYPT_ALWAYS;
1027 break;
1028 case false:
1029 result = HTTP_ENCRYPT_NEVER;
1030 break;
1032 #endif
1033 return result;
1036 /* These functions remain in source3/param for now */
1038 #include "lib/param/param_functions.c"
1040 FN_LOCAL_STRING(servicename, szService)
1041 FN_LOCAL_CONST_STRING(const_servicename, szService)
1043 /* These functions cannot be auto-generated */
1044 FN_LOCAL_BOOL(autoloaded, autoloaded)
1045 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1047 /* local prototypes */
1049 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1050 static const char *get_boolean(bool bool_value);
1051 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1052 void *userdata);
1053 static bool hash_a_service(const char *name, int number);
1054 static void free_service_byindex(int iService);
1055 static void show_parameter(int parmIndex);
1056 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1059 * This is a helper function for parametrical options support. It returns a
1060 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1061 * parametrical functions are quite simple
1063 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1064 const char *option)
1066 if (snum >= iNumServices) return NULL;
1068 if (snum < 0) {
1069 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1070 } else {
1071 return get_parametric_helper(ServicePtrs[snum],
1072 type, option, Globals.param_opt);
1077 #define MISSING_PARAMETER(name) \
1078 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1080 /*******************************************************************
1081 convenience routine to return enum parameters.
1082 ********************************************************************/
1083 static int lp_enum(const char *s,const struct enum_list *_enum)
1085 int i;
1087 if (!s || !*s || !_enum) {
1088 MISSING_PARAMETER(lp_enum);
1089 return (-1);
1092 for (i=0; _enum[i].name; i++) {
1093 if (strequal(_enum[i].name,s))
1094 return _enum[i].value;
1097 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1098 return (-1);
1101 #undef MISSING_PARAMETER
1103 /* Return parametric option from a given service. Type is a part of option before ':' */
1104 /* Parametric option has following syntax: 'Type: option = value' */
1105 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1107 struct parmlist_entry *data = get_parametrics(snum, type, option);
1109 if (data == NULL||data->value==NULL) {
1110 if (def) {
1111 return lp_string(ctx, def);
1112 } else {
1113 return NULL;
1117 return lp_string(ctx, data->value);
1120 /* Return parametric option from a given service. Type is a part of option before ':' */
1121 /* Parametric option has following syntax: 'Type: option = value' */
1122 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1124 struct parmlist_entry *data = get_parametrics(snum, type, option);
1126 if (data == NULL||data->value==NULL)
1127 return def;
1129 return data->value;
1133 /* Return parametric option from a given service. Type is a part of option before ':' */
1134 /* Parametric option has following syntax: 'Type: option = value' */
1136 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1138 struct parmlist_entry *data = get_parametrics(snum, type, option);
1140 if (data == NULL||data->value==NULL)
1141 return (const char **)def;
1143 if (data->list==NULL) {
1144 data->list = str_list_make_v3(NULL, data->value, NULL);
1147 return (const char **)data->list;
1150 /* Return parametric option from a given service. Type is a part of option before ':' */
1151 /* Parametric option has following syntax: 'Type: option = value' */
1153 int lp_parm_int(int snum, const char *type, const char *option, int def)
1155 struct parmlist_entry *data = get_parametrics(snum, type, option);
1157 if (data && data->value && *data->value)
1158 return lp_int(data->value);
1160 return def;
1163 /* Return parametric option from a given service. Type is a part of option before ':' */
1164 /* Parametric option has following syntax: 'Type: option = value' */
1166 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1168 struct parmlist_entry *data = get_parametrics(snum, type, option);
1170 if (data && data->value && *data->value)
1171 return lp_ulong(data->value);
1173 return def;
1176 /* Return parametric option from a given service. Type is a part of option before ':' */
1177 /* Parametric option has following syntax: 'Type: option = value' */
1179 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1181 struct parmlist_entry *data = get_parametrics(snum, type, option);
1183 if (data && data->value && *data->value)
1184 return lp_bool(data->value);
1186 return def;
1189 /* Return parametric option from a given service. Type is a part of option before ':' */
1190 /* Parametric option has following syntax: 'Type: option = value' */
1192 int lp_parm_enum(int snum, const char *type, const char *option,
1193 const struct enum_list *_enum, int def)
1195 struct parmlist_entry *data = get_parametrics(snum, type, option);
1197 if (data && data->value && *data->value && _enum)
1198 return lp_enum(data->value, _enum);
1200 return def;
1204 * free a param_opts structure.
1205 * param_opts handling should be moved to talloc;
1206 * then this whole functions reduces to a TALLOC_FREE().
1209 static void free_param_opts(struct parmlist_entry **popts)
1211 struct parmlist_entry *opt, *next_opt;
1213 if (*popts != NULL) {
1214 DEBUG(5, ("Freeing parametrics:\n"));
1216 opt = *popts;
1217 while (opt != NULL) {
1218 string_free(&opt->key);
1219 string_free(&opt->value);
1220 TALLOC_FREE(opt->list);
1221 next_opt = opt->next;
1222 TALLOC_FREE(opt);
1223 opt = next_opt;
1225 *popts = NULL;
1228 /***************************************************************************
1229 Free the dynamically allocated parts of a service struct.
1230 ***************************************************************************/
1232 static void free_service(struct loadparm_service *pservice)
1234 if (!pservice)
1235 return;
1237 if (pservice->szService)
1238 DEBUG(5, ("free_service: Freeing service %s\n",
1239 pservice->szService));
1241 free_parameters(pservice);
1243 string_free(&pservice->szService);
1244 TALLOC_FREE(pservice->copymap);
1246 free_param_opts(&pservice->param_opt);
1248 ZERO_STRUCTP(pservice);
1252 /***************************************************************************
1253 remove a service indexed in the ServicePtrs array from the ServiceHash
1254 and free the dynamically allocated parts
1255 ***************************************************************************/
1257 static void free_service_byindex(int idx)
1259 if ( !LP_SNUM_OK(idx) )
1260 return;
1262 ServicePtrs[idx]->valid = false;
1264 /* we have to cleanup the hash record */
1266 if (ServicePtrs[idx]->szService) {
1267 char *canon_name = canonicalize_servicename(
1268 talloc_tos(),
1269 ServicePtrs[idx]->szService );
1271 dbwrap_delete_bystring(ServiceHash, canon_name );
1272 TALLOC_FREE(canon_name);
1275 free_service(ServicePtrs[idx]);
1276 talloc_free_children(ServicePtrs[idx]);
1279 /***************************************************************************
1280 Add a new service to the services array initialising it with the given
1281 service.
1282 ***************************************************************************/
1284 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1286 int i;
1287 int num_to_alloc = iNumServices + 1;
1288 struct loadparm_service **tsp = NULL;
1290 /* it might already exist */
1291 if (name) {
1292 i = getservicebyname(name, NULL);
1293 if (i >= 0) {
1294 return (i);
1298 /* if not, then create one */
1299 i = iNumServices;
1300 tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
1301 if (tsp == NULL) {
1302 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1303 return (-1);
1305 ServicePtrs = tsp;
1306 ServicePtrs[iNumServices] = talloc_zero(NULL, struct loadparm_service);
1307 if (!ServicePtrs[iNumServices]) {
1308 DEBUG(0,("add_a_service: out of memory!\n"));
1309 return (-1);
1311 iNumServices++;
1313 ServicePtrs[i]->valid = true;
1315 copy_service(ServicePtrs[i], pservice, NULL);
1316 if (name)
1317 string_set(ServicePtrs[i], &ServicePtrs[i]->szService, name);
1319 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1320 i, ServicePtrs[i]->szService));
1322 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1323 return (-1);
1326 return (i);
1329 /***************************************************************************
1330 Convert a string to uppercase and remove whitespaces.
1331 ***************************************************************************/
1333 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1335 char *result;
1337 if ( !src ) {
1338 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1339 return NULL;
1342 result = talloc_strdup(ctx, src);
1343 SMB_ASSERT(result != NULL);
1345 if (!strlower_m(result)) {
1346 TALLOC_FREE(result);
1347 return NULL;
1349 return result;
1352 /***************************************************************************
1353 Add a name/index pair for the services array to the hash table.
1354 ***************************************************************************/
1356 static bool hash_a_service(const char *name, int idx)
1358 char *canon_name;
1360 if ( !ServiceHash ) {
1361 DEBUG(10,("hash_a_service: creating servicehash\n"));
1362 ServiceHash = db_open_rbt(NULL);
1363 if ( !ServiceHash ) {
1364 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1365 return false;
1369 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1370 idx, name));
1372 canon_name = canonicalize_servicename(talloc_tos(), name );
1374 dbwrap_store_bystring(ServiceHash, canon_name,
1375 make_tdb_data((uint8 *)&idx, sizeof(idx)),
1376 TDB_REPLACE);
1378 TALLOC_FREE(canon_name);
1380 return true;
1383 /***************************************************************************
1384 Add a new home service, with the specified home directory, defaults coming
1385 from service ifrom.
1386 ***************************************************************************/
1388 bool lp_add_home(const char *pszHomename, int iDefaultService,
1389 const char *user, const char *pszHomedir)
1391 int i;
1393 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1394 pszHomedir[0] == '\0') {
1395 return false;
1398 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1400 if (i < 0)
1401 return false;
1403 if (!(*(ServicePtrs[iDefaultService]->path))
1404 || strequal(ServicePtrs[iDefaultService]->path,
1405 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1406 string_set(ServicePtrs[i], &ServicePtrs[i]->path, pszHomedir);
1409 if (!(*(ServicePtrs[i]->comment))) {
1410 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1411 if (comment == NULL) {
1412 return false;
1414 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1415 TALLOC_FREE(comment);
1418 /* set the browseable flag from the global default */
1420 ServicePtrs[i]->browseable = sDefault.browseable;
1421 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1423 ServicePtrs[i]->autoloaded = true;
1425 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1426 user, ServicePtrs[i]->path ));
1428 return true;
1431 /***************************************************************************
1432 Add a new service, based on an old one.
1433 ***************************************************************************/
1435 int lp_add_service(const char *pszService, int iDefaultService)
1437 if (iDefaultService < 0) {
1438 return add_a_service(&sDefault, pszService);
1441 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1444 /***************************************************************************
1445 Add the IPC service.
1446 ***************************************************************************/
1448 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1450 char *comment = NULL;
1451 int i = add_a_service(&sDefault, ipc_name);
1453 if (i < 0)
1454 return false;
1456 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1457 Globals.server_string);
1458 if (comment == NULL) {
1459 return false;
1462 string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1463 string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
1464 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1465 string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1466 ServicePtrs[i]->max_connections = 0;
1467 ServicePtrs[i]->bAvailable = true;
1468 ServicePtrs[i]->read_only = true;
1469 ServicePtrs[i]->guest_only = false;
1470 ServicePtrs[i]->administrative_share = true;
1471 ServicePtrs[i]->guest_ok = guest_ok;
1472 ServicePtrs[i]->printable = false;
1473 ServicePtrs[i]->browseable = sDefault.browseable;
1475 DEBUG(3, ("adding IPC service\n"));
1477 TALLOC_FREE(comment);
1478 return true;
1481 /***************************************************************************
1482 Add a new printer service, with defaults coming from service iFrom.
1483 ***************************************************************************/
1485 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1487 const char *comment = "From Printcap";
1488 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1490 if (i < 0)
1491 return false;
1493 /* note that we do NOT default the availability flag to true - */
1494 /* we take it from the default service passed. This allows all */
1495 /* dynamic printers to be disabled by disabling the [printers] */
1496 /* entry (if/when the 'available' keyword is implemented!). */
1498 /* the printer name is set to the service name. */
1499 string_set(ServicePtrs[i], &ServicePtrs[i]->_printername, pszPrintername);
1500 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1502 /* set the browseable flag from the gloabl default */
1503 ServicePtrs[i]->browseable = sDefault.browseable;
1505 /* Printers cannot be read_only. */
1506 ServicePtrs[i]->read_only = false;
1507 /* No oplocks on printer services. */
1508 ServicePtrs[i]->oplocks = false;
1509 /* Printer services must be printable. */
1510 ServicePtrs[i]->printable = true;
1512 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1514 return true;
1518 /***************************************************************************
1519 Check whether the given parameter name is valid.
1520 Parametric options (names containing a colon) are considered valid.
1521 ***************************************************************************/
1523 bool lp_parameter_is_valid(const char *pszParmName)
1525 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1526 (strchr(pszParmName, ':') != NULL));
1529 /***************************************************************************
1530 Check whether the given name is the name of a global parameter.
1531 Returns true for strings belonging to parameters of class
1532 P_GLOBAL, false for all other strings, also for parametric options
1533 and strings not belonging to any option.
1534 ***************************************************************************/
1536 bool lp_parameter_is_global(const char *pszParmName)
1538 int num = lpcfg_map_parameter(pszParmName);
1540 if (num >= 0) {
1541 return (parm_table[num].p_class == P_GLOBAL);
1544 return false;
1547 /**************************************************************************
1548 Check whether the given name is the canonical name of a parameter.
1549 Returns false if it is not a valid parameter Name.
1550 For parametric options, true is returned.
1551 **************************************************************************/
1553 bool lp_parameter_is_canonical(const char *parm_name)
1555 if (!lp_parameter_is_valid(parm_name)) {
1556 return false;
1559 return (lpcfg_map_parameter(parm_name) ==
1560 map_parameter_canonical(parm_name, NULL));
1563 /**************************************************************************
1564 Determine the canonical name for a parameter.
1565 Indicate when it is an inverse (boolean) synonym instead of a
1566 "usual" synonym.
1567 **************************************************************************/
1569 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1570 bool *inverse)
1572 int num;
1574 if (!lp_parameter_is_valid(parm_name)) {
1575 *canon_parm = NULL;
1576 return false;
1579 num = map_parameter_canonical(parm_name, inverse);
1580 if (num < 0) {
1581 /* parametric option */
1582 *canon_parm = parm_name;
1583 } else {
1584 *canon_parm = parm_table[num].label;
1587 return true;
1591 /**************************************************************************
1592 Determine the canonical name for a parameter.
1593 Turn the value given into the inverse boolean expression when
1594 the synonym is an invers boolean synonym.
1596 Return true if parm_name is a valid parameter name and
1597 in case it is an invers boolean synonym, if the val string could
1598 successfully be converted to the reverse bool.
1599 Return false in all other cases.
1600 **************************************************************************/
1602 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1603 const char *val,
1604 const char **canon_parm,
1605 const char **canon_val)
1607 int num;
1608 bool inverse;
1610 if (!lp_parameter_is_valid(parm_name)) {
1611 *canon_parm = NULL;
1612 *canon_val = NULL;
1613 return false;
1616 num = map_parameter_canonical(parm_name, &inverse);
1617 if (num < 0) {
1618 /* parametric option */
1619 *canon_parm = parm_name;
1620 *canon_val = val;
1621 } else {
1622 *canon_parm = parm_table[num].label;
1623 if (inverse) {
1624 if (!lp_invert_boolean(val, canon_val)) {
1625 *canon_val = NULL;
1626 return false;
1628 } else {
1629 *canon_val = val;
1633 return true;
1636 /***************************************************************************
1637 Map a parameter's string representation to the index of the canonical
1638 form of the parameter (it might be a synonym).
1639 Returns -1 if the parameter string is not recognised.
1640 ***************************************************************************/
1642 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1644 int parm_num, canon_num;
1645 bool loc_inverse = false;
1647 parm_num = lpcfg_map_parameter(pszParmName);
1648 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
1649 /* invalid, parametric or no canidate for synonyms ... */
1650 goto done;
1653 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1654 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1655 parm_num = canon_num;
1656 goto done;
1660 done:
1661 if (inverse != NULL) {
1662 *inverse = loc_inverse;
1664 return parm_num;
1667 /***************************************************************************
1668 return true if parameter number parm1 is a synonym of parameter
1669 number parm2 (parm2 being the principal name).
1670 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1671 false otherwise.
1672 ***************************************************************************/
1674 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1676 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1677 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1678 (parm_table[parm1].flags & FLAG_HIDE) &&
1679 !(parm_table[parm2].flags & FLAG_HIDE))
1681 if (inverse != NULL) {
1682 if ((parm_table[parm1].type == P_BOOLREV) &&
1683 (parm_table[parm2].type == P_BOOL))
1685 *inverse = true;
1686 } else {
1687 *inverse = false;
1690 return true;
1692 return false;
1695 /***************************************************************************
1696 Show one parameter's name, type, [values,] and flags.
1697 (helper functions for show_parameter_list)
1698 ***************************************************************************/
1700 static void show_parameter(int parmIndex)
1702 int enumIndex, flagIndex;
1703 int parmIndex2;
1704 bool hadFlag;
1705 bool hadSyn;
1706 bool inverse;
1707 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1708 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1709 "P_ENUM", "P_SEP"};
1710 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
1711 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
1712 FLAG_HIDE};
1713 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
1714 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
1715 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
1717 printf("%s=%s", parm_table[parmIndex].label,
1718 type[parm_table[parmIndex].type]);
1719 if (parm_table[parmIndex].type == P_ENUM) {
1720 printf(",");
1721 for (enumIndex=0;
1722 parm_table[parmIndex].enum_list[enumIndex].name;
1723 enumIndex++)
1725 printf("%s%s",
1726 enumIndex ? "|" : "",
1727 parm_table[parmIndex].enum_list[enumIndex].name);
1730 printf(",");
1731 hadFlag = false;
1732 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1733 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1734 printf("%s%s",
1735 hadFlag ? "|" : "",
1736 flag_names[flagIndex]);
1737 hadFlag = true;
1741 /* output synonyms */
1742 hadSyn = false;
1743 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1744 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1745 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1746 parm_table[parmIndex2].label);
1747 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1748 if (!hadSyn) {
1749 printf(" (synonyms: ");
1750 hadSyn = true;
1751 } else {
1752 printf(", ");
1754 printf("%s%s", parm_table[parmIndex2].label,
1755 inverse ? "[i]" : "");
1758 if (hadSyn) {
1759 printf(")");
1762 printf("\n");
1765 /***************************************************************************
1766 Show all parameter's name, type, [values,] and flags.
1767 ***************************************************************************/
1769 void show_parameter_list(void)
1771 int classIndex, parmIndex;
1772 const char *section_names[] = { "local", "global", NULL};
1774 for (classIndex=0; section_names[classIndex]; classIndex++) {
1775 printf("[%s]\n", section_names[classIndex]);
1776 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
1777 if (parm_table[parmIndex].p_class == classIndex) {
1778 show_parameter(parmIndex);
1784 /***************************************************************************
1785 Get the standard string representation of a boolean value ("yes" or "no")
1786 ***************************************************************************/
1788 static const char *get_boolean(bool bool_value)
1790 static const char *yes_str = "yes";
1791 static const char *no_str = "no";
1793 return (bool_value ? yes_str : no_str);
1796 /***************************************************************************
1797 Provide the string of the negated boolean value associated to the boolean
1798 given as a string. Returns false if the passed string does not correctly
1799 represent a boolean.
1800 ***************************************************************************/
1802 bool lp_invert_boolean(const char *str, const char **inverse_str)
1804 bool val;
1806 if (!set_boolean(str, &val)) {
1807 return false;
1810 *inverse_str = get_boolean(!val);
1811 return true;
1814 /***************************************************************************
1815 Provide the canonical string representation of a boolean value given
1816 as a string. Return true on success, false if the string given does
1817 not correctly represent a boolean.
1818 ***************************************************************************/
1820 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
1822 bool val;
1824 if (!set_boolean(str, &val)) {
1825 return false;
1828 *canon_str = get_boolean(val);
1829 return true;
1832 /***************************************************************************
1833 Find a service by name. Otherwise works like get_service.
1834 ***************************************************************************/
1836 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
1838 int iService = -1;
1839 char *canon_name;
1840 TDB_DATA data;
1841 NTSTATUS status;
1843 if (ServiceHash == NULL) {
1844 return -1;
1847 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
1849 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
1850 &data);
1852 if (NT_STATUS_IS_OK(status) &&
1853 (data.dptr != NULL) &&
1854 (data.dsize == sizeof(iService)))
1856 iService = *(int *)data.dptr;
1859 TALLOC_FREE(canon_name);
1861 if ((iService != -1) && (LP_SNUM_OK(iService))
1862 && (pserviceDest != NULL)) {
1863 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1866 return (iService);
1869 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
1870 struct loadparm_service *lp_service(const char *pszServiceName)
1872 int iService = getservicebyname(pszServiceName, NULL);
1873 if (iService == -1 || !LP_SNUM_OK(iService)) {
1874 return NULL;
1876 return ServicePtrs[iService];
1879 struct loadparm_service *lp_servicebynum(int snum)
1881 if ((snum == -1) || !LP_SNUM_OK(snum)) {
1882 return NULL;
1884 return ServicePtrs[snum];
1887 struct loadparm_service *lp_default_loadparm_service()
1889 return &sDefault;
1892 static struct smbconf_ctx *lp_smbconf_ctx(void)
1894 sbcErr err;
1895 static struct smbconf_ctx *conf_ctx = NULL;
1897 if (conf_ctx == NULL) {
1898 err = smbconf_init(NULL, &conf_ctx, "registry:");
1899 if (!SBC_ERROR_IS_OK(err)) {
1900 DEBUG(1, ("error initializing registry configuration: "
1901 "%s\n", sbcErrorString(err)));
1902 conf_ctx = NULL;
1906 return conf_ctx;
1909 static bool process_smbconf_service(struct smbconf_service *service)
1911 uint32_t count;
1912 bool ret;
1914 if (service == NULL) {
1915 return false;
1918 ret = lp_do_section(service->name, NULL);
1919 if (ret != true) {
1920 return false;
1922 for (count = 0; count < service->num_params; count++) {
1924 if (!bInGlobalSection && bGlobalOnly) {
1925 ret = true;
1926 } else {
1927 const char *pszParmName = service->param_names[count];
1928 const char *pszParmValue = service->param_values[count];
1930 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
1932 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1933 pszParmName, pszParmValue);
1936 if (ret != true) {
1937 return false;
1940 if (iServiceIndex >= 0) {
1941 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
1943 return true;
1947 * load a service from registry and activate it
1949 bool process_registry_service(const char *service_name)
1951 sbcErr err;
1952 struct smbconf_service *service = NULL;
1953 TALLOC_CTX *mem_ctx = talloc_stackframe();
1954 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
1955 bool ret = false;
1957 if (conf_ctx == NULL) {
1958 goto done;
1961 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
1963 if (!smbconf_share_exists(conf_ctx, service_name)) {
1965 * Registry does not contain data for this service (yet),
1966 * but make sure lp_load doesn't return false.
1968 ret = true;
1969 goto done;
1972 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
1973 if (!SBC_ERROR_IS_OK(err)) {
1974 goto done;
1977 ret = process_smbconf_service(service);
1978 if (!ret) {
1979 goto done;
1982 /* store the csn */
1983 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
1985 done:
1986 TALLOC_FREE(mem_ctx);
1987 return ret;
1991 * process_registry_globals
1993 static bool process_registry_globals(void)
1995 bool ret;
1997 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
1999 if (!bInGlobalSection && bGlobalOnly) {
2000 ret = true;
2001 } else {
2002 const char *pszParmName = "registry shares";
2003 const char *pszParmValue = "yes";
2005 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2007 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2008 pszParmName, pszParmValue);
2011 if (!ret) {
2012 return ret;
2015 return process_registry_service(GLOBAL_NAME);
2018 bool process_registry_shares(void)
2020 sbcErr err;
2021 uint32_t count;
2022 struct smbconf_service **service = NULL;
2023 uint32_t num_shares = 0;
2024 TALLOC_CTX *mem_ctx = talloc_stackframe();
2025 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2026 bool ret = false;
2028 if (conf_ctx == NULL) {
2029 goto done;
2032 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2033 if (!SBC_ERROR_IS_OK(err)) {
2034 goto done;
2037 ret = true;
2039 for (count = 0; count < num_shares; count++) {
2040 if (strequal(service[count]->name, GLOBAL_NAME)) {
2041 continue;
2043 ret = process_smbconf_service(service[count]);
2044 if (!ret) {
2045 goto done;
2049 /* store the csn */
2050 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2052 done:
2053 TALLOC_FREE(mem_ctx);
2054 return ret;
2058 * reload those shares from registry that are already
2059 * activated in the services array.
2061 static bool reload_registry_shares(void)
2063 int i;
2064 bool ret = true;
2066 for (i = 0; i < iNumServices; i++) {
2067 if (!VALID(i)) {
2068 continue;
2071 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2072 continue;
2075 ret = process_registry_service(ServicePtrs[i]->szService);
2076 if (!ret) {
2077 goto done;
2081 done:
2082 return ret;
2086 #define MAX_INCLUDE_DEPTH 100
2088 static uint8_t include_depth;
2091 * Free the file lists
2093 static void free_file_list(void)
2095 struct file_lists *f;
2096 struct file_lists *next;
2098 f = file_lists;
2099 while( f ) {
2100 next = f->next;
2101 TALLOC_FREE( f );
2102 f = next;
2104 file_lists = NULL;
2109 * Utility function for outsiders to check if we're running on registry.
2111 bool lp_config_backend_is_registry(void)
2113 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2117 * Utility function to check if the config backend is FILE.
2119 bool lp_config_backend_is_file(void)
2121 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2124 /*******************************************************************
2125 Check if a config file has changed date.
2126 ********************************************************************/
2128 bool lp_file_list_changed(void)
2130 struct file_lists *f = file_lists;
2132 DEBUG(6, ("lp_file_list_changed()\n"));
2134 while (f) {
2135 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2136 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2138 if (conf_ctx == NULL) {
2139 return false;
2141 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2142 NULL))
2144 DEBUGADD(6, ("registry config changed\n"));
2145 return true;
2147 } else {
2148 time_t mod_time;
2149 char *n2 = NULL;
2151 n2 = talloc_sub_basic(talloc_tos(),
2152 get_current_username(),
2153 current_user_info.domain,
2154 f->name);
2155 if (!n2) {
2156 return false;
2158 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2159 f->name, n2, ctime(&f->modtime)));
2161 mod_time = file_modtime(n2);
2163 if (mod_time &&
2164 ((f->modtime != mod_time) ||
2165 (f->subfname == NULL) ||
2166 (strcmp(n2, f->subfname) != 0)))
2168 DEBUGADD(6,
2169 ("file %s modified: %s\n", n2,
2170 ctime(&mod_time)));
2171 f->modtime = mod_time;
2172 TALLOC_FREE(f->subfname);
2173 f->subfname = talloc_strdup(f, n2);
2174 if (f->subfname == NULL) {
2175 smb_panic("talloc_strdup failed");
2177 TALLOC_FREE(n2);
2178 return true;
2180 TALLOC_FREE(n2);
2182 f = f->next;
2184 return false;
2189 * Initialize iconv conversion descriptors.
2191 * This is called the first time it is needed, and also called again
2192 * every time the configuration is reloaded, because the charset or
2193 * codepage might have changed.
2195 static void init_iconv(void)
2197 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2198 lp_unix_charset(),
2199 true, global_iconv_handle);
2202 /***************************************************************************
2203 Handle the include operation.
2204 ***************************************************************************/
2205 static bool bAllowIncludeRegistry = true;
2207 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2208 const char *pszParmValue, char **ptr)
2210 char *fname;
2212 if (include_depth >= MAX_INCLUDE_DEPTH) {
2213 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2214 include_depth));
2215 return false;
2218 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2219 if (!bAllowIncludeRegistry) {
2220 return true;
2222 if (lp_ctx->bInGlobalSection) {
2223 bool ret;
2224 include_depth++;
2225 ret = process_registry_globals();
2226 include_depth--;
2227 return ret;
2228 } else {
2229 DEBUG(1, ("\"include = registry\" only effective "
2230 "in %s section\n", GLOBAL_NAME));
2231 return false;
2235 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2236 current_user_info.domain,
2237 pszParmValue);
2239 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2241 if (service == NULL) {
2242 string_set(Globals.ctx, ptr, fname);
2243 } else {
2244 string_set(service, ptr, fname);
2247 if (file_exist(fname)) {
2248 bool ret;
2249 include_depth++;
2250 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2251 include_depth--;
2252 TALLOC_FREE(fname);
2253 return ret;
2256 DEBUG(2, ("Can't find include file %s\n", fname));
2257 TALLOC_FREE(fname);
2258 return true;
2261 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2263 char *config_option = NULL;
2264 const char *range = NULL;
2265 bool ret = false;
2267 SMB_ASSERT(low != NULL);
2268 SMB_ASSERT(high != NULL);
2270 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2271 domain_name = "*";
2274 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2275 domain_name);
2276 if (config_option == NULL) {
2277 DEBUG(0, ("out of memory\n"));
2278 return false;
2281 range = lp_parm_const_string(-1, config_option, "range", NULL);
2282 if (range == NULL) {
2283 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2284 goto done;
2287 if (sscanf(range, "%u - %u", low, high) != 2) {
2288 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2289 range, domain_name));
2290 goto done;
2293 ret = true;
2295 done:
2296 talloc_free(config_option);
2297 return ret;
2301 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2303 return lp_idmap_range("*", low, high);
2306 const char *lp_idmap_backend(const char *domain_name)
2308 char *config_option = NULL;
2309 const char *backend = NULL;
2311 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2312 domain_name = "*";
2315 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2316 domain_name);
2317 if (config_option == NULL) {
2318 DEBUG(0, ("out of memory\n"));
2319 return false;
2322 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2323 if (backend == NULL) {
2324 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2325 goto done;
2328 done:
2329 talloc_free(config_option);
2330 return backend;
2333 const char *lp_idmap_default_backend(void)
2335 return lp_idmap_backend("*");
2338 /***************************************************************************
2339 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2340 ***************************************************************************/
2342 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2344 const char *suffix_string;
2346 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2347 Globals.ldap_suffix );
2348 if ( !suffix_string ) {
2349 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2350 return "";
2353 return suffix_string;
2356 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2358 if (Globals.szLdapMachineSuffix[0])
2359 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
2361 return lp_string(ctx, Globals.ldap_suffix);
2364 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2366 if (Globals.szLdapUserSuffix[0])
2367 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
2369 return lp_string(ctx, Globals.ldap_suffix);
2372 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2374 if (Globals.szLdapGroupSuffix[0])
2375 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
2377 return lp_string(ctx, Globals.ldap_suffix);
2380 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2382 if (Globals.szLdapIdmapSuffix[0])
2383 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
2385 return lp_string(ctx, Globals.ldap_suffix);
2389 return the parameter pointer for a parameter
2391 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2393 if (service == NULL) {
2394 if (parm->p_class == P_LOCAL)
2395 return (void *)(((char *)&sDefault)+parm->offset);
2396 else if (parm->p_class == P_GLOBAL)
2397 return (void *)(((char *)&Globals)+parm->offset);
2398 else return NULL;
2399 } else {
2400 return (void *)(((char *)service) + parm->offset);
2404 /***************************************************************************
2405 Process a parameter for a particular service number. If snum < 0
2406 then assume we are in the globals.
2407 ***************************************************************************/
2409 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2411 TALLOC_CTX *frame = talloc_stackframe();
2412 struct loadparm_context *lp_ctx;
2413 bool ok;
2415 lp_ctx = loadparm_init_s3(frame,
2416 loadparm_s3_helpers());
2417 if (lp_ctx == NULL) {
2418 DEBUG(0, ("loadparm_init_s3 failed\n"));
2419 TALLOC_FREE(frame);
2420 return false;
2423 lp_ctx->sDefault = &sDefault;
2424 lp_ctx->services = NULL; /* We do not want to access this directly */
2425 lp_ctx->bInGlobalSection = bInGlobalSection;
2426 lp_ctx->flags = flags_list;
2428 if (snum < 0) {
2429 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2430 } else {
2431 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2432 pszParmName, pszParmValue);
2435 TALLOC_FREE(frame);
2437 return ok;
2440 /***************************************************************************
2441 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2442 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2443 ***************************************************************************/
2445 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2447 int parmnum, i;
2448 parmnum = lpcfg_map_parameter(pszParmName);
2449 if (parmnum >= 0) {
2450 flags_list[parmnum] &= ~FLAG_CMDLINE;
2451 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2452 return false;
2454 flags_list[parmnum] |= FLAG_CMDLINE;
2456 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2457 * be grouped in the table, so we don't have to search the
2458 * whole table */
2459 for (i=parmnum-1;
2460 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2461 && parm_table[i].p_class == parm_table[parmnum].p_class;
2462 i--) {
2463 flags_list[i] |= FLAG_CMDLINE;
2465 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2466 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2467 flags_list[i] |= FLAG_CMDLINE;
2470 return true;
2473 /* it might be parametric */
2474 if (strchr(pszParmName, ':') != NULL) {
2475 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2476 return true;
2479 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2480 return false;
2483 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2485 bool ret;
2486 TALLOC_CTX *frame = talloc_stackframe();
2487 struct loadparm_context *lp_ctx;
2489 lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
2490 if (lp_ctx == NULL) {
2491 DEBUG(0, ("loadparm_init_s3 failed\n"));
2492 return false;
2495 ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
2497 TALLOC_FREE(frame);
2498 return ret;
2501 /***************************************************************************
2502 Process a parameter.
2503 ***************************************************************************/
2505 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2506 void *userdata)
2508 if (!bInGlobalSection && bGlobalOnly)
2509 return true;
2511 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2513 if (bInGlobalSection) {
2514 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2515 } else {
2516 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2517 pszParmName, pszParmValue);
2521 /***************************************************************************
2522 Initialize any local variables in the sDefault table, after parsing a
2523 [globals] section.
2524 ***************************************************************************/
2526 static void init_locals(void)
2529 * We run this check once the [globals] is parsed, to force
2530 * the VFS objects and other per-share settings we need for
2531 * the standard way a AD DC is operated. We may change these
2532 * as our code evolves, which is why we force these settings.
2534 * We can't do this at the end of lp_load_ex(), as by that
2535 * point the services have been loaded and they will already
2536 * have "" as their vfs objects.
2538 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2539 const char **vfs_objects = lp_vfs_objects(-1);
2540 if (!vfs_objects || !vfs_objects[0]) {
2541 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2542 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2543 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2544 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2545 } else {
2546 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2550 lp_do_parameter(-1, "map hidden", "no");
2551 lp_do_parameter(-1, "map system", "no");
2552 lp_do_parameter(-1, "map readonly", "no");
2553 lp_do_parameter(-1, "map archive", "no");
2554 lp_do_parameter(-1, "store dos attributes", "yes");
2558 /***************************************************************************
2559 Process a new section (service). At this stage all sections are services.
2560 Later we'll have special sections that permit server parameters to be set.
2561 Returns true on success, false on failure.
2562 ***************************************************************************/
2564 bool lp_do_section(const char *pszSectionName, void *userdata)
2566 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2567 bool bRetval;
2568 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2569 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2570 bRetval = false;
2572 /* if we were in a global section then do the local inits */
2573 if (bInGlobalSection && !isglobal)
2574 init_locals();
2576 /* if we've just struck a global section, note the fact. */
2577 bInGlobalSection = isglobal;
2578 lp_ctx->bInGlobalSection = isglobal;
2580 /* check for multiple global sections */
2581 if (bInGlobalSection) {
2582 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2583 return true;
2586 if (!bInGlobalSection && bGlobalOnly)
2587 return true;
2589 /* if we have a current service, tidy it up before moving on */
2590 bRetval = true;
2592 if (iServiceIndex >= 0)
2593 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2595 /* if all is still well, move to the next record in the services array */
2596 if (bRetval) {
2597 /* We put this here to avoid an odd message order if messages are */
2598 /* issued by the post-processing of a previous section. */
2599 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2601 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2602 if (iServiceIndex < 0) {
2603 DEBUG(0, ("Failed to add a new service\n"));
2604 return false;
2606 /* Clean all parametric options for service */
2607 /* They will be added during parsing again */
2608 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2611 return bRetval;
2614 /***************************************************************************
2615 Display the contents of a parameter of a single services record.
2616 ***************************************************************************/
2618 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2620 bool result = false;
2622 struct loadparm_context *lp_ctx;
2624 lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
2625 if (lp_ctx == NULL) {
2626 return false;
2629 if (isGlobal) {
2630 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2631 } else {
2632 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2634 TALLOC_FREE(lp_ctx);
2635 return result;
2638 /***************************************************************************
2639 Return info about the requested parameter (given as a string).
2640 Return NULL when the string is not a valid parameter name.
2641 ***************************************************************************/
2643 struct parm_struct *lp_get_parameter(const char *param_name)
2645 int num = lpcfg_map_parameter(param_name);
2647 if (num < 0) {
2648 return NULL;
2651 return &parm_table[num];
2654 #if 0
2655 /***************************************************************************
2656 Display the contents of a single copy structure.
2657 ***************************************************************************/
2658 static void dump_copy_map(bool *pcopymap)
2660 int i;
2661 if (!pcopymap)
2662 return;
2664 printf("\n\tNon-Copied parameters:\n");
2666 for (i = 0; parm_table[i].label; i++)
2667 if (parm_table[i].p_class == P_LOCAL &&
2668 parm_table[i].ptr && !pcopymap[i] &&
2669 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2671 printf("\t\t%s\n", parm_table[i].label);
2674 #endif
2676 /***************************************************************************
2677 Return TRUE if the passed service number is within range.
2678 ***************************************************************************/
2680 bool lp_snum_ok(int iService)
2682 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2685 /***************************************************************************
2686 Auto-load some home services.
2687 ***************************************************************************/
2689 static void lp_add_auto_services(char *str)
2691 char *s;
2692 char *p;
2693 int homes;
2694 char *saveptr;
2696 if (!str)
2697 return;
2699 s = talloc_strdup(talloc_tos(), str);
2700 if (!s) {
2701 smb_panic("talloc_strdup failed");
2702 return;
2705 homes = lp_servicenumber(HOMES_NAME);
2707 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2708 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2709 char *home;
2711 if (lp_servicenumber(p) >= 0)
2712 continue;
2714 home = get_user_home_dir(talloc_tos(), p);
2716 if (home && home[0] && homes >= 0)
2717 lp_add_home(p, homes, p, home);
2719 TALLOC_FREE(home);
2721 TALLOC_FREE(s);
2724 /***************************************************************************
2725 Auto-load one printer.
2726 ***************************************************************************/
2728 void lp_add_one_printer(const char *name, const char *comment,
2729 const char *location, void *pdata)
2731 int printers = lp_servicenumber(PRINTERS_NAME);
2732 int i;
2734 if (lp_servicenumber(name) < 0) {
2735 lp_add_printer(name, printers);
2736 if ((i = lp_servicenumber(name)) >= 0) {
2737 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
2738 ServicePtrs[i]->autoloaded = true;
2743 /***************************************************************************
2744 Have we loaded a services file yet?
2745 ***************************************************************************/
2747 bool lp_loaded(void)
2749 return (bLoaded);
2752 /***************************************************************************
2753 Unload unused services.
2754 ***************************************************************************/
2756 void lp_killunused(struct smbd_server_connection *sconn,
2757 bool (*snumused) (struct smbd_server_connection *, int))
2759 int i;
2760 for (i = 0; i < iNumServices; i++) {
2761 if (!VALID(i))
2762 continue;
2764 /* don't kill autoloaded or usershare services */
2765 if ( ServicePtrs[i]->autoloaded ||
2766 ServicePtrs[i]->usershare == USERSHARE_VALID) {
2767 continue;
2770 if (!snumused || !snumused(sconn, i)) {
2771 free_service_byindex(i);
2777 * Kill all except autoloaded and usershare services - convenience wrapper
2779 void lp_kill_all_services(void)
2781 lp_killunused(NULL, NULL);
2784 /***************************************************************************
2785 Unload a service.
2786 ***************************************************************************/
2788 void lp_killservice(int iServiceIn)
2790 if (VALID(iServiceIn)) {
2791 free_service_byindex(iServiceIn);
2795 /***************************************************************************
2796 Save the curent values of all global and sDefault parameters into the
2797 defaults union. This allows testparm to show only the
2798 changed (ie. non-default) parameters.
2799 ***************************************************************************/
2801 static void lp_save_defaults(void)
2803 int i;
2804 struct parmlist_entry * parm;
2805 for (i = 0; parm_table[i].label; i++) {
2806 if (!(flags_list[i] & FLAG_CMDLINE)) {
2807 flags_list[i] |= FLAG_DEFAULT;
2810 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
2811 && parm_table[i].p_class == parm_table[i - 1].p_class)
2812 continue;
2813 switch (parm_table[i].type) {
2814 case P_LIST:
2815 case P_CMDLIST:
2816 parm_table[i].def.lvalue = str_list_copy(
2817 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
2818 break;
2819 case P_STRING:
2820 case P_USTRING:
2821 parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i]));
2822 if (parm_table[i].def.svalue == NULL) {
2823 smb_panic("talloc_strdup failed");
2825 break;
2826 case P_BOOL:
2827 case P_BOOLREV:
2828 parm_table[i].def.bvalue =
2829 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
2830 break;
2831 case P_CHAR:
2832 parm_table[i].def.cvalue =
2833 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
2834 break;
2835 case P_INTEGER:
2836 case P_OCTAL:
2837 case P_ENUM:
2838 case P_BYTES:
2839 parm_table[i].def.ivalue =
2840 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
2841 break;
2842 case P_SEP:
2843 break;
2847 for (parm=Globals.param_opt; parm; parm=parm->next) {
2848 if (!(parm->priority & FLAG_CMDLINE)) {
2849 parm->priority |= FLAG_DEFAULT;
2853 for (parm=sDefault.param_opt; parm; parm=parm->next) {
2854 if (!(parm->priority & FLAG_CMDLINE)) {
2855 parm->priority |= FLAG_DEFAULT;
2859 defaults_saved = true;
2862 /***********************************************************
2863 If we should send plaintext/LANMAN passwords in the clinet
2864 ************************************************************/
2866 static void set_allowed_client_auth(void)
2868 if (Globals.client_ntlmv2_auth) {
2869 Globals.client_lanman_auth = false;
2871 if (!Globals.client_lanman_auth) {
2872 Globals.client_plaintext_auth = false;
2876 /***************************************************************************
2877 JRA.
2878 The following code allows smbd to read a user defined share file.
2879 Yes, this is my intent. Yes, I'm comfortable with that...
2881 THE FOLLOWING IS SECURITY CRITICAL CODE.
2883 It washes your clothes, it cleans your house, it guards you while you sleep...
2884 Do not f%^k with it....
2885 ***************************************************************************/
2887 #define MAX_USERSHARE_FILE_SIZE (10*1024)
2889 /***************************************************************************
2890 Check allowed stat state of a usershare file.
2891 Ensure we print out who is dicking with us so the admin can
2892 get their sorry ass fired.
2893 ***************************************************************************/
2895 static bool check_usershare_stat(const char *fname,
2896 const SMB_STRUCT_STAT *psbuf)
2898 if (!S_ISREG(psbuf->st_ex_mode)) {
2899 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2900 "not a regular file\n",
2901 fname, (unsigned int)psbuf->st_ex_uid ));
2902 return false;
2905 /* Ensure this doesn't have the other write bit set. */
2906 if (psbuf->st_ex_mode & S_IWOTH) {
2907 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
2908 "public write. Refusing to allow as a usershare file.\n",
2909 fname, (unsigned int)psbuf->st_ex_uid ));
2910 return false;
2913 /* Should be 10k or less. */
2914 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
2915 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2916 "too large (%u) to be a user share file.\n",
2917 fname, (unsigned int)psbuf->st_ex_uid,
2918 (unsigned int)psbuf->st_ex_size ));
2919 return false;
2922 return true;
2925 /***************************************************************************
2926 Parse the contents of a usershare file.
2927 ***************************************************************************/
2929 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
2930 SMB_STRUCT_STAT *psbuf,
2931 const char *servicename,
2932 int snum,
2933 char **lines,
2934 int numlines,
2935 char **pp_sharepath,
2936 char **pp_comment,
2937 char **pp_cp_servicename,
2938 struct security_descriptor **ppsd,
2939 bool *pallow_guest)
2941 const char **prefixallowlist = lp_usershare_prefix_allow_list();
2942 const char **prefixdenylist = lp_usershare_prefix_deny_list();
2943 int us_vers;
2944 DIR *dp;
2945 SMB_STRUCT_STAT sbuf;
2946 char *sharepath = NULL;
2947 char *comment = NULL;
2949 *pp_sharepath = NULL;
2950 *pp_comment = NULL;
2952 *pallow_guest = false;
2954 if (numlines < 4) {
2955 return USERSHARE_MALFORMED_FILE;
2958 if (strcmp(lines[0], "#VERSION 1") == 0) {
2959 us_vers = 1;
2960 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
2961 us_vers = 2;
2962 if (numlines < 5) {
2963 return USERSHARE_MALFORMED_FILE;
2965 } else {
2966 return USERSHARE_BAD_VERSION;
2969 if (strncmp(lines[1], "path=", 5) != 0) {
2970 return USERSHARE_MALFORMED_PATH;
2973 sharepath = talloc_strdup(ctx, &lines[1][5]);
2974 if (!sharepath) {
2975 return USERSHARE_POSIX_ERR;
2977 trim_string(sharepath, " ", " ");
2979 if (strncmp(lines[2], "comment=", 8) != 0) {
2980 return USERSHARE_MALFORMED_COMMENT_DEF;
2983 comment = talloc_strdup(ctx, &lines[2][8]);
2984 if (!comment) {
2985 return USERSHARE_POSIX_ERR;
2987 trim_string(comment, " ", " ");
2988 trim_char(comment, '"', '"');
2990 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
2991 return USERSHARE_MALFORMED_ACL_DEF;
2994 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
2995 return USERSHARE_ACL_ERR;
2998 if (us_vers == 2) {
2999 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3000 return USERSHARE_MALFORMED_ACL_DEF;
3002 if (lines[4][9] == 'y') {
3003 *pallow_guest = true;
3006 /* Backwards compatible extension to file version #2. */
3007 if (numlines > 5) {
3008 if (strncmp(lines[5], "sharename=", 10) != 0) {
3009 return USERSHARE_MALFORMED_SHARENAME_DEF;
3011 if (!strequal(&lines[5][10], servicename)) {
3012 return USERSHARE_BAD_SHARENAME;
3014 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3015 if (!*pp_cp_servicename) {
3016 return USERSHARE_POSIX_ERR;
3021 if (*pp_cp_servicename == NULL) {
3022 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3023 if (!*pp_cp_servicename) {
3024 return USERSHARE_POSIX_ERR;
3028 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3029 /* Path didn't change, no checks needed. */
3030 *pp_sharepath = sharepath;
3031 *pp_comment = comment;
3032 return USERSHARE_OK;
3035 /* The path *must* be absolute. */
3036 if (sharepath[0] != '/') {
3037 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3038 servicename, sharepath));
3039 return USERSHARE_PATH_NOT_ABSOLUTE;
3042 /* If there is a usershare prefix deny list ensure one of these paths
3043 doesn't match the start of the user given path. */
3044 if (prefixdenylist) {
3045 int i;
3046 for ( i=0; prefixdenylist[i]; i++ ) {
3047 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3048 servicename, i, prefixdenylist[i], sharepath ));
3049 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3050 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3051 "usershare prefix deny list entries.\n",
3052 servicename, sharepath));
3053 return USERSHARE_PATH_IS_DENIED;
3058 /* If there is a usershare prefix allow list ensure one of these paths
3059 does match the start of the user given path. */
3061 if (prefixallowlist) {
3062 int i;
3063 for ( i=0; prefixallowlist[i]; i++ ) {
3064 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3065 servicename, i, prefixallowlist[i], sharepath ));
3066 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3067 break;
3070 if (prefixallowlist[i] == NULL) {
3071 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3072 "usershare prefix allow list entries.\n",
3073 servicename, sharepath));
3074 return USERSHARE_PATH_NOT_ALLOWED;
3078 /* Ensure this is pointing to a directory. */
3079 dp = opendir(sharepath);
3081 if (!dp) {
3082 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3083 servicename, sharepath));
3084 return USERSHARE_PATH_NOT_DIRECTORY;
3087 /* Ensure the owner of the usershare file has permission to share
3088 this directory. */
3090 if (sys_stat(sharepath, &sbuf, false) == -1) {
3091 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3092 servicename, sharepath, strerror(errno) ));
3093 closedir(dp);
3094 return USERSHARE_POSIX_ERR;
3097 closedir(dp);
3099 if (!S_ISDIR(sbuf.st_ex_mode)) {
3100 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3101 servicename, sharepath ));
3102 return USERSHARE_PATH_NOT_DIRECTORY;
3105 /* Check if sharing is restricted to owner-only. */
3106 /* psbuf is the stat of the usershare definition file,
3107 sbuf is the stat of the target directory to be shared. */
3109 if (lp_usershare_owner_only()) {
3110 /* root can share anything. */
3111 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3112 return USERSHARE_PATH_NOT_ALLOWED;
3116 *pp_sharepath = sharepath;
3117 *pp_comment = comment;
3118 return USERSHARE_OK;
3121 /***************************************************************************
3122 Deal with a usershare file.
3123 Returns:
3124 >= 0 - snum
3125 -1 - Bad name, invalid contents.
3126 - service name already existed and not a usershare, problem
3127 with permissions to share directory etc.
3128 ***************************************************************************/
3130 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3132 SMB_STRUCT_STAT sbuf;
3133 SMB_STRUCT_STAT lsbuf;
3134 char *fname = NULL;
3135 char *sharepath = NULL;
3136 char *comment = NULL;
3137 char *cp_service_name = NULL;
3138 char **lines = NULL;
3139 int numlines = 0;
3140 int fd = -1;
3141 int iService = -1;
3142 TALLOC_CTX *ctx = talloc_stackframe();
3143 struct security_descriptor *psd = NULL;
3144 bool guest_ok = false;
3145 char *canon_name = NULL;
3146 bool added_service = false;
3147 int ret = -1;
3149 /* Ensure share name doesn't contain invalid characters. */
3150 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3151 DEBUG(0,("process_usershare_file: share name %s contains "
3152 "invalid characters (any of %s)\n",
3153 file_name, INVALID_SHARENAME_CHARS ));
3154 goto out;
3157 canon_name = canonicalize_servicename(ctx, file_name);
3158 if (!canon_name) {
3159 goto out;
3162 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3163 if (!fname) {
3164 goto out;
3167 /* Minimize the race condition by doing an lstat before we
3168 open and fstat. Ensure this isn't a symlink link. */
3170 if (sys_lstat(fname, &lsbuf, false) != 0) {
3171 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3172 fname, strerror(errno) ));
3173 goto out;
3176 /* This must be a regular file, not a symlink, directory or
3177 other strange filetype. */
3178 if (!check_usershare_stat(fname, &lsbuf)) {
3179 goto out;
3183 TDB_DATA data;
3184 NTSTATUS status;
3186 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3187 canon_name, &data);
3189 iService = -1;
3191 if (NT_STATUS_IS_OK(status) &&
3192 (data.dptr != NULL) &&
3193 (data.dsize == sizeof(iService))) {
3194 memcpy(&iService, data.dptr, sizeof(iService));
3198 if (iService != -1 &&
3199 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3200 &lsbuf.st_ex_mtime) == 0) {
3201 /* Nothing changed - Mark valid and return. */
3202 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3203 canon_name ));
3204 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3205 ret = iService;
3206 goto out;
3209 /* Try and open the file read only - no symlinks allowed. */
3210 #ifdef O_NOFOLLOW
3211 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3212 #else
3213 fd = open(fname, O_RDONLY, 0);
3214 #endif
3216 if (fd == -1) {
3217 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3218 fname, strerror(errno) ));
3219 goto out;
3222 /* Now fstat to be *SURE* it's a regular file. */
3223 if (sys_fstat(fd, &sbuf, false) != 0) {
3224 close(fd);
3225 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3226 fname, strerror(errno) ));
3227 goto out;
3230 /* Is it the same dev/inode as was lstated ? */
3231 if (!check_same_stat(&lsbuf, &sbuf)) {
3232 close(fd);
3233 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3234 "Symlink spoofing going on ?\n", fname ));
3235 goto out;
3238 /* This must be a regular file, not a symlink, directory or
3239 other strange filetype. */
3240 if (!check_usershare_stat(fname, &sbuf)) {
3241 close(fd);
3242 goto out;
3245 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3247 close(fd);
3248 if (lines == NULL) {
3249 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3250 fname, (unsigned int)sbuf.st_ex_uid ));
3251 goto out;
3254 if (parse_usershare_file(ctx, &sbuf, file_name,
3255 iService, lines, numlines, &sharepath,
3256 &comment, &cp_service_name,
3257 &psd, &guest_ok) != USERSHARE_OK) {
3258 goto out;
3261 /* Everything ok - add the service possibly using a template. */
3262 if (iService < 0) {
3263 const struct loadparm_service *sp = &sDefault;
3264 if (snum_template != -1) {
3265 sp = ServicePtrs[snum_template];
3268 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3269 DEBUG(0, ("process_usershare_file: Failed to add "
3270 "new service %s\n", cp_service_name));
3271 goto out;
3274 added_service = true;
3276 /* Read only is controlled by usershare ACL below. */
3277 ServicePtrs[iService]->read_only = false;
3280 /* Write the ACL of the new/modified share. */
3281 if (!set_share_security(canon_name, psd)) {
3282 DEBUG(0, ("process_usershare_file: Failed to set share "
3283 "security for user share %s\n",
3284 canon_name ));
3285 goto out;
3288 /* If from a template it may be marked invalid. */
3289 ServicePtrs[iService]->valid = true;
3291 /* Set the service as a valid usershare. */
3292 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3294 /* Set guest access. */
3295 if (lp_usershare_allow_guests()) {
3296 ServicePtrs[iService]->guest_ok = guest_ok;
3299 /* And note when it was loaded. */
3300 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3301 string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath);
3302 string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment);
3304 ret = iService;
3306 out:
3308 if (ret == -1 && iService != -1 && added_service) {
3309 lp_remove_service(iService);
3312 TALLOC_FREE(lines);
3313 TALLOC_FREE(ctx);
3314 return ret;
3317 /***************************************************************************
3318 Checks if a usershare entry has been modified since last load.
3319 ***************************************************************************/
3321 static bool usershare_exists(int iService, struct timespec *last_mod)
3323 SMB_STRUCT_STAT lsbuf;
3324 const char *usersharepath = Globals.usershare_path;
3325 char *fname;
3327 fname = talloc_asprintf(talloc_tos(),
3328 "%s/%s",
3329 usersharepath,
3330 ServicePtrs[iService]->szService);
3331 if (fname == NULL) {
3332 return false;
3335 if (sys_lstat(fname, &lsbuf, false) != 0) {
3336 TALLOC_FREE(fname);
3337 return false;
3340 if (!S_ISREG(lsbuf.st_ex_mode)) {
3341 TALLOC_FREE(fname);
3342 return false;
3345 TALLOC_FREE(fname);
3346 *last_mod = lsbuf.st_ex_mtime;
3347 return true;
3350 /***************************************************************************
3351 Load a usershare service by name. Returns a valid servicenumber or -1.
3352 ***************************************************************************/
3354 int load_usershare_service(const char *servicename)
3356 SMB_STRUCT_STAT sbuf;
3357 const char *usersharepath = Globals.usershare_path;
3358 int max_user_shares = Globals.usershare_max_shares;
3359 int snum_template = -1;
3361 if (*usersharepath == 0 || max_user_shares == 0) {
3362 return -1;
3365 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3366 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3367 usersharepath, strerror(errno) ));
3368 return -1;
3371 if (!S_ISDIR(sbuf.st_ex_mode)) {
3372 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3373 usersharepath ));
3374 return -1;
3378 * This directory must be owned by root, and have the 't' bit set.
3379 * It also must not be writable by "other".
3382 #ifdef S_ISVTX
3383 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3384 #else
3385 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3386 #endif
3387 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3388 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3389 usersharepath ));
3390 return -1;
3393 /* Ensure the template share exists if it's set. */
3394 if (Globals.usershare_template_share[0]) {
3395 /* We can't use lp_servicenumber here as we are recommending that
3396 template shares have -valid=false set. */
3397 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3398 if (ServicePtrs[snum_template]->szService &&
3399 strequal(ServicePtrs[snum_template]->szService,
3400 Globals.usershare_template_share)) {
3401 break;
3405 if (snum_template == -1) {
3406 DEBUG(0,("load_usershare_service: usershare template share %s "
3407 "does not exist.\n",
3408 Globals.usershare_template_share ));
3409 return -1;
3413 return process_usershare_file(usersharepath, servicename, snum_template);
3416 /***************************************************************************
3417 Load all user defined shares from the user share directory.
3418 We only do this if we're enumerating the share list.
3419 This is the function that can delete usershares that have
3420 been removed.
3421 ***************************************************************************/
3423 int load_usershare_shares(struct smbd_server_connection *sconn,
3424 bool (*snumused) (struct smbd_server_connection *, int))
3426 DIR *dp;
3427 SMB_STRUCT_STAT sbuf;
3428 struct dirent *de;
3429 int num_usershares = 0;
3430 int max_user_shares = Globals.usershare_max_shares;
3431 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3432 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3433 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3434 int iService;
3435 int snum_template = -1;
3436 const char *usersharepath = Globals.usershare_path;
3437 int ret = lp_numservices();
3438 TALLOC_CTX *tmp_ctx;
3440 if (max_user_shares == 0 || *usersharepath == '\0') {
3441 return lp_numservices();
3444 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3445 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3446 usersharepath, strerror(errno) ));
3447 return ret;
3451 * This directory must be owned by root, and have the 't' bit set.
3452 * It also must not be writable by "other".
3455 #ifdef S_ISVTX
3456 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3457 #else
3458 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3459 #endif
3460 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3461 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3462 usersharepath ));
3463 return ret;
3466 /* Ensure the template share exists if it's set. */
3467 if (Globals.usershare_template_share[0]) {
3468 /* We can't use lp_servicenumber here as we are recommending that
3469 template shares have -valid=false set. */
3470 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3471 if (ServicePtrs[snum_template]->szService &&
3472 strequal(ServicePtrs[snum_template]->szService,
3473 Globals.usershare_template_share)) {
3474 break;
3478 if (snum_template == -1) {
3479 DEBUG(0,("load_usershare_shares: usershare template share %s "
3480 "does not exist.\n",
3481 Globals.usershare_template_share ));
3482 return ret;
3486 /* Mark all existing usershares as pending delete. */
3487 for (iService = iNumServices - 1; iService >= 0; iService--) {
3488 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3489 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3493 dp = opendir(usersharepath);
3494 if (!dp) {
3495 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3496 usersharepath, strerror(errno) ));
3497 return ret;
3500 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3501 (de = readdir(dp));
3502 num_dir_entries++ ) {
3503 int r;
3504 const char *n = de->d_name;
3506 /* Ignore . and .. */
3507 if (*n == '.') {
3508 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3509 continue;
3513 if (n[0] == ':') {
3514 /* Temporary file used when creating a share. */
3515 num_tmp_dir_entries++;
3518 /* Allow 20% tmp entries. */
3519 if (num_tmp_dir_entries > allowed_tmp_entries) {
3520 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3521 "in directory %s\n",
3522 num_tmp_dir_entries, usersharepath));
3523 break;
3526 r = process_usershare_file(usersharepath, n, snum_template);
3527 if (r == 0) {
3528 /* Update the services count. */
3529 num_usershares++;
3530 if (num_usershares >= max_user_shares) {
3531 DEBUG(0,("load_usershare_shares: max user shares reached "
3532 "on file %s in directory %s\n",
3533 n, usersharepath ));
3534 break;
3536 } else if (r == -1) {
3537 num_bad_dir_entries++;
3540 /* Allow 20% bad entries. */
3541 if (num_bad_dir_entries > allowed_bad_entries) {
3542 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3543 "in directory %s\n",
3544 num_bad_dir_entries, usersharepath));
3545 break;
3548 /* Allow 20% bad entries. */
3549 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3550 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3551 "in directory %s\n",
3552 num_dir_entries, usersharepath));
3553 break;
3557 closedir(dp);
3559 /* Sweep through and delete any non-refreshed usershares that are
3560 not currently in use. */
3561 tmp_ctx = talloc_stackframe();
3562 for (iService = iNumServices - 1; iService >= 0; iService--) {
3563 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3564 char *servname;
3566 if (snumused && snumused(sconn, iService)) {
3567 continue;
3570 servname = lp_servicename(tmp_ctx, iService);
3572 /* Remove from the share ACL db. */
3573 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3574 servname ));
3575 delete_share_security(servname);
3576 free_service_byindex(iService);
3579 talloc_free(tmp_ctx);
3581 return lp_numservices();
3584 /********************************************************
3585 Destroy global resources allocated in this file
3586 ********************************************************/
3588 void gfree_loadparm(void)
3590 int i;
3592 free_file_list();
3594 /* Free resources allocated to services */
3596 for ( i = 0; i < iNumServices; i++ ) {
3597 if ( VALID(i) ) {
3598 free_service_byindex(i);
3602 TALLOC_FREE( ServicePtrs );
3603 iNumServices = 0;
3605 /* Now release all resources allocated to global
3606 parameters and the default service */
3608 free_global_parameters();
3612 /***************************************************************************
3613 Allow client apps to specify that they are a client
3614 ***************************************************************************/
3615 static void lp_set_in_client(bool b)
3617 in_client = b;
3621 /***************************************************************************
3622 Determine if we're running in a client app
3623 ***************************************************************************/
3624 static bool lp_is_in_client(void)
3626 return in_client;
3629 /***************************************************************************
3630 Load the services array from the services file. Return true on success,
3631 false on failure.
3632 ***************************************************************************/
3634 static bool lp_load_ex(const char *pszFname,
3635 bool global_only,
3636 bool save_defaults,
3637 bool add_ipc,
3638 bool initialize_globals,
3639 bool allow_include_registry,
3640 bool load_all_shares)
3642 char *n2 = NULL;
3643 bool bRetval;
3644 TALLOC_CTX *frame = talloc_stackframe();
3645 struct loadparm_context *lp_ctx;
3647 bRetval = false;
3649 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3651 bInGlobalSection = true;
3652 bGlobalOnly = global_only;
3653 bAllowIncludeRegistry = allow_include_registry;
3655 lp_ctx = loadparm_init_s3(talloc_tos(),
3656 loadparm_s3_helpers());
3658 lp_ctx->sDefault = &sDefault;
3659 lp_ctx->bInGlobalSection = bInGlobalSection;
3661 init_globals(lp_ctx, initialize_globals);
3663 free_file_list();
3665 if (save_defaults) {
3666 init_locals();
3667 lp_save_defaults();
3670 if (!initialize_globals) {
3671 free_param_opts(&Globals.param_opt);
3672 apply_lp_set_cmdline();
3675 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
3677 /* We get sections first, so have to start 'behind' to make up */
3678 iServiceIndex = -1;
3680 if (lp_config_backend_is_file()) {
3681 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
3682 current_user_info.domain,
3683 pszFname);
3684 if (!n2) {
3685 smb_panic("lp_load_ex: out of memory");
3688 add_to_file_list(NULL, &file_lists, pszFname, n2);
3690 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
3691 TALLOC_FREE(n2);
3693 /* finish up the last section */
3694 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3695 if (bRetval) {
3696 if (iServiceIndex >= 0) {
3697 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
3701 if (lp_config_backend_is_registry()) {
3702 bool ok;
3703 /* config backend changed to registry in config file */
3705 * We need to use this extra global variable here to
3706 * survive restart: init_globals uses this as a default
3707 * for config_backend. Otherwise, init_globals would
3708 * send us into an endless loop here.
3711 config_backend = CONFIG_BACKEND_REGISTRY;
3712 /* start over */
3713 DEBUG(1, ("lp_load_ex: changing to config backend "
3714 "registry\n"));
3715 init_globals(lp_ctx, true);
3717 TALLOC_FREE(lp_ctx);
3719 lp_kill_all_services();
3720 ok = lp_load_ex(pszFname, global_only, save_defaults,
3721 add_ipc, initialize_globals,
3722 allow_include_registry,
3723 load_all_shares);
3724 TALLOC_FREE(frame);
3725 return ok;
3727 } else if (lp_config_backend_is_registry()) {
3728 bRetval = process_registry_globals();
3729 } else {
3730 DEBUG(0, ("Illegal config backend given: %d\n",
3731 lp_config_backend()));
3732 bRetval = false;
3735 if (bRetval && lp_registry_shares()) {
3736 if (load_all_shares) {
3737 bRetval = process_registry_shares();
3738 } else {
3739 bRetval = reload_registry_shares();
3744 char *serv = lp_auto_services(talloc_tos());
3745 lp_add_auto_services(serv);
3746 TALLOC_FREE(serv);
3749 if (add_ipc) {
3750 /* When 'restrict anonymous = 2' guest connections to ipc$
3751 are denied */
3752 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3753 if ( lp_enable_asu_support() ) {
3754 lp_add_ipc("ADMIN$", false);
3758 set_allowed_client_auth();
3760 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
3761 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
3762 lp_password_server()));
3765 bLoaded = true;
3767 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
3768 /* if we_are_a_wins_server is true and we are in the client */
3769 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
3770 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3773 init_iconv();
3775 fault_configure(smb_panic_s3);
3778 * We run this check once the whole smb.conf is parsed, to
3779 * force some settings for the standard way a AD DC is
3780 * operated. We may changed these as our code evolves, which
3781 * is why we force these settings.
3783 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3784 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
3786 lp_do_parameter(-1, "winbindd:use external pipes", "true");
3788 lp_do_parameter(-1, "rpc_server:default", "external");
3789 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
3790 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
3791 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
3792 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
3793 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
3794 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
3795 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
3796 lp_do_parameter(-1, "rpc_server:tcpip", "no");
3799 bAllowIncludeRegistry = true;
3801 TALLOC_FREE(frame);
3802 return (bRetval);
3805 bool lp_load(const char *pszFname,
3806 bool global_only,
3807 bool save_defaults,
3808 bool add_ipc,
3809 bool initialize_globals)
3811 return lp_load_ex(pszFname,
3812 global_only,
3813 save_defaults,
3814 add_ipc,
3815 initialize_globals,
3816 true, /* allow_include_registry */
3817 false); /* load_all_shares*/
3820 bool lp_load_initial_only(const char *pszFname)
3822 return lp_load_ex(pszFname,
3823 true, /* global only */
3824 false, /* save_defaults */
3825 false, /* add_ipc */
3826 true, /* initialize_globals */
3827 false, /* allow_include_registry */
3828 false); /* load_all_shares*/
3832 * most common lp_load wrapper, loading only the globals
3834 bool lp_load_global(const char *file_name)
3836 return lp_load_ex(file_name,
3837 true, /* global_only */
3838 false, /* save_defaults */
3839 false, /* add_ipc */
3840 true, /* initialize_globals */
3841 true, /* allow_include_registry */
3842 false); /* load_all_shares*/
3846 * lp_load wrapper, especially for clients
3848 bool lp_load_client(const char *file_name)
3850 lp_set_in_client(true);
3852 return lp_load_global(file_name);
3856 * lp_load wrapper, loading only globals, but intended
3857 * for subsequent calls, not reinitializing the globals
3858 * to default values
3860 bool lp_load_global_no_reinit(const char *file_name)
3862 return lp_load_ex(file_name,
3863 true, /* global_only */
3864 false, /* save_defaults */
3865 false, /* add_ipc */
3866 false, /* initialize_globals */
3867 true, /* allow_include_registry */
3868 false); /* load_all_shares*/
3872 * lp_load wrapper, especially for clients, no reinitialization
3874 bool lp_load_client_no_reinit(const char *file_name)
3876 lp_set_in_client(true);
3878 return lp_load_global_no_reinit(file_name);
3881 bool lp_load_with_registry_shares(const char *pszFname,
3882 bool global_only,
3883 bool save_defaults,
3884 bool add_ipc,
3885 bool initialize_globals)
3887 return lp_load_ex(pszFname,
3888 global_only,
3889 save_defaults,
3890 add_ipc,
3891 initialize_globals,
3892 true, /* allow_include_registry */
3893 true); /* load_all_shares*/
3896 /***************************************************************************
3897 Return the max number of services.
3898 ***************************************************************************/
3900 int lp_numservices(void)
3902 return (iNumServices);
3905 /***************************************************************************
3906 Display the contents of the services array in human-readable form.
3907 ***************************************************************************/
3909 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
3911 int iService;
3912 struct loadparm_context *lp_ctx;
3914 if (show_defaults)
3915 defaults_saved = false;
3917 lp_ctx = loadparm_init_s3(talloc_tos(),
3918 loadparm_s3_helpers());
3919 if (lp_ctx == NULL) {
3920 DEBUG(0, ("loadparm_init_s3 failed\n"));
3921 return;
3924 lp_ctx->sDefault = &sDefault;
3925 lp_ctx->services = ServicePtrs;
3927 lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
3929 lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
3931 for (iService = 0; iService < maxtoprint; iService++) {
3932 fprintf(f,"\n");
3933 lp_dump_one(f, show_defaults, iService);
3937 /***************************************************************************
3938 Display the contents of one service in human-readable form.
3939 ***************************************************************************/
3941 void lp_dump_one(FILE * f, bool show_defaults, int snum)
3943 if (VALID(snum)) {
3944 if (ServicePtrs[snum]->szService[0] == '\0')
3945 return;
3946 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
3947 flags_list, show_defaults);
3951 /***************************************************************************
3952 Return the number of the service with the given name, or -1 if it doesn't
3953 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3954 getservicebyname()! This works ONLY if all services have been loaded, and
3955 does not copy the found service.
3956 ***************************************************************************/
3958 int lp_servicenumber(const char *pszServiceName)
3960 int iService;
3961 fstring serviceName;
3963 if (!pszServiceName) {
3964 return GLOBAL_SECTION_SNUM;
3967 for (iService = iNumServices - 1; iService >= 0; iService--) {
3968 if (VALID(iService) && ServicePtrs[iService]->szService) {
3970 * The substitution here is used to support %U is
3971 * service names
3973 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3974 standard_sub_basic(get_current_username(),
3975 current_user_info.domain,
3976 serviceName,sizeof(serviceName));
3977 if (strequal(serviceName, pszServiceName)) {
3978 break;
3983 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
3984 struct timespec last_mod;
3986 if (!usershare_exists(iService, &last_mod)) {
3987 /* Remove the share security tdb entry for it. */
3988 delete_share_security(lp_servicename(talloc_tos(), iService));
3989 /* Remove it from the array. */
3990 free_service_byindex(iService);
3991 /* Doesn't exist anymore. */
3992 return GLOBAL_SECTION_SNUM;
3995 /* Has it been modified ? If so delete and reload. */
3996 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3997 &last_mod) < 0) {
3998 /* Remove it from the array. */
3999 free_service_byindex(iService);
4000 /* and now reload it. */
4001 iService = load_usershare_service(pszServiceName);
4005 if (iService < 0) {
4006 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4007 return GLOBAL_SECTION_SNUM;
4010 return (iService);
4013 /*******************************************************************
4014 A useful volume label function.
4015 ********************************************************************/
4017 const char *volume_label(TALLOC_CTX *ctx, int snum)
4019 char *ret;
4020 const char *label = lp_volume(ctx, snum);
4021 if (!*label) {
4022 label = lp_servicename(ctx, snum);
4025 /* This returns a 33 byte guarenteed null terminated string. */
4026 ret = talloc_strndup(ctx, label, 32);
4027 if (!ret) {
4028 return "";
4030 return ret;
4033 /*******************************************************************
4034 Get the default server type we will announce as via nmbd.
4035 ********************************************************************/
4037 int lp_default_server_announce(void)
4039 int default_server_announce = 0;
4040 default_server_announce |= SV_TYPE_WORKSTATION;
4041 default_server_announce |= SV_TYPE_SERVER;
4042 default_server_announce |= SV_TYPE_SERVER_UNIX;
4044 /* note that the flag should be set only if we have a
4045 printer service but nmbd doesn't actually load the
4046 services so we can't tell --jerry */
4048 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4050 default_server_announce |= SV_TYPE_SERVER_NT;
4051 default_server_announce |= SV_TYPE_NT;
4053 switch (lp_server_role()) {
4054 case ROLE_DOMAIN_MEMBER:
4055 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4056 break;
4057 case ROLE_DOMAIN_PDC:
4058 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4059 break;
4060 case ROLE_DOMAIN_BDC:
4061 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4062 break;
4063 case ROLE_STANDALONE:
4064 default:
4065 break;
4067 if (lp_time_server())
4068 default_server_announce |= SV_TYPE_TIME_SOURCE;
4070 if (lp_host_msdfs())
4071 default_server_announce |= SV_TYPE_DFS_SERVER;
4073 return default_server_announce;
4076 /***********************************************************
4077 If we are PDC then prefer us as DMB
4078 ************************************************************/
4080 bool lp_domain_master(void)
4082 if (Globals._domain_master == Auto)
4083 return (lp_server_role() == ROLE_DOMAIN_PDC);
4085 return (bool)Globals._domain_master;
4088 /***********************************************************
4089 If we are PDC then prefer us as DMB
4090 ************************************************************/
4092 static bool lp_domain_master_true_or_auto(void)
4094 if (Globals._domain_master) /* auto or yes */
4095 return true;
4097 return false;
4100 /***********************************************************
4101 If we are DMB then prefer us as LMB
4102 ************************************************************/
4104 bool lp_preferred_master(void)
4106 if (Globals.iPreferredMaster == Auto)
4107 return (lp_local_master() && lp_domain_master());
4109 return (bool)Globals.iPreferredMaster;
4112 /*******************************************************************
4113 Remove a service.
4114 ********************************************************************/
4116 void lp_remove_service(int snum)
4118 ServicePtrs[snum]->valid = false;
4121 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4123 const char *ret = lp__printername(ctx, snum);
4124 if (ret == NULL || *ret == '\0') {
4125 ret = lp_const_servicename(snum);
4128 return ret;
4132 /***********************************************************
4133 Allow daemons such as winbindd to fix their logfile name.
4134 ************************************************************/
4136 void lp_set_logfile(const char *name)
4138 string_set(Globals.ctx, &Globals.logfile, name);
4139 debug_set_logfile(name);
4142 /*******************************************************************
4143 Return the max print jobs per queue.
4144 ********************************************************************/
4146 int lp_maxprintjobs(int snum)
4148 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4149 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4150 maxjobs = PRINT_MAX_JOBID - 1;
4152 return maxjobs;
4155 const char *lp_printcapname(void)
4157 if ((Globals.szPrintcapname != NULL) &&
4158 (Globals.szPrintcapname[0] != '\0'))
4159 return Globals.szPrintcapname;
4161 if (sDefault.printing == PRINT_CUPS) {
4162 return "cups";
4165 if (sDefault.printing == PRINT_BSD)
4166 return "/etc/printcap";
4168 return PRINTCAP_NAME;
4171 static uint32 spoolss_state;
4173 bool lp_disable_spoolss( void )
4175 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4176 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4178 return spoolss_state == SVCCTL_STOPPED ? true : false;
4181 void lp_set_spoolss_state( uint32 state )
4183 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4185 spoolss_state = state;
4188 uint32 lp_get_spoolss_state( void )
4190 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4193 /*******************************************************************
4194 Ensure we don't use sendfile if server smb signing is active.
4195 ********************************************************************/
4197 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4199 bool sign_active = false;
4201 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4202 if (get_Protocol() < PROTOCOL_NT1) {
4203 return false;
4205 if (signing_state) {
4206 sign_active = smb_signing_is_active(signing_state);
4208 return (lp__use_sendfile(snum) &&
4209 (get_remote_arch() != RA_WIN95) &&
4210 !sign_active);
4213 /*******************************************************************
4214 Turn off sendfile if we find the underlying OS doesn't support it.
4215 ********************************************************************/
4217 void set_use_sendfile(int snum, bool val)
4219 if (LP_SNUM_OK(snum))
4220 ServicePtrs[snum]->_use_sendfile = val;
4221 else
4222 sDefault._use_sendfile = val;
4225 /*******************************************************************
4226 Turn off storing DOS attributes if this share doesn't support it.
4227 ********************************************************************/
4229 void set_store_dos_attributes(int snum, bool val)
4231 if (!LP_SNUM_OK(snum))
4232 return;
4233 ServicePtrs[(snum)]->store_dos_attributes = val;
4236 void lp_set_mangling_method(const char *new_method)
4238 string_set(Globals.ctx, &Globals.mangling_method, new_method);
4241 /*******************************************************************
4242 Global state for POSIX pathname processing.
4243 ********************************************************************/
4245 static bool posix_pathnames;
4247 bool lp_posix_pathnames(void)
4249 return posix_pathnames;
4252 /*******************************************************************
4253 Change everything needed to ensure POSIX pathname processing (currently
4254 not much).
4255 ********************************************************************/
4257 void lp_set_posix_pathnames(void)
4259 posix_pathnames = true;
4262 /*******************************************************************
4263 Global state for POSIX lock processing - CIFS unix extensions.
4264 ********************************************************************/
4266 bool posix_default_lock_was_set;
4267 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4269 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4271 if (posix_default_lock_was_set) {
4272 return posix_cifsx_locktype;
4273 } else {
4274 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
4278 /*******************************************************************
4279 ********************************************************************/
4281 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4283 posix_default_lock_was_set = true;
4284 posix_cifsx_locktype = val;
4287 int lp_min_receive_file_size(void)
4289 if (Globals.iminreceivefile < 0) {
4290 return 0;
4292 return Globals.iminreceivefile;
4295 /*******************************************************************
4296 Safe wide links checks.
4297 This helper function always verify the validity of wide links,
4298 even after a configuration file reload.
4299 ********************************************************************/
4301 static bool lp_widelinks_internal(int snum)
4303 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
4304 sDefault.bWidelinks);
4307 void widelinks_warning(int snum)
4309 if (lp_allow_insecure_wide_links()) {
4310 return;
4313 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
4314 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4315 "These parameters are incompatible. "
4316 "Wide links will be disabled for this share.\n",
4317 lp_servicename(talloc_tos(), snum) ));
4321 bool lp_widelinks(int snum)
4323 /* wide links is always incompatible with unix extensions */
4324 if (lp_unix_extensions()) {
4326 * Unless we have "allow insecure widelinks"
4327 * turned on.
4329 if (!lp_allow_insecure_wide_links()) {
4330 return false;
4334 return lp_widelinks_internal(snum);
4337 int lp_server_role(void)
4339 return lp_find_server_role(lp__server_role(),
4340 lp__security(),
4341 lp__domain_logons(),
4342 lp_domain_master_true_or_auto());
4345 int lp_security(void)
4347 return lp_find_security(lp__server_role(),
4348 lp__security());
4351 struct loadparm_global * get_globals(void)
4353 return &Globals;
4356 unsigned int * get_flags(void)
4358 if (flags_list == NULL) {
4359 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
4362 return flags_list;