loadparm: Fix memory leak issue.
[Samba.git] / source3 / param / loadparm.c
blobc576b22f143be05af707a4da1d6f688a901a3b15
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"
72 #include "librpc/gen_ndr/nbt.h"
74 #ifdef HAVE_SYS_SYSCTL_H
75 #include <sys/sysctl.h>
76 #endif
78 #ifdef HAVE_HTTPCONNECTENCRYPT
79 #include <cups/http.h>
80 #endif
82 bool bLoaded = false;
84 extern userdom_struct current_user_info;
86 /* the special value for the include parameter
87 * to be interpreted not as a file name but to
88 * trigger loading of the global smb.conf options
89 * from registry. */
90 #ifndef INCLUDE_REGISTRY_NAME
91 #define INCLUDE_REGISTRY_NAME "registry"
92 #endif
94 static bool in_client = false; /* Not in the client by default */
95 static struct smbconf_csn conf_last_csn;
97 static int config_backend = CONFIG_BACKEND_FILE;
99 /* some helpful bits */
100 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
101 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
103 #define USERSHARE_VALID 1
104 #define USERSHARE_PENDING_DELETE 2
106 static bool defaults_saved = false;
108 #include "lib/param/param_global.h"
110 static struct loadparm_global Globals;
112 /* This is a default service used to prime a services structure */
113 static struct loadparm_service sDefault =
115 .valid = true,
116 .autoloaded = false,
117 .usershare = 0,
118 .usershare_last_mod = {0, 0},
119 .szService = NULL,
120 .path = NULL,
121 .username = NULL,
122 .invalid_users = NULL,
123 .valid_users = NULL,
124 .admin_users = NULL,
125 .szCopy = NULL,
126 .szInclude = NULL,
127 .preexec = NULL,
128 .postexec = NULL,
129 .root_preexec = NULL,
130 .root_postexec = NULL,
131 .cups_options = NULL,
132 .print_command = NULL,
133 .lpq_command = NULL,
134 .lprm_command = NULL,
135 .lppause_command = NULL,
136 .lpresume_command = NULL,
137 .queuepause_command = NULL,
138 .queueresume_command = NULL,
139 ._printername = NULL,
140 .printjob_username = NULL,
141 .dont_descend = NULL,
142 .hosts_allow = NULL,
143 .hosts_deny = NULL,
144 .magic_script = NULL,
145 .magic_output = NULL,
146 .veto_files = NULL,
147 .hide_files = NULL,
148 .veto_oplock_files = NULL,
149 .comment = NULL,
150 .force_user = NULL,
151 .force_group = NULL,
152 .read_list = NULL,
153 .write_list = NULL,
154 .volume = NULL,
155 .fstype = NULL,
156 .vfs_objects = NULL,
157 .msdfs_proxy = NULL,
158 .aio_write_behind = NULL,
159 .dfree_command = NULL,
160 .min_print_space = 0,
161 .iMaxPrintJobs = 1000,
162 .max_reported_print_jobs = 0,
163 .write_cache_size = 0,
164 .create_mask = 0744,
165 .force_create_mode = 0,
166 .directory_mask = 0755,
167 .force_directory_mode = 0,
168 .max_connections = 0,
169 .default_case = CASE_LOWER,
170 .printing = DEFAULT_PRINTING,
171 .oplock_contention_limit = 2,
172 .csc_policy = 0,
173 .block_size = 1024,
174 .dfree_cache_time = 0,
175 .preexec_close = false,
176 .root_preexec_close = false,
177 .case_sensitive = Auto,
178 .preserve_case = true,
179 .short_preserve_case = true,
180 .hide_dot_files = true,
181 .hide_special_files = false,
182 .hide_unreadable = false,
183 .hide_unwriteable_files = false,
184 .browseable = true,
185 .access_based_share_enum = false,
186 .bAvailable = true,
187 .read_only = true,
188 .spotlight = false,
189 .guest_only = false,
190 .administrative_share = false,
191 .guest_ok = false,
192 .printable = false,
193 .print_notify_backchannel = false,
194 .map_system = false,
195 .map_hidden = false,
196 .map_archive = true,
197 .store_dos_attributes = false,
198 .dmapi_support = false,
199 .locking = true,
200 .strict_locking = Auto,
201 .posix_locking = true,
202 .oplocks = true,
203 .kernel_oplocks = false,
204 .level2_oplocks = true,
205 .only_user = false,
206 .mangled_names = true,
207 .bWidelinks = false,
208 .follow_symlinks = true,
209 .sync_always = false,
210 .strict_allocate = false,
211 .strict_rename = false,
212 .strict_sync = false,
213 .mangling_char = '~',
214 .copymap = NULL,
215 .delete_readonly = false,
216 .fake_oplocks = false,
217 .delete_veto_files = false,
218 .dos_filemode = false,
219 .dos_filetimes = true,
220 .dos_filetime_resolution = false,
221 .fake_directory_create_times = false,
222 .blocking_locks = true,
223 .inherit_permissions = false,
224 .inherit_acls = false,
225 .inherit_owner = false,
226 .msdfs_root = false,
227 .msdfs_shuffle_referrals = false,
228 .use_client_driver = false,
229 .default_devmode = true,
230 .force_printername = false,
231 .nt_acl_support = true,
232 .force_unknown_acl_user = false,
233 ._use_sendfile = false,
234 .profile_acls = false,
235 .map_acl_inherit = false,
236 .afs_share = false,
237 .ea_support = false,
238 .acl_check_permissions = true,
239 .acl_map_full_control = true,
240 .acl_group_control = false,
241 .acl_allow_execute_always = false,
242 .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
243 .aio_read_size = 0,
244 .aio_write_size = 0,
245 .map_readonly = MAP_READONLY_YES,
246 .directory_name_cache_size = 100,
247 .smb_encrypt = SMB_SIGNING_DEFAULT,
248 .kernel_share_modes = true,
249 .durable_handles = true,
250 .param_opt = NULL,
251 .dummy = ""
254 /* local variables */
255 static struct loadparm_service **ServicePtrs = NULL;
256 static int iNumServices = 0;
257 static int iServiceIndex = 0;
258 static struct db_context *ServiceHash;
259 static bool bInGlobalSection = true;
260 static bool bGlobalOnly = false;
261 static struct file_lists *file_lists = NULL;
262 static unsigned int *flags_list = NULL;
264 static void set_allowed_client_auth(void);
266 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
267 static void free_param_opts(struct parmlist_entry **popts);
270 * Function to return the default value for the maximum number of open
271 * file descriptors permitted. This function tries to consult the
272 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
273 * the smaller of those.
275 static int max_open_files(void)
277 int sysctl_max = MAX_OPEN_FILES;
278 int rlimit_max = MAX_OPEN_FILES;
280 #ifdef HAVE_SYSCTLBYNAME
282 size_t size = sizeof(sysctl_max);
283 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
286 #endif
288 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
290 struct rlimit rl;
292 ZERO_STRUCT(rl);
294 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
295 rlimit_max = rl.rlim_cur;
297 #if defined(RLIM_INFINITY)
298 if(rl.rlim_cur == RLIM_INFINITY)
299 rlimit_max = MAX_OPEN_FILES;
300 #endif
302 #endif
304 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
305 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
306 "minimum Windows limit (%d)\n",
307 sysctl_max,
308 MIN_OPEN_FILES_WINDOWS));
309 sysctl_max = MIN_OPEN_FILES_WINDOWS;
312 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
313 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
314 "minimum Windows limit (%d)\n",
315 rlimit_max,
316 MIN_OPEN_FILES_WINDOWS));
317 rlimit_max = MIN_OPEN_FILES_WINDOWS;
320 return MIN(sysctl_max, rlimit_max);
324 * Common part of freeing allocated data for one parameter.
326 static void free_one_parameter_common(void *parm_ptr,
327 struct parm_struct parm)
329 if ((parm.type == P_STRING) ||
330 (parm.type == P_USTRING))
332 lpcfg_string_free((char**)parm_ptr);
333 } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
334 TALLOC_FREE(*((char***)parm_ptr));
339 * Free the allocated data for one parameter for a share
340 * given as a service struct.
342 static void free_one_parameter(struct loadparm_service *service,
343 struct parm_struct parm)
345 void *parm_ptr;
347 if (parm.p_class != P_LOCAL) {
348 return;
351 parm_ptr = lp_parm_ptr(service, &parm);
353 free_one_parameter_common(parm_ptr, parm);
357 * Free the allocated parameter data of a share given
358 * as a service struct.
360 static void free_parameters(struct loadparm_service *service)
362 uint32_t i;
364 for (i=0; parm_table[i].label; i++) {
365 free_one_parameter(service, parm_table[i]);
370 * Free the allocated data for one parameter for a given share
371 * specified by an snum.
373 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
375 void *parm_ptr;
377 if (snum < 0) {
378 parm_ptr = lp_parm_ptr(NULL, &parm);
379 } else if (parm.p_class != P_LOCAL) {
380 return;
381 } else {
382 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
385 free_one_parameter_common(parm_ptr, parm);
389 * Free the allocated parameter data for a share specified
390 * by an snum.
392 static void free_parameters_by_snum(int snum)
394 uint32_t i;
396 for (i=0; parm_table[i].label; i++) {
397 free_one_parameter_by_snum(snum, parm_table[i]);
402 * Free the allocated global parameters.
404 static void free_global_parameters(void)
406 uint32_t i;
407 struct parm_struct *parm;
409 free_param_opts(&Globals.param_opt);
410 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
412 /* Reset references in the defaults because the context is going to be freed */
413 for (i=0; parm_table[i].label; i++) {
414 parm = &parm_table[i];
415 if ((parm->type == P_STRING) ||
416 (parm->type == P_USTRING)) {
417 if ((parm->def.svalue != NULL) &&
418 (*(parm->def.svalue) != '\0')) {
419 if (talloc_parent(parm->def.svalue) == Globals.ctx) {
420 parm->def.svalue = NULL;
425 TALLOC_FREE(Globals.ctx);
428 struct lp_stored_option {
429 struct lp_stored_option *prev, *next;
430 const char *label;
431 const char *value;
434 static struct lp_stored_option *stored_options;
437 save options set by lp_set_cmdline() into a list. This list is
438 re-applied when we do a globals reset, so that cmdline set options
439 are sticky across reloads of smb.conf
441 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
443 struct lp_stored_option *entry, *entry_next;
444 for (entry = stored_options; entry != NULL; entry = entry_next) {
445 entry_next = entry->next;
446 if (strcmp(pszParmName, entry->label) == 0) {
447 DLIST_REMOVE(stored_options, entry);
448 talloc_free(entry);
449 break;
453 entry = talloc(NULL, struct lp_stored_option);
454 if (!entry) {
455 return false;
458 entry->label = talloc_strdup(entry, pszParmName);
459 if (!entry->label) {
460 talloc_free(entry);
461 return false;
464 entry->value = talloc_strdup(entry, pszParmValue);
465 if (!entry->value) {
466 talloc_free(entry);
467 return false;
470 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
472 return true;
475 static bool apply_lp_set_cmdline(void)
477 struct lp_stored_option *entry = NULL;
478 for (entry = stored_options; entry != NULL; entry = entry->next) {
479 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
480 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
481 entry->label, entry->value));
482 return false;
485 return true;
488 /***************************************************************************
489 Initialise the global parameter structure.
490 ***************************************************************************/
492 static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
494 static bool done_init = false;
495 char *s = NULL;
496 int i;
498 /* If requested to initialize only once and we've already done it... */
499 if (!reinit_globals && done_init) {
500 /* ... then we have nothing more to do */
501 return;
504 if (!done_init) {
505 /* The logfile can be set before this is invoked. Free it if so. */
506 lpcfg_string_free(&Globals.logfile);
507 done_init = true;
508 } else {
509 free_global_parameters();
512 /* This memset and the free_global_parameters() above will
513 * wipe out smb.conf options set with lp_set_cmdline(). The
514 * apply_lp_set_cmdline() call puts these values back in the
515 * table once the defaults are set */
516 ZERO_STRUCT(Globals);
518 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
520 /* Initialize the flags list if necessary */
521 if (flags_list == NULL) {
522 get_flags();
525 for (i = 0; parm_table[i].label; i++) {
526 if ((parm_table[i].type == P_STRING ||
527 parm_table[i].type == P_USTRING))
529 lpcfg_string_set(
530 Globals.ctx,
531 (char **)lp_parm_ptr(NULL, &parm_table[i]),
532 "");
537 lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
538 lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U");
540 init_printer_values(lp_ctx, Globals.ctx, &sDefault);
542 sDefault.ntvfs_handler = str_list_make_v3_const(NULL, "unixuid default", NULL);
544 DEBUG(3, ("Initialising global parameters\n"));
546 /* Must manually force to upper case here, as this does not go via the handler */
547 lpcfg_string_set(Globals.ctx, &Globals.netbios_name,
548 myhostname_upper());
550 lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file,
551 get_dyn_SMB_PASSWD_FILE());
552 lpcfg_string_set(Globals.ctx, &Globals.private_dir,
553 get_dyn_PRIVATE_DIR());
555 /* use the new 'hash2' method by default, with a prefix of 1 */
556 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
557 Globals.mangle_prefix = 1;
559 lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
561 /* using UTF8 by default allows us to support all chars */
562 lpcfg_string_set(Globals.ctx, &Globals.unix_charset,
563 DEFAULT_UNIX_CHARSET);
565 /* Use codepage 850 as a default for the dos character set */
566 lpcfg_string_set(Globals.ctx, &Globals.dos_charset,
567 DEFAULT_DOS_CHARSET);
570 * Allow the default PASSWD_CHAT to be overridden in local.h.
572 lpcfg_string_set(Globals.ctx, &Globals.passwd_chat,
573 DEFAULT_PASSWD_CHAT);
575 lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
577 lpcfg_string_set(Globals.ctx, &Globals.passwd_program, "");
578 lpcfg_string_set(Globals.ctx, &Globals.lock_directory,
579 get_dyn_LOCKDIR());
580 lpcfg_string_set(Globals.ctx, &Globals.state_directory,
581 get_dyn_STATEDIR());
582 lpcfg_string_set(Globals.ctx, &Globals.cache_directory,
583 get_dyn_CACHEDIR());
584 lpcfg_string_set(Globals.ctx, &Globals.pid_directory,
585 get_dyn_PIDDIR());
586 lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address,
587 "0.0.0.0");
589 * By default support explicit binding to broadcast
590 * addresses.
592 Globals.nmbd_bind_explicit_broadcast = true;
594 s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
595 if (s == NULL) {
596 smb_panic("init_globals: ENOMEM");
598 lpcfg_string_set(Globals.ctx, &Globals.server_string, s);
599 TALLOC_FREE(s);
600 #ifdef DEVELOPER
601 lpcfg_string_set(Globals.ctx, &Globals.panic_action,
602 "/bin/sleep 999999999");
603 #endif
605 lpcfg_string_set(Globals.ctx, &Globals.socket_options,
606 DEFAULT_SOCKET_OPTIONS);
608 lpcfg_string_set(Globals.ctx, &Globals.logon_drive, "");
609 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
610 lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
611 lpcfg_string_set(Globals.ctx, &Globals.logon_path,
612 "\\\\%N\\%U\\profile");
614 Globals.name_resolve_order = str_list_make_v3_const(NULL, "lmhosts wins host bcast", NULL);
615 lpcfg_string_set(Globals.ctx, &Globals.password_server, "*");
617 Globals.algorithmic_rid_base = BASE_RID;
619 Globals.load_printers = true;
620 Globals.printcap_cache_time = 750; /* 12.5 minutes */
622 Globals.config_backend = config_backend;
623 Globals._server_role = ROLE_AUTO;
625 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
626 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
627 Globals.max_xmit = 0x4104;
628 Globals.max_mux = 50; /* This is *needed* for profile support. */
629 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
630 Globals._disable_spoolss = false;
631 Globals.max_smbd_processes = 0;/* no limit specified */
632 Globals.username_level = 0;
633 Globals.deadtime = 0;
634 Globals.getwd_cache = true;
635 Globals.large_readwrite = true;
636 Globals.max_log_size = 5000;
637 Globals.max_open_files = max_open_files();
638 Globals.server_max_protocol = PROTOCOL_SMB3_11;
639 Globals.server_min_protocol = PROTOCOL_LANMAN1;
640 Globals._client_max_protocol = PROTOCOL_DEFAULT;
641 Globals.client_min_protocol = PROTOCOL_CORE;
642 Globals._security = SEC_AUTO;
643 Globals.encrypt_passwords = true;
644 Globals.client_schannel = Auto;
645 Globals.winbind_sealed_pipes = true;
646 Globals.require_strong_key = true;
647 Globals.server_schannel = Auto;
648 Globals.read_raw = true;
649 Globals.write_raw = true;
650 Globals.null_passwords = false;
651 Globals.old_password_allowed_period = 60;
652 Globals.obey_pam_restrictions = false;
653 Globals.syslog = 1;
654 Globals.syslog_only = false;
655 Globals.timestamp_logs = true;
656 lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
657 Globals.debug_prefix_timestamp = false;
658 Globals.debug_hires_timestamp = true;
659 Globals.debug_pid = false;
660 Globals.debug_uid = false;
661 Globals.debug_class = false;
662 Globals.enable_core_files = true;
663 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
664 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
665 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
666 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
667 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
668 Globals.lm_interval = 60;
669 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
670 Globals.nis_homedir = false;
671 #ifdef WITH_NISPLUS_HOME
672 lpcfg_string_set(Globals.ctx, &Globals.homedir_map,
673 "auto_home.org_dir");
674 #else
675 lpcfg_string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
676 #endif
677 #endif
678 Globals.time_server = false;
679 Globals.bind_interfaces_only = false;
680 Globals.unix_password_sync = false;
681 Globals.pam_password_change = false;
682 Globals.passwd_chat_debug = false;
683 Globals.passwd_chat_timeout = 2; /* 2 second default. */
684 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
685 Globals.nt_status_support = true; /* Use NT status by default. */
686 Globals.smbd_profiling_level = 0;
687 Globals.stat_cache = true; /* use stat cache by default */
688 Globals.max_stat_cache_size = 256; /* 256k by default */
689 Globals.restrict_anonymous = 0;
690 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
691 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
692 Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
693 Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
694 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 */
695 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
697 Globals.map_to_guest = 0; /* By Default, "Never" */
698 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
699 Globals.enhanced_browsing = true;
700 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
701 #ifdef MMAP_BLACKLIST
702 Globals.use_mmap = false;
703 #else
704 Globals.use_mmap = true;
705 #endif
706 Globals.unicode = true;
707 Globals.unix_extensions = true;
708 Globals.reset_on_zero_vc = false;
709 Globals.log_writeable_files_on_exit = false;
710 Globals.create_krb5_conf = true;
711 Globals.winbindMaxDomainConnections = 1;
713 /* hostname lookups can be very expensive and are broken on
714 a large number of sites (tridge) */
715 Globals.hostname_lookups = false;
717 Globals.change_notify = true,
718 Globals.kernel_change_notify = true,
720 lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
721 lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, "");
722 lpcfg_string_set(Globals.ctx, &Globals.szLdapMachineSuffix, "");
723 lpcfg_string_set(Globals.ctx, &Globals.szLdapUserSuffix, "");
724 lpcfg_string_set(Globals.ctx, &Globals.szLdapGroupSuffix, "");
725 lpcfg_string_set(Globals.ctx, &Globals.szLdapIdmapSuffix, "");
727 lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
728 Globals.ldap_ssl = LDAP_SSL_START_TLS;
729 Globals.ldap_ssl_ads = false;
730 Globals.ldap_deref = -1;
731 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
732 Globals.ldap_delete_dn = false;
733 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
734 Globals.ldap_follow_referral = Auto;
735 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
736 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
737 Globals.ldap_page_size = LDAP_PAGE_SIZE;
739 Globals.ldap_debug_level = 0;
740 Globals.ldap_debug_threshold = 10;
742 Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
744 /* This is what we tell the afs client. in reality we set the token
745 * to never expire, though, when this runs out the afs client will
746 * forget the token. Set to 0 to get NEVERDATE.*/
747 Globals.afs_token_lifetime = 604800;
748 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
750 /* these parameters are set to defaults that are more appropriate
751 for the increasing samba install base:
753 as a member of the workgroup, that will possibly become a
754 _local_ master browser (lm = true). this is opposed to a forced
755 local master browser startup (pm = true).
757 doesn't provide WINS server service by default (wsupp = false),
758 and doesn't provide domain master browser services by default, either.
762 Globals.show_add_printer_wizard = true;
763 Globals.os_level = 20;
764 Globals.local_master = true;
765 Globals._domain_master = Auto; /* depending on _domain_logons */
766 Globals._domain_logons = false;
767 Globals.browse_list = true;
768 Globals.we_are_a_wins_server = false;
769 Globals.wins_proxy = false;
771 TALLOC_FREE(Globals.init_logon_delayed_hosts);
772 Globals.init_logon_delay = 100; /* 100 ms default delay */
774 Globals.wins_dns_proxy = true;
776 Globals.allow_trusted_domains = true;
777 lpcfg_string_set(Globals.ctx, &Globals.szIdmapBackend, "tdb");
779 lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
780 lpcfg_string_set(Globals.ctx, &Globals.template_homedir, "/home/%D/%U");
781 lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\");
782 lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
784 lpcfg_string_set(Globals.ctx, &Globals.cups_server, "");
785 lpcfg_string_set(Globals.ctx, &Globals.iprint_server, "");
787 lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, "");
789 Globals.cluster_addresses = NULL;
790 Globals.clustering = false;
791 Globals.ctdb_timeout = 0;
792 Globals.ctdb_locktime_warn_threshold = 0;
794 Globals.winbind_cache_time = 300; /* 5 minutes */
795 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
796 Globals.winbind_request_timeout = 60; /* 60 seconds */
797 Globals.winbind_max_clients = 200;
798 Globals.winbind_enum_users = false;
799 Globals.winbind_enum_groups = false;
800 Globals.winbind_use_default_domain = false;
801 Globals.winbind_trusted_domains_only = false;
802 Globals.winbind_nested_groups = true;
803 Globals.winbind_expand_groups = 0;
804 Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
805 Globals.winbind_refresh_tickets = false;
806 Globals.winbind_offline_logon = false;
808 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
809 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
811 Globals.passdb_expand_explicit = false;
813 Globals.name_cache_timeout = 660; /* In seconds */
815 Globals.use_spnego = true;
816 Globals.client_use_spnego = true;
818 Globals.client_signing = SMB_SIGNING_DEFAULT;
819 Globals.server_signing = SMB_SIGNING_DEFAULT;
821 Globals.defer_sharing_violations = true;
822 Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
824 Globals.enable_privileges = true;
825 Globals.host_msdfs = true;
826 Globals.enable_asu_support = false;
828 /* User defined shares. */
829 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
830 if (s == NULL) {
831 smb_panic("init_globals: ENOMEM");
833 lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s);
834 TALLOC_FREE(s);
835 lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, "");
836 Globals.usershare_max_shares = 0;
837 /* By default disallow sharing of directories not owned by the sharer. */
838 Globals.usershare_owner_only = true;
839 /* By default disallow guest access to usershares. */
840 Globals.usershare_allow_guests = false;
842 Globals.keepalive = DEFAULT_KEEPALIVE;
844 /* By default no shares out of the registry */
845 Globals.registry_shares = false;
847 Globals.iminreceivefile = 0;
849 Globals.map_untrusted_to_domain = false;
850 Globals.multicast_dns_register = true;
852 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
853 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
854 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
855 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
856 Globals.smb2_leases = false;
858 lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir,
859 get_dyn_NCALRPCDIR());
861 Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
863 Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
865 Globals.tls_enabled = true;
867 lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
868 lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
869 lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
870 lpcfg_string_set(Globals.ctx, &Globals.tls_priority, "NORMAL:-VERS-SSL3.0");
872 lpcfg_string_set(Globals.ctx, &Globals.share_backend, "classic");
874 Globals.iPreferredMaster = Auto;
876 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
878 lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
879 get_dyn_NTP_SIGND_SOCKET_DIR());
881 lpcfg_string_set(Globals.ctx,
882 &Globals.winbindd_privileged_socket_directory,
883 get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
885 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
886 if (s == NULL) {
887 smb_panic("init_globals: ENOMEM");
889 Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
890 TALLOC_FREE(s);
892 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
893 if (s == NULL) {
894 smb_panic("init_globals: ENOMEM");
896 Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
897 TALLOC_FREE(s);
899 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
900 if (s == NULL) {
901 smb_panic("init_globals: ENOMEM");
903 Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
904 TALLOC_FREE(s);
906 Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
908 Globals.rndc_command = str_list_make_v3_const(NULL, "/usr/sbin/rndc", NULL);
910 Globals.cldap_port = 389;
912 Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
914 Globals.nbt_port = NBT_NAME_SERVICE_PORT;
916 Globals.krb5_port = 88;
918 Globals.kpasswd_port = 464;
920 Globals.web_port = 901;
922 /* Now put back the settings that were set with lp_set_cmdline() */
923 apply_lp_set_cmdline();
926 /* Convenience routine to setup an lp_context with additional s3 variables */
927 static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
929 struct loadparm_context *lp_ctx;
931 lp_ctx = loadparm_init_s3(mem_ctx,
932 loadparm_s3_helpers());
933 if (lp_ctx == NULL) {
934 DEBUG(0, ("loadparm_init_s3 failed\n"));
935 return NULL;
938 lp_ctx->sDefault = &sDefault;
939 lp_ctx->services = NULL; /* We do not want to access this directly */
940 lp_ctx->bInGlobalSection = bInGlobalSection;
941 lp_ctx->flags = flags_list;
943 return lp_ctx;
946 /*******************************************************************
947 Convenience routine to grab string parameters into talloced memory
948 and run standard_sub_basic on them. The buffers can be written to by
949 callers without affecting the source string.
950 ********************************************************************/
952 char *lp_string(TALLOC_CTX *ctx, const char *s)
954 char *ret;
956 /* The follow debug is useful for tracking down memory problems
957 especially if you have an inner loop that is calling a lp_*()
958 function that returns a string. Perhaps this debug should be
959 present all the time? */
961 #if 0
962 DEBUG(10, ("lp_string(%s)\n", s));
963 #endif
964 if (!s) {
965 return NULL;
968 ret = talloc_sub_basic(ctx,
969 get_current_username(),
970 current_user_info.domain,
972 if (trim_char(ret, '\"', '\"')) {
973 if (strchr(ret,'\"') != NULL) {
974 TALLOC_FREE(ret);
975 ret = talloc_sub_basic(ctx,
976 get_current_username(),
977 current_user_info.domain,
981 return ret;
985 In this section all the functions that are used to access the
986 parameters from the rest of the program are defined
989 #define FN_GLOBAL_STRING(fn_name,ptr) \
990 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
991 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
992 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
993 #define FN_GLOBAL_LIST(fn_name,ptr) \
994 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
995 #define FN_GLOBAL_BOOL(fn_name,ptr) \
996 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
997 #define FN_GLOBAL_CHAR(fn_name,ptr) \
998 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
999 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1000 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1002 #define FN_LOCAL_STRING(fn_name,val) \
1003 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));}
1004 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1005 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1006 #define FN_LOCAL_LIST(fn_name,val) \
1007 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1008 #define FN_LOCAL_BOOL(fn_name,val) \
1009 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1010 #define FN_LOCAL_INTEGER(fn_name,val) \
1011 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1013 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1014 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1015 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1016 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1017 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1018 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1020 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
1021 winbindMaxDomainConnections)
1023 int lp_winbind_max_domain_connections(void)
1025 if (lp_winbind_offline_logon() &&
1026 lp_winbind_max_domain_connections_int() > 1) {
1027 DEBUG(1, ("offline logons active, restricting max domain "
1028 "connections to 1\n"));
1029 return 1;
1031 return MAX(1, lp_winbind_max_domain_connections_int());
1034 int lp_smb2_max_credits(void)
1036 if (Globals.ismb2_max_credits == 0) {
1037 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1039 return Globals.ismb2_max_credits;
1041 int lp_cups_encrypt(void)
1043 int result = 0;
1044 #ifdef HAVE_HTTPCONNECTENCRYPT
1045 switch (Globals.CupsEncrypt) {
1046 case Auto:
1047 result = HTTP_ENCRYPT_REQUIRED;
1048 break;
1049 case true:
1050 result = HTTP_ENCRYPT_ALWAYS;
1051 break;
1052 case false:
1053 result = HTTP_ENCRYPT_NEVER;
1054 break;
1056 #endif
1057 return result;
1060 /* These functions remain in source3/param for now */
1062 #include "lib/param/param_functions.c"
1064 FN_LOCAL_STRING(servicename, szService)
1065 FN_LOCAL_CONST_STRING(const_servicename, szService)
1067 /* These functions cannot be auto-generated */
1068 FN_LOCAL_BOOL(autoloaded, autoloaded)
1069 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1071 /* local prototypes */
1073 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1074 static const char *get_boolean(bool bool_value);
1075 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1076 void *userdata);
1077 static bool hash_a_service(const char *name, int number);
1078 static void free_service_byindex(int iService);
1079 static void show_parameter(int parmIndex);
1080 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1083 * This is a helper function for parametrical options support. It returns a
1084 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1085 * parametrical functions are quite simple
1087 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1088 const char *option)
1090 if (snum >= iNumServices) return NULL;
1092 if (snum < 0) {
1093 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1094 } else {
1095 return get_parametric_helper(ServicePtrs[snum],
1096 type, option, Globals.param_opt);
1100 static void discard_whitespace(char *str)
1102 size_t len = strlen(str);
1103 size_t i = 0;
1105 while (i < len) {
1106 if (isspace(str[i])) {
1107 memmove(&str[i], &str[i+1], len-i);
1108 len -= 1;
1109 continue;
1111 i += 1;
1116 * @brief Go through all global parametric parameters
1118 * @param regex_str A regular expression to scan param for
1119 * @param max_matches Max number of submatches the regexp expects
1120 * @param cb Function to call on match. Should return true
1121 * when it wants wi_scan_global_parametrics to stop
1122 * scanning
1123 * @param private_data Anonymous pointer passed to cb
1125 * @return 0: success, regcomp/regexec return value on error.
1126 * See "man regexec" for possible errors
1129 int lp_wi_scan_global_parametrics(
1130 const char *regex_str, size_t max_matches,
1131 bool (*cb)(const char *string, regmatch_t matches[],
1132 void *private_data),
1133 void *private_data)
1135 struct parmlist_entry *data;
1136 regex_t regex;
1137 int ret;
1139 ret = regcomp(&regex, regex_str, REG_ICASE);
1140 if (ret != 0) {
1141 return ret;
1144 for (data = Globals.param_opt; data != NULL; data = data->next) {
1145 size_t keylen = strlen(data->key);
1146 char key[keylen+1];
1147 regmatch_t matches[max_matches];
1148 bool stop;
1150 memcpy(key, data->key, sizeof(key));
1151 discard_whitespace(key);
1153 ret = regexec(&regex, key, max_matches, matches, 0);
1154 if (ret == REG_NOMATCH) {
1155 continue;
1157 if (ret != 0) {
1158 goto fail;
1161 stop = cb(key, matches, private_data);
1162 if (stop) {
1163 break;
1167 ret = 0;
1168 fail:
1169 regfree(&regex);
1170 return ret;
1174 #define MISSING_PARAMETER(name) \
1175 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1177 /*******************************************************************
1178 convenience routine to return enum parameters.
1179 ********************************************************************/
1180 static int lp_enum(const char *s,const struct enum_list *_enum)
1182 int i;
1184 if (!s || !*s || !_enum) {
1185 MISSING_PARAMETER(lp_enum);
1186 return (-1);
1189 for (i=0; _enum[i].name; i++) {
1190 if (strequal(_enum[i].name,s))
1191 return _enum[i].value;
1194 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1195 return (-1);
1198 #undef MISSING_PARAMETER
1200 /* Return parametric option from a given service. Type is a part of option before ':' */
1201 /* Parametric option has following syntax: 'Type: option = value' */
1202 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1204 struct parmlist_entry *data = get_parametrics(snum, type, option);
1206 if (data == NULL||data->value==NULL) {
1207 if (def) {
1208 return lp_string(ctx, def);
1209 } else {
1210 return NULL;
1214 return lp_string(ctx, data->value);
1217 /* Return parametric option from a given service. Type is a part of option before ':' */
1218 /* Parametric option has following syntax: 'Type: option = value' */
1219 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1221 struct parmlist_entry *data = get_parametrics(snum, type, option);
1223 if (data == NULL||data->value==NULL)
1224 return def;
1226 return data->value;
1230 /* Return parametric option from a given service. Type is a part of option before ':' */
1231 /* Parametric option has following syntax: 'Type: option = value' */
1233 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1235 struct parmlist_entry *data = get_parametrics(snum, type, option);
1237 if (data == NULL||data->value==NULL)
1238 return (const char **)def;
1240 if (data->list==NULL) {
1241 data->list = str_list_make_v3(NULL, data->value, NULL);
1244 return discard_const_p(const char *, data->list);
1247 /* Return parametric option from a given service. Type is a part of option before ':' */
1248 /* Parametric option has following syntax: 'Type: option = value' */
1250 int lp_parm_int(int snum, const char *type, const char *option, int def)
1252 struct parmlist_entry *data = get_parametrics(snum, type, option);
1254 if (data && data->value && *data->value)
1255 return lp_int(data->value);
1257 return def;
1260 /* Return parametric option from a given service. Type is a part of option before ':' */
1261 /* Parametric option has following syntax: 'Type: option = value' */
1263 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1265 struct parmlist_entry *data = get_parametrics(snum, type, option);
1267 if (data && data->value && *data->value)
1268 return lp_ulong(data->value);
1270 return def;
1273 /* Return parametric option from a given service. Type is a part of option before ':' */
1274 /* Parametric option has following syntax: 'Type: option = value' */
1276 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1278 struct parmlist_entry *data = get_parametrics(snum, type, option);
1280 if (data && data->value && *data->value)
1281 return lp_bool(data->value);
1283 return def;
1286 /* Return parametric option from a given service. Type is a part of option before ':' */
1287 /* Parametric option has following syntax: 'Type: option = value' */
1289 int lp_parm_enum(int snum, const char *type, const char *option,
1290 const struct enum_list *_enum, int def)
1292 struct parmlist_entry *data = get_parametrics(snum, type, option);
1294 if (data && data->value && *data->value && _enum)
1295 return lp_enum(data->value, _enum);
1297 return def;
1301 * free a param_opts structure.
1302 * param_opts handling should be moved to talloc;
1303 * then this whole functions reduces to a TALLOC_FREE().
1306 static void free_param_opts(struct parmlist_entry **popts)
1308 struct parmlist_entry *opt, *next_opt;
1310 if (*popts != NULL) {
1311 DEBUG(5, ("Freeing parametrics:\n"));
1313 opt = *popts;
1314 while (opt != NULL) {
1315 lpcfg_string_free(&opt->key);
1316 lpcfg_string_free(&opt->value);
1317 TALLOC_FREE(opt->list);
1318 next_opt = opt->next;
1319 TALLOC_FREE(opt);
1320 opt = next_opt;
1322 *popts = NULL;
1325 /***************************************************************************
1326 Free the dynamically allocated parts of a service struct.
1327 ***************************************************************************/
1329 static void free_service(struct loadparm_service *pservice)
1331 if (!pservice)
1332 return;
1334 if (pservice->szService)
1335 DEBUG(5, ("free_service: Freeing service %s\n",
1336 pservice->szService));
1338 free_parameters(pservice);
1340 lpcfg_string_free(&pservice->szService);
1341 TALLOC_FREE(pservice->copymap);
1343 free_param_opts(&pservice->param_opt);
1345 ZERO_STRUCTP(pservice);
1349 /***************************************************************************
1350 remove a service indexed in the ServicePtrs array from the ServiceHash
1351 and free the dynamically allocated parts
1352 ***************************************************************************/
1354 static void free_service_byindex(int idx)
1356 if ( !LP_SNUM_OK(idx) )
1357 return;
1359 ServicePtrs[idx]->valid = false;
1361 /* we have to cleanup the hash record */
1363 if (ServicePtrs[idx]->szService) {
1364 char *canon_name = canonicalize_servicename(
1365 talloc_tos(),
1366 ServicePtrs[idx]->szService );
1368 dbwrap_delete_bystring(ServiceHash, canon_name );
1369 TALLOC_FREE(canon_name);
1372 free_service(ServicePtrs[idx]);
1373 talloc_free_children(ServicePtrs[idx]);
1376 /***************************************************************************
1377 Add a new service to the services array initialising it with the given
1378 service.
1379 ***************************************************************************/
1381 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1383 int i;
1384 int num_to_alloc = iNumServices + 1;
1385 struct loadparm_service **tsp = NULL;
1387 /* it might already exist */
1388 if (name) {
1389 i = getservicebyname(name, NULL);
1390 if (i >= 0) {
1391 return (i);
1395 /* if not, then create one */
1396 i = iNumServices;
1397 tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
1398 if (tsp == NULL) {
1399 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1400 return (-1);
1402 ServicePtrs = tsp;
1403 ServicePtrs[iNumServices] = talloc_zero(ServicePtrs, struct loadparm_service);
1404 if (!ServicePtrs[iNumServices]) {
1405 DEBUG(0,("add_a_service: out of memory!\n"));
1406 return (-1);
1408 iNumServices++;
1410 ServicePtrs[i]->valid = true;
1412 copy_service(ServicePtrs[i], pservice, NULL);
1413 if (name)
1414 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
1415 name);
1417 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1418 i, ServicePtrs[i]->szService));
1420 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1421 return (-1);
1424 return (i);
1427 /***************************************************************************
1428 Convert a string to uppercase and remove whitespaces.
1429 ***************************************************************************/
1431 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1433 char *result;
1435 if ( !src ) {
1436 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1437 return NULL;
1440 result = talloc_strdup(ctx, src);
1441 SMB_ASSERT(result != NULL);
1443 if (!strlower_m(result)) {
1444 TALLOC_FREE(result);
1445 return NULL;
1447 return result;
1450 /***************************************************************************
1451 Add a name/index pair for the services array to the hash table.
1452 ***************************************************************************/
1454 static bool hash_a_service(const char *name, int idx)
1456 char *canon_name;
1458 if ( !ServiceHash ) {
1459 DEBUG(10,("hash_a_service: creating servicehash\n"));
1460 ServiceHash = db_open_rbt(NULL);
1461 if ( !ServiceHash ) {
1462 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1463 return false;
1467 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1468 idx, name));
1470 canon_name = canonicalize_servicename(talloc_tos(), name );
1472 dbwrap_store_bystring(ServiceHash, canon_name,
1473 make_tdb_data((uint8_t *)&idx, sizeof(idx)),
1474 TDB_REPLACE);
1476 TALLOC_FREE(canon_name);
1478 return true;
1481 /***************************************************************************
1482 Add a new home service, with the specified home directory, defaults coming
1483 from service ifrom.
1484 ***************************************************************************/
1486 bool lp_add_home(const char *pszHomename, int iDefaultService,
1487 const char *user, const char *pszHomedir)
1489 int i;
1491 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1492 pszHomedir[0] == '\0') {
1493 return false;
1496 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1498 if (i < 0)
1499 return false;
1501 if (!(*(ServicePtrs[iDefaultService]->path))
1502 || strequal(ServicePtrs[iDefaultService]->path,
1503 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1504 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
1505 pszHomedir);
1508 if (!(*(ServicePtrs[i]->comment))) {
1509 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1510 if (comment == NULL) {
1511 return false;
1513 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment,
1514 comment);
1515 TALLOC_FREE(comment);
1518 /* set the browseable flag from the global default */
1520 ServicePtrs[i]->browseable = sDefault.browseable;
1521 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1523 ServicePtrs[i]->autoloaded = true;
1525 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1526 user, ServicePtrs[i]->path ));
1528 return true;
1531 /***************************************************************************
1532 Add a new service, based on an old one.
1533 ***************************************************************************/
1535 int lp_add_service(const char *pszService, int iDefaultService)
1537 if (iDefaultService < 0) {
1538 return add_a_service(&sDefault, pszService);
1541 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1544 /***************************************************************************
1545 Add the IPC service.
1546 ***************************************************************************/
1548 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1550 char *comment = NULL;
1551 int i = add_a_service(&sDefault, ipc_name);
1553 if (i < 0)
1554 return false;
1556 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1557 Globals.server_string);
1558 if (comment == NULL) {
1559 return false;
1562 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1563 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
1564 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1565 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1566 ServicePtrs[i]->max_connections = 0;
1567 ServicePtrs[i]->bAvailable = true;
1568 ServicePtrs[i]->read_only = true;
1569 ServicePtrs[i]->guest_only = false;
1570 ServicePtrs[i]->administrative_share = true;
1571 ServicePtrs[i]->guest_ok = guest_ok;
1572 ServicePtrs[i]->printable = false;
1573 ServicePtrs[i]->browseable = sDefault.browseable;
1575 DEBUG(3, ("adding IPC service\n"));
1577 TALLOC_FREE(comment);
1578 return true;
1581 /***************************************************************************
1582 Add a new printer service, with defaults coming from service iFrom.
1583 ***************************************************************************/
1585 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1587 const char *comment = "From Printcap";
1588 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1590 if (i < 0)
1591 return false;
1593 /* note that we do NOT default the availability flag to true - */
1594 /* we take it from the default service passed. This allows all */
1595 /* dynamic printers to be disabled by disabling the [printers] */
1596 /* entry (if/when the 'available' keyword is implemented!). */
1598 /* the printer name is set to the service name. */
1599 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername,
1600 pszPrintername);
1601 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1603 /* set the browseable flag from the gloabl default */
1604 ServicePtrs[i]->browseable = sDefault.browseable;
1606 /* Printers cannot be read_only. */
1607 ServicePtrs[i]->read_only = false;
1608 /* No oplocks on printer services. */
1609 ServicePtrs[i]->oplocks = false;
1610 /* Printer services must be printable. */
1611 ServicePtrs[i]->printable = true;
1613 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1615 return true;
1619 /***************************************************************************
1620 Check whether the given parameter name is valid.
1621 Parametric options (names containing a colon) are considered valid.
1622 ***************************************************************************/
1624 bool lp_parameter_is_valid(const char *pszParmName)
1626 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1627 (strchr(pszParmName, ':') != NULL));
1630 /***************************************************************************
1631 Check whether the given name is the name of a global parameter.
1632 Returns true for strings belonging to parameters of class
1633 P_GLOBAL, false for all other strings, also for parametric options
1634 and strings not belonging to any option.
1635 ***************************************************************************/
1637 bool lp_parameter_is_global(const char *pszParmName)
1639 int num = lpcfg_map_parameter(pszParmName);
1641 if (num >= 0) {
1642 return (parm_table[num].p_class == P_GLOBAL);
1645 return false;
1648 /**************************************************************************
1649 Determine the canonical name for a parameter.
1650 Indicate when it is an inverse (boolean) synonym instead of a
1651 "usual" synonym.
1652 **************************************************************************/
1654 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1655 bool *inverse)
1657 int num;
1659 if (!lp_parameter_is_valid(parm_name)) {
1660 *canon_parm = NULL;
1661 return false;
1664 num = map_parameter_canonical(parm_name, inverse);
1665 if (num < 0) {
1666 /* parametric option */
1667 *canon_parm = parm_name;
1668 } else {
1669 *canon_parm = parm_table[num].label;
1672 return true;
1676 /**************************************************************************
1677 Determine the canonical name for a parameter.
1678 Turn the value given into the inverse boolean expression when
1679 the synonym is an invers boolean synonym.
1681 Return true if parm_name is a valid parameter name and
1682 in case it is an invers boolean synonym, if the val string could
1683 successfully be converted to the reverse bool.
1684 Return false in all other cases.
1685 **************************************************************************/
1687 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1688 const char *val,
1689 const char **canon_parm,
1690 const char **canon_val)
1692 int num;
1693 bool inverse;
1695 if (!lp_parameter_is_valid(parm_name)) {
1696 *canon_parm = NULL;
1697 *canon_val = NULL;
1698 return false;
1701 num = map_parameter_canonical(parm_name, &inverse);
1702 if (num < 0) {
1703 /* parametric option */
1704 *canon_parm = parm_name;
1705 *canon_val = val;
1706 } else {
1707 *canon_parm = parm_table[num].label;
1708 if (inverse) {
1709 if (!lp_invert_boolean(val, canon_val)) {
1710 *canon_val = NULL;
1711 return false;
1713 } else {
1714 *canon_val = val;
1718 return true;
1721 /***************************************************************************
1722 Map a parameter's string representation to the index of the canonical
1723 form of the parameter (it might be a synonym).
1724 Returns -1 if the parameter string is not recognised.
1725 ***************************************************************************/
1727 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1729 int parm_num, canon_num;
1730 bool loc_inverse = false;
1732 parm_num = lpcfg_map_parameter(pszParmName);
1733 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
1734 /* invalid, parametric or no canidate for synonyms ... */
1735 goto done;
1738 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1739 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1740 parm_num = canon_num;
1741 goto done;
1745 done:
1746 if (inverse != NULL) {
1747 *inverse = loc_inverse;
1749 return parm_num;
1752 /***************************************************************************
1753 return true if parameter number parm1 is a synonym of parameter
1754 number parm2 (parm2 being the principal name).
1755 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1756 false otherwise.
1757 ***************************************************************************/
1759 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1761 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1762 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1763 (parm_table[parm1].flags & FLAG_SYNONYM) &&
1764 !(parm_table[parm2].flags & FLAG_SYNONYM))
1766 if (inverse != NULL) {
1767 if ((parm_table[parm1].type == P_BOOLREV) &&
1768 (parm_table[parm2].type == P_BOOL))
1770 *inverse = true;
1771 } else {
1772 *inverse = false;
1775 return true;
1777 return false;
1780 /***************************************************************************
1781 Show one parameter's name, type, [values,] and flags.
1782 (helper functions for show_parameter_list)
1783 ***************************************************************************/
1785 static void show_parameter(int parmIndex)
1787 int enumIndex, flagIndex;
1788 int parmIndex2;
1789 bool hadFlag;
1790 bool hadSyn;
1791 bool inverse;
1792 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1793 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1794 "P_ENUM", "P_BYTES", "P_CMDLIST" };
1795 unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
1796 const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
1798 printf("%s=%s", parm_table[parmIndex].label,
1799 type[parm_table[parmIndex].type]);
1800 if (parm_table[parmIndex].type == P_ENUM) {
1801 printf(",");
1802 for (enumIndex=0;
1803 parm_table[parmIndex].enum_list[enumIndex].name;
1804 enumIndex++)
1806 printf("%s%s",
1807 enumIndex ? "|" : "",
1808 parm_table[parmIndex].enum_list[enumIndex].name);
1811 printf(",");
1812 hadFlag = false;
1813 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1814 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1815 printf("%s%s",
1816 hadFlag ? "|" : "",
1817 flag_names[flagIndex]);
1818 hadFlag = true;
1822 /* output synonyms */
1823 hadSyn = false;
1824 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1825 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1826 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1827 parm_table[parmIndex2].label);
1828 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1829 if (!hadSyn) {
1830 printf(" (synonyms: ");
1831 hadSyn = true;
1832 } else {
1833 printf(", ");
1835 printf("%s%s", parm_table[parmIndex2].label,
1836 inverse ? "[i]" : "");
1839 if (hadSyn) {
1840 printf(")");
1843 printf("\n");
1846 /***************************************************************************
1847 Show all parameter's name, type, [values,] and flags.
1848 ***************************************************************************/
1850 void show_parameter_list(void)
1852 int classIndex, parmIndex;
1853 const char *section_names[] = { "local", "global", NULL};
1855 for (classIndex=0; section_names[classIndex]; classIndex++) {
1856 printf("[%s]\n", section_names[classIndex]);
1857 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
1858 if (parm_table[parmIndex].p_class == classIndex) {
1859 show_parameter(parmIndex);
1865 /***************************************************************************
1866 Get the standard string representation of a boolean value ("yes" or "no")
1867 ***************************************************************************/
1869 static const char *get_boolean(bool bool_value)
1871 static const char *yes_str = "yes";
1872 static const char *no_str = "no";
1874 return (bool_value ? yes_str : no_str);
1877 /***************************************************************************
1878 Provide the string of the negated boolean value associated to the boolean
1879 given as a string. Returns false if the passed string does not correctly
1880 represent a boolean.
1881 ***************************************************************************/
1883 bool lp_invert_boolean(const char *str, const char **inverse_str)
1885 bool val;
1887 if (!set_boolean(str, &val)) {
1888 return false;
1891 *inverse_str = get_boolean(!val);
1892 return true;
1895 /***************************************************************************
1896 Provide the canonical string representation of a boolean value given
1897 as a string. Return true on success, false if the string given does
1898 not correctly represent a boolean.
1899 ***************************************************************************/
1901 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
1903 bool val;
1905 if (!set_boolean(str, &val)) {
1906 return false;
1909 *canon_str = get_boolean(val);
1910 return true;
1913 /***************************************************************************
1914 Find a service by name. Otherwise works like get_service.
1915 ***************************************************************************/
1917 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
1919 int iService = -1;
1920 char *canon_name;
1921 TDB_DATA data;
1922 NTSTATUS status;
1924 if (ServiceHash == NULL) {
1925 return -1;
1928 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
1930 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
1931 &data);
1933 if (NT_STATUS_IS_OK(status) &&
1934 (data.dptr != NULL) &&
1935 (data.dsize == sizeof(iService)))
1937 iService = *(int *)data.dptr;
1940 TALLOC_FREE(canon_name);
1942 if ((iService != -1) && (LP_SNUM_OK(iService))
1943 && (pserviceDest != NULL)) {
1944 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1947 return (iService);
1950 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
1951 struct loadparm_service *lp_service(const char *pszServiceName)
1953 int iService = getservicebyname(pszServiceName, NULL);
1954 if (iService == -1 || !LP_SNUM_OK(iService)) {
1955 return NULL;
1957 return ServicePtrs[iService];
1960 struct loadparm_service *lp_servicebynum(int snum)
1962 if ((snum == -1) || !LP_SNUM_OK(snum)) {
1963 return NULL;
1965 return ServicePtrs[snum];
1968 struct loadparm_service *lp_default_loadparm_service()
1970 return &sDefault;
1973 static struct smbconf_ctx *lp_smbconf_ctx(void)
1975 sbcErr err;
1976 static struct smbconf_ctx *conf_ctx = NULL;
1978 if (conf_ctx == NULL) {
1979 err = smbconf_init(NULL, &conf_ctx, "registry:");
1980 if (!SBC_ERROR_IS_OK(err)) {
1981 DEBUG(1, ("error initializing registry configuration: "
1982 "%s\n", sbcErrorString(err)));
1983 conf_ctx = NULL;
1987 return conf_ctx;
1990 static bool process_smbconf_service(struct smbconf_service *service)
1992 uint32_t count;
1993 bool ret;
1995 if (service == NULL) {
1996 return false;
1999 ret = lp_do_section(service->name, NULL);
2000 if (ret != true) {
2001 return false;
2003 for (count = 0; count < service->num_params; count++) {
2005 if (!bInGlobalSection && bGlobalOnly) {
2006 ret = true;
2007 } else {
2008 const char *pszParmName = service->param_names[count];
2009 const char *pszParmValue = service->param_values[count];
2011 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2013 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2014 pszParmName, pszParmValue);
2017 if (ret != true) {
2018 return false;
2021 if (iServiceIndex >= 0) {
2022 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2024 return true;
2028 * load a service from registry and activate it
2030 bool process_registry_service(const char *service_name)
2032 sbcErr err;
2033 struct smbconf_service *service = NULL;
2034 TALLOC_CTX *mem_ctx = talloc_stackframe();
2035 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2036 bool ret = false;
2038 if (conf_ctx == NULL) {
2039 goto done;
2042 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2044 if (!smbconf_share_exists(conf_ctx, service_name)) {
2046 * Registry does not contain data for this service (yet),
2047 * but make sure lp_load doesn't return false.
2049 ret = true;
2050 goto done;
2053 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2054 if (!SBC_ERROR_IS_OK(err)) {
2055 goto done;
2058 ret = process_smbconf_service(service);
2059 if (!ret) {
2060 goto done;
2063 /* store the csn */
2064 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2066 done:
2067 TALLOC_FREE(mem_ctx);
2068 return ret;
2072 * process_registry_globals
2074 static bool process_registry_globals(void)
2076 bool ret;
2078 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2080 if (!bInGlobalSection && bGlobalOnly) {
2081 ret = true;
2082 } else {
2083 const char *pszParmName = "registry shares";
2084 const char *pszParmValue = "yes";
2086 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2088 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2089 pszParmName, pszParmValue);
2092 if (!ret) {
2093 return ret;
2096 return process_registry_service(GLOBAL_NAME);
2099 bool process_registry_shares(void)
2101 sbcErr err;
2102 uint32_t count;
2103 struct smbconf_service **service = NULL;
2104 uint32_t num_shares = 0;
2105 TALLOC_CTX *mem_ctx = talloc_stackframe();
2106 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2107 bool ret = false;
2109 if (conf_ctx == NULL) {
2110 goto done;
2113 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2114 if (!SBC_ERROR_IS_OK(err)) {
2115 goto done;
2118 ret = true;
2120 for (count = 0; count < num_shares; count++) {
2121 if (strequal(service[count]->name, GLOBAL_NAME)) {
2122 continue;
2124 ret = process_smbconf_service(service[count]);
2125 if (!ret) {
2126 goto done;
2130 /* store the csn */
2131 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2133 done:
2134 TALLOC_FREE(mem_ctx);
2135 return ret;
2139 * reload those shares from registry that are already
2140 * activated in the services array.
2142 static bool reload_registry_shares(void)
2144 int i;
2145 bool ret = true;
2147 for (i = 0; i < iNumServices; i++) {
2148 if (!VALID(i)) {
2149 continue;
2152 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2153 continue;
2156 ret = process_registry_service(ServicePtrs[i]->szService);
2157 if (!ret) {
2158 goto done;
2162 done:
2163 return ret;
2167 #define MAX_INCLUDE_DEPTH 100
2169 static uint8_t include_depth;
2172 * Free the file lists
2174 static void free_file_list(void)
2176 struct file_lists *f;
2177 struct file_lists *next;
2179 f = file_lists;
2180 while( f ) {
2181 next = f->next;
2182 TALLOC_FREE( f );
2183 f = next;
2185 file_lists = NULL;
2190 * Utility function for outsiders to check if we're running on registry.
2192 bool lp_config_backend_is_registry(void)
2194 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2198 * Utility function to check if the config backend is FILE.
2200 bool lp_config_backend_is_file(void)
2202 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2205 /*******************************************************************
2206 Check if a config file has changed date.
2207 ********************************************************************/
2209 bool lp_file_list_changed(void)
2211 struct file_lists *f = file_lists;
2213 DEBUG(6, ("lp_file_list_changed()\n"));
2215 while (f) {
2216 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2217 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2219 if (conf_ctx == NULL) {
2220 return false;
2222 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2223 NULL))
2225 DEBUGADD(6, ("registry config changed\n"));
2226 return true;
2228 } else {
2229 time_t mod_time;
2230 char *n2 = NULL;
2232 n2 = talloc_sub_basic(talloc_tos(),
2233 get_current_username(),
2234 current_user_info.domain,
2235 f->name);
2236 if (!n2) {
2237 return false;
2239 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2240 f->name, n2, ctime(&f->modtime)));
2242 mod_time = file_modtime(n2);
2244 if (mod_time &&
2245 ((f->modtime != mod_time) ||
2246 (f->subfname == NULL) ||
2247 (strcmp(n2, f->subfname) != 0)))
2249 DEBUGADD(6,
2250 ("file %s modified: %s\n", n2,
2251 ctime(&mod_time)));
2252 f->modtime = mod_time;
2253 TALLOC_FREE(f->subfname);
2254 f->subfname = talloc_strdup(f, n2);
2255 if (f->subfname == NULL) {
2256 smb_panic("talloc_strdup failed");
2258 TALLOC_FREE(n2);
2259 return true;
2261 TALLOC_FREE(n2);
2263 f = f->next;
2265 return false;
2270 * Initialize iconv conversion descriptors.
2272 * This is called the first time it is needed, and also called again
2273 * every time the configuration is reloaded, because the charset or
2274 * codepage might have changed.
2276 static void init_iconv(void)
2278 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2279 lp_unix_charset(),
2280 true, global_iconv_handle);
2283 /***************************************************************************
2284 Handle the include operation.
2285 ***************************************************************************/
2286 static bool bAllowIncludeRegistry = true;
2288 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2289 const char *pszParmValue, char **ptr)
2291 char *fname;
2293 if (include_depth >= MAX_INCLUDE_DEPTH) {
2294 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2295 include_depth));
2296 return false;
2299 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2300 if (!bAllowIncludeRegistry) {
2301 return true;
2303 if (lp_ctx->bInGlobalSection) {
2304 bool ret;
2305 include_depth++;
2306 ret = process_registry_globals();
2307 include_depth--;
2308 return ret;
2309 } else {
2310 DEBUG(1, ("\"include = registry\" only effective "
2311 "in %s section\n", GLOBAL_NAME));
2312 return false;
2316 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2317 current_user_info.domain,
2318 pszParmValue);
2320 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2322 if (service == NULL) {
2323 lpcfg_string_set(Globals.ctx, ptr, fname);
2324 } else {
2325 lpcfg_string_set(service, ptr, fname);
2328 if (file_exist(fname)) {
2329 bool ret;
2330 include_depth++;
2331 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2332 include_depth--;
2333 TALLOC_FREE(fname);
2334 return ret;
2337 DEBUG(2, ("Can't find include file %s\n", fname));
2338 TALLOC_FREE(fname);
2339 return true;
2342 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2344 char *config_option = NULL;
2345 const char *range = NULL;
2346 bool ret = false;
2348 SMB_ASSERT(low != NULL);
2349 SMB_ASSERT(high != NULL);
2351 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2352 domain_name = "*";
2355 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2356 domain_name);
2357 if (config_option == NULL) {
2358 DEBUG(0, ("out of memory\n"));
2359 return false;
2362 range = lp_parm_const_string(-1, config_option, "range", NULL);
2363 if (range == NULL) {
2364 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2365 goto done;
2368 if (sscanf(range, "%u - %u", low, high) != 2) {
2369 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2370 range, domain_name));
2371 goto done;
2374 ret = true;
2376 done:
2377 talloc_free(config_option);
2378 return ret;
2382 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2384 return lp_idmap_range("*", low, high);
2387 const char *lp_idmap_backend(const char *domain_name)
2389 char *config_option = NULL;
2390 const char *backend = NULL;
2392 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2393 domain_name = "*";
2396 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2397 domain_name);
2398 if (config_option == NULL) {
2399 DEBUG(0, ("out of memory\n"));
2400 return false;
2403 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2404 if (backend == NULL) {
2405 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2406 goto done;
2409 done:
2410 talloc_free(config_option);
2411 return backend;
2414 const char *lp_idmap_default_backend(void)
2416 return lp_idmap_backend("*");
2419 /***************************************************************************
2420 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2421 ***************************************************************************/
2423 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2425 const char *suffix_string;
2427 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2428 Globals.ldap_suffix );
2429 if ( !suffix_string ) {
2430 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2431 return "";
2434 return suffix_string;
2437 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2439 if (Globals.szLdapMachineSuffix[0])
2440 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
2442 return lp_string(ctx, Globals.ldap_suffix);
2445 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2447 if (Globals.szLdapUserSuffix[0])
2448 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
2450 return lp_string(ctx, Globals.ldap_suffix);
2453 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2455 if (Globals.szLdapGroupSuffix[0])
2456 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
2458 return lp_string(ctx, Globals.ldap_suffix);
2461 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2463 if (Globals.szLdapIdmapSuffix[0])
2464 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
2466 return lp_string(ctx, Globals.ldap_suffix);
2470 return the parameter pointer for a parameter
2472 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2474 if (service == NULL) {
2475 if (parm->p_class == P_LOCAL)
2476 return (void *)(((char *)&sDefault)+parm->offset);
2477 else if (parm->p_class == P_GLOBAL)
2478 return (void *)(((char *)&Globals)+parm->offset);
2479 else return NULL;
2480 } else {
2481 return (void *)(((char *)service) + parm->offset);
2485 /***************************************************************************
2486 Process a parameter for a particular service number. If snum < 0
2487 then assume we are in the globals.
2488 ***************************************************************************/
2490 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2492 TALLOC_CTX *frame = talloc_stackframe();
2493 struct loadparm_context *lp_ctx;
2494 bool ok;
2496 lp_ctx = setup_lp_context(frame);
2497 if (lp_ctx == NULL) {
2498 TALLOC_FREE(frame);
2499 return false;
2502 if (snum < 0) {
2503 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2504 } else {
2505 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2506 pszParmName, pszParmValue);
2509 TALLOC_FREE(frame);
2511 return ok;
2514 /***************************************************************************
2515 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2516 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2517 ***************************************************************************/
2519 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2521 int parmnum, i;
2522 parmnum = lpcfg_map_parameter(pszParmName);
2523 if (parmnum >= 0) {
2524 flags_list[parmnum] &= ~FLAG_CMDLINE;
2525 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2526 return false;
2528 flags_list[parmnum] |= FLAG_CMDLINE;
2530 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2531 * be grouped in the table, so we don't have to search the
2532 * whole table */
2533 for (i=parmnum-1;
2534 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2535 && parm_table[i].p_class == parm_table[parmnum].p_class;
2536 i--) {
2537 flags_list[i] |= FLAG_CMDLINE;
2539 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2540 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2541 flags_list[i] |= FLAG_CMDLINE;
2544 return true;
2547 /* it might be parametric */
2548 if (strchr(pszParmName, ':') != NULL) {
2549 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2550 return true;
2553 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2554 return false;
2557 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2559 bool ret;
2560 TALLOC_CTX *frame = talloc_stackframe();
2561 struct loadparm_context *lp_ctx;
2563 lp_ctx = setup_lp_context(frame);
2564 if (lp_ctx == NULL) {
2565 TALLOC_FREE(frame);
2566 return false;
2569 ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
2571 TALLOC_FREE(frame);
2572 return ret;
2575 /***************************************************************************
2576 Process a parameter.
2577 ***************************************************************************/
2579 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2580 void *userdata)
2582 if (!bInGlobalSection && bGlobalOnly)
2583 return true;
2585 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2587 if (bInGlobalSection) {
2588 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2589 } else {
2590 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2591 pszParmName, pszParmValue);
2595 /***************************************************************************
2596 Initialize any local variables in the sDefault table, after parsing a
2597 [globals] section.
2598 ***************************************************************************/
2600 static void init_locals(void)
2603 * We run this check once the [globals] is parsed, to force
2604 * the VFS objects and other per-share settings we need for
2605 * the standard way a AD DC is operated. We may change these
2606 * as our code evolves, which is why we force these settings.
2608 * We can't do this at the end of lp_load_ex(), as by that
2609 * point the services have been loaded and they will already
2610 * have "" as their vfs objects.
2612 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2613 const char **vfs_objects = lp_vfs_objects(-1);
2614 if (!vfs_objects || !vfs_objects[0]) {
2615 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2616 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2617 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2618 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2619 } else {
2620 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2624 lp_do_parameter(-1, "map hidden", "no");
2625 lp_do_parameter(-1, "map system", "no");
2626 lp_do_parameter(-1, "map readonly", "no");
2627 lp_do_parameter(-1, "map archive", "no");
2628 lp_do_parameter(-1, "store dos attributes", "yes");
2632 /***************************************************************************
2633 Process a new section (service). At this stage all sections are services.
2634 Later we'll have special sections that permit server parameters to be set.
2635 Returns true on success, false on failure.
2636 ***************************************************************************/
2638 bool lp_do_section(const char *pszSectionName, void *userdata)
2640 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2641 bool bRetval;
2642 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2643 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2644 bRetval = false;
2646 /* if we were in a global section then do the local inits */
2647 if (bInGlobalSection && !isglobal)
2648 init_locals();
2650 /* if we've just struck a global section, note the fact. */
2651 bInGlobalSection = isglobal;
2652 if (lp_ctx != NULL) {
2653 lp_ctx->bInGlobalSection = isglobal;
2656 /* check for multiple global sections */
2657 if (bInGlobalSection) {
2658 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2659 return true;
2662 if (!bInGlobalSection && bGlobalOnly)
2663 return true;
2665 /* if we have a current service, tidy it up before moving on */
2666 bRetval = true;
2668 if (iServiceIndex >= 0)
2669 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2671 /* if all is still well, move to the next record in the services array */
2672 if (bRetval) {
2673 /* We put this here to avoid an odd message order if messages are */
2674 /* issued by the post-processing of a previous section. */
2675 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2677 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2678 if (iServiceIndex < 0) {
2679 DEBUG(0, ("Failed to add a new service\n"));
2680 return false;
2682 /* Clean all parametric options for service */
2683 /* They will be added during parsing again */
2684 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2687 return bRetval;
2690 /***************************************************************************
2691 Display the contents of a parameter of a single services record.
2692 ***************************************************************************/
2694 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2696 bool result = false;
2697 struct loadparm_context *lp_ctx;
2699 lp_ctx = setup_lp_context(talloc_tos());
2700 if (lp_ctx == NULL) {
2701 return false;
2704 if (isGlobal) {
2705 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2706 } else {
2707 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2709 TALLOC_FREE(lp_ctx);
2710 return result;
2713 #if 0
2714 /***************************************************************************
2715 Display the contents of a single copy structure.
2716 ***************************************************************************/
2717 static void dump_copy_map(bool *pcopymap)
2719 int i;
2720 if (!pcopymap)
2721 return;
2723 printf("\n\tNon-Copied parameters:\n");
2725 for (i = 0; parm_table[i].label; i++)
2726 if (parm_table[i].p_class == P_LOCAL &&
2727 parm_table[i].ptr && !pcopymap[i] &&
2728 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2730 printf("\t\t%s\n", parm_table[i].label);
2733 #endif
2735 /***************************************************************************
2736 Return TRUE if the passed service number is within range.
2737 ***************************************************************************/
2739 bool lp_snum_ok(int iService)
2741 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2744 /***************************************************************************
2745 Auto-load some home services.
2746 ***************************************************************************/
2748 static void lp_add_auto_services(char *str)
2750 char *s;
2751 char *p;
2752 int homes;
2753 char *saveptr;
2755 if (!str)
2756 return;
2758 s = talloc_strdup(talloc_tos(), str);
2759 if (!s) {
2760 smb_panic("talloc_strdup failed");
2761 return;
2764 homes = lp_servicenumber(HOMES_NAME);
2766 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2767 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2768 char *home;
2770 if (lp_servicenumber(p) >= 0)
2771 continue;
2773 home = get_user_home_dir(talloc_tos(), p);
2775 if (home && home[0] && homes >= 0)
2776 lp_add_home(p, homes, p, home);
2778 TALLOC_FREE(home);
2780 TALLOC_FREE(s);
2783 /***************************************************************************
2784 Auto-load one printer.
2785 ***************************************************************************/
2787 void lp_add_one_printer(const char *name, const char *comment,
2788 const char *location, void *pdata)
2790 int printers = lp_servicenumber(PRINTERS_NAME);
2791 int i;
2793 if (lp_servicenumber(name) < 0) {
2794 lp_add_printer(name, printers);
2795 if ((i = lp_servicenumber(name)) >= 0) {
2796 lpcfg_string_set(ServicePtrs[i],
2797 &ServicePtrs[i]->comment, comment);
2798 ServicePtrs[i]->autoloaded = true;
2803 /***************************************************************************
2804 Have we loaded a services file yet?
2805 ***************************************************************************/
2807 bool lp_loaded(void)
2809 return (bLoaded);
2812 /***************************************************************************
2813 Unload unused services.
2814 ***************************************************************************/
2816 void lp_killunused(struct smbd_server_connection *sconn,
2817 bool (*snumused) (struct smbd_server_connection *, int))
2819 int i;
2820 for (i = 0; i < iNumServices; i++) {
2821 if (!VALID(i))
2822 continue;
2824 /* don't kill autoloaded or usershare services */
2825 if ( ServicePtrs[i]->autoloaded ||
2826 ServicePtrs[i]->usershare == USERSHARE_VALID) {
2827 continue;
2830 if (!snumused || !snumused(sconn, i)) {
2831 free_service_byindex(i);
2837 * Kill all except autoloaded and usershare services - convenience wrapper
2839 void lp_kill_all_services(void)
2841 lp_killunused(NULL, NULL);
2844 /***************************************************************************
2845 Unload a service.
2846 ***************************************************************************/
2848 void lp_killservice(int iServiceIn)
2850 if (VALID(iServiceIn)) {
2851 free_service_byindex(iServiceIn);
2855 /***************************************************************************
2856 Save the curent values of all global and sDefault parameters into the
2857 defaults union. This allows testparm to show only the
2858 changed (ie. non-default) parameters.
2859 ***************************************************************************/
2861 static void lp_save_defaults(void)
2863 int i;
2864 struct parmlist_entry * parm;
2865 for (i = 0; parm_table[i].label; i++) {
2866 if (!(flags_list[i] & FLAG_CMDLINE)) {
2867 flags_list[i] |= FLAG_DEFAULT;
2870 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
2871 && parm_table[i].p_class == parm_table[i - 1].p_class)
2872 continue;
2873 switch (parm_table[i].type) {
2874 case P_LIST:
2875 case P_CMDLIST:
2876 parm_table[i].def.lvalue = str_list_copy(
2877 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
2878 break;
2879 case P_STRING:
2880 case P_USTRING:
2881 lpcfg_string_set(
2882 Globals.ctx,
2883 &parm_table[i].def.svalue,
2884 *(char **)lp_parm_ptr(
2885 NULL, &parm_table[i]));
2886 if (parm_table[i].def.svalue == NULL) {
2887 smb_panic("lpcfg_string_set() failed");
2889 break;
2890 case P_BOOL:
2891 case P_BOOLREV:
2892 parm_table[i].def.bvalue =
2893 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
2894 break;
2895 case P_CHAR:
2896 parm_table[i].def.cvalue =
2897 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
2898 break;
2899 case P_INTEGER:
2900 case P_OCTAL:
2901 case P_ENUM:
2902 case P_BYTES:
2903 parm_table[i].def.ivalue =
2904 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
2905 break;
2909 for (parm=Globals.param_opt; parm; parm=parm->next) {
2910 if (!(parm->priority & FLAG_CMDLINE)) {
2911 parm->priority |= FLAG_DEFAULT;
2915 for (parm=sDefault.param_opt; parm; parm=parm->next) {
2916 if (!(parm->priority & FLAG_CMDLINE)) {
2917 parm->priority |= FLAG_DEFAULT;
2921 defaults_saved = true;
2924 /***********************************************************
2925 If we should send plaintext/LANMAN passwords in the clinet
2926 ************************************************************/
2928 static void set_allowed_client_auth(void)
2930 if (Globals.client_ntlmv2_auth) {
2931 Globals.client_lanman_auth = false;
2933 if (!Globals.client_lanman_auth) {
2934 Globals.client_plaintext_auth = false;
2938 /***************************************************************************
2939 JRA.
2940 The following code allows smbd to read a user defined share file.
2941 Yes, this is my intent. Yes, I'm comfortable with that...
2943 THE FOLLOWING IS SECURITY CRITICAL CODE.
2945 It washes your clothes, it cleans your house, it guards you while you sleep...
2946 Do not f%^k with it....
2947 ***************************************************************************/
2949 #define MAX_USERSHARE_FILE_SIZE (10*1024)
2951 /***************************************************************************
2952 Check allowed stat state of a usershare file.
2953 Ensure we print out who is dicking with us so the admin can
2954 get their sorry ass fired.
2955 ***************************************************************************/
2957 static bool check_usershare_stat(const char *fname,
2958 const SMB_STRUCT_STAT *psbuf)
2960 if (!S_ISREG(psbuf->st_ex_mode)) {
2961 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2962 "not a regular file\n",
2963 fname, (unsigned int)psbuf->st_ex_uid ));
2964 return false;
2967 /* Ensure this doesn't have the other write bit set. */
2968 if (psbuf->st_ex_mode & S_IWOTH) {
2969 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
2970 "public write. Refusing to allow as a usershare file.\n",
2971 fname, (unsigned int)psbuf->st_ex_uid ));
2972 return false;
2975 /* Should be 10k or less. */
2976 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
2977 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2978 "too large (%u) to be a user share file.\n",
2979 fname, (unsigned int)psbuf->st_ex_uid,
2980 (unsigned int)psbuf->st_ex_size ));
2981 return false;
2984 return true;
2987 /***************************************************************************
2988 Parse the contents of a usershare file.
2989 ***************************************************************************/
2991 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
2992 SMB_STRUCT_STAT *psbuf,
2993 const char *servicename,
2994 int snum,
2995 char **lines,
2996 int numlines,
2997 char **pp_sharepath,
2998 char **pp_comment,
2999 char **pp_cp_servicename,
3000 struct security_descriptor **ppsd,
3001 bool *pallow_guest)
3003 const char **prefixallowlist = lp_usershare_prefix_allow_list();
3004 const char **prefixdenylist = lp_usershare_prefix_deny_list();
3005 int us_vers;
3006 DIR *dp;
3007 SMB_STRUCT_STAT sbuf;
3008 char *sharepath = NULL;
3009 char *comment = NULL;
3011 *pp_sharepath = NULL;
3012 *pp_comment = NULL;
3014 *pallow_guest = false;
3016 if (numlines < 4) {
3017 return USERSHARE_MALFORMED_FILE;
3020 if (strcmp(lines[0], "#VERSION 1") == 0) {
3021 us_vers = 1;
3022 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3023 us_vers = 2;
3024 if (numlines < 5) {
3025 return USERSHARE_MALFORMED_FILE;
3027 } else {
3028 return USERSHARE_BAD_VERSION;
3031 if (strncmp(lines[1], "path=", 5) != 0) {
3032 return USERSHARE_MALFORMED_PATH;
3035 sharepath = talloc_strdup(ctx, &lines[1][5]);
3036 if (!sharepath) {
3037 return USERSHARE_POSIX_ERR;
3039 trim_string(sharepath, " ", " ");
3041 if (strncmp(lines[2], "comment=", 8) != 0) {
3042 return USERSHARE_MALFORMED_COMMENT_DEF;
3045 comment = talloc_strdup(ctx, &lines[2][8]);
3046 if (!comment) {
3047 return USERSHARE_POSIX_ERR;
3049 trim_string(comment, " ", " ");
3050 trim_char(comment, '"', '"');
3052 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3053 return USERSHARE_MALFORMED_ACL_DEF;
3056 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3057 return USERSHARE_ACL_ERR;
3060 if (us_vers == 2) {
3061 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3062 return USERSHARE_MALFORMED_ACL_DEF;
3064 if (lines[4][9] == 'y') {
3065 *pallow_guest = true;
3068 /* Backwards compatible extension to file version #2. */
3069 if (numlines > 5) {
3070 if (strncmp(lines[5], "sharename=", 10) != 0) {
3071 return USERSHARE_MALFORMED_SHARENAME_DEF;
3073 if (!strequal(&lines[5][10], servicename)) {
3074 return USERSHARE_BAD_SHARENAME;
3076 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3077 if (!*pp_cp_servicename) {
3078 return USERSHARE_POSIX_ERR;
3083 if (*pp_cp_servicename == NULL) {
3084 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3085 if (!*pp_cp_servicename) {
3086 return USERSHARE_POSIX_ERR;
3090 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3091 /* Path didn't change, no checks needed. */
3092 *pp_sharepath = sharepath;
3093 *pp_comment = comment;
3094 return USERSHARE_OK;
3097 /* The path *must* be absolute. */
3098 if (sharepath[0] != '/') {
3099 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3100 servicename, sharepath));
3101 return USERSHARE_PATH_NOT_ABSOLUTE;
3104 /* If there is a usershare prefix deny list ensure one of these paths
3105 doesn't match the start of the user given path. */
3106 if (prefixdenylist) {
3107 int i;
3108 for ( i=0; prefixdenylist[i]; i++ ) {
3109 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3110 servicename, i, prefixdenylist[i], sharepath ));
3111 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3112 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3113 "usershare prefix deny list entries.\n",
3114 servicename, sharepath));
3115 return USERSHARE_PATH_IS_DENIED;
3120 /* If there is a usershare prefix allow list ensure one of these paths
3121 does match the start of the user given path. */
3123 if (prefixallowlist) {
3124 int i;
3125 for ( i=0; prefixallowlist[i]; i++ ) {
3126 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3127 servicename, i, prefixallowlist[i], sharepath ));
3128 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3129 break;
3132 if (prefixallowlist[i] == NULL) {
3133 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3134 "usershare prefix allow list entries.\n",
3135 servicename, sharepath));
3136 return USERSHARE_PATH_NOT_ALLOWED;
3140 /* Ensure this is pointing to a directory. */
3141 dp = opendir(sharepath);
3143 if (!dp) {
3144 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3145 servicename, sharepath));
3146 return USERSHARE_PATH_NOT_DIRECTORY;
3149 /* Ensure the owner of the usershare file has permission to share
3150 this directory. */
3152 if (sys_stat(sharepath, &sbuf, false) == -1) {
3153 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3154 servicename, sharepath, strerror(errno) ));
3155 closedir(dp);
3156 return USERSHARE_POSIX_ERR;
3159 closedir(dp);
3161 if (!S_ISDIR(sbuf.st_ex_mode)) {
3162 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3163 servicename, sharepath ));
3164 return USERSHARE_PATH_NOT_DIRECTORY;
3167 /* Check if sharing is restricted to owner-only. */
3168 /* psbuf is the stat of the usershare definition file,
3169 sbuf is the stat of the target directory to be shared. */
3171 if (lp_usershare_owner_only()) {
3172 /* root can share anything. */
3173 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3174 return USERSHARE_PATH_NOT_ALLOWED;
3178 *pp_sharepath = sharepath;
3179 *pp_comment = comment;
3180 return USERSHARE_OK;
3183 /***************************************************************************
3184 Deal with a usershare file.
3185 Returns:
3186 >= 0 - snum
3187 -1 - Bad name, invalid contents.
3188 - service name already existed and not a usershare, problem
3189 with permissions to share directory etc.
3190 ***************************************************************************/
3192 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3194 SMB_STRUCT_STAT sbuf;
3195 SMB_STRUCT_STAT lsbuf;
3196 char *fname = NULL;
3197 char *sharepath = NULL;
3198 char *comment = NULL;
3199 char *cp_service_name = NULL;
3200 char **lines = NULL;
3201 int numlines = 0;
3202 int fd = -1;
3203 int iService = -1;
3204 TALLOC_CTX *ctx = talloc_stackframe();
3205 struct security_descriptor *psd = NULL;
3206 bool guest_ok = false;
3207 char *canon_name = NULL;
3208 bool added_service = false;
3209 int ret = -1;
3211 /* Ensure share name doesn't contain invalid characters. */
3212 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3213 DEBUG(0,("process_usershare_file: share name %s contains "
3214 "invalid characters (any of %s)\n",
3215 file_name, INVALID_SHARENAME_CHARS ));
3216 goto out;
3219 canon_name = canonicalize_servicename(ctx, file_name);
3220 if (!canon_name) {
3221 goto out;
3224 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3225 if (!fname) {
3226 goto out;
3229 /* Minimize the race condition by doing an lstat before we
3230 open and fstat. Ensure this isn't a symlink link. */
3232 if (sys_lstat(fname, &lsbuf, false) != 0) {
3233 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3234 fname, strerror(errno) ));
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, &lsbuf)) {
3241 goto out;
3245 TDB_DATA data;
3246 NTSTATUS status;
3248 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3249 canon_name, &data);
3251 iService = -1;
3253 if (NT_STATUS_IS_OK(status) &&
3254 (data.dptr != NULL) &&
3255 (data.dsize == sizeof(iService))) {
3256 memcpy(&iService, data.dptr, sizeof(iService));
3260 if (iService != -1 &&
3261 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3262 &lsbuf.st_ex_mtime) == 0) {
3263 /* Nothing changed - Mark valid and return. */
3264 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3265 canon_name ));
3266 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3267 ret = iService;
3268 goto out;
3271 /* Try and open the file read only - no symlinks allowed. */
3272 #ifdef O_NOFOLLOW
3273 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3274 #else
3275 fd = open(fname, O_RDONLY, 0);
3276 #endif
3278 if (fd == -1) {
3279 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3280 fname, strerror(errno) ));
3281 goto out;
3284 /* Now fstat to be *SURE* it's a regular file. */
3285 if (sys_fstat(fd, &sbuf, false) != 0) {
3286 close(fd);
3287 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3288 fname, strerror(errno) ));
3289 goto out;
3292 /* Is it the same dev/inode as was lstated ? */
3293 if (!check_same_stat(&lsbuf, &sbuf)) {
3294 close(fd);
3295 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3296 "Symlink spoofing going on ?\n", fname ));
3297 goto out;
3300 /* This must be a regular file, not a symlink, directory or
3301 other strange filetype. */
3302 if (!check_usershare_stat(fname, &sbuf)) {
3303 close(fd);
3304 goto out;
3307 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3309 close(fd);
3310 if (lines == NULL) {
3311 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3312 fname, (unsigned int)sbuf.st_ex_uid ));
3313 goto out;
3316 if (parse_usershare_file(ctx, &sbuf, file_name,
3317 iService, lines, numlines, &sharepath,
3318 &comment, &cp_service_name,
3319 &psd, &guest_ok) != USERSHARE_OK) {
3320 goto out;
3323 /* Everything ok - add the service possibly using a template. */
3324 if (iService < 0) {
3325 const struct loadparm_service *sp = &sDefault;
3326 if (snum_template != -1) {
3327 sp = ServicePtrs[snum_template];
3330 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3331 DEBUG(0, ("process_usershare_file: Failed to add "
3332 "new service %s\n", cp_service_name));
3333 goto out;
3336 added_service = true;
3338 /* Read only is controlled by usershare ACL below. */
3339 ServicePtrs[iService]->read_only = false;
3342 /* Write the ACL of the new/modified share. */
3343 if (!set_share_security(canon_name, psd)) {
3344 DEBUG(0, ("process_usershare_file: Failed to set share "
3345 "security for user share %s\n",
3346 canon_name ));
3347 goto out;
3350 /* If from a template it may be marked invalid. */
3351 ServicePtrs[iService]->valid = true;
3353 /* Set the service as a valid usershare. */
3354 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3356 /* Set guest access. */
3357 if (lp_usershare_allow_guests()) {
3358 ServicePtrs[iService]->guest_ok = guest_ok;
3361 /* And note when it was loaded. */
3362 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3363 lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path,
3364 sharepath);
3365 lpcfg_string_set(ServicePtrs[iService],
3366 &ServicePtrs[iService]->comment, comment);
3368 ret = iService;
3370 out:
3372 if (ret == -1 && iService != -1 && added_service) {
3373 lp_remove_service(iService);
3376 TALLOC_FREE(lines);
3377 TALLOC_FREE(ctx);
3378 return ret;
3381 /***************************************************************************
3382 Checks if a usershare entry has been modified since last load.
3383 ***************************************************************************/
3385 static bool usershare_exists(int iService, struct timespec *last_mod)
3387 SMB_STRUCT_STAT lsbuf;
3388 const char *usersharepath = Globals.usershare_path;
3389 char *fname;
3391 fname = talloc_asprintf(talloc_tos(),
3392 "%s/%s",
3393 usersharepath,
3394 ServicePtrs[iService]->szService);
3395 if (fname == NULL) {
3396 return false;
3399 if (sys_lstat(fname, &lsbuf, false) != 0) {
3400 TALLOC_FREE(fname);
3401 return false;
3404 if (!S_ISREG(lsbuf.st_ex_mode)) {
3405 TALLOC_FREE(fname);
3406 return false;
3409 TALLOC_FREE(fname);
3410 *last_mod = lsbuf.st_ex_mtime;
3411 return true;
3414 /***************************************************************************
3415 Load a usershare service by name. Returns a valid servicenumber or -1.
3416 ***************************************************************************/
3418 int load_usershare_service(const char *servicename)
3420 SMB_STRUCT_STAT sbuf;
3421 const char *usersharepath = Globals.usershare_path;
3422 int max_user_shares = Globals.usershare_max_shares;
3423 int snum_template = -1;
3425 if (*usersharepath == 0 || max_user_shares == 0) {
3426 return -1;
3429 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3430 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3431 usersharepath, strerror(errno) ));
3432 return -1;
3435 if (!S_ISDIR(sbuf.st_ex_mode)) {
3436 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3437 usersharepath ));
3438 return -1;
3442 * This directory must be owned by root, and have the 't' bit set.
3443 * It also must not be writable by "other".
3446 #ifdef S_ISVTX
3447 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3448 #else
3449 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3450 #endif
3451 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3452 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3453 usersharepath ));
3454 return -1;
3457 /* Ensure the template share exists if it's set. */
3458 if (Globals.usershare_template_share[0]) {
3459 /* We can't use lp_servicenumber here as we are recommending that
3460 template shares have -valid=false set. */
3461 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3462 if (ServicePtrs[snum_template]->szService &&
3463 strequal(ServicePtrs[snum_template]->szService,
3464 Globals.usershare_template_share)) {
3465 break;
3469 if (snum_template == -1) {
3470 DEBUG(0,("load_usershare_service: usershare template share %s "
3471 "does not exist.\n",
3472 Globals.usershare_template_share ));
3473 return -1;
3477 return process_usershare_file(usersharepath, servicename, snum_template);
3480 /***************************************************************************
3481 Load all user defined shares from the user share directory.
3482 We only do this if we're enumerating the share list.
3483 This is the function that can delete usershares that have
3484 been removed.
3485 ***************************************************************************/
3487 int load_usershare_shares(struct smbd_server_connection *sconn,
3488 bool (*snumused) (struct smbd_server_connection *, int))
3490 DIR *dp;
3491 SMB_STRUCT_STAT sbuf;
3492 struct dirent *de;
3493 int num_usershares = 0;
3494 int max_user_shares = Globals.usershare_max_shares;
3495 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3496 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3497 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3498 int iService;
3499 int snum_template = -1;
3500 const char *usersharepath = Globals.usershare_path;
3501 int ret = lp_numservices();
3502 TALLOC_CTX *tmp_ctx;
3504 if (max_user_shares == 0 || *usersharepath == '\0') {
3505 return lp_numservices();
3508 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3509 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3510 usersharepath, strerror(errno) ));
3511 return ret;
3515 * This directory must be owned by root, and have the 't' bit set.
3516 * It also must not be writable by "other".
3519 #ifdef S_ISVTX
3520 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3521 #else
3522 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3523 #endif
3524 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3525 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3526 usersharepath ));
3527 return ret;
3530 /* Ensure the template share exists if it's set. */
3531 if (Globals.usershare_template_share[0]) {
3532 /* We can't use lp_servicenumber here as we are recommending that
3533 template shares have -valid=false set. */
3534 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3535 if (ServicePtrs[snum_template]->szService &&
3536 strequal(ServicePtrs[snum_template]->szService,
3537 Globals.usershare_template_share)) {
3538 break;
3542 if (snum_template == -1) {
3543 DEBUG(0,("load_usershare_shares: usershare template share %s "
3544 "does not exist.\n",
3545 Globals.usershare_template_share ));
3546 return ret;
3550 /* Mark all existing usershares as pending delete. */
3551 for (iService = iNumServices - 1; iService >= 0; iService--) {
3552 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3553 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3557 dp = opendir(usersharepath);
3558 if (!dp) {
3559 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3560 usersharepath, strerror(errno) ));
3561 return ret;
3564 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3565 (de = readdir(dp));
3566 num_dir_entries++ ) {
3567 int r;
3568 const char *n = de->d_name;
3570 /* Ignore . and .. */
3571 if (*n == '.') {
3572 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3573 continue;
3577 if (n[0] == ':') {
3578 /* Temporary file used when creating a share. */
3579 num_tmp_dir_entries++;
3582 /* Allow 20% tmp entries. */
3583 if (num_tmp_dir_entries > allowed_tmp_entries) {
3584 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3585 "in directory %s\n",
3586 num_tmp_dir_entries, usersharepath));
3587 break;
3590 r = process_usershare_file(usersharepath, n, snum_template);
3591 if (r == 0) {
3592 /* Update the services count. */
3593 num_usershares++;
3594 if (num_usershares >= max_user_shares) {
3595 DEBUG(0,("load_usershare_shares: max user shares reached "
3596 "on file %s in directory %s\n",
3597 n, usersharepath ));
3598 break;
3600 } else if (r == -1) {
3601 num_bad_dir_entries++;
3604 /* Allow 20% bad entries. */
3605 if (num_bad_dir_entries > allowed_bad_entries) {
3606 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3607 "in directory %s\n",
3608 num_bad_dir_entries, usersharepath));
3609 break;
3612 /* Allow 20% bad entries. */
3613 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3614 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3615 "in directory %s\n",
3616 num_dir_entries, usersharepath));
3617 break;
3621 closedir(dp);
3623 /* Sweep through and delete any non-refreshed usershares that are
3624 not currently in use. */
3625 tmp_ctx = talloc_stackframe();
3626 for (iService = iNumServices - 1; iService >= 0; iService--) {
3627 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3628 char *servname;
3630 if (snumused && snumused(sconn, iService)) {
3631 continue;
3634 servname = lp_servicename(tmp_ctx, iService);
3636 /* Remove from the share ACL db. */
3637 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3638 servname ));
3639 delete_share_security(servname);
3640 free_service_byindex(iService);
3643 talloc_free(tmp_ctx);
3645 return lp_numservices();
3648 /********************************************************
3649 Destroy global resources allocated in this file
3650 ********************************************************/
3652 void gfree_loadparm(void)
3654 int i;
3656 free_file_list();
3658 /* Free resources allocated to services */
3660 for ( i = 0; i < iNumServices; i++ ) {
3661 if ( VALID(i) ) {
3662 free_service_byindex(i);
3666 TALLOC_FREE( ServicePtrs );
3667 iNumServices = 0;
3669 /* Now release all resources allocated to global
3670 parameters and the default service */
3672 free_global_parameters();
3676 /***************************************************************************
3677 Allow client apps to specify that they are a client
3678 ***************************************************************************/
3679 static void lp_set_in_client(bool b)
3681 in_client = b;
3685 /***************************************************************************
3686 Determine if we're running in a client app
3687 ***************************************************************************/
3688 static bool lp_is_in_client(void)
3690 return in_client;
3693 static void lp_enforce_ad_dc_settings(void)
3695 lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3696 lp_do_parameter(GLOBAL_SECTION_SNUM,
3697 "winbindd:use external pipes", "true");
3698 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
3699 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
3700 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
3701 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
3702 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
3703 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
3704 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
3705 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
3706 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
3709 /***************************************************************************
3710 Load the services array from the services file. Return true on success,
3711 false on failure.
3712 ***************************************************************************/
3714 static bool lp_load_ex(const char *pszFname,
3715 bool global_only,
3716 bool save_defaults,
3717 bool add_ipc,
3718 bool reinit_globals,
3719 bool allow_include_registry,
3720 bool load_all_shares)
3722 char *n2 = NULL;
3723 bool bRetval;
3724 TALLOC_CTX *frame = talloc_stackframe();
3725 struct loadparm_context *lp_ctx;
3727 bRetval = false;
3729 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3731 bInGlobalSection = true;
3732 bGlobalOnly = global_only;
3733 bAllowIncludeRegistry = allow_include_registry;
3735 lp_ctx = setup_lp_context(talloc_tos());
3737 init_globals(lp_ctx, reinit_globals);
3739 free_file_list();
3741 if (save_defaults) {
3742 init_locals();
3743 lp_save_defaults();
3746 if (!reinit_globals) {
3747 free_param_opts(&Globals.param_opt);
3748 apply_lp_set_cmdline();
3751 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
3753 /* We get sections first, so have to start 'behind' to make up */
3754 iServiceIndex = -1;
3756 if (lp_config_backend_is_file()) {
3757 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
3758 current_user_info.domain,
3759 pszFname);
3760 if (!n2) {
3761 smb_panic("lp_load_ex: out of memory");
3764 add_to_file_list(NULL, &file_lists, pszFname, n2);
3766 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
3767 TALLOC_FREE(n2);
3769 /* finish up the last section */
3770 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3771 if (bRetval) {
3772 if (iServiceIndex >= 0) {
3773 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
3777 if (lp_config_backend_is_registry()) {
3778 bool ok;
3779 /* config backend changed to registry in config file */
3781 * We need to use this extra global variable here to
3782 * survive restart: init_globals uses this as a default
3783 * for config_backend. Otherwise, init_globals would
3784 * send us into an endless loop here.
3787 config_backend = CONFIG_BACKEND_REGISTRY;
3788 /* start over */
3789 DEBUG(1, ("lp_load_ex: changing to config backend "
3790 "registry\n"));
3791 init_globals(lp_ctx, true);
3793 TALLOC_FREE(lp_ctx);
3795 lp_kill_all_services();
3796 ok = lp_load_ex(pszFname, global_only, save_defaults,
3797 add_ipc, reinit_globals,
3798 allow_include_registry,
3799 load_all_shares);
3800 TALLOC_FREE(frame);
3801 return ok;
3803 } else if (lp_config_backend_is_registry()) {
3804 bRetval = process_registry_globals();
3805 } else {
3806 DEBUG(0, ("Illegal config backend given: %d\n",
3807 lp_config_backend()));
3808 bRetval = false;
3811 if (bRetval && lp_registry_shares()) {
3812 if (load_all_shares) {
3813 bRetval = process_registry_shares();
3814 } else {
3815 bRetval = reload_registry_shares();
3820 char *serv = lp_auto_services(talloc_tos());
3821 lp_add_auto_services(serv);
3822 TALLOC_FREE(serv);
3825 if (add_ipc) {
3826 /* When 'restrict anonymous = 2' guest connections to ipc$
3827 are denied */
3828 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3829 if ( lp_enable_asu_support() ) {
3830 lp_add_ipc("ADMIN$", false);
3834 set_allowed_client_auth();
3836 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
3837 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
3838 lp_password_server()));
3841 bLoaded = true;
3843 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
3844 /* if we_are_a_wins_server is true and we are in the client */
3845 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
3846 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3849 init_iconv();
3851 fault_configure(smb_panic_s3);
3854 * We run this check once the whole smb.conf is parsed, to
3855 * force some settings for the standard way a AD DC is
3856 * operated. We may change these as our code evolves, which
3857 * is why we force these settings.
3859 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3860 lp_enforce_ad_dc_settings();
3863 bAllowIncludeRegistry = true;
3865 TALLOC_FREE(frame);
3866 return (bRetval);
3869 static bool lp_load(const char *pszFname,
3870 bool global_only,
3871 bool save_defaults,
3872 bool add_ipc,
3873 bool reinit_globals)
3875 return lp_load_ex(pszFname,
3876 global_only,
3877 save_defaults,
3878 add_ipc,
3879 reinit_globals,
3880 true, /* allow_include_registry */
3881 false); /* load_all_shares*/
3884 bool lp_load_initial_only(const char *pszFname)
3886 return lp_load_ex(pszFname,
3887 true, /* global only */
3888 true, /* save_defaults */
3889 false, /* add_ipc */
3890 true, /* reinit_globals */
3891 false, /* allow_include_registry */
3892 false); /* load_all_shares*/
3896 * most common lp_load wrapper, loading only the globals
3898 bool lp_load_global(const char *file_name)
3900 return lp_load(file_name,
3901 true, /* global_only */
3902 false, /* save_defaults */
3903 false, /* add_ipc */
3904 true); /* reinit_globals */
3908 * The typical lp_load wrapper with shares, loads global and
3909 * shares, including IPC, but does not force immediate
3910 * loading of all shares from registry.
3912 bool lp_load_with_shares(const char *file_name)
3914 return lp_load(file_name,
3915 false, /* global_only */
3916 false, /* save_defaults */
3917 true, /* add_ipc */
3918 true); /* reinit_globals */
3922 * lp_load wrapper, especially for clients
3924 bool lp_load_client(const char *file_name)
3926 lp_set_in_client(true);
3928 return lp_load_global(file_name);
3932 * lp_load wrapper, loading only globals, but intended
3933 * for subsequent calls, not reinitializing the globals
3934 * to default values
3936 bool lp_load_global_no_reinit(const char *file_name)
3938 return lp_load(file_name,
3939 true, /* global_only */
3940 false, /* save_defaults */
3941 false, /* add_ipc */
3942 false); /* reinit_globals */
3946 * lp_load wrapper, loading globals and shares,
3947 * intended for subsequent calls, i.e. not reinitializing
3948 * the globals to default values.
3950 bool lp_load_no_reinit(const char *file_name)
3952 return lp_load(file_name,
3953 false, /* global_only */
3954 false, /* save_defaults */
3955 false, /* add_ipc */
3956 false); /* reinit_globals */
3961 * lp_load wrapper, especially for clients, no reinitialization
3963 bool lp_load_client_no_reinit(const char *file_name)
3965 lp_set_in_client(true);
3967 return lp_load_global_no_reinit(file_name);
3970 bool lp_load_with_registry_shares(const char *pszFname)
3972 return lp_load_ex(pszFname,
3973 false, /* global_only */
3974 true, /* save_defaults */
3975 false, /* add_ipc */
3976 false, /* reinit_globals */
3977 true, /* allow_include_registry */
3978 true); /* load_all_shares*/
3981 /***************************************************************************
3982 Return the max number of services.
3983 ***************************************************************************/
3985 int lp_numservices(void)
3987 return (iNumServices);
3990 /***************************************************************************
3991 Display the contents of the services array in human-readable form.
3992 ***************************************************************************/
3994 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
3996 int iService;
3997 struct loadparm_context *lp_ctx;
3999 if (show_defaults)
4000 defaults_saved = false;
4002 lp_ctx = setup_lp_context(talloc_tos());
4003 if (lp_ctx == NULL) {
4004 return;
4007 lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
4009 lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
4011 for (iService = 0; iService < maxtoprint; iService++) {
4012 fprintf(f,"\n");
4013 lp_dump_one(f, show_defaults, iService);
4017 /***************************************************************************
4018 Display the contents of one service in human-readable form.
4019 ***************************************************************************/
4021 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4023 if (VALID(snum)) {
4024 if (ServicePtrs[snum]->szService[0] == '\0')
4025 return;
4026 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
4027 flags_list, show_defaults);
4031 /***************************************************************************
4032 Return the number of the service with the given name, or -1 if it doesn't
4033 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4034 getservicebyname()! This works ONLY if all services have been loaded, and
4035 does not copy the found service.
4036 ***************************************************************************/
4038 int lp_servicenumber(const char *pszServiceName)
4040 int iService;
4041 fstring serviceName;
4043 if (!pszServiceName) {
4044 return GLOBAL_SECTION_SNUM;
4047 for (iService = iNumServices - 1; iService >= 0; iService--) {
4048 if (VALID(iService) && ServicePtrs[iService]->szService) {
4050 * The substitution here is used to support %U in
4051 * service names
4053 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4054 standard_sub_basic(get_current_username(),
4055 current_user_info.domain,
4056 serviceName,sizeof(serviceName));
4057 if (strequal(serviceName, pszServiceName)) {
4058 break;
4063 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4064 struct timespec last_mod;
4066 if (!usershare_exists(iService, &last_mod)) {
4067 /* Remove the share security tdb entry for it. */
4068 delete_share_security(lp_servicename(talloc_tos(), iService));
4069 /* Remove it from the array. */
4070 free_service_byindex(iService);
4071 /* Doesn't exist anymore. */
4072 return GLOBAL_SECTION_SNUM;
4075 /* Has it been modified ? If so delete and reload. */
4076 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4077 &last_mod) < 0) {
4078 /* Remove it from the array. */
4079 free_service_byindex(iService);
4080 /* and now reload it. */
4081 iService = load_usershare_service(pszServiceName);
4085 if (iService < 0) {
4086 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4087 return GLOBAL_SECTION_SNUM;
4090 return (iService);
4093 /*******************************************************************
4094 A useful volume label function.
4095 ********************************************************************/
4097 const char *volume_label(TALLOC_CTX *ctx, int snum)
4099 char *ret;
4100 const char *label = lp_volume(ctx, snum);
4101 if (!*label) {
4102 label = lp_servicename(ctx, snum);
4105 /* This returns a 33 byte guarenteed null terminated string. */
4106 ret = talloc_strndup(ctx, label, 32);
4107 if (!ret) {
4108 return "";
4110 return ret;
4113 /*******************************************************************
4114 Get the default server type we will announce as via nmbd.
4115 ********************************************************************/
4117 int lp_default_server_announce(void)
4119 int default_server_announce = 0;
4120 default_server_announce |= SV_TYPE_WORKSTATION;
4121 default_server_announce |= SV_TYPE_SERVER;
4122 default_server_announce |= SV_TYPE_SERVER_UNIX;
4124 /* note that the flag should be set only if we have a
4125 printer service but nmbd doesn't actually load the
4126 services so we can't tell --jerry */
4128 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4130 default_server_announce |= SV_TYPE_SERVER_NT;
4131 default_server_announce |= SV_TYPE_NT;
4133 switch (lp_server_role()) {
4134 case ROLE_DOMAIN_MEMBER:
4135 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4136 break;
4137 case ROLE_DOMAIN_PDC:
4138 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4139 break;
4140 case ROLE_DOMAIN_BDC:
4141 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4142 break;
4143 case ROLE_STANDALONE:
4144 default:
4145 break;
4147 if (lp_time_server())
4148 default_server_announce |= SV_TYPE_TIME_SOURCE;
4150 if (lp_host_msdfs())
4151 default_server_announce |= SV_TYPE_DFS_SERVER;
4153 return default_server_announce;
4156 /***********************************************************
4157 If we are PDC then prefer us as DMB
4158 ************************************************************/
4160 bool lp_domain_master(void)
4162 if (Globals._domain_master == Auto)
4163 return (lp_server_role() == ROLE_DOMAIN_PDC);
4165 return (bool)Globals._domain_master;
4168 /***********************************************************
4169 If we are PDC then prefer us as DMB
4170 ************************************************************/
4172 static bool lp_domain_master_true_or_auto(void)
4174 if (Globals._domain_master) /* auto or yes */
4175 return true;
4177 return false;
4180 /***********************************************************
4181 If we are DMB then prefer us as LMB
4182 ************************************************************/
4184 bool lp_preferred_master(void)
4186 if (Globals.iPreferredMaster == Auto)
4187 return (lp_local_master() && lp_domain_master());
4189 return (bool)Globals.iPreferredMaster;
4192 /*******************************************************************
4193 Remove a service.
4194 ********************************************************************/
4196 void lp_remove_service(int snum)
4198 ServicePtrs[snum]->valid = false;
4201 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4203 const char *ret = lp__printername(ctx, snum);
4204 if (ret == NULL || *ret == '\0') {
4205 ret = lp_const_servicename(snum);
4208 return ret;
4212 /***********************************************************
4213 Allow daemons such as winbindd to fix their logfile name.
4214 ************************************************************/
4216 void lp_set_logfile(const char *name)
4218 lpcfg_string_set(Globals.ctx, &Globals.logfile, name);
4219 debug_set_logfile(name);
4222 /*******************************************************************
4223 Return the max print jobs per queue.
4224 ********************************************************************/
4226 int lp_maxprintjobs(int snum)
4228 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4229 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4230 maxjobs = PRINT_MAX_JOBID - 1;
4232 return maxjobs;
4235 const char *lp_printcapname(void)
4237 if ((Globals.szPrintcapname != NULL) &&
4238 (Globals.szPrintcapname[0] != '\0'))
4239 return Globals.szPrintcapname;
4241 if (sDefault.printing == PRINT_CUPS) {
4242 return "cups";
4245 if (sDefault.printing == PRINT_BSD)
4246 return "/etc/printcap";
4248 return PRINTCAP_NAME;
4251 static uint32_t spoolss_state;
4253 bool lp_disable_spoolss( void )
4255 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4256 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4258 return spoolss_state == SVCCTL_STOPPED ? true : false;
4261 void lp_set_spoolss_state( uint32_t state )
4263 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4265 spoolss_state = state;
4268 uint32_t lp_get_spoolss_state( void )
4270 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4273 /*******************************************************************
4274 Ensure we don't use sendfile if server smb signing is active.
4275 ********************************************************************/
4277 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4279 bool sign_active = false;
4281 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4282 if (get_Protocol() < PROTOCOL_NT1) {
4283 return false;
4285 if (signing_state) {
4286 sign_active = smb_signing_is_active(signing_state);
4288 return (lp__use_sendfile(snum) &&
4289 (get_remote_arch() != RA_WIN95) &&
4290 !sign_active);
4293 /*******************************************************************
4294 Turn off sendfile if we find the underlying OS doesn't support it.
4295 ********************************************************************/
4297 void set_use_sendfile(int snum, bool val)
4299 if (LP_SNUM_OK(snum))
4300 ServicePtrs[snum]->_use_sendfile = val;
4301 else
4302 sDefault._use_sendfile = val;
4305 void lp_set_mangling_method(const char *new_method)
4307 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method);
4310 /*******************************************************************
4311 Global state for POSIX pathname processing.
4312 ********************************************************************/
4314 static bool posix_pathnames;
4316 bool lp_posix_pathnames(void)
4318 return posix_pathnames;
4321 /*******************************************************************
4322 Change everything needed to ensure POSIX pathname processing (currently
4323 not much).
4324 ********************************************************************/
4326 void lp_set_posix_pathnames(void)
4328 posix_pathnames = true;
4331 /*******************************************************************
4332 Global state for POSIX lock processing - CIFS unix extensions.
4333 ********************************************************************/
4335 bool posix_default_lock_was_set;
4336 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4338 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4340 if (posix_default_lock_was_set) {
4341 return posix_cifsx_locktype;
4342 } else {
4343 return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
4344 POSIX_LOCK : WINDOWS_LOCK;
4348 /*******************************************************************
4349 ********************************************************************/
4351 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4353 posix_default_lock_was_set = true;
4354 posix_cifsx_locktype = val;
4357 int lp_min_receive_file_size(void)
4359 if (Globals.iminreceivefile < 0) {
4360 return 0;
4362 return Globals.iminreceivefile;
4365 /*******************************************************************
4366 Safe wide links checks.
4367 This helper function always verify the validity of wide links,
4368 even after a configuration file reload.
4369 ********************************************************************/
4371 static bool lp_widelinks_internal(int snum)
4373 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
4374 sDefault.bWidelinks);
4377 void widelinks_warning(int snum)
4379 if (lp_allow_insecure_wide_links()) {
4380 return;
4383 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
4384 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4385 "These parameters are incompatible. "
4386 "Wide links will be disabled for this share.\n",
4387 lp_servicename(talloc_tos(), snum) ));
4391 bool lp_widelinks(int snum)
4393 /* wide links is always incompatible with unix extensions */
4394 if (lp_unix_extensions()) {
4396 * Unless we have "allow insecure widelinks"
4397 * turned on.
4399 if (!lp_allow_insecure_wide_links()) {
4400 return false;
4404 return lp_widelinks_internal(snum);
4407 int lp_server_role(void)
4409 return lp_find_server_role(lp__server_role(),
4410 lp__security(),
4411 lp__domain_logons(),
4412 lp_domain_master_true_or_auto());
4415 int lp_security(void)
4417 return lp_find_security(lp__server_role(),
4418 lp__security());
4421 int lp_client_max_protocol(void)
4423 int client_max_protocol = lp__client_max_protocol();
4424 if (client_max_protocol == PROTOCOL_DEFAULT) {
4425 return PROTOCOL_NT1;
4427 return client_max_protocol;
4430 int lp_winbindd_max_protocol(void)
4432 int client_max_protocol = lp__client_max_protocol();
4433 if (client_max_protocol == PROTOCOL_DEFAULT) {
4434 return PROTOCOL_LATEST;
4436 return client_max_protocol;
4439 struct loadparm_global * get_globals(void)
4441 return &Globals;
4444 unsigned int * get_flags(void)
4446 if (flags_list == NULL) {
4447 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
4450 return flags_list;