smbd: Fix some whitespace
[Samba.git] / source3 / param / loadparm.c
blob6b2f23ce633a371295b0b24f47b3afa4799fd4fb
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 #define LOADPARM_SUBSTITUTION_INTERNALS 1
57 #include "includes.h"
58 #include "system/filesys.h"
59 #include "util_tdb.h"
60 #include "lib/param/loadparm.h"
61 #include "lib/param/param.h"
62 #include "printing.h"
63 #include "lib/smbconf/smbconf.h"
64 #include "lib/smbconf/smbconf_init.h"
66 #include "include/smb_ldap.h"
67 #include "../librpc/gen_ndr/svcctl.h"
68 #include "intl.h"
69 #include "../libcli/smb/smb_signing.h"
70 #include "dbwrap/dbwrap.h"
71 #include "dbwrap/dbwrap_rbt.h"
72 #include "../lib/util/bitmap.h"
73 #include "librpc/gen_ndr/nbt.h"
74 #include "librpc/gen_ndr/dns.h"
75 #include "source4/lib/tls/tls.h"
76 #include "libcli/auth/ntlm_check.h"
77 #include "lib/crypto/gnutls_helpers.h"
78 #include "lib/util/string_wrappers.h"
79 #include "auth/credentials/credentials.h"
80 #include "source3/lib/substitute.h"
81 #include "source3/librpc/gen_ndr/ads.h"
82 #include "lib/util/time_basic.h"
83 #include "libds/common/flags.h"
85 #ifdef HAVE_SYS_SYSCTL_H
86 #include <sys/sysctl.h>
87 #endif
89 bool b_loaded = false;
91 /* the special value for the include parameter
92 * to be interpreted not as a file name but to
93 * trigger loading of the global smb.conf options
94 * from registry. */
95 #ifndef INCLUDE_REGISTRY_NAME
96 #define INCLUDE_REGISTRY_NAME "registry"
97 #endif
99 static bool in_client = false; /* Not in the client by default */
100 static struct smbconf_csn conf_last_csn;
102 static int config_backend = CONFIG_BACKEND_FILE;
104 /* some helpful bits */
105 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && \
106 (ServicePtrs != NULL) && \
107 (ServicePtrs[(i)] != NULL) && ServicePtrs[(i)]->valid)
108 #define VALID(i) ((ServicePtrs != NULL) && (ServicePtrs[i]!= NULL) && \
109 ServicePtrs[i]->valid)
111 #define USERSHARE_VALID 1
112 #define USERSHARE_PENDING_DELETE 2
114 static bool defaults_saved = false;
116 #include "lib/param/param_global.h"
118 static struct loadparm_global Globals;
120 /* This is a default service used to prime a services structure */
121 static const struct loadparm_service _sDefault =
123 .valid = true,
124 .autoloaded = false,
125 .usershare = 0,
126 .usershare_last_mod = {0, 0},
127 .szService = NULL,
128 .path = NULL,
129 .invalid_users = NULL,
130 .valid_users = NULL,
131 .admin_users = NULL,
132 .copy = NULL,
133 .include = NULL,
134 .preexec = NULL,
135 .postexec = NULL,
136 .root_preexec = NULL,
137 .root_postexec = NULL,
138 .cups_options = NULL,
139 .print_command = NULL,
140 .lpq_command = NULL,
141 .lprm_command = NULL,
142 .lppause_command = NULL,
143 .lpresume_command = NULL,
144 .queuepause_command = NULL,
145 .queueresume_command = NULL,
146 ._printername = NULL,
147 .printjob_username = NULL,
148 .dont_descend = NULL,
149 .hosts_allow = NULL,
150 .hosts_deny = NULL,
151 .magic_script = NULL,
152 .magic_output = NULL,
153 .veto_files = NULL,
154 .hide_files = NULL,
155 .veto_oplock_files = NULL,
156 .comment = NULL,
157 .force_user = NULL,
158 .force_group = NULL,
159 .read_list = NULL,
160 .write_list = NULL,
161 .volume = NULL,
162 .fstype = NULL,
163 .vfs_objects = NULL,
164 .msdfs_proxy = NULL,
165 .aio_write_behind = NULL,
166 .dfree_command = NULL,
167 .min_print_space = 0,
168 .max_print_jobs = 1000,
169 .max_reported_print_jobs = 0,
170 .create_mask = 0744,
171 .force_create_mode = 0,
172 .directory_mask = 0755,
173 .force_directory_mode = 0,
174 .max_connections = 0,
175 .default_case = CASE_LOWER,
176 .printing = DEFAULT_PRINTING,
177 .csc_policy = 0,
178 .block_size = 1024,
179 .dfree_cache_time = 0,
180 .preexec_close = false,
181 .root_preexec_close = false,
182 .case_sensitive = Auto,
183 .preserve_case = true,
184 .short_preserve_case = true,
185 .hide_dot_files = true,
186 .hide_special_files = false,
187 .hide_unreadable = false,
188 .hide_unwriteable_files = false,
189 .browseable = true,
190 .access_based_share_enum = false,
191 .available = true,
192 .read_only = true,
193 .spotlight = false,
194 .guest_only = false,
195 .administrative_share = false,
196 .guest_ok = false,
197 .printable = false,
198 .print_notify_backchannel = false,
199 .map_system = false,
200 .map_hidden = false,
201 .map_archive = true,
202 .store_dos_attributes = true,
203 .smbd_max_xattr_size = 65536,
204 .dmapi_support = false,
205 .locking = true,
206 .strict_locking = Auto,
207 .posix_locking = true,
208 .oplocks = true,
209 .kernel_oplocks = false,
210 .level2_oplocks = true,
211 .mangled_names = MANGLED_NAMES_ILLEGAL,
212 .wide_links = false,
213 .follow_symlinks = true,
214 .sync_always = false,
215 .strict_allocate = false,
216 .strict_rename = false,
217 .strict_sync = true,
218 .mangling_char = '~',
219 .copymap = NULL,
220 .delete_readonly = false,
221 .fake_oplocks = false,
222 .delete_veto_files = false,
223 .dos_filemode = false,
224 .dos_filetimes = true,
225 .dos_filetime_resolution = false,
226 .fake_directory_create_times = false,
227 .blocking_locks = true,
228 .inherit_permissions = false,
229 .inherit_acls = false,
230 .inherit_owner = false,
231 .msdfs_root = false,
232 .msdfs_shuffle_referrals = false,
233 .use_client_driver = false,
234 .default_devmode = true,
235 .force_printername = false,
236 .nt_acl_support = true,
237 .force_unknown_acl_user = false,
238 ._use_sendfile = false,
239 .map_acl_inherit = false,
240 .afs_share = false,
241 .ea_support = true,
242 .acl_check_permissions = true,
243 .acl_map_full_control = true,
244 .acl_group_control = false,
245 .acl_allow_execute_always = false,
246 .acl_flag_inherited_canonicalization = true,
247 .aio_read_size = 1,
248 .aio_write_size = 1,
249 .map_readonly = MAP_READONLY_NO,
250 .server_smb_encrypt = SMB_ENCRYPTION_DEFAULT,
251 .kernel_share_modes = false,
252 .durable_handles = true,
253 .check_parent_directory_delete_on_close = false,
254 .param_opt = NULL,
255 .smbd_search_ask_sharemode = true,
256 .smbd_getinfo_ask_sharemode = true,
257 .spotlight_backend = SPOTLIGHT_BACKEND_NOINDEX,
258 .honor_change_notify_privilege = false,
259 .volume_serial_number = -1,
260 .dummy = ""
264 * This is a copy of the default service structure. Service options in the
265 * global section would otherwise overwrite the initial default values.
267 static struct loadparm_service sDefault;
269 /* local variables */
270 static struct loadparm_service **ServicePtrs = NULL;
271 static int iNumServices = 0;
272 static int iServiceIndex = 0;
273 static struct db_context *ServiceHash;
274 static bool bInGlobalSection = true;
275 static bool bGlobalOnly = false;
276 static struct file_lists *file_lists = NULL;
277 static unsigned int *flags_list = NULL;
279 static void set_allowed_client_auth(void);
281 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
282 static void free_param_opts(struct parmlist_entry **popts);
285 * Function to return the default value for the maximum number of open
286 * file descriptors permitted. This function tries to consult the
287 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
288 * the smaller of those.
290 static int max_open_files(void)
292 int sysctl_max = MAX_OPEN_FILES;
293 int rlimit_max = MAX_OPEN_FILES;
295 #ifdef HAVE_SYSCTLBYNAME
297 size_t size = sizeof(sysctl_max);
298 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
301 #endif
303 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
305 struct rlimit rl;
307 ZERO_STRUCT(rl);
309 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
310 rlimit_max = rl.rlim_cur;
312 #if defined(RLIM_INFINITY)
313 if(rl.rlim_cur == RLIM_INFINITY)
314 rlimit_max = MAX_OPEN_FILES;
315 #endif
317 #endif
319 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
320 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
321 "minimum Windows limit (%d)\n",
322 sysctl_max,
323 MIN_OPEN_FILES_WINDOWS));
324 sysctl_max = MIN_OPEN_FILES_WINDOWS;
327 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
328 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
329 "minimum Windows limit (%d)\n",
330 rlimit_max,
331 MIN_OPEN_FILES_WINDOWS));
332 rlimit_max = MIN_OPEN_FILES_WINDOWS;
335 return MIN(sysctl_max, rlimit_max);
339 * Common part of freeing allocated data for one parameter.
341 static void free_one_parameter_common(void *parm_ptr,
342 struct parm_struct parm)
344 if ((parm.type == P_STRING) ||
345 (parm.type == P_USTRING))
347 lpcfg_string_free((char**)parm_ptr);
348 } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
349 TALLOC_FREE(*((char***)parm_ptr));
354 * Free the allocated data for one parameter for a share
355 * given as a service struct.
357 static void free_one_parameter(struct loadparm_service *service,
358 struct parm_struct parm)
360 void *parm_ptr;
362 if (parm.p_class != P_LOCAL) {
363 return;
366 parm_ptr = lp_parm_ptr(service, &parm);
368 free_one_parameter_common(parm_ptr, parm);
372 * Free the allocated parameter data of a share given
373 * as a service struct.
375 static void free_parameters(struct loadparm_service *service)
377 uint32_t i;
379 for (i=0; parm_table[i].label; i++) {
380 free_one_parameter(service, parm_table[i]);
385 * Free the allocated data for one parameter for a given share
386 * specified by an snum.
388 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
390 void *parm_ptr;
392 if (snum < 0) {
393 parm_ptr = lp_parm_ptr(NULL, &parm);
394 } else if (parm.p_class != P_LOCAL) {
395 return;
396 } else {
397 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
400 free_one_parameter_common(parm_ptr, parm);
404 * Free the allocated parameter data for a share specified
405 * by an snum.
407 static void free_parameters_by_snum(int snum)
409 uint32_t i;
411 for (i=0; parm_table[i].label; i++) {
412 free_one_parameter_by_snum(snum, parm_table[i]);
417 * Free the allocated global parameters.
419 static void free_global_parameters(void)
421 uint32_t i;
422 struct parm_struct *parm;
424 free_param_opts(&Globals.param_opt);
425 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
427 /* Reset references in the defaults because the context is going to be freed */
428 for (i=0; parm_table[i].label; i++) {
429 parm = &parm_table[i];
430 if ((parm->type == P_STRING) ||
431 (parm->type == P_USTRING)) {
432 if ((parm->def.svalue != NULL) &&
433 (*(parm->def.svalue) != '\0')) {
434 if (talloc_parent(parm->def.svalue) == Globals.ctx) {
435 parm->def.svalue = NULL;
440 TALLOC_FREE(Globals.ctx);
443 struct lp_stored_option {
444 struct lp_stored_option *prev, *next;
445 const char *label;
446 const char *value;
449 static struct lp_stored_option *stored_options;
452 save options set by lp_set_cmdline() into a list. This list is
453 re-applied when we do a globals reset, so that cmdline set options
454 are sticky across reloads of smb.conf
456 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
458 struct lp_stored_option *entry, *entry_next;
459 for (entry = stored_options; entry != NULL; entry = entry_next) {
460 entry_next = entry->next;
461 if (strcmp(pszParmName, entry->label) == 0) {
462 DLIST_REMOVE(stored_options, entry);
463 talloc_free(entry);
464 break;
468 entry = talloc(NULL, struct lp_stored_option);
469 if (!entry) {
470 return false;
473 entry->label = talloc_strdup(entry, pszParmName);
474 if (!entry->label) {
475 talloc_free(entry);
476 return false;
479 entry->value = talloc_strdup(entry, pszParmValue);
480 if (!entry->value) {
481 talloc_free(entry);
482 return false;
485 DLIST_ADD_END(stored_options, entry);
487 return true;
490 static bool apply_lp_set_cmdline(void)
492 struct lp_stored_option *entry = NULL;
493 for (entry = stored_options; entry != NULL; entry = entry->next) {
494 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
495 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
496 entry->label, entry->value));
497 return false;
500 return true;
503 /***************************************************************************
504 Initialise the global parameter structure.
505 ***************************************************************************/
507 void loadparm_s3_init_globals(struct loadparm_context *lp_ctx,
508 bool reinit_globals)
510 static bool done_init = false;
511 char *s = NULL;
512 int i;
514 /* If requested to initialize only once and we've already done it... */
515 if (!reinit_globals && done_init) {
516 /* ... then we have nothing more to do */
517 return;
520 if (!done_init) {
521 /* The logfile can be set before this is invoked. Free it if so. */
522 lpcfg_string_free(&Globals.logfile);
523 done_init = true;
524 } else {
525 free_global_parameters();
528 /* This memset and the free_global_parameters() above will
529 * wipe out smb.conf options set with lp_set_cmdline(). The
530 * apply_lp_set_cmdline() call puts these values back in the
531 * table once the defaults are set */
532 ZERO_STRUCT(Globals);
534 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
536 /* Initialize the flags list if necessary */
537 if (flags_list == NULL) {
538 get_flags();
541 for (i = 0; parm_table[i].label; i++) {
542 if ((parm_table[i].type == P_STRING ||
543 parm_table[i].type == P_USTRING))
545 lpcfg_string_set(
546 Globals.ctx,
547 (char **)lp_parm_ptr(NULL, &parm_table[i]),
548 "");
553 lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
554 lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U");
556 init_printer_values(lp_ctx, Globals.ctx, &sDefault);
558 sDefault.ntvfs_handler = str_list_make_v3_const(Globals.ctx, "unixuid default", NULL);
560 DEBUG(3, ("Initialising global parameters\n"));
562 /* Must manually force to upper case here, as this does not go via the handler */
563 lpcfg_string_set(Globals.ctx, &Globals.netbios_name,
564 myhostname_upper());
566 lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file,
567 get_dyn_SMB_PASSWD_FILE());
568 lpcfg_string_set(Globals.ctx, &Globals.private_dir,
569 get_dyn_PRIVATE_DIR());
570 lpcfg_string_set(Globals.ctx, &Globals.binddns_dir,
571 get_dyn_BINDDNS_DIR());
573 /* use the new 'hash2' method by default, with a prefix of 1 */
574 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
575 Globals.mangle_prefix = 1;
577 lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
579 /* using UTF8 by default allows us to support all chars */
580 lpcfg_string_set(Globals.ctx, &Globals.unix_charset,
581 DEFAULT_UNIX_CHARSET);
583 /* Use codepage 850 as a default for the dos character set */
584 lpcfg_string_set(Globals.ctx, &Globals.dos_charset,
585 DEFAULT_DOS_CHARSET);
588 * Allow the default PASSWD_CHAT to be overridden in local.h.
590 lpcfg_string_set(Globals.ctx, &Globals.passwd_chat,
591 DEFAULT_PASSWD_CHAT);
593 lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
595 lpcfg_string_set(Globals.ctx, &Globals.passwd_program, "");
596 lpcfg_string_set(Globals.ctx, &Globals.lock_directory,
597 get_dyn_LOCKDIR());
598 lpcfg_string_set(Globals.ctx, &Globals.state_directory,
599 get_dyn_STATEDIR());
600 lpcfg_string_set(Globals.ctx, &Globals.cache_directory,
601 get_dyn_CACHEDIR());
602 lpcfg_string_set(Globals.ctx, &Globals.pid_directory,
603 get_dyn_PIDDIR());
604 lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address,
605 "0.0.0.0");
607 * By default support explicit binding to broadcast
608 * addresses.
610 Globals.nmbd_bind_explicit_broadcast = true;
612 s = talloc_asprintf(Globals.ctx, "Samba %s", samba_version_string());
613 if (s == NULL) {
614 smb_panic("init_globals: ENOMEM");
616 lpcfg_string_set(Globals.ctx, &Globals.server_string, s);
617 TALLOC_FREE(s);
618 #ifdef DEVELOPER
619 lpcfg_string_set(Globals.ctx, &Globals.panic_action,
620 "/bin/sleep 999999999");
621 #endif
623 lpcfg_string_set(Globals.ctx, &Globals.socket_options,
624 DEFAULT_SOCKET_OPTIONS);
626 lpcfg_string_set(Globals.ctx, &Globals.logon_drive, "");
627 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
628 lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
629 lpcfg_string_set(Globals.ctx, &Globals.logon_path,
630 "\\\\%N\\%U\\profile");
632 Globals.name_resolve_order =
633 str_list_make_v3_const(Globals.ctx,
634 DEFAULT_NAME_RESOLVE_ORDER,
635 NULL);
636 lpcfg_string_set(Globals.ctx, &Globals.password_server, "*");
638 Globals.algorithmic_rid_base = BASE_RID;
640 Globals.load_printers = true;
641 Globals.printcap_cache_time = 750; /* 12.5 minutes */
643 Globals.config_backend = config_backend;
644 Globals._server_role = ROLE_AUTO;
646 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
647 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
648 Globals.max_xmit = 0x4104;
649 Globals.max_mux = 50; /* This is *needed* for profile support. */
650 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
651 Globals._disable_spoolss = false;
652 Globals.max_smbd_processes = 0;/* no limit specified */
653 Globals.username_level = 0;
654 Globals.deadtime = 10080;
655 Globals.getwd_cache = true;
656 Globals.large_readwrite = true;
657 Globals.max_log_size = 5000;
658 Globals.max_open_files = max_open_files();
659 Globals.server_max_protocol = PROTOCOL_SMB3_11;
660 Globals.server_min_protocol = PROTOCOL_SMB2_02;
661 Globals._client_max_protocol = PROTOCOL_DEFAULT;
662 Globals.client_min_protocol = PROTOCOL_SMB2_02;
663 Globals._client_ipc_max_protocol = PROTOCOL_DEFAULT;
664 Globals._client_ipc_min_protocol = PROTOCOL_DEFAULT;
665 Globals._security = SEC_AUTO;
666 Globals.encrypt_passwords = true;
667 Globals.client_schannel = true;
668 Globals.winbind_sealed_pipes = true;
669 Globals.require_strong_key = true;
670 Globals.reject_md5_servers = true;
671 Globals.server_schannel = true;
672 Globals.server_schannel_require_seal = true;
673 Globals.reject_md5_clients = true;
674 Globals.read_raw = true;
675 Globals.write_raw = true;
676 Globals.null_passwords = false;
677 Globals.old_password_allowed_period = 60;
678 Globals.obey_pam_restrictions = false;
679 Globals.syslog = 1;
680 Globals.syslog_only = false;
681 Globals.timestamp_logs = true;
682 lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
683 Globals.debug_prefix_timestamp = false;
684 Globals.debug_hires_timestamp = true;
685 Globals.debug_syslog_format = false;
686 Globals.debug_pid = false;
687 Globals.debug_uid = false;
688 Globals.debug_class = false;
689 Globals.enable_core_files = true;
690 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
691 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
692 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
693 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
694 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
695 Globals.lm_interval = 60;
696 Globals.time_server = false;
697 Globals.bind_interfaces_only = false;
698 Globals.unix_password_sync = false;
699 Globals.pam_password_change = false;
700 Globals.passwd_chat_debug = false;
701 Globals.passwd_chat_timeout = 2; /* 2 second default. */
702 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
703 Globals.nt_status_support = true; /* Use NT status by default. */
704 Globals.smbd_profiling_level = 0;
705 Globals.stat_cache = true; /* use stat cache by default */
706 Globals.max_stat_cache_size = 512; /* 512k by default */
707 Globals.restrict_anonymous = 0;
708 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
709 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
710 Globals._lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
711 Globals.ntlm_auth = NTLM_AUTH_NTLMV2_ONLY; /* Do NOT use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
712 Globals.nt_hash_store = NT_HASH_STORE_ALWAYS; /* Fill in NT hash when setting password */
713 Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */
714 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 */
715 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
717 Globals.allow_dcerpc_auth_level_connect = false; /* we don't allow this by default */
719 Globals.map_to_guest = 0; /* By Default, "Never" */
720 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
721 Globals.enhanced_browsing = true;
722 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
723 Globals.use_mmap = true;
724 Globals.unicode = true;
725 Globals.smb1_unix_extensions = true;
726 Globals.reset_on_zero_vc = false;
727 Globals.log_writeable_files_on_exit = false;
728 Globals.create_krb5_conf = true;
729 Globals.include_system_krb5_conf = true;
730 Globals._winbind_max_domain_connections = 1;
732 /* hostname lookups can be very expensive and are broken on
733 a large number of sites (tridge) */
734 Globals.hostname_lookups = false;
736 Globals.change_notify = true,
737 Globals.kernel_change_notify = true,
739 lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
740 lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, "");
741 lpcfg_string_set(Globals.ctx, &Globals._ldap_machine_suffix, "");
742 lpcfg_string_set(Globals.ctx, &Globals._ldap_user_suffix, "");
743 lpcfg_string_set(Globals.ctx, &Globals._ldap_group_suffix, "");
744 lpcfg_string_set(Globals.ctx, &Globals._ldap_idmap_suffix, "");
746 lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
747 Globals.ldap_ssl = LDAP_SSL_START_TLS;
748 Globals.ldap_deref = -1;
749 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
750 Globals.ldap_delete_dn = false;
751 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
752 Globals.ldap_follow_referral = Auto;
753 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
754 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
755 Globals.ldap_page_size = LDAP_PAGE_SIZE;
757 Globals.ldap_debug_level = 0;
758 Globals.ldap_debug_threshold = 10;
760 Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SEAL;
762 Globals.ldap_server_require_strong_auth =
763 LDAP_SERVER_REQUIRE_STRONG_AUTH_YES;
765 /* This is what we tell the afs client. in reality we set the token
766 * to never expire, though, when this runs out the afs client will
767 * forget the token. Set to 0 to get NEVERDATE.*/
768 Globals.afs_token_lifetime = 604800;
769 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
771 /* these parameters are set to defaults that are more appropriate
772 for the increasing samba install base:
774 as a member of the workgroup, that will possibly become a
775 _local_ master browser (lm = true). this is opposed to a forced
776 local master browser startup (pm = true).
778 doesn't provide WINS server service by default (wsupp = false),
779 and doesn't provide domain master browser services by default, either.
783 Globals.show_add_printer_wizard = true;
784 Globals.os_level = 20;
785 Globals.local_master = true;
786 Globals._domain_master = Auto; /* depending on _domain_logons */
787 Globals._domain_logons = false;
788 Globals.browse_list = true;
789 Globals.we_are_a_wins_server = false;
790 Globals.wins_proxy = false;
792 TALLOC_FREE(Globals.init_logon_delayed_hosts);
793 Globals.init_logon_delay = 100; /* 100 ms default delay */
795 Globals.wins_dns_proxy = true;
796 Globals.dns_port = DNS_SERVICE_PORT;
798 Globals.allow_trusted_domains = true;
799 lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb");
801 lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
802 lpcfg_string_set(Globals.ctx, &Globals.template_homedir,
803 "/home/%D/%U");
804 lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\");
805 lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory,
806 dyn_WINBINDD_SOCKET_DIR);
808 lpcfg_string_set(Globals.ctx, &Globals.cups_server, "");
809 lpcfg_string_set(Globals.ctx, &Globals.iprint_server, "");
811 lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, "");
813 Globals.cluster_addresses = NULL;
814 Globals.clustering = false;
815 Globals.ctdb_timeout = 0;
816 Globals.ctdb_locktime_warn_threshold = 0;
818 Globals.winbind_cache_time = 300; /* 5 minutes */
819 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
820 Globals.winbind_request_timeout = 60; /* 60 seconds */
821 Globals.winbind_max_clients = 200;
822 Globals.winbind_enum_users = false;
823 Globals.winbind_enum_groups = false;
824 Globals.winbind_use_default_domain = false;
825 Globals.winbind_nested_groups = true;
826 Globals.winbind_expand_groups = 0;
827 Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
828 Globals.winbind_refresh_tickets = false;
829 Globals.winbind_offline_logon = false;
830 Globals.winbind_scan_trusted_domains = false;
832 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
833 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
835 Globals.passdb_expand_explicit = false;
837 Globals.name_cache_timeout = 660; /* In seconds */
839 Globals.client_use_spnego = true;
841 Globals.client_signing = SMB_SIGNING_DEFAULT;
842 Globals._client_ipc_signing = SMB_SIGNING_DEFAULT;
843 Globals.server_signing = SMB_SIGNING_DEFAULT;
845 Globals.defer_sharing_violations = true;
846 Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
848 Globals.enable_privileges = true;
849 Globals.host_msdfs = true;
850 Globals.enable_asu_support = false;
852 /* User defined shares. */
853 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
854 if (s == NULL) {
855 smb_panic("init_globals: ENOMEM");
857 lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s);
858 TALLOC_FREE(s);
859 lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, "");
860 Globals.usershare_max_shares = 0;
861 /* By default disallow sharing of directories not owned by the sharer. */
862 Globals.usershare_owner_only = true;
863 /* By default disallow guest access to usershares. */
864 Globals.usershare_allow_guests = false;
866 Globals.keepalive = DEFAULT_KEEPALIVE;
868 /* By default no shares out of the registry */
869 Globals.registry_shares = false;
871 Globals.min_receivefile_size = 0;
873 Globals.multicast_dns_register = true;
875 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
876 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
877 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
878 Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
879 Globals.smb2_leases = true;
880 Globals.server_multi_channel_support = true;
882 lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir,
883 get_dyn_NCALRPCDIR());
885 Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
887 Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
889 Globals.tls_enabled = true;
890 Globals.tls_verify_peer = TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE;
892 lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
893 lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
894 lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
895 lpcfg_string_set(Globals.ctx,
896 &Globals.tls_priority,
897 "NORMAL:-VERS-SSL3.0");
899 Globals._preferred_master = Auto;
901 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
902 Globals.dns_zone_scavenging = false;
904 lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
905 get_dyn_NTP_SIGND_SOCKET_DIR());
907 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
908 if (s == NULL) {
909 smb_panic("init_globals: ENOMEM");
911 Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
912 TALLOC_FREE(s);
914 #ifdef MIT_KDC_PATH
915 Globals.mit_kdc_command = str_list_make_v3_const(NULL, MIT_KDC_PATH, NULL);
916 #endif
918 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
919 if (s == NULL) {
920 smb_panic("init_globals: ENOMEM");
922 Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
923 TALLOC_FREE(s);
925 s = talloc_asprintf(talloc_tos(), "%s/samba-gpupdate", get_dyn_SCRIPTSBINDIR());
926 if (s == NULL) {
927 smb_panic("init_globals: ENOMEM");
929 Globals.gpo_update_command = str_list_make_v3_const(NULL, s, NULL);
930 TALLOC_FREE(s);
932 Globals.apply_group_policies = false;
934 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
935 if (s == NULL) {
936 smb_panic("init_globals: ENOMEM");
938 Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
939 TALLOC_FREE(s);
941 Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
943 Globals.cldap_port = 389;
945 Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
947 Globals.nbt_port = NBT_NAME_SERVICE_PORT;
949 Globals.krb5_port = 88;
951 Globals.kpasswd_port = 464;
953 Globals.kdc_enable_fast = true;
955 Globals.aio_max_threads = 100;
957 lpcfg_string_set(Globals.ctx,
958 &Globals.rpc_server_dynamic_port_range,
959 "49152-65535");
960 Globals.rpc_low_port = SERVER_TCP_LOW_PORT;
961 Globals.rpc_high_port = SERVER_TCP_HIGH_PORT;
962 Globals.prefork_children = 4;
963 Globals.prefork_backoff_increment = 10;
964 Globals.prefork_maximum_backoff = 120;
966 Globals.ldap_max_anonymous_request_size = 256000;
967 Globals.ldap_max_authenticated_request_size = 16777216;
968 Globals.ldap_max_search_request_size = 256000;
970 /* Async DNS query timeout (in seconds). */
971 Globals.async_dns_timeout = 10;
973 Globals.client_smb_encrypt = SMB_ENCRYPTION_DEFAULT;
975 Globals._client_use_kerberos = CRED_USE_KERBEROS_DESIRED;
977 Globals.client_protection = CRED_CLIENT_PROTECTION_DEFAULT;
979 Globals.winbind_use_krb5_enterprise_principals = true;
981 Globals.client_smb3_signing_algorithms =
982 str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
983 Globals.server_smb3_signing_algorithms =
984 str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
986 Globals.client_smb3_encryption_algorithms =
987 str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
988 Globals.server_smb3_encryption_algorithms =
989 str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
991 Globals.min_domain_uid = 1000;
994 * By default allow smbd and winbindd to start samba-dcerpcd as
995 * a named-pipe helper.
997 Globals.rpc_start_on_demand_helpers = true;
999 Globals.ad_dc_functional_level = DS_DOMAIN_FUNCTION_2008_R2,
1001 Globals.acl_claims_evaluation = ACL_CLAIMS_EVALUATION_AD_DC_ONLY;
1003 /* Now put back the settings that were set with lp_set_cmdline() */
1004 apply_lp_set_cmdline();
1007 /* Convenience routine to setup an lp_context with additional s3 variables */
1008 static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
1010 struct loadparm_context *lp_ctx;
1012 lp_ctx = loadparm_init_s3(mem_ctx,
1013 loadparm_s3_helpers());
1014 if (lp_ctx == NULL) {
1015 DEBUG(0, ("loadparm_init_s3 failed\n"));
1016 return NULL;
1019 lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
1020 if (lp_ctx->sDefault == NULL) {
1021 DBG_ERR("talloc_zero failed\n");
1022 TALLOC_FREE(lp_ctx);
1023 return NULL;
1026 *lp_ctx->sDefault = _sDefault;
1027 lp_ctx->services = NULL; /* We do not want to access this directly */
1028 lp_ctx->bInGlobalSection = bInGlobalSection;
1029 lp_ctx->flags = flags_list;
1031 return lp_ctx;
1034 /*******************************************************************
1035 Convenience routine to grab string parameters into talloced memory
1036 and run standard_sub_basic on them. The buffers can be written to by
1037 callers without affecting the source string.
1038 ********************************************************************/
1040 static char *loadparm_s3_global_substitution_fn(
1041 TALLOC_CTX *mem_ctx,
1042 const struct loadparm_substitution *lp_sub,
1043 const char *s,
1044 void *private_data)
1046 char *ret;
1048 /* The follow debug is useful for tracking down memory problems
1049 especially if you have an inner loop that is calling a lp_*()
1050 function that returns a string. Perhaps this debug should be
1051 present all the time? */
1053 #if 0
1054 DEBUG(10, ("lp_string(%s)\n", s));
1055 #endif
1056 if (!s) {
1057 return NULL;
1060 ret = talloc_sub_basic(mem_ctx,
1061 get_current_username(),
1062 get_current_user_info_domain(),
1064 if (trim_char(ret, '\"', '\"')) {
1065 if (strchr(ret,'\"') != NULL) {
1066 TALLOC_FREE(ret);
1067 ret = talloc_sub_basic(mem_ctx,
1068 get_current_username(),
1069 get_current_user_info_domain(),
1073 return ret;
1076 static const struct loadparm_substitution s3_global_substitution = {
1077 .substituted_string_fn = loadparm_s3_global_substitution_fn,
1080 const struct loadparm_substitution *loadparm_s3_global_substitution(void)
1082 return &s3_global_substitution;
1086 In this section all the functions that are used to access the
1087 parameters from the rest of the program are defined
1090 #define FN_GLOBAL_SUBSTITUTED_STRING(fn_name,ptr) \
1091 char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub) \
1092 {return lpcfg_substituted_string(ctx, lp_sub, *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : "");}
1093 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1094 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1095 #define FN_GLOBAL_LIST(fn_name,ptr) \
1096 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1097 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1098 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1099 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1100 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1101 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1102 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1104 #define FN_LOCAL_SUBSTITUTED_STRING(fn_name,val) \
1105 char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub, int i) \
1106 {return lpcfg_substituted_string((ctx), lp_sub, (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1107 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1108 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1109 #define FN_LOCAL_LIST(fn_name,val) \
1110 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1111 #define FN_LOCAL_BOOL(fn_name,val) \
1112 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1113 #define FN_LOCAL_INTEGER(fn_name,val) \
1114 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1116 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1117 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1118 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1119 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1120 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1121 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1123 int lp_winbind_max_domain_connections(void)
1125 if (lp_winbind_offline_logon() &&
1126 lp__winbind_max_domain_connections() > 1) {
1127 DEBUG(1, ("offline logons active, restricting max domain "
1128 "connections to 1\n"));
1129 return 1;
1131 return MAX(1, lp__winbind_max_domain_connections());
1134 /* These functions remain in source3/param for now */
1136 #include "lib/param/param_functions.c"
1138 FN_LOCAL_SUBSTITUTED_STRING(servicename, szService)
1139 FN_LOCAL_CONST_STRING(const_servicename, szService)
1141 /* These functions cannot be auto-generated */
1142 FN_LOCAL_BOOL(autoloaded, autoloaded)
1143 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1145 /* local prototypes */
1147 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1148 static const char *get_boolean(bool bool_value);
1149 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1150 void *userdata);
1151 static bool hash_a_service(const char *name, int number);
1152 static void free_service_byindex(int iService);
1153 static void show_parameter(int parmIndex);
1154 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1155 static bool lp_parameter_value_is_valid(const char *parm_name, const char *val);
1158 * This is a helper function for parametrical options support. It returns a
1159 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1160 * parametrical functions are quite simple
1162 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1163 const char *option)
1165 if (snum >= iNumServices) return NULL;
1167 if (snum < 0) {
1168 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1169 } else {
1170 return get_parametric_helper(ServicePtrs[snum],
1171 type, option, Globals.param_opt);
1175 static void discard_whitespace(char *str)
1177 size_t len = strlen(str);
1178 size_t i = 0;
1180 while (i < len) {
1181 if (isspace(str[i])) {
1182 memmove(&str[i], &str[i+1], len-i);
1183 len -= 1;
1184 continue;
1186 i += 1;
1191 * @brief Go through all global parametric parameters
1193 * @param regex_str A regular expression to scan param for
1194 * @param max_matches Max number of submatches the regexp expects
1195 * @param cb Function to call on match. Should return true
1196 * when it wants wi_scan_global_parametrics to stop
1197 * scanning
1198 * @param private_data Anonymous pointer passed to cb
1200 * @return 0: success, regcomp/regexec return value on error.
1201 * See "man regexec" for possible errors
1204 int lp_wi_scan_global_parametrics(
1205 const char *regex_str, size_t max_matches,
1206 bool (*cb)(const char *string, regmatch_t matches[],
1207 void *private_data),
1208 void *private_data)
1210 struct parmlist_entry *data;
1211 regex_t regex;
1212 int ret;
1214 ret = regcomp(&regex, regex_str, REG_ICASE);
1215 if (ret != 0) {
1216 return ret;
1219 for (data = Globals.param_opt; data != NULL; data = data->next) {
1220 size_t keylen = strlen(data->key);
1221 char key[keylen+1];
1222 regmatch_t matches[max_matches];
1223 bool stop;
1225 memcpy(key, data->key, sizeof(key));
1226 discard_whitespace(key);
1228 ret = regexec(&regex, key, max_matches, matches, 0);
1229 if (ret == REG_NOMATCH) {
1230 continue;
1232 if (ret != 0) {
1233 goto fail;
1236 stop = cb(key, matches, private_data);
1237 if (stop) {
1238 break;
1242 ret = 0;
1243 fail:
1244 regfree(&regex);
1245 return ret;
1249 #define MISSING_PARAMETER(name) \
1250 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1252 /*******************************************************************
1253 convenience routine to return enum parameters.
1254 ********************************************************************/
1255 static int lp_enum(const char *s,const struct enum_list *_enum)
1257 int i;
1259 if (!s || !*s || !_enum) {
1260 MISSING_PARAMETER(lp_enum);
1261 return (-1);
1264 for (i=0; _enum[i].name; i++) {
1265 if (strequal(_enum[i].name,s))
1266 return _enum[i].value;
1269 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1270 return (-1);
1273 #undef MISSING_PARAMETER
1275 /* Return parametric option from a given service. Type is a part of option before ':' */
1276 /* Parametric option has following syntax: 'Type: option = value' */
1277 char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx,
1278 const struct loadparm_substitution *lp_sub,
1279 int snum,
1280 const char *type,
1281 const char *option,
1282 const char *def)
1284 struct parmlist_entry *data = get_parametrics(snum, type, option);
1286 SMB_ASSERT(lp_sub != NULL);
1288 if (data == NULL||data->value==NULL) {
1289 if (def) {
1290 return lpcfg_substituted_string(mem_ctx, lp_sub, def);
1291 } else {
1292 return NULL;
1296 return lpcfg_substituted_string(mem_ctx, lp_sub, data->value);
1299 /* Return parametric option from a given service. Type is a part of option before ':' */
1300 /* Parametric option has following syntax: 'Type: option = value' */
1301 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1303 struct parmlist_entry *data = get_parametrics(snum, type, option);
1305 if (data == NULL||data->value==NULL)
1306 return def;
1308 return data->value;
1312 /* Return parametric option from a given service. Type is a part of option before ':' */
1313 /* Parametric option has following syntax: 'Type: option = value' */
1315 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1317 struct parmlist_entry *data = get_parametrics(snum, type, option);
1319 if (data == NULL||data->value==NULL)
1320 return (const char **)def;
1322 if (data->list==NULL) {
1323 data->list = str_list_make_v3(NULL, data->value, NULL);
1326 return discard_const_p(const char *, data->list);
1329 /* Return parametric option from a given service. Type is a part of option before ':' */
1330 /* Parametric option has following syntax: 'Type: option = value' */
1332 int lp_parm_int(int snum, const char *type, const char *option, int def)
1334 struct parmlist_entry *data = get_parametrics(snum, type, option);
1336 if (data && data->value && *data->value)
1337 return lp_int(data->value);
1339 return def;
1342 /* Return parametric option from a given service. Type is a part of option before ':' */
1343 /* Parametric option has following syntax: 'Type: option = value' */
1345 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1347 struct parmlist_entry *data = get_parametrics(snum, type, option);
1349 if (data && data->value && *data->value)
1350 return lp_ulong(data->value);
1352 return def;
1355 /* Return parametric option from a given service. Type is a part of option before ':' */
1356 /* Parametric option has following syntax: 'Type: option = value' */
1358 unsigned long long lp_parm_ulonglong(int snum, const char *type,
1359 const char *option, unsigned long long def)
1361 struct parmlist_entry *data = get_parametrics(snum, type, option);
1363 if (data && data->value && *data->value) {
1364 return lp_ulonglong(data->value);
1367 return def;
1370 /* Return parametric option from a given service. Type is a part of option
1371 * before ':' */
1372 /* Parametric option has following syntax: 'Type: option = value' */
1374 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1376 struct parmlist_entry *data = get_parametrics(snum, type, option);
1378 if (data && data->value && *data->value)
1379 return lp_bool(data->value);
1381 return def;
1384 /* Return parametric option from a given service. Type is a part of option before ':' */
1385 /* Parametric option has following syntax: 'Type: option = value' */
1387 int lp_parm_enum(int snum, const char *type, const char *option,
1388 const struct enum_list *_enum, int def)
1390 struct parmlist_entry *data = get_parametrics(snum, type, option);
1392 if (data && data->value && *data->value && _enum)
1393 return lp_enum(data->value, _enum);
1395 return def;
1399 * free a param_opts structure.
1400 * param_opts handling should be moved to talloc;
1401 * then this whole functions reduces to a TALLOC_FREE().
1404 static void free_param_opts(struct parmlist_entry **popts)
1406 struct parmlist_entry *opt, *next_opt;
1408 if (*popts != NULL) {
1409 DEBUG(5, ("Freeing parametrics:\n"));
1411 opt = *popts;
1412 while (opt != NULL) {
1413 lpcfg_string_free(&opt->key);
1414 lpcfg_string_free(&opt->value);
1415 TALLOC_FREE(opt->list);
1416 next_opt = opt->next;
1417 TALLOC_FREE(opt);
1418 opt = next_opt;
1420 *popts = NULL;
1423 /***************************************************************************
1424 Free the dynamically allocated parts of a service struct.
1425 ***************************************************************************/
1427 static void free_service(struct loadparm_service *pservice)
1429 if (!pservice)
1430 return;
1432 if (pservice->szService)
1433 DEBUG(5, ("free_service: Freeing service %s\n",
1434 pservice->szService));
1436 free_parameters(pservice);
1438 lpcfg_string_free(&pservice->szService);
1439 TALLOC_FREE(pservice->copymap);
1441 free_param_opts(&pservice->param_opt);
1443 ZERO_STRUCTP(pservice);
1447 /***************************************************************************
1448 remove a service indexed in the ServicePtrs array from the ServiceHash
1449 and free the dynamically allocated parts
1450 ***************************************************************************/
1452 static void free_service_byindex(int idx)
1454 if ( !LP_SNUM_OK(idx) )
1455 return;
1457 ServicePtrs[idx]->valid = false;
1459 /* we have to cleanup the hash record */
1461 if (ServicePtrs[idx]->szService) {
1462 char *canon_name = canonicalize_servicename(
1463 talloc_tos(),
1464 ServicePtrs[idx]->szService );
1466 dbwrap_delete_bystring(ServiceHash, canon_name );
1467 TALLOC_FREE(canon_name);
1470 free_service(ServicePtrs[idx]);
1471 TALLOC_FREE(ServicePtrs[idx]);
1474 /***************************************************************************
1475 Add a new service to the services array initialising it with the given
1476 service.
1477 ***************************************************************************/
1479 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1481 int i;
1482 struct loadparm_service **tsp = NULL;
1484 /* it might already exist */
1485 if (name) {
1486 i = getservicebyname(name, NULL);
1487 if (i >= 0) {
1488 return (i);
1492 /* Re use empty slots if any before allocating new one.*/
1493 for (i=0; i < iNumServices; i++) {
1494 if (ServicePtrs[i] == NULL) {
1495 break;
1498 if (i == iNumServices) {
1499 /* if not, then create one */
1500 tsp = talloc_realloc(NULL, ServicePtrs,
1501 struct loadparm_service *,
1502 iNumServices + 1);
1503 if (tsp == NULL) {
1504 DEBUG(0, ("add_a_service: failed to enlarge "
1505 "ServicePtrs!\n"));
1506 return (-1);
1508 ServicePtrs = tsp;
1509 iNumServices++;
1511 ServicePtrs[i] = talloc_zero(ServicePtrs, struct loadparm_service);
1512 if (!ServicePtrs[i]) {
1513 DEBUG(0,("add_a_service: out of memory!\n"));
1514 return (-1);
1517 ServicePtrs[i]->valid = true;
1519 copy_service(ServicePtrs[i], pservice, NULL);
1520 if (name)
1521 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
1522 name);
1524 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1525 i, ServicePtrs[i]->szService));
1527 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1528 return (-1);
1531 return (i);
1534 /***************************************************************************
1535 Convert a string to uppercase and remove whitespaces.
1536 ***************************************************************************/
1538 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1540 char *result;
1542 if ( !src ) {
1543 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1544 return NULL;
1547 result = talloc_strdup(ctx, src);
1548 SMB_ASSERT(result != NULL);
1550 if (!strlower_m(result)) {
1551 TALLOC_FREE(result);
1552 return NULL;
1554 return result;
1557 /***************************************************************************
1558 Add a name/index pair for the services array to the hash table.
1559 ***************************************************************************/
1561 static bool hash_a_service(const char *name, int idx)
1563 char *canon_name;
1565 if ( !ServiceHash ) {
1566 DEBUG(10,("hash_a_service: creating servicehash\n"));
1567 ServiceHash = db_open_rbt(NULL);
1568 if ( !ServiceHash ) {
1569 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1570 return false;
1574 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1575 idx, name));
1577 canon_name = canonicalize_servicename(talloc_tos(), name );
1579 dbwrap_store_bystring(ServiceHash, canon_name,
1580 make_tdb_data((uint8_t *)&idx, sizeof(idx)),
1581 TDB_REPLACE);
1583 TALLOC_FREE(canon_name);
1585 return true;
1588 /***************************************************************************
1589 Add a new home service, with the specified home directory, defaults coming
1590 from service ifrom.
1591 ***************************************************************************/
1593 bool lp_add_home(const char *pszHomename, int iDefaultService,
1594 const char *user, const char *pszHomedir)
1596 const struct loadparm_substitution *lp_sub =
1597 loadparm_s3_global_substitution();
1598 int i;
1599 char *global_path;
1601 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1602 pszHomedir[0] == '\0') {
1603 return false;
1606 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1608 if (i < 0)
1609 return false;
1611 global_path = lp_path(talloc_tos(), lp_sub, GLOBAL_SECTION_SNUM);
1612 if (!(*(ServicePtrs[iDefaultService]->path))
1613 || strequal(ServicePtrs[iDefaultService]->path, global_path)) {
1614 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
1615 pszHomedir);
1617 TALLOC_FREE(global_path);
1619 if (!(*(ServicePtrs[i]->comment))) {
1620 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1621 if (comment == NULL) {
1622 return false;
1624 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment,
1625 comment);
1626 TALLOC_FREE(comment);
1629 /* set the browseable flag from the global default */
1631 ServicePtrs[i]->browseable = sDefault.browseable;
1632 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1634 ServicePtrs[i]->autoloaded = true;
1636 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1637 user, ServicePtrs[i]->path ));
1639 return true;
1642 /***************************************************************************
1643 Add a new service, based on an old one.
1644 ***************************************************************************/
1646 int lp_add_service(const char *pszService, int iDefaultService)
1648 if (iDefaultService < 0) {
1649 return add_a_service(&sDefault, pszService);
1652 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1655 /***************************************************************************
1656 Add the IPC service.
1657 ***************************************************************************/
1659 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1661 char *comment = NULL;
1662 int i = add_a_service(&sDefault, ipc_name);
1664 if (i < 0)
1665 return false;
1667 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1668 Globals.server_string);
1669 if (comment == NULL) {
1670 return false;
1673 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1674 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1675 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1676 ServicePtrs[i]->max_connections = 0;
1677 ServicePtrs[i]->available = true;
1678 ServicePtrs[i]->read_only = true;
1679 ServicePtrs[i]->guest_only = false;
1680 ServicePtrs[i]->administrative_share = true;
1681 ServicePtrs[i]->guest_ok = guest_ok;
1682 ServicePtrs[i]->printable = false;
1683 ServicePtrs[i]->browseable = sDefault.browseable;
1684 ServicePtrs[i]->autoloaded = false;
1686 DEBUG(3, ("adding IPC service\n"));
1688 TALLOC_FREE(comment);
1689 return true;
1692 /***************************************************************************
1693 Add a new printer service, with defaults coming from service iFrom.
1694 ***************************************************************************/
1696 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1698 const char *comment = "From Printcap";
1699 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1701 if (i < 0)
1702 return false;
1704 /* note that we do NOT default the availability flag to true - */
1705 /* we take it from the default service passed. This allows all */
1706 /* dynamic printers to be disabled by disabling the [printers] */
1707 /* entry (if/when the 'available' keyword is implemented!). */
1709 /* the printer name is set to the service name. */
1710 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername,
1711 pszPrintername);
1712 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1714 /* set the browseable flag from the global default */
1715 ServicePtrs[i]->browseable = sDefault.browseable;
1717 /* Printers cannot be read_only. */
1718 ServicePtrs[i]->read_only = false;
1719 /* No oplocks on printer services. */
1720 ServicePtrs[i]->oplocks = false;
1721 /* Printer services must be printable. */
1722 ServicePtrs[i]->printable = true;
1724 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1726 return true;
1730 /***************************************************************************
1731 Check whether the given parameter name is valid.
1732 Parametric options (names containing a colon) are considered valid.
1733 ***************************************************************************/
1735 bool lp_parameter_is_valid(const char *pszParmName)
1737 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1738 (strchr(pszParmName, ':') != NULL));
1741 /***************************************************************************
1742 Check whether the given name is the name of a global parameter.
1743 Returns true for strings belonging to parameters of class
1744 P_GLOBAL, false for all other strings, also for parametric options
1745 and strings not belonging to any option.
1746 ***************************************************************************/
1748 bool lp_parameter_is_global(const char *pszParmName)
1750 int num = lpcfg_map_parameter(pszParmName);
1752 if (num >= 0) {
1753 return (parm_table[num].p_class == P_GLOBAL);
1756 return false;
1759 /**************************************************************************
1760 Determine the canonical name for a parameter.
1761 Indicate when it is an inverse (boolean) synonym instead of a
1762 "usual" synonym.
1763 **************************************************************************/
1765 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1766 bool *inverse)
1768 int num;
1770 if (!lp_parameter_is_valid(parm_name)) {
1771 *canon_parm = NULL;
1772 return false;
1775 num = map_parameter_canonical(parm_name, inverse);
1776 if (num < 0) {
1777 /* parametric option */
1778 *canon_parm = parm_name;
1779 } else {
1780 *canon_parm = parm_table[num].label;
1783 return true;
1787 /**************************************************************************
1788 Determine the canonical name for a parameter.
1789 Turn the value given into the inverse boolean expression when
1790 the synonym is an inverse boolean synonym.
1792 Return true if
1793 - parm_name is a valid parameter name and
1794 - val is a valid value for this parameter and
1795 - in case the parameter is an inverse boolean synonym, if the val
1796 string could successfully be converted to the reverse bool.
1797 Return false in all other cases.
1798 **************************************************************************/
1800 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1801 const char *val,
1802 const char **canon_parm,
1803 const char **canon_val)
1805 int num;
1806 bool inverse;
1807 bool ret;
1809 if (!lp_parameter_is_valid(parm_name)) {
1810 *canon_parm = NULL;
1811 *canon_val = NULL;
1812 return false;
1815 num = map_parameter_canonical(parm_name, &inverse);
1816 if (num < 0) {
1817 /* parametric option */
1818 *canon_parm = parm_name;
1819 *canon_val = val;
1820 return true;
1823 *canon_parm = parm_table[num].label;
1824 if (inverse) {
1825 if (!lp_invert_boolean(val, canon_val)) {
1826 *canon_val = NULL;
1827 return false;
1829 } else {
1830 *canon_val = val;
1833 ret = lp_parameter_value_is_valid(*canon_parm, *canon_val);
1835 return ret;
1838 /***************************************************************************
1839 Map a parameter's string representation to the index of the canonical
1840 form of the parameter (it might be a synonym).
1841 Returns -1 if the parameter string is not recognised.
1842 ***************************************************************************/
1844 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1846 int parm_num, canon_num;
1847 bool loc_inverse = false;
1849 parm_num = lpcfg_map_parameter(pszParmName);
1850 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
1851 /* invalid, parametric or no candidate for synonyms ... */
1852 goto done;
1855 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1856 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1857 parm_num = canon_num;
1858 goto done;
1862 done:
1863 if (inverse != NULL) {
1864 *inverse = loc_inverse;
1866 return parm_num;
1869 /***************************************************************************
1870 return true if parameter number parm1 is a synonym of parameter
1871 number parm2 (parm2 being the principal name).
1872 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1873 false otherwise.
1874 ***************************************************************************/
1876 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1878 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1879 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1880 (parm_table[parm1].flags & FLAG_SYNONYM) &&
1881 !(parm_table[parm2].flags & FLAG_SYNONYM))
1883 if (inverse != NULL) {
1884 if ((parm_table[parm1].type == P_BOOLREV) &&
1885 (parm_table[parm2].type == P_BOOL))
1887 *inverse = true;
1888 } else {
1889 *inverse = false;
1892 return true;
1894 return false;
1897 /***************************************************************************
1898 Show one parameter's name, type, [values,] and flags.
1899 (helper functions for show_parameter_list)
1900 ***************************************************************************/
1902 static void show_parameter(int parmIndex)
1904 size_t enumIndex, flagIndex;
1905 size_t parmIndex2;
1906 bool hadFlag;
1907 bool hadSyn;
1908 bool inverse;
1909 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1910 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1911 "P_ENUM", "P_BYTES", "P_CMDLIST" };
1912 unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
1913 const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
1915 printf("%s=%s", parm_table[parmIndex].label,
1916 type[parm_table[parmIndex].type]);
1917 if (parm_table[parmIndex].type == P_ENUM) {
1918 printf(",");
1919 for (enumIndex=0;
1920 parm_table[parmIndex].enum_list[enumIndex].name;
1921 enumIndex++)
1923 printf("%s%s",
1924 enumIndex ? "|" : "",
1925 parm_table[parmIndex].enum_list[enumIndex].name);
1928 printf(",");
1929 hadFlag = false;
1930 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1931 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1932 printf("%s%s",
1933 hadFlag ? "|" : "",
1934 flag_names[flagIndex]);
1935 hadFlag = true;
1939 /* output synonyms */
1940 hadSyn = false;
1941 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1942 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1943 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1944 parm_table[parmIndex2].label);
1945 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1946 if (!hadSyn) {
1947 printf(" (synonyms: ");
1948 hadSyn = true;
1949 } else {
1950 printf(", ");
1952 printf("%s%s", parm_table[parmIndex2].label,
1953 inverse ? "[i]" : "");
1956 if (hadSyn) {
1957 printf(")");
1960 printf("\n");
1964 * Check the value for a P_ENUM
1966 static bool check_enum_parameter(struct parm_struct *parm, const char *value)
1968 int i;
1970 for (i = 0; parm->enum_list[i].name; i++) {
1971 if (strwicmp(value, parm->enum_list[i].name) == 0) {
1972 return true;
1975 return false;
1978 /**************************************************************************
1979 Check whether the given value is valid for the given parameter name.
1980 **************************************************************************/
1982 static bool lp_parameter_value_is_valid(const char *parm_name, const char *val)
1984 bool ret = false, tmp_bool;
1985 int num = lpcfg_map_parameter(parm_name), tmp_int;
1986 uint64_t tmp_int64 = 0;
1987 struct parm_struct *parm;
1989 /* parametric options (parameter names containing a colon) cannot
1990 be checked and are therefore considered valid. */
1991 if (strchr(parm_name, ':') != NULL) {
1992 return true;
1995 if (num >= 0) {
1996 parm = &parm_table[num];
1997 switch (parm->type) {
1998 case P_BOOL:
1999 case P_BOOLREV:
2000 ret = set_boolean(val, &tmp_bool);
2001 break;
2003 case P_INTEGER:
2004 ret = (sscanf(val, "%d", &tmp_int) == 1);
2005 break;
2007 case P_OCTAL:
2008 ret = (sscanf(val, "%o", &tmp_int) == 1);
2009 break;
2011 case P_ENUM:
2012 ret = check_enum_parameter(parm, val);
2013 break;
2015 case P_BYTES:
2016 if (conv_str_size_error(val, &tmp_int64) &&
2017 tmp_int64 <= INT_MAX) {
2018 ret = true;
2020 break;
2022 case P_CHAR:
2023 case P_LIST:
2024 case P_STRING:
2025 case P_USTRING:
2026 case P_CMDLIST:
2027 ret = true;
2028 break;
2031 return ret;
2034 /***************************************************************************
2035 Show all parameter's name, type, [values,] and flags.
2036 ***************************************************************************/
2038 void show_parameter_list(void)
2040 int classIndex, parmIndex;
2041 const char *section_names[] = { "local", "global", NULL};
2043 for (classIndex=0; section_names[classIndex]; classIndex++) {
2044 printf("[%s]\n", section_names[classIndex]);
2045 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2046 if (parm_table[parmIndex].p_class == classIndex) {
2047 show_parameter(parmIndex);
2053 /***************************************************************************
2054 Get the standard string representation of a boolean value ("yes" or "no")
2055 ***************************************************************************/
2057 static const char *get_boolean(bool bool_value)
2059 static const char *yes_str = "yes";
2060 static const char *no_str = "no";
2062 return (bool_value ? yes_str : no_str);
2065 /***************************************************************************
2066 Provide the string of the negated boolean value associated to the boolean
2067 given as a string. Returns false if the passed string does not correctly
2068 represent a boolean.
2069 ***************************************************************************/
2071 bool lp_invert_boolean(const char *str, const char **inverse_str)
2073 bool val;
2075 if (!set_boolean(str, &val)) {
2076 return false;
2079 *inverse_str = get_boolean(!val);
2080 return true;
2083 /***************************************************************************
2084 Provide the canonical string representation of a boolean value given
2085 as a string. Return true on success, false if the string given does
2086 not correctly represent a boolean.
2087 ***************************************************************************/
2089 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2091 bool val;
2093 if (!set_boolean(str, &val)) {
2094 return false;
2097 *canon_str = get_boolean(val);
2098 return true;
2101 /***************************************************************************
2102 Find a service by name. Otherwise works like get_service.
2103 ***************************************************************************/
2105 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2107 int iService = -1;
2108 char *canon_name;
2109 TDB_DATA data;
2110 NTSTATUS status;
2112 if (ServiceHash == NULL) {
2113 return -1;
2116 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2118 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2119 &data);
2121 if (NT_STATUS_IS_OK(status) &&
2122 (data.dptr != NULL) &&
2123 (data.dsize == sizeof(iService)))
2125 memcpy(&iService, data.dptr, sizeof(iService));
2128 TALLOC_FREE(canon_name);
2130 if ((iService != -1) && (LP_SNUM_OK(iService))
2131 && (pserviceDest != NULL)) {
2132 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2135 return (iService);
2138 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2139 struct loadparm_service *lp_service(const char *pszServiceName)
2141 int iService = getservicebyname(pszServiceName, NULL);
2142 if (iService == -1 || !LP_SNUM_OK(iService)) {
2143 return NULL;
2145 return ServicePtrs[iService];
2148 struct loadparm_service *lp_servicebynum(int snum)
2150 if ((snum == -1) || !LP_SNUM_OK(snum)) {
2151 return NULL;
2153 return ServicePtrs[snum];
2156 struct loadparm_service *lp_default_loadparm_service(void)
2158 return &sDefault;
2161 static struct smbconf_ctx *lp_smbconf_ctx(void)
2163 sbcErr err;
2164 static struct smbconf_ctx *conf_ctx = NULL;
2166 if (conf_ctx == NULL) {
2167 err = smbconf_init(NULL, &conf_ctx, "registry:");
2168 if (!SBC_ERROR_IS_OK(err)) {
2169 DEBUG(1, ("error initializing registry configuration: "
2170 "%s\n", sbcErrorString(err)));
2171 conf_ctx = NULL;
2175 return conf_ctx;
2178 static bool process_smbconf_service(struct smbconf_service *service)
2180 uint32_t count;
2181 bool ret;
2183 if (service == NULL) {
2184 return false;
2187 ret = lp_do_section(service->name, NULL);
2188 if (ret != true) {
2189 return false;
2191 for (count = 0; count < service->num_params; count++) {
2193 if (!bInGlobalSection && bGlobalOnly) {
2194 ret = true;
2195 } else {
2196 const char *pszParmName = service->param_names[count];
2197 const char *pszParmValue = service->param_values[count];
2199 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2201 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2202 pszParmName, pszParmValue);
2205 if (ret != true) {
2206 return false;
2209 if (iServiceIndex >= 0) {
2210 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2212 return true;
2216 * load a service from registry and activate it
2218 bool process_registry_service(const char *service_name)
2220 sbcErr err;
2221 struct smbconf_service *service = NULL;
2222 TALLOC_CTX *mem_ctx = talloc_stackframe();
2223 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2224 bool ret = false;
2226 if (conf_ctx == NULL) {
2227 goto done;
2230 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2232 if (!smbconf_share_exists(conf_ctx, service_name)) {
2234 * Registry does not contain data for this service (yet),
2235 * but make sure lp_load doesn't return false.
2237 ret = true;
2238 goto done;
2241 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2242 if (!SBC_ERROR_IS_OK(err)) {
2243 goto done;
2246 ret = process_smbconf_service(service);
2247 if (!ret) {
2248 goto done;
2251 /* store the csn */
2252 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2254 done:
2255 TALLOC_FREE(mem_ctx);
2256 return ret;
2260 * process_registry_globals
2262 static bool process_registry_globals(void)
2264 bool ret;
2266 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2268 if (!bInGlobalSection && bGlobalOnly) {
2269 ret = true;
2270 } else {
2271 const char *pszParmName = "registry shares";
2272 const char *pszParmValue = "yes";
2274 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2276 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2277 pszParmName, pszParmValue);
2280 if (!ret) {
2281 return ret;
2284 return process_registry_service(GLOBAL_NAME);
2287 bool process_registry_shares(void)
2289 sbcErr err;
2290 uint32_t count;
2291 struct smbconf_service **service = NULL;
2292 uint32_t num_shares = 0;
2293 TALLOC_CTX *mem_ctx = talloc_stackframe();
2294 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2295 bool ret = false;
2297 if (conf_ctx == NULL) {
2298 goto done;
2301 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2302 if (!SBC_ERROR_IS_OK(err)) {
2303 goto done;
2306 ret = true;
2308 for (count = 0; count < num_shares; count++) {
2309 if (strequal(service[count]->name, GLOBAL_NAME)) {
2310 continue;
2312 ret = process_smbconf_service(service[count]);
2313 if (!ret) {
2314 goto done;
2318 /* store the csn */
2319 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2321 done:
2322 TALLOC_FREE(mem_ctx);
2323 return ret;
2327 * reload those shares from registry that are already
2328 * activated in the services array.
2330 static bool reload_registry_shares(void)
2332 int i;
2333 bool ret = true;
2335 for (i = 0; i < iNumServices; i++) {
2336 if (!VALID(i)) {
2337 continue;
2340 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2341 continue;
2344 ret = process_registry_service(ServicePtrs[i]->szService);
2345 if (!ret) {
2346 goto done;
2350 done:
2351 return ret;
2355 #define MAX_INCLUDE_DEPTH 100
2357 static uint8_t include_depth;
2360 * Free the file lists
2362 static void free_file_list(void)
2364 struct file_lists *f;
2365 struct file_lists *next;
2367 f = file_lists;
2368 while( f ) {
2369 next = f->next;
2370 TALLOC_FREE( f );
2371 f = next;
2373 file_lists = NULL;
2378 * Utility function for outsiders to check if we're running on registry.
2380 bool lp_config_backend_is_registry(void)
2382 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2386 * Utility function to check if the config backend is FILE.
2388 bool lp_config_backend_is_file(void)
2390 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2393 /*******************************************************************
2394 Check if a config file has changed date.
2395 ********************************************************************/
2397 bool lp_file_list_changed(void)
2399 struct file_lists *f = file_lists;
2401 DEBUG(6, ("lp_file_list_changed()\n"));
2403 while (f) {
2404 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2405 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2407 if (conf_ctx == NULL) {
2408 return false;
2410 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2411 NULL))
2413 DEBUGADD(6, ("registry config changed\n"));
2414 return true;
2416 } else {
2417 struct timespec mod_time = {
2418 .tv_sec = 0,
2420 struct timeval_buf tbuf = {
2421 .buf = {0},
2423 char *n2 = NULL;
2424 struct stat sb = {0};
2425 int rc;
2427 n2 = talloc_sub_basic(talloc_tos(),
2428 get_current_username(),
2429 get_current_user_info_domain(),
2430 f->name);
2431 if (!n2) {
2432 return false;
2434 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2435 f->name, n2,
2436 timespec_string_buf(&f->modtime,
2437 true,
2438 &tbuf)));
2440 rc = stat(n2, &sb);
2441 if (rc == 0) {
2442 mod_time = get_mtimespec(&sb);
2445 if (mod_time.tv_sec > 0 &&
2446 ((timespec_compare(&mod_time, &f->modtime) != 0) ||
2447 (f->subfname == NULL) ||
2448 (strcmp(n2, f->subfname) != 0)))
2450 f->modtime = mod_time;
2452 DEBUGADD(6,
2453 ("file %s modified: %s\n", n2,
2454 timespec_string_buf(&f->modtime,
2455 true,
2456 &tbuf)));
2458 TALLOC_FREE(f->subfname);
2459 f->subfname = talloc_strdup(f, n2);
2460 if (f->subfname == NULL) {
2461 smb_panic("talloc_strdup failed");
2463 TALLOC_FREE(n2);
2464 return true;
2466 TALLOC_FREE(n2);
2468 f = f->next;
2470 return false;
2475 * Initialize iconv conversion descriptors.
2477 * This is called the first time it is needed, and also called again
2478 * every time the configuration is reloaded, because the charset or
2479 * codepage might have changed.
2481 static void init_iconv(void)
2483 struct smb_iconv_handle *ret = NULL;
2485 ret = reinit_iconv_handle(NULL,
2486 lp_dos_charset(),
2487 lp_unix_charset());
2488 if (ret == NULL) {
2489 smb_panic("reinit_iconv_handle failed");
2493 /***************************************************************************
2494 Handle the include operation.
2495 ***************************************************************************/
2496 static bool bAllowIncludeRegistry = true;
2498 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2499 const char *pszParmValue, char **ptr)
2501 char *fname;
2503 if (include_depth >= MAX_INCLUDE_DEPTH) {
2504 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2505 include_depth));
2506 return false;
2509 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2510 if (!bAllowIncludeRegistry) {
2511 return true;
2513 if (lp_ctx->bInGlobalSection) {
2514 bool ret;
2515 include_depth++;
2516 ret = process_registry_globals();
2517 include_depth--;
2518 return ret;
2519 } else {
2520 DEBUG(1, ("\"include = registry\" only effective "
2521 "in %s section\n", GLOBAL_NAME));
2522 return false;
2526 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2527 get_current_user_info_domain(),
2528 pszParmValue);
2530 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2532 if (service == NULL) {
2533 lpcfg_string_set(Globals.ctx, ptr, fname);
2534 } else {
2535 lpcfg_string_set(service, ptr, fname);
2538 if (file_exist(fname)) {
2539 bool ret;
2540 include_depth++;
2541 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2542 include_depth--;
2543 TALLOC_FREE(fname);
2544 return ret;
2547 DEBUG(2, ("Can't find include file %s\n", fname));
2548 TALLOC_FREE(fname);
2549 return true;
2552 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2554 char *config_option = NULL;
2555 const char *range = NULL;
2556 bool ret = false;
2558 SMB_ASSERT(low != NULL);
2559 SMB_ASSERT(high != NULL);
2561 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2562 domain_name = "*";
2565 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2566 domain_name);
2567 if (config_option == NULL) {
2568 DEBUG(0, ("out of memory\n"));
2569 return false;
2572 range = lp_parm_const_string(-1, config_option, "range", NULL);
2573 if (range == NULL) {
2574 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2575 goto done;
2578 if (sscanf(range, "%u - %u", low, high) != 2) {
2579 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2580 range, domain_name));
2581 goto done;
2584 ret = true;
2586 done:
2587 talloc_free(config_option);
2588 return ret;
2592 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2594 return lp_idmap_range("*", low, high);
2597 const char *lp_idmap_backend(const char *domain_name)
2599 char *config_option = NULL;
2600 const char *backend = NULL;
2602 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2603 domain_name = "*";
2606 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2607 domain_name);
2608 if (config_option == NULL) {
2609 DEBUG(0, ("out of memory\n"));
2610 return false;
2613 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2614 if (backend == NULL) {
2615 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2616 goto done;
2619 done:
2620 talloc_free(config_option);
2621 return backend;
2624 const char *lp_idmap_default_backend(void)
2626 return lp_idmap_backend("*");
2629 /***************************************************************************
2630 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2631 ***************************************************************************/
2633 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2635 const char *suffix_string;
2637 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2638 Globals.ldap_suffix );
2639 if ( !suffix_string ) {
2640 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2641 return "";
2644 return suffix_string;
2647 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2649 if (Globals._ldap_machine_suffix[0])
2650 return append_ldap_suffix(ctx, Globals._ldap_machine_suffix);
2652 return talloc_strdup(ctx, Globals.ldap_suffix);
2655 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2657 if (Globals._ldap_user_suffix[0])
2658 return append_ldap_suffix(ctx, Globals._ldap_user_suffix);
2660 return talloc_strdup(ctx, Globals.ldap_suffix);
2663 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2665 if (Globals._ldap_group_suffix[0])
2666 return append_ldap_suffix(ctx, Globals._ldap_group_suffix);
2668 return talloc_strdup(ctx, Globals.ldap_suffix);
2671 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2673 if (Globals._ldap_idmap_suffix[0])
2674 return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix);
2676 return talloc_strdup(ctx, Globals.ldap_suffix);
2680 return the parameter pointer for a parameter
2682 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2684 if (service == NULL) {
2685 if (parm->p_class == P_LOCAL)
2686 return (void *)(((char *)&sDefault)+parm->offset);
2687 else if (parm->p_class == P_GLOBAL)
2688 return (void *)(((char *)&Globals)+parm->offset);
2689 else return NULL;
2690 } else {
2691 return (void *)(((char *)service) + parm->offset);
2695 /***************************************************************************
2696 Process a parameter for a particular service number. If snum < 0
2697 then assume we are in the globals.
2698 ***************************************************************************/
2700 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2702 TALLOC_CTX *frame = talloc_stackframe();
2703 struct loadparm_context *lp_ctx;
2704 bool ok;
2706 lp_ctx = setup_lp_context(frame);
2707 if (lp_ctx == NULL) {
2708 TALLOC_FREE(frame);
2709 return false;
2712 if (snum < 0) {
2713 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2714 } else {
2715 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2716 pszParmName, pszParmValue);
2719 TALLOC_FREE(frame);
2721 return ok;
2724 /***************************************************************************
2725 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2726 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2727 ***************************************************************************/
2729 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2731 int parmnum, i;
2732 parmnum = lpcfg_map_parameter(pszParmName);
2733 if (parmnum >= 0) {
2734 flags_list[parmnum] &= ~FLAG_CMDLINE;
2735 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2736 return false;
2738 flags_list[parmnum] |= FLAG_CMDLINE;
2740 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2741 * be grouped in the table, so we don't have to search the
2742 * whole table */
2743 for (i=parmnum-1;
2744 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2745 && parm_table[i].p_class == parm_table[parmnum].p_class;
2746 i--) {
2747 flags_list[i] |= FLAG_CMDLINE;
2749 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2750 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2751 flags_list[i] |= FLAG_CMDLINE;
2754 return true;
2757 /* it might be parametric */
2758 if (strchr(pszParmName, ':') != NULL) {
2759 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2760 return true;
2763 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2764 return false;
2767 /***************************************************************************
2768 Process a parameter.
2769 ***************************************************************************/
2771 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2772 void *userdata)
2774 if (!bInGlobalSection && bGlobalOnly)
2775 return true;
2777 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2779 if (bInGlobalSection) {
2780 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2781 } else {
2782 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2783 pszParmName, pszParmValue);
2788 static const char *ad_dc_req_vfs_mods[] = {"dfs_samba4", "acl_xattr", NULL};
2791 * check that @vfs_objects includes all vfs modules required by an AD DC.
2793 static bool check_ad_dc_required_mods(const char **vfs_objects)
2795 int i;
2796 int j;
2797 int got_req;
2799 for (i = 0; ad_dc_req_vfs_mods[i] != NULL; i++) {
2800 got_req = false;
2801 for (j = 0; vfs_objects[j] != NULL; j++) {
2802 if (!strwicmp(ad_dc_req_vfs_mods[i], vfs_objects[j])) {
2803 got_req = true;
2804 break;
2807 if (!got_req) {
2808 DEBUG(0, ("vfs objects specified without required AD "
2809 "DC module: %s\n", ad_dc_req_vfs_mods[i]));
2810 return false;
2814 DEBUG(6, ("vfs objects specified with all required AD DC modules\n"));
2815 return true;
2819 /***************************************************************************
2820 Initialize any local variables in the sDefault table, after parsing a
2821 [globals] section.
2822 ***************************************************************************/
2824 static void init_locals(void)
2827 * We run this check once the [globals] is parsed, to force
2828 * the VFS objects and other per-share settings we need for
2829 * the standard way a AD DC is operated. We may change these
2830 * as our code evolves, which is why we force these settings.
2832 * We can't do this at the end of lp_load_ex(), as by that
2833 * point the services have been loaded and they will already
2834 * have "" as their vfs objects.
2836 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2837 const char **vfs_objects = lp_vfs_objects(-1);
2838 if (vfs_objects != NULL) {
2839 /* ignore return, only warn if modules are missing */
2840 check_ad_dc_required_mods(vfs_objects);
2841 } else {
2842 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2843 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2844 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2845 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2846 } else {
2847 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2851 lp_do_parameter(-1, "map hidden", "no");
2852 lp_do_parameter(-1, "map system", "no");
2853 lp_do_parameter(-1, "map readonly", "no");
2854 lp_do_parameter(-1, "map archive", "no");
2855 lp_do_parameter(-1, "store dos attributes", "yes");
2859 /***************************************************************************
2860 Process a new section (service). At this stage all sections are services.
2861 Later we'll have special sections that permit server parameters to be set.
2862 Returns true on success, false on failure.
2863 ***************************************************************************/
2865 bool lp_do_section(const char *pszSectionName, void *userdata)
2867 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2868 bool bRetval;
2869 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2870 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2872 /* if we were in a global section then do the local inits */
2873 if (bInGlobalSection && !isglobal)
2874 init_locals();
2876 /* if we've just struck a global section, note the fact. */
2877 bInGlobalSection = isglobal;
2878 if (lp_ctx != NULL) {
2879 lp_ctx->bInGlobalSection = isglobal;
2882 /* check for multiple global sections */
2883 if (bInGlobalSection) {
2884 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2885 return true;
2888 if (!bInGlobalSection && bGlobalOnly)
2889 return true;
2891 /* if we have a current service, tidy it up before moving on */
2892 bRetval = true;
2894 if ((iServiceIndex >= 0) && (ServicePtrs[iServiceIndex] != NULL))
2895 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2897 /* if all is still well, move to the next record in the services array */
2898 if (bRetval) {
2899 /* We put this here to avoid an odd message order if messages are */
2900 /* issued by the post-processing of a previous section. */
2901 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2903 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2904 if (iServiceIndex < 0) {
2905 DEBUG(0, ("Failed to add a new service\n"));
2906 return false;
2908 /* Clean all parametric options for service */
2909 /* They will be added during parsing again */
2910 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2913 return bRetval;
2916 /***************************************************************************
2917 Display the contents of a parameter of a single services record.
2918 ***************************************************************************/
2920 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2922 bool result = false;
2923 struct loadparm_context *lp_ctx;
2925 lp_ctx = setup_lp_context(talloc_tos());
2926 if (lp_ctx == NULL) {
2927 return false;
2930 if (isGlobal) {
2931 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2932 } else {
2933 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2935 TALLOC_FREE(lp_ctx);
2936 return result;
2939 #if 0
2940 /***************************************************************************
2941 Display the contents of a single copy structure.
2942 ***************************************************************************/
2943 static void dump_copy_map(bool *pcopymap)
2945 int i;
2946 if (!pcopymap)
2947 return;
2949 printf("\n\tNon-Copied parameters:\n");
2951 for (i = 0; parm_table[i].label; i++)
2952 if (parm_table[i].p_class == P_LOCAL &&
2953 parm_table[i].ptr && !pcopymap[i] &&
2954 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2956 printf("\t\t%s\n", parm_table[i].label);
2959 #endif
2961 /***************************************************************************
2962 Return TRUE if the passed service number is within range.
2963 ***************************************************************************/
2965 bool lp_snum_ok(int iService)
2967 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->available);
2970 /***************************************************************************
2971 Auto-load some home services.
2972 ***************************************************************************/
2974 static void lp_add_auto_services(const char *str)
2976 char *s;
2977 char *p;
2978 int homes;
2979 char *saveptr;
2981 if (!str)
2982 return;
2984 s = talloc_strdup(talloc_tos(), str);
2985 if (!s) {
2986 smb_panic("talloc_strdup failed");
2987 return;
2990 homes = lp_servicenumber(HOMES_NAME);
2992 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2993 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2994 char *home;
2996 if (lp_servicenumber(p) >= 0)
2997 continue;
2999 home = get_user_home_dir(talloc_tos(), p);
3001 if (home && home[0] && homes >= 0)
3002 lp_add_home(p, homes, p, home);
3004 TALLOC_FREE(home);
3006 TALLOC_FREE(s);
3009 /***************************************************************************
3010 Auto-load one printer.
3011 ***************************************************************************/
3013 void lp_add_one_printer(const char *name, const char *comment,
3014 const char *location, void *pdata)
3016 int printers = lp_servicenumber(PRINTERS_NAME);
3017 int i;
3019 if (lp_servicenumber(name) < 0) {
3020 lp_add_printer(name, printers);
3021 if ((i = lp_servicenumber(name)) >= 0) {
3022 lpcfg_string_set(ServicePtrs[i],
3023 &ServicePtrs[i]->comment, comment);
3024 ServicePtrs[i]->autoloaded = true;
3029 /***************************************************************************
3030 Have we loaded a services file yet?
3031 ***************************************************************************/
3033 bool lp_loaded(void)
3035 return (b_loaded);
3038 /***************************************************************************
3039 Unload unused services.
3040 ***************************************************************************/
3042 void lp_killunused(struct smbd_server_connection *sconn,
3043 bool (*snumused) (struct smbd_server_connection *, int))
3045 int i;
3046 for (i = 0; i < iNumServices; i++) {
3047 if (!VALID(i))
3048 continue;
3050 /* don't kill autoloaded or usershare services */
3051 if ( ServicePtrs[i]->autoloaded ||
3052 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3053 continue;
3056 if (!snumused || !snumused(sconn, i)) {
3057 free_service_byindex(i);
3063 * Kill all except autoloaded and usershare services - convenience wrapper
3065 void lp_kill_all_services(void)
3067 lp_killunused(NULL, NULL);
3070 /***************************************************************************
3071 Unload a service.
3072 ***************************************************************************/
3074 void lp_killservice(int iServiceIn)
3076 if (VALID(iServiceIn)) {
3077 free_service_byindex(iServiceIn);
3081 /***************************************************************************
3082 Save the current values of all global and sDefault parameters into the
3083 defaults union. This allows testparm to show only the
3084 changed (ie. non-default) parameters.
3085 ***************************************************************************/
3087 static void lp_save_defaults(void)
3089 int i;
3090 struct parmlist_entry * parm;
3091 for (i = 0; parm_table[i].label; i++) {
3092 if (!(flags_list[i] & FLAG_CMDLINE)) {
3093 flags_list[i] |= FLAG_DEFAULT;
3096 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3097 && parm_table[i].p_class == parm_table[i - 1].p_class)
3098 continue;
3099 switch (parm_table[i].type) {
3100 case P_LIST:
3101 case P_CMDLIST:
3102 parm_table[i].def.lvalue = str_list_copy(
3103 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3104 break;
3105 case P_STRING:
3106 case P_USTRING:
3107 lpcfg_string_set(
3108 Globals.ctx,
3109 &parm_table[i].def.svalue,
3110 *(char **)lp_parm_ptr(
3111 NULL, &parm_table[i]));
3112 if (parm_table[i].def.svalue == NULL) {
3113 smb_panic("lpcfg_string_set() failed");
3115 break;
3116 case P_BOOL:
3117 case P_BOOLREV:
3118 parm_table[i].def.bvalue =
3119 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3120 break;
3121 case P_CHAR:
3122 parm_table[i].def.cvalue =
3123 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3124 break;
3125 case P_INTEGER:
3126 case P_OCTAL:
3127 case P_ENUM:
3128 case P_BYTES:
3129 parm_table[i].def.ivalue =
3130 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3131 break;
3135 for (parm=Globals.param_opt; parm; parm=parm->next) {
3136 if (!(parm->priority & FLAG_CMDLINE)) {
3137 parm->priority |= FLAG_DEFAULT;
3141 for (parm=sDefault.param_opt; parm; parm=parm->next) {
3142 if (!(parm->priority & FLAG_CMDLINE)) {
3143 parm->priority |= FLAG_DEFAULT;
3147 defaults_saved = true;
3150 /***********************************************************
3151 If we should send plaintext/LANMAN passwords in the client
3152 ************************************************************/
3154 static void set_allowed_client_auth(void)
3156 if (Globals.client_ntlmv2_auth) {
3157 Globals.client_lanman_auth = false;
3159 if (!Globals.client_lanman_auth) {
3160 Globals.client_plaintext_auth = false;
3164 /***************************************************************************
3165 JRA.
3166 The following code allows smbd to read a user defined share file.
3167 Yes, this is my intent. Yes, I'm comfortable with that...
3169 THE FOLLOWING IS SECURITY CRITICAL CODE.
3171 It washes your clothes, it cleans your house, it guards you while you sleep...
3172 Do not f%^k with it....
3173 ***************************************************************************/
3175 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3177 /***************************************************************************
3178 Check allowed stat state of a usershare file.
3179 Ensure we print out who is dicking with us so the admin can
3180 get their sorry ass fired.
3181 ***************************************************************************/
3183 static bool check_usershare_stat(const char *fname,
3184 const SMB_STRUCT_STAT *psbuf)
3186 if (!S_ISREG(psbuf->st_ex_mode)) {
3187 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3188 "not a regular file\n",
3189 fname, (unsigned int)psbuf->st_ex_uid ));
3190 return false;
3193 /* Ensure this doesn't have the other write bit set. */
3194 if (psbuf->st_ex_mode & S_IWOTH) {
3195 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3196 "public write. Refusing to allow as a usershare file.\n",
3197 fname, (unsigned int)psbuf->st_ex_uid ));
3198 return false;
3201 /* Should be 10k or less. */
3202 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3203 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3204 "too large (%u) to be a user share file.\n",
3205 fname, (unsigned int)psbuf->st_ex_uid,
3206 (unsigned int)psbuf->st_ex_size ));
3207 return false;
3210 return true;
3213 /***************************************************************************
3214 Parse the contents of a usershare file.
3215 ***************************************************************************/
3217 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3218 SMB_STRUCT_STAT *psbuf,
3219 const char *servicename,
3220 int snum,
3221 char **lines,
3222 int numlines,
3223 char **pp_sharepath,
3224 char **pp_comment,
3225 char **pp_cp_servicename,
3226 struct security_descriptor **ppsd,
3227 bool *pallow_guest)
3229 const char **prefixallowlist = lp_usershare_prefix_allow_list();
3230 const char **prefixdenylist = lp_usershare_prefix_deny_list();
3231 int us_vers;
3232 DIR *dp;
3233 SMB_STRUCT_STAT sbuf;
3234 char *sharepath = NULL;
3235 char *comment = NULL;
3237 *pp_sharepath = NULL;
3238 *pp_comment = NULL;
3240 *pallow_guest = false;
3242 if (numlines < 4) {
3243 return USERSHARE_MALFORMED_FILE;
3246 if (strcmp(lines[0], "#VERSION 1") == 0) {
3247 us_vers = 1;
3248 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3249 us_vers = 2;
3250 if (numlines < 5) {
3251 return USERSHARE_MALFORMED_FILE;
3253 } else {
3254 return USERSHARE_BAD_VERSION;
3257 if (strncmp(lines[1], "path=", 5) != 0) {
3258 return USERSHARE_MALFORMED_PATH;
3261 sharepath = talloc_strdup(ctx, &lines[1][5]);
3262 if (!sharepath) {
3263 return USERSHARE_POSIX_ERR;
3265 trim_string(sharepath, " ", " ");
3267 if (strncmp(lines[2], "comment=", 8) != 0) {
3268 return USERSHARE_MALFORMED_COMMENT_DEF;
3271 comment = talloc_strdup(ctx, &lines[2][8]);
3272 if (!comment) {
3273 return USERSHARE_POSIX_ERR;
3275 trim_string(comment, " ", " ");
3276 trim_char(comment, '"', '"');
3278 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3279 return USERSHARE_MALFORMED_ACL_DEF;
3282 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3283 return USERSHARE_ACL_ERR;
3286 if (us_vers == 2) {
3287 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3288 return USERSHARE_MALFORMED_ACL_DEF;
3290 if (lines[4][9] == 'y') {
3291 *pallow_guest = true;
3294 /* Backwards compatible extension to file version #2. */
3295 if (numlines > 5) {
3296 if (strncmp(lines[5], "sharename=", 10) != 0) {
3297 return USERSHARE_MALFORMED_SHARENAME_DEF;
3299 if (!strequal(&lines[5][10], servicename)) {
3300 return USERSHARE_BAD_SHARENAME;
3302 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3303 if (!*pp_cp_servicename) {
3304 return USERSHARE_POSIX_ERR;
3309 if (*pp_cp_servicename == NULL) {
3310 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3311 if (!*pp_cp_servicename) {
3312 return USERSHARE_POSIX_ERR;
3316 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3317 /* Path didn't change, no checks needed. */
3318 *pp_sharepath = sharepath;
3319 *pp_comment = comment;
3320 return USERSHARE_OK;
3323 /* The path *must* be absolute. */
3324 if (sharepath[0] != '/') {
3325 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3326 servicename, sharepath));
3327 return USERSHARE_PATH_NOT_ABSOLUTE;
3330 /* If there is a usershare prefix deny list ensure one of these paths
3331 doesn't match the start of the user given path. */
3332 if (prefixdenylist) {
3333 int i;
3334 for ( i=0; prefixdenylist[i]; i++ ) {
3335 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3336 servicename, i, prefixdenylist[i], sharepath ));
3337 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3338 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3339 "usershare prefix deny list entries.\n",
3340 servicename, sharepath));
3341 return USERSHARE_PATH_IS_DENIED;
3346 /* If there is a usershare prefix allow list ensure one of these paths
3347 does match the start of the user given path. */
3349 if (prefixallowlist) {
3350 int i;
3351 for ( i=0; prefixallowlist[i]; i++ ) {
3352 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3353 servicename, i, prefixallowlist[i], sharepath ));
3354 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3355 break;
3358 if (prefixallowlist[i] == NULL) {
3359 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3360 "usershare prefix allow list entries.\n",
3361 servicename, sharepath));
3362 return USERSHARE_PATH_NOT_ALLOWED;
3366 /* Ensure this is pointing to a directory. */
3367 dp = opendir(sharepath);
3369 if (!dp) {
3370 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3371 servicename, sharepath));
3372 return USERSHARE_PATH_NOT_DIRECTORY;
3375 /* Ensure the owner of the usershare file has permission to share
3376 this directory. */
3378 if (sys_stat(sharepath, &sbuf, false) == -1) {
3379 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3380 servicename, sharepath, strerror(errno) ));
3381 closedir(dp);
3382 return USERSHARE_POSIX_ERR;
3385 closedir(dp);
3387 if (!S_ISDIR(sbuf.st_ex_mode)) {
3388 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3389 servicename, sharepath ));
3390 return USERSHARE_PATH_NOT_DIRECTORY;
3393 /* Check if sharing is restricted to owner-only. */
3394 /* psbuf is the stat of the usershare definition file,
3395 sbuf is the stat of the target directory to be shared. */
3397 if (lp_usershare_owner_only()) {
3398 /* root can share anything. */
3399 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3400 return USERSHARE_PATH_NOT_ALLOWED;
3404 *pp_sharepath = sharepath;
3405 *pp_comment = comment;
3406 return USERSHARE_OK;
3409 /***************************************************************************
3410 Deal with a usershare file.
3411 Returns:
3412 >= 0 - snum
3413 -1 - Bad name, invalid contents.
3414 - service name already existed and not a usershare, problem
3415 with permissions to share directory etc.
3416 ***************************************************************************/
3418 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3420 SMB_STRUCT_STAT sbuf;
3421 SMB_STRUCT_STAT lsbuf;
3422 char *fname = NULL;
3423 char *sharepath = NULL;
3424 char *comment = NULL;
3425 char *cp_service_name = NULL;
3426 char **lines = NULL;
3427 int numlines = 0;
3428 int fd = -1;
3429 int iService = -1;
3430 TALLOC_CTX *ctx = talloc_stackframe();
3431 struct security_descriptor *psd = NULL;
3432 bool guest_ok = false;
3433 char *canon_name = NULL;
3434 bool added_service = false;
3435 int ret = -1;
3436 NTSTATUS status;
3438 /* Ensure share name doesn't contain invalid characters. */
3439 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3440 DEBUG(0,("process_usershare_file: share name %s contains "
3441 "invalid characters (any of %s)\n",
3442 file_name, INVALID_SHARENAME_CHARS ));
3443 goto out;
3446 canon_name = canonicalize_servicename(ctx, file_name);
3447 if (!canon_name) {
3448 goto out;
3451 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3452 if (!fname) {
3453 goto out;
3456 /* Minimize the race condition by doing an lstat before we
3457 open and fstat. Ensure this isn't a symlink link. */
3459 if (sys_lstat(fname, &lsbuf, false) != 0) {
3460 if (errno == ENOENT) {
3461 /* Unknown share requested. Just ignore. */
3462 goto out;
3464 /* Only log messages for meaningful problems. */
3465 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3466 fname, strerror(errno) ));
3467 goto out;
3470 /* This must be a regular file, not a symlink, directory or
3471 other strange filetype. */
3472 if (!check_usershare_stat(fname, &lsbuf)) {
3473 goto out;
3477 TDB_DATA data;
3479 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3480 canon_name, &data);
3482 iService = -1;
3484 if (NT_STATUS_IS_OK(status) &&
3485 (data.dptr != NULL) &&
3486 (data.dsize == sizeof(iService))) {
3487 memcpy(&iService, data.dptr, sizeof(iService));
3491 if (iService != -1 &&
3492 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3493 &lsbuf.st_ex_mtime) == 0) {
3494 /* Nothing changed - Mark valid and return. */
3495 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3496 canon_name ));
3497 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3498 ret = iService;
3499 goto out;
3502 /* Try and open the file read only - no symlinks allowed. */
3503 #ifdef O_NOFOLLOW
3504 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3505 #else
3506 fd = open(fname, O_RDONLY, 0);
3507 #endif
3509 if (fd == -1) {
3510 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3511 fname, strerror(errno) ));
3512 goto out;
3515 /* Now fstat to be *SURE* it's a regular file. */
3516 if (sys_fstat(fd, &sbuf, false) != 0) {
3517 close(fd);
3518 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3519 fname, strerror(errno) ));
3520 goto out;
3523 /* Is it the same dev/inode as was lstated ? */
3524 if (!check_same_stat(&lsbuf, &sbuf)) {
3525 close(fd);
3526 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3527 "Symlink spoofing going on ?\n", fname ));
3528 goto out;
3531 /* This must be a regular file, not a symlink, directory or
3532 other strange filetype. */
3533 if (!check_usershare_stat(fname, &sbuf)) {
3534 close(fd);
3535 goto out;
3538 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3540 close(fd);
3541 if (lines == NULL) {
3542 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3543 fname, (unsigned int)sbuf.st_ex_uid ));
3544 goto out;
3547 if (parse_usershare_file(ctx, &sbuf, file_name,
3548 iService, lines, numlines, &sharepath,
3549 &comment, &cp_service_name,
3550 &psd, &guest_ok) != USERSHARE_OK) {
3551 goto out;
3554 /* Everything ok - add the service possibly using a template. */
3555 if (iService < 0) {
3556 const struct loadparm_service *sp = &sDefault;
3557 if (snum_template != -1) {
3558 sp = ServicePtrs[snum_template];
3561 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3562 DEBUG(0, ("process_usershare_file: Failed to add "
3563 "new service %s\n", cp_service_name));
3564 goto out;
3567 added_service = true;
3569 /* Read only is controlled by usershare ACL below. */
3570 ServicePtrs[iService]->read_only = false;
3573 /* Write the ACL of the new/modified share. */
3574 status = set_share_security(canon_name, psd);
3575 if (!NT_STATUS_IS_OK(status)) {
3576 DEBUG(0, ("process_usershare_file: Failed to set share "
3577 "security for user share %s\n",
3578 canon_name ));
3579 goto out;
3582 /* If from a template it may be marked invalid. */
3583 ServicePtrs[iService]->valid = true;
3585 /* Set the service as a valid usershare. */
3586 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3588 /* Set guest access. */
3589 if (lp_usershare_allow_guests()) {
3590 ServicePtrs[iService]->guest_ok = guest_ok;
3593 /* And note when it was loaded. */
3594 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3595 lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path,
3596 sharepath);
3597 lpcfg_string_set(ServicePtrs[iService],
3598 &ServicePtrs[iService]->comment, comment);
3600 ret = iService;
3602 out:
3604 if (ret == -1 && iService != -1 && added_service) {
3605 lp_remove_service(iService);
3608 TALLOC_FREE(lines);
3609 TALLOC_FREE(ctx);
3610 return ret;
3613 /***************************************************************************
3614 Checks if a usershare entry has been modified since last load.
3615 ***************************************************************************/
3617 static bool usershare_exists(int iService, struct timespec *last_mod)
3619 SMB_STRUCT_STAT lsbuf;
3620 const char *usersharepath = Globals.usershare_path;
3621 char *fname;
3623 fname = talloc_asprintf(talloc_tos(),
3624 "%s/%s",
3625 usersharepath,
3626 ServicePtrs[iService]->szService);
3627 if (fname == NULL) {
3628 return false;
3631 if (sys_lstat(fname, &lsbuf, false) != 0) {
3632 TALLOC_FREE(fname);
3633 return false;
3636 if (!S_ISREG(lsbuf.st_ex_mode)) {
3637 TALLOC_FREE(fname);
3638 return false;
3641 TALLOC_FREE(fname);
3642 *last_mod = lsbuf.st_ex_mtime;
3643 return true;
3646 static bool usershare_directory_is_root(uid_t uid)
3648 if (uid == 0) {
3649 return true;
3652 if (uid_wrapper_enabled()) {
3653 return true;
3656 return false;
3659 /***************************************************************************
3660 Load a usershare service by name. Returns a valid servicenumber or -1.
3661 ***************************************************************************/
3663 int load_usershare_service(const char *servicename)
3665 SMB_STRUCT_STAT sbuf;
3666 const char *usersharepath = Globals.usershare_path;
3667 int max_user_shares = Globals.usershare_max_shares;
3668 int snum_template = -1;
3670 if (servicename[0] == '\0') {
3671 /* Invalid service name. */
3672 return -1;
3675 if (*usersharepath == 0 || max_user_shares == 0) {
3676 return -1;
3679 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3680 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3681 usersharepath, strerror(errno) ));
3682 return -1;
3685 if (!S_ISDIR(sbuf.st_ex_mode)) {
3686 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3687 usersharepath ));
3688 return -1;
3692 * This directory must be owned by root, and have the 't' bit set.
3693 * It also must not be writable by "other".
3696 #ifdef S_ISVTX
3697 if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3698 !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3699 #else
3700 if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3701 (sbuf.st_ex_mode & S_IWOTH)) {
3702 #endif
3703 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3704 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3705 usersharepath ));
3706 return -1;
3709 /* Ensure the template share exists if it's set. */
3710 if (Globals.usershare_template_share[0]) {
3711 /* We can't use lp_servicenumber here as we are recommending that
3712 template shares have -valid=false set. */
3713 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3714 if (ServicePtrs[snum_template]->szService &&
3715 strequal(ServicePtrs[snum_template]->szService,
3716 Globals.usershare_template_share)) {
3717 break;
3721 if (snum_template == -1) {
3722 DEBUG(0,("load_usershare_service: usershare template share %s "
3723 "does not exist.\n",
3724 Globals.usershare_template_share ));
3725 return -1;
3729 return process_usershare_file(usersharepath, servicename, snum_template);
3732 /***************************************************************************
3733 Load all user defined shares from the user share directory.
3734 We only do this if we're enumerating the share list.
3735 This is the function that can delete usershares that have
3736 been removed.
3737 ***************************************************************************/
3739 int load_usershare_shares(struct smbd_server_connection *sconn,
3740 bool (*snumused) (struct smbd_server_connection *, int))
3742 DIR *dp;
3743 SMB_STRUCT_STAT sbuf;
3744 struct dirent *de;
3745 int num_usershares = 0;
3746 int max_user_shares = Globals.usershare_max_shares;
3747 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3748 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3749 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3750 int iService;
3751 int snum_template = -1;
3752 const char *usersharepath = Globals.usershare_path;
3753 int ret = lp_numservices();
3754 TALLOC_CTX *tmp_ctx;
3756 if (max_user_shares == 0 || *usersharepath == '\0') {
3757 return lp_numservices();
3760 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3761 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3762 usersharepath, strerror(errno) ));
3763 return ret;
3767 * This directory must be owned by root, and have the 't' bit set.
3768 * It also must not be writable by "other".
3771 #ifdef S_ISVTX
3772 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3773 #else
3774 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3775 #endif
3776 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3777 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3778 usersharepath ));
3779 return ret;
3782 /* Ensure the template share exists if it's set. */
3783 if (Globals.usershare_template_share[0]) {
3784 /* We can't use lp_servicenumber here as we are recommending that
3785 template shares have -valid=false set. */
3786 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3787 if (ServicePtrs[snum_template]->szService &&
3788 strequal(ServicePtrs[snum_template]->szService,
3789 Globals.usershare_template_share)) {
3790 break;
3794 if (snum_template == -1) {
3795 DEBUG(0,("load_usershare_shares: usershare template share %s "
3796 "does not exist.\n",
3797 Globals.usershare_template_share ));
3798 return ret;
3802 /* Mark all existing usershares as pending delete. */
3803 for (iService = iNumServices - 1; iService >= 0; iService--) {
3804 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3805 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3809 dp = opendir(usersharepath);
3810 if (!dp) {
3811 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3812 usersharepath, strerror(errno) ));
3813 return ret;
3816 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3817 (de = readdir(dp));
3818 num_dir_entries++ ) {
3819 int r;
3820 const char *n = de->d_name;
3822 /* Ignore . and .. */
3823 if (*n == '.') {
3824 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3825 continue;
3829 if (n[0] == ':') {
3830 /* Temporary file used when creating a share. */
3831 num_tmp_dir_entries++;
3834 /* Allow 20% tmp entries. */
3835 if (num_tmp_dir_entries > allowed_tmp_entries) {
3836 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3837 "in directory %s\n",
3838 num_tmp_dir_entries, usersharepath));
3839 break;
3842 r = process_usershare_file(usersharepath, n, snum_template);
3843 if (r == 0) {
3844 /* Update the services count. */
3845 num_usershares++;
3846 if (num_usershares >= max_user_shares) {
3847 DEBUG(0,("load_usershare_shares: max user shares reached "
3848 "on file %s in directory %s\n",
3849 n, usersharepath ));
3850 break;
3852 } else if (r == -1) {
3853 num_bad_dir_entries++;
3856 /* Allow 20% bad entries. */
3857 if (num_bad_dir_entries > allowed_bad_entries) {
3858 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3859 "in directory %s\n",
3860 num_bad_dir_entries, usersharepath));
3861 break;
3864 /* Allow 20% bad entries. */
3865 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3866 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3867 "in directory %s\n",
3868 num_dir_entries, usersharepath));
3869 break;
3873 closedir(dp);
3875 /* Sweep through and delete any non-refreshed usershares that are
3876 not currently in use. */
3877 tmp_ctx = talloc_stackframe();
3878 for (iService = iNumServices - 1; iService >= 0; iService--) {
3879 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3880 const struct loadparm_substitution *lp_sub =
3881 loadparm_s3_global_substitution();
3882 char *servname;
3884 if (snumused && snumused(sconn, iService)) {
3885 continue;
3888 servname = lp_servicename(tmp_ctx, lp_sub, iService);
3890 /* Remove from the share ACL db. */
3891 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3892 servname ));
3893 delete_share_security(servname);
3894 free_service_byindex(iService);
3897 talloc_free(tmp_ctx);
3899 return lp_numservices();
3902 /********************************************************
3903 Destroy global resources allocated in this file
3904 ********************************************************/
3906 void gfree_loadparm(void)
3908 int i;
3910 free_file_list();
3912 /* Free resources allocated to services */
3914 for ( i = 0; i < iNumServices; i++ ) {
3915 if ( VALID(i) ) {
3916 free_service_byindex(i);
3920 TALLOC_FREE( ServicePtrs );
3921 iNumServices = 0;
3923 /* Now release all resources allocated to global
3924 parameters and the default service */
3926 free_global_parameters();
3930 /***************************************************************************
3931 Allow client apps to specify that they are a client
3932 ***************************************************************************/
3933 static void lp_set_in_client(bool b)
3935 in_client = b;
3939 /***************************************************************************
3940 Determine if we're running in a client app
3941 ***************************************************************************/
3942 static bool lp_is_in_client(void)
3944 return in_client;
3947 static void lp_enforce_ad_dc_settings(void)
3949 lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3950 lp_do_parameter(GLOBAL_SECTION_SNUM,
3951 "winbindd:use external pipes", "true");
3952 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
3953 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
3954 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
3955 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
3956 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
3957 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
3958 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
3959 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
3960 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
3963 /***************************************************************************
3964 Load the services array from the services file. Return true on success,
3965 false on failure.
3966 ***************************************************************************/
3968 static bool lp_load_ex(const char *pszFname,
3969 bool global_only,
3970 bool save_defaults,
3971 bool add_ipc,
3972 bool reinit_globals,
3973 bool allow_include_registry,
3974 bool load_all_shares)
3976 char *n2 = NULL;
3977 bool bRetval;
3978 TALLOC_CTX *frame = talloc_stackframe();
3979 struct loadparm_context *lp_ctx;
3980 int max_protocol, min_protocol;
3982 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3984 bInGlobalSection = true;
3985 bGlobalOnly = global_only;
3986 bAllowIncludeRegistry = allow_include_registry;
3987 sDefault = _sDefault;
3989 lp_ctx = setup_lp_context(talloc_tos());
3991 loadparm_s3_init_globals(lp_ctx, reinit_globals);
3993 free_file_list();
3995 if (save_defaults) {
3996 init_locals();
3997 lp_save_defaults();
4000 if (!reinit_globals) {
4001 free_param_opts(&Globals.param_opt);
4002 apply_lp_set_cmdline();
4005 lp_do_parameter(-1, "idmap config * : backend", Globals.idmap_backend);
4007 /* We get sections first, so have to start 'behind' to make up */
4008 iServiceIndex = -1;
4010 if (lp_config_backend_is_file()) {
4011 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4012 get_current_user_info_domain(),
4013 pszFname);
4014 if (!n2) {
4015 smb_panic("lp_load_ex: out of memory");
4018 add_to_file_list(NULL, &file_lists, pszFname, n2);
4020 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
4021 TALLOC_FREE(n2);
4023 /* finish up the last section */
4024 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4025 if (bRetval) {
4026 if (iServiceIndex >= 0) {
4027 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
4031 if (lp_config_backend_is_registry()) {
4032 bool ok;
4033 /* config backend changed to registry in config file */
4035 * We need to use this extra global variable here to
4036 * survive restart: init_globals uses this as a default
4037 * for config_backend. Otherwise, init_globals would
4038 * send us into an endless loop here.
4041 config_backend = CONFIG_BACKEND_REGISTRY;
4042 /* start over */
4043 DEBUG(1, ("lp_load_ex: changing to config backend "
4044 "registry\n"));
4045 loadparm_s3_init_globals(lp_ctx, true);
4047 TALLOC_FREE(lp_ctx);
4049 lp_kill_all_services();
4050 ok = lp_load_ex(pszFname, global_only, save_defaults,
4051 add_ipc, reinit_globals,
4052 allow_include_registry,
4053 load_all_shares);
4054 TALLOC_FREE(frame);
4055 return ok;
4057 } else if (lp_config_backend_is_registry()) {
4058 bRetval = process_registry_globals();
4059 } else {
4060 DEBUG(0, ("Illegal config backend given: %d\n",
4061 lp_config_backend()));
4062 bRetval = false;
4065 if (bRetval && lp_registry_shares()) {
4066 if (load_all_shares) {
4067 bRetval = process_registry_shares();
4068 } else {
4069 bRetval = reload_registry_shares();
4074 const struct loadparm_substitution *lp_sub =
4075 loadparm_s3_global_substitution();
4076 char *serv = lp_auto_services(talloc_tos(), lp_sub);
4077 lp_add_auto_services(serv);
4078 TALLOC_FREE(serv);
4081 if (add_ipc) {
4082 /* When 'restrict anonymous = 2' guest connections to ipc$
4083 are denied */
4084 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4085 if ( lp_enable_asu_support() ) {
4086 lp_add_ipc("ADMIN$", false);
4090 set_allowed_client_auth();
4092 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4093 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4094 lp_password_server()));
4097 b_loaded = true;
4099 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4100 /* if we_are_a_wins_server is true and we are in the client */
4101 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4102 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4105 init_iconv();
4107 fault_configure(smb_panic_s3);
4110 * We run this check once the whole smb.conf is parsed, to
4111 * force some settings for the standard way a AD DC is
4112 * operated. We may change these as our code evolves, which
4113 * is why we force these settings.
4115 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4116 lp_enforce_ad_dc_settings();
4119 bAllowIncludeRegistry = true;
4121 /* Check if command line max protocol < min protocol, if so
4122 * report a warning to the user.
4124 max_protocol = lp_client_max_protocol();
4125 min_protocol = lp_client_min_protocol();
4126 if (max_protocol < min_protocol) {
4127 const char *max_protocolp, *min_protocolp;
4128 max_protocolp = lpcfg_get_smb_protocol(max_protocol);
4129 min_protocolp = lpcfg_get_smb_protocol(min_protocol);
4130 DBG_ERR("Max protocol %s is less than min protocol %s.\n",
4131 max_protocolp, min_protocolp);
4134 TALLOC_FREE(frame);
4135 return (bRetval);
4138 static bool lp_load(const char *pszFname,
4139 bool global_only,
4140 bool save_defaults,
4141 bool add_ipc,
4142 bool reinit_globals)
4144 return lp_load_ex(pszFname,
4145 global_only,
4146 save_defaults,
4147 add_ipc,
4148 reinit_globals,
4149 true, /* allow_include_registry */
4150 false); /* load_all_shares*/
4153 bool lp_load_initial_only(const char *pszFname)
4155 return lp_load_ex(pszFname,
4156 true, /* global only */
4157 true, /* save_defaults */
4158 false, /* add_ipc */
4159 true, /* reinit_globals */
4160 false, /* allow_include_registry */
4161 false); /* load_all_shares*/
4165 * most common lp_load wrapper, loading only the globals
4167 * If this is used in a daemon or client utility it should be called
4168 * after processing popt.
4170 bool lp_load_global(const char *file_name)
4172 return lp_load(file_name,
4173 true, /* global_only */
4174 false, /* save_defaults */
4175 false, /* add_ipc */
4176 true); /* reinit_globals */
4180 * The typical lp_load wrapper with shares, loads global and
4181 * shares, including IPC, but does not force immediate
4182 * loading of all shares from registry.
4184 bool lp_load_with_shares(const char *file_name)
4186 return lp_load(file_name,
4187 false, /* global_only */
4188 false, /* save_defaults */
4189 true, /* add_ipc */
4190 true); /* reinit_globals */
4194 * lp_load wrapper, especially for clients
4196 bool lp_load_client(const char *file_name)
4198 lp_set_in_client(true);
4200 return lp_load_global(file_name);
4204 * lp_load wrapper, loading only globals, but intended
4205 * for subsequent calls, not reinitializing the globals
4206 * to default values
4208 bool lp_load_global_no_reinit(const char *file_name)
4210 return lp_load(file_name,
4211 true, /* global_only */
4212 false, /* save_defaults */
4213 false, /* add_ipc */
4214 false); /* reinit_globals */
4218 * lp_load wrapper, loading globals and shares,
4219 * intended for subsequent calls, i.e. not reinitializing
4220 * the globals to default values.
4222 bool lp_load_no_reinit(const char *file_name)
4224 return lp_load(file_name,
4225 false, /* global_only */
4226 false, /* save_defaults */
4227 false, /* add_ipc */
4228 false); /* reinit_globals */
4233 * lp_load wrapper, especially for clients, no reinitialization
4235 bool lp_load_client_no_reinit(const char *file_name)
4237 lp_set_in_client(true);
4239 return lp_load_global_no_reinit(file_name);
4242 bool lp_load_with_registry_shares(const char *pszFname)
4244 return lp_load_ex(pszFname,
4245 false, /* global_only */
4246 true, /* save_defaults */
4247 false, /* add_ipc */
4248 true, /* reinit_globals */
4249 true, /* allow_include_registry */
4250 true); /* load_all_shares*/
4253 /***************************************************************************
4254 Return the max number of services.
4255 ***************************************************************************/
4257 int lp_numservices(void)
4259 return (iNumServices);
4262 /***************************************************************************
4263 Display the contents of the services array in human-readable form.
4264 ***************************************************************************/
4266 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4268 int iService;
4269 struct loadparm_context *lp_ctx;
4271 if (show_defaults)
4272 defaults_saved = false;
4274 lp_ctx = setup_lp_context(talloc_tos());
4275 if (lp_ctx == NULL) {
4276 return;
4279 lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
4281 lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
4283 for (iService = 0; iService < maxtoprint; iService++) {
4284 fprintf(f,"\n");
4285 lp_dump_one(f, show_defaults, iService);
4287 TALLOC_FREE(lp_ctx);
4290 /***************************************************************************
4291 Display the contents of one service in human-readable form.
4292 ***************************************************************************/
4294 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4296 if (VALID(snum)) {
4297 if (ServicePtrs[snum]->szService[0] == '\0')
4298 return;
4299 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
4300 flags_list, show_defaults);
4304 /***************************************************************************
4305 Return the number of the service with the given name, or -1 if it doesn't
4306 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4307 getservicebyname()! This works ONLY if all services have been loaded, and
4308 does not copy the found service.
4309 ***************************************************************************/
4311 int lp_servicenumber(const char *pszServiceName)
4313 int iService;
4314 fstring serviceName;
4316 if (!pszServiceName) {
4317 return GLOBAL_SECTION_SNUM;
4320 for (iService = iNumServices - 1; iService >= 0; iService--) {
4321 if (VALID(iService) && ServicePtrs[iService]->szService) {
4323 * The substitution here is used to support %U in
4324 * service names
4326 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4327 standard_sub_basic(get_current_username(),
4328 get_current_user_info_domain(),
4329 serviceName,sizeof(serviceName));
4330 if (strequal(serviceName, pszServiceName)) {
4331 break;
4336 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4337 struct timespec last_mod;
4339 if (!usershare_exists(iService, &last_mod)) {
4340 /* Remove the share security tdb entry for it. */
4341 delete_share_security(lp_const_servicename(iService));
4342 /* Remove it from the array. */
4343 free_service_byindex(iService);
4344 /* Doesn't exist anymore. */
4345 return GLOBAL_SECTION_SNUM;
4348 /* Has it been modified ? If so delete and reload. */
4349 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4350 &last_mod) < 0) {
4351 /* Remove it from the array. */
4352 free_service_byindex(iService);
4353 /* and now reload it. */
4354 iService = load_usershare_service(pszServiceName);
4358 if (iService < 0) {
4359 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4360 return GLOBAL_SECTION_SNUM;
4363 return (iService);
4366 /*******************************************************************
4367 A useful volume label function.
4368 ********************************************************************/
4370 const char *volume_label(TALLOC_CTX *ctx, int snum)
4372 const struct loadparm_substitution *lp_sub =
4373 loadparm_s3_global_substitution();
4374 char *ret;
4375 const char *label = lp_volume(ctx, lp_sub, snum);
4376 size_t end = 32;
4378 if (!*label) {
4379 label = lp_servicename(ctx, lp_sub, snum);
4383 * Volume label can be a max of 32 bytes. Make sure to truncate
4384 * it at a codepoint boundary if it's longer than 32 and contains
4385 * multibyte characters. Windows insists on a volume label being
4386 * a valid mb sequence, and errors out if not.
4388 if (strlen(label) > 32) {
4390 * A MB char can be a max of 5 bytes, thus
4391 * we should have a valid mb character at a
4392 * minimum position of (32-5) = 27.
4394 while (end >= 27) {
4396 * Check if a codepoint starting from next byte
4397 * is valid. If yes, then the current byte is the
4398 * end of a MB or ascii sequence and the label can
4399 * be safely truncated here. If not, keep going
4400 * backwards till a valid codepoint is found.
4402 size_t len = 0;
4403 const char *s = &label[end];
4404 codepoint_t c = next_codepoint(s, &len);
4405 if (c != INVALID_CODEPOINT) {
4406 break;
4408 end--;
4412 /* This returns a max of 33 byte guaranteed null terminated string. */
4413 ret = talloc_strndup(ctx, label, end);
4414 if (!ret) {
4415 return "";
4417 return ret;
4420 /*******************************************************************
4421 Get the default server type we will announce as via nmbd.
4422 ********************************************************************/
4424 int lp_default_server_announce(void)
4426 int default_server_announce = 0;
4427 default_server_announce |= SV_TYPE_WORKSTATION;
4428 default_server_announce |= SV_TYPE_SERVER;
4429 default_server_announce |= SV_TYPE_SERVER_UNIX;
4431 /* note that the flag should be set only if we have a
4432 printer service but nmbd doesn't actually load the
4433 services so we can't tell --jerry */
4435 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4437 default_server_announce |= SV_TYPE_SERVER_NT;
4438 default_server_announce |= SV_TYPE_NT;
4440 switch (lp_server_role()) {
4441 case ROLE_DOMAIN_MEMBER:
4442 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4443 break;
4444 case ROLE_DOMAIN_PDC:
4445 case ROLE_IPA_DC:
4446 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4447 break;
4448 case ROLE_DOMAIN_BDC:
4449 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4450 break;
4451 case ROLE_STANDALONE:
4452 default:
4453 break;
4455 if (lp_time_server())
4456 default_server_announce |= SV_TYPE_TIME_SOURCE;
4458 if (lp_host_msdfs())
4459 default_server_announce |= SV_TYPE_DFS_SERVER;
4461 return default_server_announce;
4464 /***********************************************************
4465 If we are PDC then prefer us as DMB
4466 ************************************************************/
4468 bool lp_domain_master(void)
4470 if (Globals._domain_master == Auto)
4471 return (lp_server_role() == ROLE_DOMAIN_PDC ||
4472 lp_server_role() == ROLE_IPA_DC);
4474 return (bool)Globals._domain_master;
4477 /***********************************************************
4478 If we are PDC then prefer us as DMB
4479 ************************************************************/
4481 static bool lp_domain_master_true_or_auto(void)
4483 if (Globals._domain_master) /* auto or yes */
4484 return true;
4486 return false;
4489 /***********************************************************
4490 If we are DMB then prefer us as LMB
4491 ************************************************************/
4493 bool lp_preferred_master(void)
4495 int preferred_master = lp__preferred_master();
4497 if (preferred_master == Auto)
4498 return (lp_local_master() && lp_domain_master());
4500 return (bool)preferred_master;
4503 /*******************************************************************
4504 Remove a service.
4505 ********************************************************************/
4507 void lp_remove_service(int snum)
4509 ServicePtrs[snum]->valid = false;
4512 const char *lp_printername(TALLOC_CTX *ctx,
4513 const struct loadparm_substitution *lp_sub,
4514 int snum)
4516 const char *ret = lp__printername(ctx, lp_sub, snum);
4518 if (ret == NULL || *ret == '\0') {
4519 ret = lp_const_servicename(snum);
4522 return ret;
4526 /***********************************************************
4527 Allow daemons such as winbindd to fix their logfile name.
4528 ************************************************************/
4530 void lp_set_logfile(const char *name)
4532 lpcfg_string_set(Globals.ctx, &Globals.logfile, name);
4533 debug_set_logfile(name);
4536 /*******************************************************************
4537 Return the max print jobs per queue.
4538 ********************************************************************/
4540 int lp_maxprintjobs(int snum)
4542 int maxjobs = lp_max_print_jobs(snum);
4544 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4545 maxjobs = PRINT_MAX_JOBID - 1;
4547 return maxjobs;
4550 const char *lp_printcapname(void)
4552 const char *printcap_name = lp_printcap_name();
4554 if ((printcap_name != NULL) &&
4555 (printcap_name[0] != '\0'))
4556 return printcap_name;
4558 if (sDefault.printing == PRINT_CUPS) {
4559 return "cups";
4562 if (sDefault.printing == PRINT_BSD)
4563 return "/etc/printcap";
4565 return PRINTCAP_NAME;
4568 static uint32_t spoolss_state;
4570 bool lp_disable_spoolss( void )
4572 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4573 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4575 return spoolss_state == SVCCTL_STOPPED ? true : false;
4578 void lp_set_spoolss_state( uint32_t state )
4580 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4582 spoolss_state = state;
4585 uint32_t lp_get_spoolss_state( void )
4587 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4590 /*******************************************************************
4591 Turn off sendfile if we find the underlying OS doesn't support it.
4592 ********************************************************************/
4594 void set_use_sendfile(int snum, bool val)
4596 if (LP_SNUM_OK(snum))
4597 ServicePtrs[snum]->_use_sendfile = val;
4598 else
4599 sDefault._use_sendfile = val;
4602 void lp_set_mangling_method(const char *new_method)
4604 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method);
4607 /*******************************************************************
4608 Global state for POSIX pathname processing.
4609 ********************************************************************/
4611 static bool posix_pathnames;
4613 bool lp_posix_pathnames(void)
4615 return posix_pathnames;
4618 /*******************************************************************
4619 Change everything needed to ensure POSIX pathname processing (currently
4620 not much).
4621 ********************************************************************/
4623 void lp_set_posix_pathnames(void)
4625 posix_pathnames = true;
4628 /*******************************************************************
4629 Global state for POSIX lock processing - CIFS unix extensions.
4630 ********************************************************************/
4632 bool posix_default_lock_was_set;
4633 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4635 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4637 if (posix_default_lock_was_set) {
4638 return posix_cifsx_locktype;
4639 } else {
4640 return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
4641 POSIX_LOCK : WINDOWS_LOCK;
4645 /*******************************************************************
4646 ********************************************************************/
4648 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4650 posix_default_lock_was_set = true;
4651 posix_cifsx_locktype = val;
4654 int lp_min_receive_file_size(void)
4656 int min_receivefile_size = lp_min_receivefile_size();
4658 if (min_receivefile_size < 0) {
4659 return 0;
4661 return min_receivefile_size;
4664 /*******************************************************************
4665 Safe wide links checks.
4666 This helper function always verify the validity of wide links,
4667 even after a configuration file reload.
4668 ********************************************************************/
4670 void widelinks_warning(int snum)
4672 if (lp_allow_insecure_wide_links()) {
4673 return;
4676 if (lp_wide_links(snum)) {
4677 if (lp_smb1_unix_extensions()) {
4678 DBG_ERR("Share '%s' has wide links and SMB1 unix "
4679 "extensions enabled. "
4680 "These parameters are incompatible. "
4681 "Wide links will be disabled for this share.\n",
4682 lp_const_servicename(snum));
4687 bool lp_widelinks(int snum)
4689 /* wide links is always incompatible with unix extensions */
4690 if (lp_smb1_unix_extensions()) {
4692 * Unless we have "allow insecure widelinks"
4693 * turned on.
4695 if (!lp_allow_insecure_wide_links()) {
4696 return false;
4700 return lp_wide_links(snum);
4703 int lp_server_role(void)
4705 return lp_find_server_role(lp__server_role(),
4706 lp__security(),
4707 lp__domain_logons(),
4708 lp_domain_master_true_or_auto());
4711 int lp_security(void)
4713 return lp_find_security(lp__server_role(),
4714 lp__security());
4717 int lp_client_max_protocol(void)
4719 int client_max_protocol = lp__client_max_protocol();
4720 if (client_max_protocol == PROTOCOL_DEFAULT) {
4721 return PROTOCOL_LATEST;
4723 return client_max_protocol;
4726 int lp_client_ipc_min_protocol(void)
4728 int client_ipc_min_protocol = lp__client_ipc_min_protocol();
4729 if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
4730 client_ipc_min_protocol = lp_client_min_protocol();
4732 if (client_ipc_min_protocol < PROTOCOL_NT1) {
4733 return PROTOCOL_NT1;
4735 return client_ipc_min_protocol;
4738 int lp_client_ipc_max_protocol(void)
4740 int client_ipc_max_protocol = lp__client_ipc_max_protocol();
4741 if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
4742 return PROTOCOL_LATEST;
4744 if (client_ipc_max_protocol < PROTOCOL_NT1) {
4745 return PROTOCOL_NT1;
4747 return client_ipc_max_protocol;
4750 int lp_client_ipc_signing(void)
4752 int client_ipc_signing = lp__client_ipc_signing();
4753 if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
4754 return SMB_SIGNING_REQUIRED;
4756 return client_ipc_signing;
4759 enum credentials_use_kerberos lp_client_use_kerberos(void)
4761 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
4762 return CRED_USE_KERBEROS_REQUIRED;
4765 return lp__client_use_kerberos();
4769 int lp_rpc_low_port(void)
4771 return Globals.rpc_low_port;
4774 int lp_rpc_high_port(void)
4776 return Globals.rpc_high_port;
4780 * Do not allow LanMan auth if unless NTLMv1 is also allowed
4782 * This also ensures it is disabled if NTLM is totally disabled
4784 bool lp_lanman_auth(void)
4786 enum ntlm_auth_level ntlm_auth_level = lp_ntlm_auth();
4788 if (ntlm_auth_level == NTLM_AUTH_ON) {
4789 return lp__lanman_auth();
4790 } else {
4791 return false;
4795 struct loadparm_global * get_globals(void)
4797 return &Globals;
4800 unsigned int * get_flags(void)
4802 if (flags_list == NULL) {
4803 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
4806 return flags_list;
4809 enum samba_weak_crypto lp_weak_crypto(void)
4811 if (Globals.weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) {
4812 Globals.weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED;
4814 if (samba_gnutls_weak_crypto_allowed()) {
4815 Globals.weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED;
4819 return Globals.weak_crypto;
4822 uint32_t lp_get_async_dns_timeout(void)
4825 * Clamp minimum async dns timeout to 1 second
4826 * as per the man page.
4828 return MAX(Globals.async_dns_timeout, 1);