vfs_gpfs: add gpfs:clamp_invalid_times
[samba.git] / source3 / param / loadparm.c
blob71a40e55d7c31e929ac0af273f496a05cd4e8f7f
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 "lib/util/util_file.h"
59 #include "system/filesys.h"
60 #include "util_tdb.h"
61 #include "lib/param/loadparm.h"
62 #include "lib/param/param.h"
63 #include "printing.h"
64 #include "lib/smbconf/smbconf.h"
65 #include "lib/smbconf/smbconf_init.h"
67 #include "include/smb_ldap.h"
68 #include "../librpc/gen_ndr/svcctl.h"
69 #include "intl.h"
70 #include "../libcli/smb/smb_signing.h"
71 #include "dbwrap/dbwrap.h"
72 #include "dbwrap/dbwrap_rbt.h"
73 #include "../lib/util/bitmap.h"
74 #include "librpc/gen_ndr/nbt.h"
75 #include "librpc/gen_ndr/dns.h"
76 #include "source4/lib/tls/tls.h"
77 #include "libcli/auth/ntlm_check.h"
78 #include "lib/crypto/gnutls_helpers.h"
79 #include "lib/util/string_wrappers.h"
80 #include "auth/credentials/credentials.h"
81 #include "source3/lib/substitute.h"
82 #include "source3/librpc/gen_ndr/ads.h"
83 #include "lib/util/time_basic.h"
84 #include "libds/common/flags.h"
86 #ifdef HAVE_SYS_SYSCTL_H
87 #include <sys/sysctl.h>
88 #endif
90 bool b_loaded = false;
92 /* the special value for the include parameter
93 * to be interpreted not as a file name but to
94 * trigger loading of the global smb.conf options
95 * from registry. */
96 #ifndef INCLUDE_REGISTRY_NAME
97 #define INCLUDE_REGISTRY_NAME "registry"
98 #endif
100 static bool in_client = false; /* Not in the client by default */
101 static struct smbconf_csn conf_last_csn;
103 static int config_backend = CONFIG_BACKEND_FILE;
105 /* some helpful bits */
106 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && \
107 (ServicePtrs != NULL) && \
108 (ServicePtrs[(i)] != NULL) && ServicePtrs[(i)]->valid)
109 #define VALID(i) ((ServicePtrs != NULL) && (ServicePtrs[i]!= NULL) && \
110 ServicePtrs[i]->valid)
112 #define USERSHARE_VALID 1
113 #define USERSHARE_PENDING_DELETE 2
115 static bool defaults_saved = false;
117 #include "lib/param/param_global.h"
119 static struct loadparm_global Globals;
121 /* This is a default service used to prime a services structure */
122 static const struct loadparm_service _sDefault =
124 .valid = true,
125 .autoloaded = false,
126 .usershare = 0,
127 .usershare_last_mod = {0, 0},
128 .szService = NULL,
129 .path = NULL,
130 .invalid_users = NULL,
131 .valid_users = NULL,
132 .admin_users = NULL,
133 .copy = NULL,
134 .include = NULL,
135 .preexec = NULL,
136 .postexec = NULL,
137 .root_preexec = NULL,
138 .root_postexec = NULL,
139 .cups_options = NULL,
140 .print_command = NULL,
141 .lpq_command = NULL,
142 .lprm_command = NULL,
143 .lppause_command = NULL,
144 .lpresume_command = NULL,
145 .queuepause_command = NULL,
146 .queueresume_command = NULL,
147 ._printername = NULL,
148 .printjob_username = NULL,
149 .dont_descend = NULL,
150 .hosts_allow = NULL,
151 .hosts_deny = NULL,
152 .magic_script = NULL,
153 .magic_output = NULL,
154 .veto_files = NULL,
155 .hide_files = NULL,
156 .veto_oplock_files = NULL,
157 .comment = NULL,
158 .force_user = NULL,
159 .force_group = NULL,
160 .read_list = NULL,
161 .write_list = NULL,
162 .volume = NULL,
163 .fstype = NULL,
164 .vfs_objects = NULL,
165 .vfs_mkdir_use_tmp_name = Auto,
166 .msdfs_proxy = NULL,
167 .aio_write_behind = NULL,
168 .dfree_command = NULL,
169 .min_print_space = 0,
170 .max_print_jobs = 1000,
171 .max_reported_print_jobs = 0,
172 .create_mask = 0744,
173 .force_create_mode = 0,
174 .directory_mask = 0755,
175 .force_directory_mode = 0,
176 .max_connections = 0,
177 .default_case = CASE_LOWER,
178 .printing = DEFAULT_PRINTING,
179 .csc_policy = 0,
180 .block_size = 1024,
181 .dfree_cache_time = 0,
182 .preexec_close = false,
183 .root_preexec_close = false,
184 .case_sensitive = Auto,
185 .preserve_case = true,
186 .short_preserve_case = true,
187 .hide_dot_files = true,
188 .hide_special_files = false,
189 .hide_unreadable = false,
190 .hide_unwriteable_files = false,
191 .browseable = true,
192 .access_based_share_enum = false,
193 .available = true,
194 .read_only = true,
195 .spotlight = false,
196 .guest_only = false,
197 .administrative_share = false,
198 .guest_ok = false,
199 .printable = false,
200 .print_notify_backchannel = false,
201 .map_system = false,
202 .map_hidden = false,
203 .map_archive = true,
204 .store_dos_attributes = true,
205 .smbd_max_xattr_size = 65536,
206 .dmapi_support = false,
207 .locking = true,
208 .strict_locking = Auto,
209 .posix_locking = true,
210 .oplocks = true,
211 .kernel_oplocks = false,
212 .level2_oplocks = true,
213 .mangled_names = MANGLED_NAMES_ILLEGAL,
214 .wide_links = false,
215 .follow_symlinks = true,
216 .sync_always = false,
217 .strict_allocate = false,
218 ._strict_rename = false,
219 .strict_sync = true,
220 .mangling_char = '~',
221 .copymap = NULL,
222 .delete_readonly = false,
223 .fake_oplocks = false,
224 .delete_veto_files = false,
225 .dos_filemode = false,
226 .dos_filetimes = true,
227 .dos_filetime_resolution = false,
228 .fake_directory_create_times = false,
229 .blocking_locks = true,
230 .inherit_permissions = false,
231 .inherit_acls = false,
232 .inherit_owner = false,
233 .msdfs_root = false,
234 .msdfs_shuffle_referrals = false,
235 .use_client_driver = false,
236 .default_devmode = true,
237 .force_printername = false,
238 .nt_acl_support = true,
239 .force_unknown_acl_user = false,
240 ._use_sendfile = false,
241 .map_acl_inherit = false,
242 .afs_share = false,
243 .ea_support = true,
244 .acl_check_permissions = true,
245 .acl_map_full_control = true,
246 .acl_group_control = false,
247 .acl_allow_execute_always = false,
248 .acl_flag_inherited_canonicalization = true,
249 .aio_read_size = 1,
250 .aio_write_size = 1,
251 .map_readonly = MAP_READONLY_NO,
252 .server_smb_encrypt = SMB_ENCRYPTION_DEFAULT,
253 .kernel_share_modes = false,
254 .durable_handles = true,
255 .check_parent_directory_delete_on_close = false,
256 .param_opt = NULL,
257 .smbd_search_ask_sharemode = true,
258 .smbd_getinfo_ask_sharemode = true,
259 .spotlight_backend = SPOTLIGHT_BACKEND_NOINDEX,
260 .honor_change_notify_privilege = false,
261 .volume_serial_number = -1,
262 .dummy = ""
266 * This is a copy of the default service structure. Service options in the
267 * global section would otherwise overwrite the initial default values.
269 static struct loadparm_service sDefault;
271 /* local variables */
272 static struct loadparm_service **ServicePtrs = NULL;
273 static int iNumServices = 0;
274 static int iServiceIndex = 0;
275 static struct db_context *ServiceHash;
276 static bool bInGlobalSection = true;
277 static bool bGlobalOnly = false;
278 static struct file_lists *file_lists = NULL;
279 static unsigned int *flags_list = NULL;
281 static void set_allowed_client_auth(void);
283 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
284 static void free_param_opts(struct parmlist_entry **popts);
287 * Function to return the default value for the maximum number of open
288 * file descriptors permitted. This function tries to consult the
289 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
290 * the smaller of those.
292 static int max_open_files(void)
294 int sysctl_max = MAX_OPEN_FILES;
295 int rlimit_max = MAX_OPEN_FILES;
297 #ifdef HAVE_SYSCTLBYNAME
299 size_t size = sizeof(sysctl_max);
300 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
303 #endif
305 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
307 struct rlimit rl;
309 ZERO_STRUCT(rl);
311 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
312 rlimit_max = rl.rlim_cur;
314 #if defined(RLIM_INFINITY)
315 if(rl.rlim_cur == RLIM_INFINITY)
316 rlimit_max = MAX_OPEN_FILES;
317 #endif
319 #endif
321 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
322 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
323 "minimum Windows limit (%d)\n",
324 sysctl_max,
325 MIN_OPEN_FILES_WINDOWS));
326 sysctl_max = MIN_OPEN_FILES_WINDOWS;
329 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
330 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
331 "minimum Windows limit (%d)\n",
332 rlimit_max,
333 MIN_OPEN_FILES_WINDOWS));
334 rlimit_max = MIN_OPEN_FILES_WINDOWS;
337 return MIN(sysctl_max, rlimit_max);
341 * Common part of freeing allocated data for one parameter.
343 static void free_one_parameter_common(void *parm_ptr,
344 struct parm_struct parm)
346 if ((parm.type == P_STRING) ||
347 (parm.type == P_USTRING))
349 lpcfg_string_free((char**)parm_ptr);
350 } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
351 TALLOC_FREE(*((char***)parm_ptr));
356 * Free the allocated data for one parameter for a share
357 * given as a service struct.
359 static void free_one_parameter(struct loadparm_service *service,
360 struct parm_struct parm)
362 void *parm_ptr;
364 if (parm.p_class != P_LOCAL) {
365 return;
368 parm_ptr = lp_parm_ptr(service, &parm);
370 free_one_parameter_common(parm_ptr, parm);
374 * Free the allocated parameter data of a share given
375 * as a service struct.
377 static void free_parameters(struct loadparm_service *service)
379 uint32_t i;
381 for (i=0; parm_table[i].label; i++) {
382 free_one_parameter(service, parm_table[i]);
387 * Free the allocated data for one parameter for a given share
388 * specified by an snum.
390 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
392 void *parm_ptr;
394 if (snum < 0) {
395 parm_ptr = lp_parm_ptr(NULL, &parm);
396 } else if (parm.p_class != P_LOCAL) {
397 return;
398 } else {
399 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
402 free_one_parameter_common(parm_ptr, parm);
406 * Free the allocated parameter data for a share specified
407 * by an snum.
409 static void free_parameters_by_snum(int snum)
411 uint32_t i;
413 for (i=0; parm_table[i].label; i++) {
414 free_one_parameter_by_snum(snum, parm_table[i]);
419 * Free the allocated global parameters.
421 static void free_global_parameters(void)
423 uint32_t i;
424 struct parm_struct *parm;
426 free_param_opts(&Globals.param_opt);
427 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
429 /* Reset references in the defaults because the context is going to be freed */
430 for (i=0; parm_table[i].label; i++) {
431 parm = &parm_table[i];
432 if ((parm->type == P_STRING) ||
433 (parm->type == P_USTRING)) {
434 if ((parm->def.svalue != NULL) &&
435 (*(parm->def.svalue) != '\0')) {
436 if (talloc_parent(parm->def.svalue) == Globals.ctx) {
437 parm->def.svalue = NULL;
442 TALLOC_FREE(Globals.ctx);
445 struct lp_stored_option {
446 struct lp_stored_option *prev, *next;
447 const char *label;
448 const char *value;
451 static struct lp_stored_option *stored_options;
454 save options set by lp_set_cmdline() into a list. This list is
455 re-applied when we do a globals reset, so that cmdline set options
456 are sticky across reloads of smb.conf
458 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
460 struct lp_stored_option *entry, *entry_next;
461 for (entry = stored_options; entry != NULL; entry = entry_next) {
462 entry_next = entry->next;
463 if (strcmp(pszParmName, entry->label) == 0) {
464 DLIST_REMOVE(stored_options, entry);
465 talloc_free(entry);
466 break;
470 entry = talloc(NULL, struct lp_stored_option);
471 if (!entry) {
472 return false;
475 entry->label = talloc_strdup(entry, pszParmName);
476 if (!entry->label) {
477 talloc_free(entry);
478 return false;
481 entry->value = talloc_strdup(entry, pszParmValue);
482 if (!entry->value) {
483 talloc_free(entry);
484 return false;
487 DLIST_ADD_END(stored_options, entry);
489 return true;
492 static bool apply_lp_set_cmdline(void)
494 struct lp_stored_option *entry = NULL;
495 for (entry = stored_options; entry != NULL; entry = entry->next) {
496 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
497 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
498 entry->label, entry->value));
499 return false;
502 return true;
505 /***************************************************************************
506 Initialise the global parameter structure.
507 ***************************************************************************/
509 void loadparm_s3_init_globals(struct loadparm_context *lp_ctx,
510 bool reinit_globals)
512 static bool done_init = false;
513 char *s = NULL;
514 int i;
516 /* If requested to initialize only once and we've already done it... */
517 if (!reinit_globals && done_init) {
518 /* ... then we have nothing more to do */
519 return;
522 if (!done_init) {
523 /* The logfile can be set before this is invoked. Free it if so. */
524 lpcfg_string_free(&Globals.logfile);
525 done_init = true;
526 } else {
527 free_global_parameters();
530 /* This memset and the free_global_parameters() above will
531 * wipe out smb.conf options set with lp_set_cmdline(). The
532 * apply_lp_set_cmdline() call puts these values back in the
533 * table once the defaults are set */
534 ZERO_STRUCT(Globals);
536 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
538 /* Initialize the flags list if necessary */
539 if (flags_list == NULL) {
540 get_flags();
543 for (i = 0; parm_table[i].label; i++) {
544 if ((parm_table[i].type == P_STRING ||
545 parm_table[i].type == P_USTRING))
547 lpcfg_string_set(
548 Globals.ctx,
549 (char **)lp_parm_ptr(NULL, &parm_table[i]),
550 "");
555 lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
556 lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U");
558 init_printer_values(lp_ctx, Globals.ctx, &sDefault);
560 sDefault.ntvfs_handler = str_list_make_v3_const(Globals.ctx, "unixuid default", NULL);
562 DEBUG(3, ("Initialising global parameters\n"));
564 /* Must manually force to upper case here, as this does not go via the handler */
565 lpcfg_string_set(Globals.ctx, &Globals.netbios_name,
566 myhostname_upper());
568 lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file,
569 get_dyn_SMB_PASSWD_FILE());
570 lpcfg_string_set(Globals.ctx, &Globals.private_dir,
571 get_dyn_PRIVATE_DIR());
572 lpcfg_string_set(Globals.ctx, &Globals.binddns_dir,
573 get_dyn_BINDDNS_DIR());
575 /* use the new 'hash2' method by default, with a prefix of 1 */
576 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
577 Globals.mangle_prefix = 1;
579 lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
581 /* using UTF8 by default allows us to support all chars */
582 lpcfg_string_set(Globals.ctx, &Globals.unix_charset,
583 DEFAULT_UNIX_CHARSET);
585 /* Use codepage 850 as a default for the dos character set */
586 lpcfg_string_set(Globals.ctx, &Globals.dos_charset,
587 DEFAULT_DOS_CHARSET);
590 * Allow the default PASSWD_CHAT to be overridden in local.h.
592 lpcfg_string_set(Globals.ctx, &Globals.passwd_chat,
593 DEFAULT_PASSWD_CHAT);
595 lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
597 lpcfg_string_set(Globals.ctx, &Globals.passwd_program, "");
598 lpcfg_string_set(Globals.ctx, &Globals.lock_directory,
599 get_dyn_LOCKDIR());
600 lpcfg_string_set(Globals.ctx, &Globals.state_directory,
601 get_dyn_STATEDIR());
602 lpcfg_string_set(Globals.ctx, &Globals.cache_directory,
603 get_dyn_CACHEDIR());
604 lpcfg_string_set(Globals.ctx, &Globals.pid_directory,
605 get_dyn_PIDDIR());
606 lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address,
607 "0.0.0.0");
609 * By default support explicit binding to broadcast
610 * addresses.
612 Globals.nmbd_bind_explicit_broadcast = true;
614 s = talloc_asprintf(Globals.ctx, "Samba %s", samba_version_string());
615 if (s == NULL) {
616 smb_panic("init_globals: ENOMEM");
618 lpcfg_string_set(Globals.ctx, &Globals.server_string, s);
619 TALLOC_FREE(s);
620 #ifdef DEVELOPER
621 lpcfg_string_set(Globals.ctx, &Globals.panic_action,
622 "/bin/sleep 999999999");
623 #endif
625 lpcfg_string_set(Globals.ctx, &Globals.socket_options,
626 DEFAULT_SOCKET_OPTIONS);
628 lpcfg_string_set(Globals.ctx, &Globals.logon_drive, "");
629 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
630 lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
631 lpcfg_string_set(Globals.ctx, &Globals.logon_path,
632 "\\\\%N\\%U\\profile");
634 Globals.name_resolve_order =
635 str_list_make_v3_const(Globals.ctx,
636 DEFAULT_NAME_RESOLVE_ORDER,
637 NULL);
638 lpcfg_string_set(Globals.ctx, &Globals.password_server, "*");
640 Globals.algorithmic_rid_base = BASE_RID;
642 Globals.load_printers = true;
643 Globals.printcap_cache_time = 750; /* 12.5 minutes */
645 Globals.config_backend = config_backend;
646 Globals._server_role = ROLE_AUTO;
648 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
649 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
650 Globals.max_xmit = 0x4104;
651 Globals.max_mux = 50; /* This is *needed* for profile support. */
652 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
653 Globals._disable_spoolss = false;
654 Globals.max_smbd_processes = 0;/* no limit specified */
655 Globals.username_level = 0;
656 Globals.deadtime = 10080;
657 Globals.getwd_cache = true;
658 Globals.large_readwrite = true;
659 Globals.max_log_size = 5000;
660 Globals.max_open_files = max_open_files();
661 Globals.server_max_protocol = PROTOCOL_SMB3_11;
662 Globals.server_min_protocol = PROTOCOL_SMB2_02;
663 Globals._client_max_protocol = PROTOCOL_DEFAULT;
664 Globals.client_min_protocol = PROTOCOL_SMB2_02;
665 Globals._client_ipc_max_protocol = PROTOCOL_DEFAULT;
666 Globals._client_ipc_min_protocol = PROTOCOL_DEFAULT;
667 Globals._security = SEC_AUTO;
668 Globals.encrypt_passwords = true;
669 Globals.client_schannel = true;
670 Globals.winbind_sealed_pipes = true;
671 Globals.require_strong_key = true;
672 Globals.reject_md5_servers = true;
673 Globals._client_use_krb5_netlogon = LP_ENUM_Default;
674 Globals.server_schannel = true;
675 Globals.server_schannel_require_seal = true;
676 Globals.reject_md5_clients = true;
677 Globals.read_raw = true;
678 Globals.write_raw = true;
679 Globals.null_passwords = false;
680 Globals.old_password_allowed_period = 60;
681 Globals.obey_pam_restrictions = false;
682 Globals.syslog = 1;
683 Globals.syslog_only = false;
684 Globals.timestamp_logs = true;
685 lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
686 Globals.debug_prefix_timestamp = false;
687 Globals.debug_hires_timestamp = true;
688 Globals.debug_syslog_format = false;
689 Globals.debug_pid = false;
690 Globals.debug_uid = false;
691 Globals.debug_class = false;
692 Globals.enable_core_files = true;
693 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
694 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
695 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
696 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
697 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
698 Globals.lm_interval = 60;
699 Globals.time_server = false;
700 Globals.bind_interfaces_only = false;
701 Globals.unix_password_sync = false;
702 Globals.pam_password_change = false;
703 Globals.passwd_chat_debug = false;
704 Globals.passwd_chat_timeout = 2; /* 2 second default. */
705 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
706 Globals.nt_status_support = true; /* Use NT status by default. */
707 Globals.smbd_profiling_level = 0;
708 Globals.stat_cache = true; /* use stat cache by default */
709 Globals.max_stat_cache_size = 512; /* 512k by default */
710 Globals.restrict_anonymous = 0;
711 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
712 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
713 Globals._lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
714 Globals.ntlm_auth = NTLM_AUTH_NTLMV2_ONLY; /* Do NOT use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
715 Globals.nt_hash_store = NT_HASH_STORE_ALWAYS; /* Fill in NT hash when setting password */
716 Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */
717 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 */
718 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
720 Globals.allow_dcerpc_auth_level_connect = false; /* we don't allow this by default */
722 Globals.map_to_guest = 0; /* By Default, "Never" */
723 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
724 Globals.enhanced_browsing = true;
725 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
726 Globals.use_mmap = true;
727 Globals.unicode = true;
728 Globals.smb1_unix_extensions = true;
729 Globals.reset_on_zero_vc = false;
730 Globals.log_writeable_files_on_exit = false;
731 Globals.create_krb5_conf = true;
732 Globals.include_system_krb5_conf = true;
733 Globals._winbind_max_domain_connections = 1;
735 /* hostname lookups can be very expensive and are broken on
736 a large number of sites (tridge) */
737 Globals.hostname_lookups = false;
739 Globals.change_notify = true,
740 Globals.kernel_change_notify = true,
742 lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
743 lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, "");
744 lpcfg_string_set(Globals.ctx, &Globals._ldap_machine_suffix, "");
745 lpcfg_string_set(Globals.ctx, &Globals._ldap_user_suffix, "");
746 lpcfg_string_set(Globals.ctx, &Globals._ldap_group_suffix, "");
747 lpcfg_string_set(Globals.ctx, &Globals._ldap_idmap_suffix, "");
749 lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
750 Globals.ldap_ssl = LDAP_SSL_START_TLS;
751 Globals.ldap_deref = -1;
752 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
753 Globals.ldap_delete_dn = false;
754 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
755 Globals.ldap_follow_referral = Auto;
756 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
757 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
758 Globals.ldap_page_size = LDAP_PAGE_SIZE;
760 Globals.ldap_debug_level = 0;
761 Globals.ldap_debug_threshold = 10;
763 Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SEAL;
765 Globals.ldap_server_require_strong_auth =
766 LDAP_SERVER_REQUIRE_STRONG_AUTH_YES;
768 /* This is what we tell the afs client. in reality we set the token
769 * to never expire, though, when this runs out the afs client will
770 * forget the token. Set to 0 to get NEVERDATE.*/
771 Globals.afs_token_lifetime = 604800;
772 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
774 /* these parameters are set to defaults that are more appropriate
775 for the increasing samba install base:
777 as a member of the workgroup, that will possibly become a
778 _local_ master browser (lm = true). this is opposed to a forced
779 local master browser startup (pm = true).
781 doesn't provide WINS server service by default (wsupp = false),
782 and doesn't provide domain master browser services by default, either.
786 Globals.show_add_printer_wizard = true;
787 Globals.os_level = 20;
788 Globals.local_master = true;
789 Globals._domain_master = Auto; /* depending on _domain_logons */
790 Globals._domain_logons = false;
791 Globals.browse_list = true;
792 Globals.we_are_a_wins_server = false;
793 Globals.wins_proxy = false;
795 TALLOC_FREE(Globals.init_logon_delayed_hosts);
796 Globals.init_logon_delay = 100; /* 100 ms default delay */
798 Globals.wins_dns_proxy = true;
799 Globals.dns_port = DNS_SERVICE_PORT;
801 Globals.allow_trusted_domains = true;
802 lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb");
804 lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
805 lpcfg_string_set(Globals.ctx, &Globals.template_homedir,
806 "/home/%D/%U");
807 lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\");
808 lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory,
809 dyn_WINBINDD_SOCKET_DIR);
811 lpcfg_string_set(Globals.ctx, &Globals.cups_server, "");
812 lpcfg_string_set(Globals.ctx, &Globals.iprint_server, "");
814 lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, "");
816 Globals.cluster_addresses = NULL;
817 Globals.clustering = false;
818 Globals.ctdb_timeout = 0;
819 Globals.ctdb_locktime_warn_threshold = 0;
821 Globals.winbind_cache_time = 300; /* 5 minutes */
822 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
823 Globals.winbind_request_timeout = 60; /* 60 seconds */
824 Globals.winbind_max_clients = 200;
825 Globals.winbind_enum_users = false;
826 Globals.winbind_enum_groups = false;
827 Globals.winbind_use_default_domain = false;
828 Globals.winbind_nested_groups = true;
829 Globals.winbind_expand_groups = 0;
830 Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
831 Globals.winbind_refresh_tickets = false;
832 Globals.winbind_offline_logon = false;
833 Globals.winbind_scan_trusted_domains = false;
835 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
836 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
838 Globals.passdb_expand_explicit = false;
840 Globals.name_cache_timeout = 660; /* In seconds */
842 Globals.client_use_spnego = true;
844 Globals.client_signing = SMB_SIGNING_DEFAULT;
845 Globals._client_ipc_signing = SMB_SIGNING_DEFAULT;
846 Globals.server_signing = SMB_SIGNING_DEFAULT;
848 Globals.defer_sharing_violations = true;
849 Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
851 Globals.enable_privileges = true;
852 Globals.host_msdfs = true;
853 Globals.enable_asu_support = false;
855 /* User defined shares. */
856 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
857 if (s == NULL) {
858 smb_panic("init_globals: ENOMEM");
860 lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s);
861 TALLOC_FREE(s);
862 lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, "");
863 Globals.usershare_max_shares = 0;
864 /* By default disallow sharing of directories not owned by the sharer. */
865 Globals.usershare_owner_only = true;
866 /* By default disallow guest access to usershares. */
867 Globals.usershare_allow_guests = false;
869 Globals.keepalive = DEFAULT_KEEPALIVE;
871 /* By default no shares out of the registry */
872 Globals.registry_shares = false;
874 Globals.min_receivefile_size = 0;
876 Globals.multicast_dns_register = true;
878 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
879 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
880 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
881 Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
882 Globals.smb2_leases = true;
883 Globals._smb3_directory_leases = Auto;
884 Globals.server_multi_channel_support = true;
886 lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir,
887 get_dyn_NCALRPCDIR());
889 Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
891 Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
893 Globals.tls_enabled = true;
894 Globals.tls_verify_peer = TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE;
896 lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
897 lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
898 lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
899 lpcfg_string_set(Globals.ctx,
900 &Globals.tls_priority,
901 "NORMAL:-VERS-SSL3.0");
903 Globals._preferred_master = Auto;
905 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
906 Globals.dns_zone_scavenging = false;
908 lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
909 get_dyn_NTP_SIGND_SOCKET_DIR());
911 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
912 if (s == NULL) {
913 smb_panic("init_globals: ENOMEM");
915 Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
916 TALLOC_FREE(s);
918 #ifdef MIT_KDC_PATH
919 Globals.mit_kdc_command = str_list_make_v3_const(NULL, MIT_KDC_PATH, NULL);
920 #endif
922 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
923 if (s == NULL) {
924 smb_panic("init_globals: ENOMEM");
926 Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
927 TALLOC_FREE(s);
929 s = talloc_asprintf(talloc_tos(), "%s/samba-gpupdate", get_dyn_SCRIPTSBINDIR());
930 if (s == NULL) {
931 smb_panic("init_globals: ENOMEM");
933 Globals.gpo_update_command = str_list_make_v3_const(NULL, s, NULL);
934 TALLOC_FREE(s);
936 Globals.apply_group_policies = false;
938 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
939 if (s == NULL) {
940 smb_panic("init_globals: ENOMEM");
942 Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
943 TALLOC_FREE(s);
945 Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
947 Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
949 Globals.nbt_port = NBT_NAME_SERVICE_PORT;
951 Globals.krb5_port = 88;
953 Globals.kpasswd_port = 464;
955 Globals.kdc_enable_fast = true;
957 Globals.winbind_debug_traceid = true;
959 Globals.aio_max_threads = 100;
961 lpcfg_string_set(Globals.ctx,
962 &Globals.rpc_server_dynamic_port_range,
963 "49152-65535");
964 Globals.rpc_low_port = SERVER_TCP_LOW_PORT;
965 Globals.rpc_high_port = SERVER_TCP_HIGH_PORT;
966 Globals.prefork_children = 4;
967 Globals.prefork_backoff_increment = 10;
968 Globals.prefork_maximum_backoff = 120;
970 Globals.ldap_max_anonymous_request_size = 256000;
971 Globals.ldap_max_authenticated_request_size = 16777216;
972 Globals.ldap_max_search_request_size = 256000;
974 /* Async DNS query timeout (in seconds). */
975 Globals.async_dns_timeout = 10;
977 Globals.client_smb_encrypt = SMB_ENCRYPTION_DEFAULT;
979 Globals._client_use_kerberos = CRED_USE_KERBEROS_DESIRED;
981 Globals.client_protection = CRED_CLIENT_PROTECTION_DEFAULT;
983 Globals.winbind_use_krb5_enterprise_principals = true;
985 Globals.client_smb3_signing_algorithms =
986 str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
987 Globals.server_smb3_signing_algorithms =
988 str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
990 Globals.client_smb3_encryption_algorithms =
991 str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
992 Globals.server_smb3_encryption_algorithms =
993 str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
995 Globals.min_domain_uid = 1000;
998 * By default allow smbd and winbindd to start samba-dcerpcd as
999 * a named-pipe helper.
1001 Globals.rpc_start_on_demand_helpers = true;
1003 Globals.ad_dc_functional_level = DS_DOMAIN_FUNCTION_2008_R2,
1005 Globals.acl_claims_evaluation = ACL_CLAIMS_EVALUATION_AD_DC_ONLY;
1007 /* Set the default Himmelblaud globals */
1008 lpcfg_string_set(Globals.ctx,
1009 &Globals.himmelblaud_hsm_pin_path,
1010 get_dyn_HIMMELBLAUD_HSM_PIN_PATH());
1011 Globals.himmelblaud_hello_enabled = false;
1012 Globals.himmelblaud_sfa_fallback = false;
1014 /* Now put back the settings that were set with lp_set_cmdline() */
1015 apply_lp_set_cmdline();
1018 /* Convenience routine to setup an lp_context with additional s3 variables */
1019 static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
1021 struct loadparm_context *lp_ctx;
1023 lp_ctx = loadparm_init_s3(mem_ctx,
1024 loadparm_s3_helpers());
1025 if (lp_ctx == NULL) {
1026 DEBUG(0, ("loadparm_init_s3 failed\n"));
1027 return NULL;
1030 lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
1031 if (lp_ctx->sDefault == NULL) {
1032 DBG_ERR("talloc_zero failed\n");
1033 TALLOC_FREE(lp_ctx);
1034 return NULL;
1037 *lp_ctx->sDefault = _sDefault;
1038 lp_ctx->services = NULL; /* We do not want to access this directly */
1039 lp_ctx->bInGlobalSection = bInGlobalSection;
1040 lp_ctx->flags = flags_list;
1042 return lp_ctx;
1045 /*******************************************************************
1046 Convenience routine to grab string parameters into talloced memory
1047 and run standard_sub_basic on them. The buffers can be written to by
1048 callers without affecting the source string.
1049 ********************************************************************/
1051 static char *loadparm_s3_global_substitution_fn(
1052 TALLOC_CTX *mem_ctx,
1053 const struct loadparm_substitution *lp_sub,
1054 const char *s,
1055 void *private_data)
1057 char *ret;
1059 /* The follow debug is useful for tracking down memory problems
1060 especially if you have an inner loop that is calling a lp_*()
1061 function that returns a string. Perhaps this debug should be
1062 present all the time? */
1064 #if 0
1065 DEBUG(10, ("lp_string(%s)\n", s));
1066 #endif
1067 if (!s) {
1068 return NULL;
1071 ret = talloc_sub_basic(mem_ctx,
1072 get_current_username(),
1073 get_current_user_info_domain(),
1075 if (trim_char(ret, '\"', '\"')) {
1076 if (strchr(ret,'\"') != NULL) {
1077 TALLOC_FREE(ret);
1078 ret = talloc_sub_basic(mem_ctx,
1079 get_current_username(),
1080 get_current_user_info_domain(),
1084 return ret;
1087 static const struct loadparm_substitution s3_global_substitution = {
1088 .substituted_string_fn = loadparm_s3_global_substitution_fn,
1091 const struct loadparm_substitution *loadparm_s3_global_substitution(void)
1093 return &s3_global_substitution;
1097 In this section all the functions that are used to access the
1098 parameters from the rest of the program are defined
1101 #define FN_GLOBAL_SUBSTITUTED_STRING(fn_name,ptr) \
1102 char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub) \
1103 {return lpcfg_substituted_string(ctx, lp_sub, *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : "");}
1104 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1105 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1106 #define FN_GLOBAL_LIST(fn_name,ptr) \
1107 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1108 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1109 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1110 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1111 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1112 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1113 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1115 #define FN_LOCAL_SUBSTITUTED_STRING(fn_name,val) \
1116 char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub, int i) \
1117 {return lpcfg_substituted_string((ctx), lp_sub, (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1118 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1119 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1120 #define FN_LOCAL_LIST(fn_name,val) \
1121 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1122 #define FN_LOCAL_BOOL(fn_name,val) \
1123 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1124 #define FN_LOCAL_INTEGER(fn_name,val) \
1125 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1127 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1128 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1129 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1130 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1131 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1132 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1134 int lp_winbind_max_domain_connections(void)
1136 if (lp_winbind_offline_logon() &&
1137 lp__winbind_max_domain_connections() > 1) {
1138 DEBUG(1, ("offline logons active, restricting max domain "
1139 "connections to 1\n"));
1140 return 1;
1142 return MAX(1, lp__winbind_max_domain_connections());
1145 /* These functions remain in source3/param for now */
1147 #include "lib/param/param_functions.c"
1149 FN_LOCAL_SUBSTITUTED_STRING(servicename, szService)
1150 FN_LOCAL_CONST_STRING(const_servicename, szService)
1152 /* These functions cannot be auto-generated */
1153 FN_LOCAL_BOOL(autoloaded, autoloaded)
1154 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1156 /* local prototypes */
1158 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1159 static const char *get_boolean(bool bool_value);
1160 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1161 void *userdata);
1162 static bool hash_a_service(const char *name, int number);
1163 static void free_service_byindex(int iService);
1164 static void show_parameter(int parmIndex);
1165 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1166 static bool lp_parameter_value_is_valid(const char *parm_name, const char *val);
1169 * This is a helper function for parametrical options support. It returns a
1170 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1171 * parametrical functions are quite simple
1173 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1174 const char *option)
1176 if (snum >= iNumServices) return NULL;
1178 if (snum < 0) {
1179 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1180 } else {
1181 return get_parametric_helper(ServicePtrs[snum],
1182 type, option, Globals.param_opt);
1186 static void discard_whitespace(char *str)
1188 size_t len = strlen(str);
1189 size_t i = 0;
1191 while (i < len) {
1192 if (isspace(str[i])) {
1193 memmove(&str[i], &str[i+1], len-i);
1194 len -= 1;
1195 continue;
1197 i += 1;
1202 * @brief Go through all global parametric parameters
1204 * @param regex_str A regular expression to scan param for
1205 * @param max_matches Max number of submatches the regexp expects
1206 * @param cb Function to call on match. Should return true
1207 * when it wants wi_scan_global_parametrics to stop
1208 * scanning
1209 * @param private_data Anonymous pointer passed to cb
1211 * @return 0: success, regcomp/regexec return value on error.
1212 * See "man regexec" for possible errors
1215 static int lp_wi_scan_parametrics(struct parmlist_entry *parmlist,
1216 const char *regex_str,
1217 size_t max_matches,
1218 bool (*cb)(const char *string,
1219 regmatch_t matches[],
1220 void *private_data),
1221 void *private_data)
1223 struct parmlist_entry *data;
1224 regex_t regex;
1225 int ret;
1227 ret = regcomp(&regex, regex_str, REG_ICASE);
1228 if (ret != 0) {
1229 return ret;
1232 for (data = parmlist; data != NULL; data = data->next) {
1233 size_t keylen = strlen(data->key);
1234 char key[keylen+1];
1235 regmatch_t matches[max_matches];
1236 bool stop;
1238 memcpy(key, data->key, sizeof(key));
1239 discard_whitespace(key);
1241 ret = regexec(&regex, key, max_matches, matches, 0);
1242 if (ret == REG_NOMATCH) {
1243 continue;
1245 if (ret != 0) {
1246 goto fail;
1249 stop = cb(key, matches, private_data);
1250 if (stop) {
1251 break;
1255 ret = 0;
1256 fail:
1257 regfree(&regex);
1258 return ret;
1261 int lp_wi_scan_global_parametrics(const char *regex_str,
1262 size_t max_matches,
1263 bool (*cb)(const char *string,
1264 regmatch_t matches[],
1265 void *private_data),
1266 void *private_data)
1268 int ret = lp_wi_scan_parametrics(
1269 Globals.param_opt, regex_str, max_matches, cb, private_data);
1270 return ret;
1273 int lp_wi_scan_share_parametrics(int snum,
1274 const char *regex_str,
1275 size_t max_matches,
1276 bool (*cb)(const char *string,
1277 regmatch_t matches[],
1278 void *private_data),
1279 void *private_data)
1281 struct loadparm_service *s = NULL;
1282 int ret;
1284 if (!LP_SNUM_OK(snum)) {
1286 * We return regex return values here, REG_NOMATCH is
1287 * the closest I could find.
1289 return REG_NOMATCH;
1291 s = ServicePtrs[snum];
1293 ret = lp_wi_scan_parametrics(
1294 s->param_opt, regex_str, max_matches, cb, private_data);
1295 return ret;
1298 #define MISSING_PARAMETER(name) \
1299 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1301 /*******************************************************************
1302 convenience routine to return enum parameters.
1303 ********************************************************************/
1304 static int lp_enum(const char *s,const struct enum_list *_enum)
1306 int i;
1308 if (!s || !*s || !_enum) {
1309 MISSING_PARAMETER(lp_enum);
1310 return (-1);
1313 for (i=0; _enum[i].name; i++) {
1314 if (strequal(_enum[i].name,s))
1315 return _enum[i].value;
1318 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1319 return (-1);
1322 #undef MISSING_PARAMETER
1324 /* Return parametric option from a given service. Type is a part of option before ':' */
1325 /* Parametric option has following syntax: 'Type: option = value' */
1326 char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx,
1327 const struct loadparm_substitution *lp_sub,
1328 int snum,
1329 const char *type,
1330 const char *option,
1331 const char *def)
1333 struct parmlist_entry *data = get_parametrics(snum, type, option);
1335 SMB_ASSERT(lp_sub != NULL);
1337 if (data == NULL||data->value==NULL) {
1338 if (def) {
1339 return lpcfg_substituted_string(mem_ctx, lp_sub, def);
1340 } else {
1341 return NULL;
1345 return lpcfg_substituted_string(mem_ctx, lp_sub, data->value);
1348 /* Return parametric option from a given service. Type is a part of option before ':' */
1349 /* Parametric option has following syntax: 'Type: option = value' */
1350 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1352 struct parmlist_entry *data = get_parametrics(snum, type, option);
1354 if (data == NULL||data->value==NULL)
1355 return def;
1357 return data->value;
1361 /* Return parametric option from a given service. Type is a part of option before ':' */
1362 /* Parametric option has following syntax: 'Type: option = value' */
1364 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1366 struct parmlist_entry *data = get_parametrics(snum, type, option);
1368 if (data == NULL||data->value==NULL)
1369 return (const char **)def;
1371 if (data->list==NULL) {
1372 data->list = str_list_make_v3(NULL, data->value, NULL);
1375 return discard_const_p(const char *, data->list);
1378 /* Return parametric option from a given service. Type is a part of option before ':' */
1379 /* Parametric option has following syntax: 'Type: option = value' */
1381 int lp_parm_int(int snum, const char *type, const char *option, int def)
1383 struct parmlist_entry *data = get_parametrics(snum, type, option);
1385 if (data && data->value && *data->value)
1386 return lp_int(data->value);
1388 return def;
1391 /* Return parametric option from a given service. Type is a part of option before ':' */
1392 /* Parametric option has following syntax: 'Type: option = value' */
1394 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1396 struct parmlist_entry *data = get_parametrics(snum, type, option);
1398 if (data && data->value && *data->value)
1399 return lp_ulong(data->value);
1401 return def;
1404 /* Return parametric option from a given service. Type is a part of option before ':' */
1405 /* Parametric option has following syntax: 'Type: option = value' */
1407 unsigned long long lp_parm_ulonglong(int snum, const char *type,
1408 const char *option, unsigned long long def)
1410 struct parmlist_entry *data = get_parametrics(snum, type, option);
1412 if (data && data->value && *data->value) {
1413 return lp_ulonglong(data->value);
1416 return def;
1419 /* Return parametric option from a given service. Type is a part of option
1420 * before ':' */
1421 /* Parametric option has following syntax: 'Type: option = value' */
1423 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1425 struct parmlist_entry *data = get_parametrics(snum, type, option);
1427 if (data && data->value && *data->value)
1428 return lp_bool(data->value);
1430 return def;
1433 /* Return parametric option from a given service. Type is a part of option before ':' */
1434 /* Parametric option has following syntax: 'Type: option = value' */
1436 int lp_parm_enum(int snum, const char *type, const char *option,
1437 const struct enum_list *_enum, int def)
1439 struct parmlist_entry *data = get_parametrics(snum, type, option);
1441 if (data && data->value && *data->value && _enum)
1442 return lp_enum(data->value, _enum);
1444 return def;
1448 * free a param_opts structure.
1449 * param_opts handling should be moved to talloc;
1450 * then this whole functions reduces to a TALLOC_FREE().
1453 static void free_param_opts(struct parmlist_entry **popts)
1455 struct parmlist_entry *opt, *next_opt;
1457 if (*popts != NULL) {
1458 DEBUG(5, ("Freeing parametrics:\n"));
1460 opt = *popts;
1461 while (opt != NULL) {
1462 lpcfg_string_free(&opt->key);
1463 lpcfg_string_free(&opt->value);
1464 TALLOC_FREE(opt->list);
1465 next_opt = opt->next;
1466 TALLOC_FREE(opt);
1467 opt = next_opt;
1469 *popts = NULL;
1472 /***************************************************************************
1473 Free the dynamically allocated parts of a service struct.
1474 ***************************************************************************/
1476 static void free_service(struct loadparm_service *pservice)
1478 if (!pservice)
1479 return;
1481 if (pservice->szService)
1482 DEBUG(5, ("free_service: Freeing service %s\n",
1483 pservice->szService));
1485 free_parameters(pservice);
1487 lpcfg_string_free(&pservice->szService);
1488 TALLOC_FREE(pservice->copymap);
1490 free_param_opts(&pservice->param_opt);
1492 ZERO_STRUCTP(pservice);
1496 /***************************************************************************
1497 remove a service indexed in the ServicePtrs array from the ServiceHash
1498 and free the dynamically allocated parts
1499 ***************************************************************************/
1501 static void free_service_byindex(int idx)
1503 if ( !LP_SNUM_OK(idx) )
1504 return;
1506 ServicePtrs[idx]->valid = false;
1508 /* we have to cleanup the hash record */
1510 if (ServicePtrs[idx]->szService) {
1511 char *canon_name = canonicalize_servicename(
1512 talloc_tos(),
1513 ServicePtrs[idx]->szService );
1515 dbwrap_delete_bystring(ServiceHash, canon_name );
1516 TALLOC_FREE(canon_name);
1519 free_service(ServicePtrs[idx]);
1520 TALLOC_FREE(ServicePtrs[idx]);
1523 /***************************************************************************
1524 Add a new service to the services array initialising it with the given
1525 service.
1526 ***************************************************************************/
1528 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1530 int i;
1531 struct loadparm_service **tsp = NULL;
1533 /* it might already exist */
1534 if (name) {
1535 i = getservicebyname(name, NULL);
1536 if (i >= 0) {
1537 return (i);
1541 /* Re use empty slots if any before allocating new one.*/
1542 for (i=0; i < iNumServices; i++) {
1543 if (ServicePtrs[i] == NULL) {
1544 break;
1547 if (i == iNumServices) {
1548 /* if not, then create one */
1549 tsp = talloc_realloc(NULL, ServicePtrs,
1550 struct loadparm_service *,
1551 iNumServices + 1);
1552 if (tsp == NULL) {
1553 DEBUG(0, ("add_a_service: failed to enlarge "
1554 "ServicePtrs!\n"));
1555 return (-1);
1557 ServicePtrs = tsp;
1558 iNumServices++;
1560 ServicePtrs[i] = talloc_zero(ServicePtrs, struct loadparm_service);
1561 if (!ServicePtrs[i]) {
1562 DEBUG(0,("add_a_service: out of memory!\n"));
1563 return (-1);
1566 ServicePtrs[i]->valid = true;
1568 copy_service(ServicePtrs[i], pservice, NULL);
1569 if (name)
1570 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
1571 name);
1573 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1574 i, ServicePtrs[i]->szService));
1576 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1577 return (-1);
1580 return (i);
1583 /***************************************************************************
1584 Convert a string to uppercase and remove whitespaces.
1585 ***************************************************************************/
1587 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1589 char *result;
1591 if ( !src ) {
1592 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1593 return NULL;
1596 result = talloc_strdup(ctx, src);
1597 SMB_ASSERT(result != NULL);
1599 if (!strlower_m(result)) {
1600 TALLOC_FREE(result);
1601 return NULL;
1603 return result;
1606 /***************************************************************************
1607 Add a name/index pair for the services array to the hash table.
1608 ***************************************************************************/
1610 static bool hash_a_service(const char *name, int idx)
1612 char *canon_name;
1614 if ( !ServiceHash ) {
1615 DEBUG(10,("hash_a_service: creating servicehash\n"));
1616 ServiceHash = db_open_rbt(NULL);
1617 if ( !ServiceHash ) {
1618 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1619 return false;
1623 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1624 idx, name));
1626 canon_name = canonicalize_servicename(talloc_tos(), name );
1628 dbwrap_store_bystring(ServiceHash, canon_name,
1629 make_tdb_data((uint8_t *)&idx, sizeof(idx)),
1630 TDB_REPLACE);
1632 TALLOC_FREE(canon_name);
1634 return true;
1637 /***************************************************************************
1638 Add a new home service, with the specified home directory, defaults coming
1639 from service ifrom.
1640 ***************************************************************************/
1642 bool lp_add_home(const char *pszHomename, int iDefaultService,
1643 const char *user, const char *pszHomedir)
1645 const struct loadparm_substitution *lp_sub =
1646 loadparm_s3_global_substitution();
1647 int i;
1648 char *global_path;
1650 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1651 pszHomedir[0] == '\0') {
1652 return false;
1655 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1657 if (i < 0)
1658 return false;
1660 global_path = lp_path(talloc_tos(), lp_sub, GLOBAL_SECTION_SNUM);
1661 if (!(*(ServicePtrs[iDefaultService]->path))
1662 || strequal(ServicePtrs[iDefaultService]->path, global_path)) {
1663 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
1664 pszHomedir);
1666 TALLOC_FREE(global_path);
1668 if (!(*(ServicePtrs[i]->comment))) {
1669 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1670 if (comment == NULL) {
1671 return false;
1673 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment,
1674 comment);
1675 TALLOC_FREE(comment);
1678 /* set the browseable flag from the global default */
1680 ServicePtrs[i]->browseable = sDefault.browseable;
1681 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1683 ServicePtrs[i]->autoloaded = true;
1685 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1686 user, ServicePtrs[i]->path ));
1688 return true;
1691 /***************************************************************************
1692 Add a new service, based on an old one.
1693 ***************************************************************************/
1695 int lp_add_service(const char *pszService, int iDefaultService)
1697 if (iDefaultService < 0) {
1698 return add_a_service(&sDefault, pszService);
1701 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1704 /***************************************************************************
1705 Add the IPC service.
1706 ***************************************************************************/
1708 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1710 char *comment = NULL;
1711 int i = add_a_service(&sDefault, ipc_name);
1713 if (i < 0)
1714 return false;
1716 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1717 Globals.server_string);
1718 if (comment == NULL) {
1719 return false;
1722 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1723 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1724 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1725 ServicePtrs[i]->max_connections = 0;
1726 ServicePtrs[i]->available = true;
1727 ServicePtrs[i]->read_only = true;
1728 ServicePtrs[i]->guest_only = false;
1729 ServicePtrs[i]->administrative_share = true;
1730 ServicePtrs[i]->guest_ok = guest_ok;
1731 ServicePtrs[i]->printable = false;
1732 ServicePtrs[i]->browseable = sDefault.browseable;
1733 ServicePtrs[i]->autoloaded = false;
1735 DEBUG(3, ("adding IPC service\n"));
1737 TALLOC_FREE(comment);
1738 return true;
1741 /***************************************************************************
1742 Add a new printer service, with defaults coming from service iFrom.
1743 ***************************************************************************/
1745 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1747 const char *comment = "From Printcap";
1748 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1750 if (i < 0)
1751 return false;
1753 /* note that we do NOT default the availability flag to true - */
1754 /* we take it from the default service passed. This allows all */
1755 /* dynamic printers to be disabled by disabling the [printers] */
1756 /* entry (if/when the 'available' keyword is implemented!). */
1758 /* the printer name is set to the service name. */
1759 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername,
1760 pszPrintername);
1761 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1763 /* set the browseable flag from the global default */
1764 ServicePtrs[i]->browseable = sDefault.browseable;
1766 /* Printers cannot be read_only. */
1767 ServicePtrs[i]->read_only = false;
1768 /* No oplocks on printer services. */
1769 ServicePtrs[i]->oplocks = false;
1770 /* Printer services must be printable. */
1771 ServicePtrs[i]->printable = true;
1773 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1775 return true;
1779 /***************************************************************************
1780 Check whether the given parameter name is valid.
1781 Parametric options (names containing a colon) are considered valid.
1782 ***************************************************************************/
1784 bool lp_parameter_is_valid(const char *pszParmName)
1786 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1787 (strchr(pszParmName, ':') != NULL));
1790 /***************************************************************************
1791 Check whether the given name is the name of a global parameter.
1792 Returns true for strings belonging to parameters of class
1793 P_GLOBAL, false for all other strings, also for parametric options
1794 and strings not belonging to any option.
1795 ***************************************************************************/
1797 bool lp_parameter_is_global(const char *pszParmName)
1799 int num = lpcfg_map_parameter(pszParmName);
1801 if (num >= 0) {
1802 return (parm_table[num].p_class == P_GLOBAL);
1805 return false;
1808 /**************************************************************************
1809 Determine the canonical name for a parameter.
1810 Indicate when it is an inverse (boolean) synonym instead of a
1811 "usual" synonym.
1812 **************************************************************************/
1814 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1815 bool *inverse)
1817 int num;
1819 if (!lp_parameter_is_valid(parm_name)) {
1820 *canon_parm = NULL;
1821 return false;
1824 num = map_parameter_canonical(parm_name, inverse);
1825 if (num < 0) {
1826 /* parametric option */
1827 *canon_parm = parm_name;
1828 } else {
1829 *canon_parm = parm_table[num].label;
1832 return true;
1836 /**************************************************************************
1837 Determine the canonical name for a parameter.
1838 Turn the value given into the inverse boolean expression when
1839 the synonym is an inverse boolean synonym.
1841 Return true if
1842 - parm_name is a valid parameter name and
1843 - val is a valid value for this parameter and
1844 - in case the parameter is an inverse boolean synonym, if the val
1845 string could successfully be converted to the reverse bool.
1846 Return false in all other cases.
1847 **************************************************************************/
1849 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1850 const char *val,
1851 const char **canon_parm,
1852 const char **canon_val)
1854 int num;
1855 bool inverse;
1856 bool ret;
1858 if (!lp_parameter_is_valid(parm_name)) {
1859 *canon_parm = NULL;
1860 *canon_val = NULL;
1861 return false;
1864 num = map_parameter_canonical(parm_name, &inverse);
1865 if (num < 0) {
1866 /* parametric option */
1867 *canon_parm = parm_name;
1868 *canon_val = val;
1869 return true;
1872 *canon_parm = parm_table[num].label;
1873 if (inverse) {
1874 if (!lp_invert_boolean(val, canon_val)) {
1875 *canon_val = NULL;
1876 return false;
1878 } else {
1879 *canon_val = val;
1882 ret = lp_parameter_value_is_valid(*canon_parm, *canon_val);
1884 return ret;
1887 /***************************************************************************
1888 Map a parameter's string representation to the index of the canonical
1889 form of the parameter (it might be a synonym).
1890 Returns -1 if the parameter string is not recognised.
1891 ***************************************************************************/
1893 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1895 int parm_num, canon_num;
1896 bool loc_inverse = false;
1898 parm_num = lpcfg_map_parameter(pszParmName);
1899 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
1900 /* invalid, parametric or no candidate for synonyms ... */
1901 goto done;
1904 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1905 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1906 parm_num = canon_num;
1907 goto done;
1911 done:
1912 if (inverse != NULL) {
1913 *inverse = loc_inverse;
1915 return parm_num;
1918 /***************************************************************************
1919 return true if parameter number parm1 is a synonym of parameter
1920 number parm2 (parm2 being the principal name).
1921 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1922 false otherwise.
1923 ***************************************************************************/
1925 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1927 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1928 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1929 (parm_table[parm1].flags & FLAG_SYNONYM) &&
1930 !(parm_table[parm2].flags & FLAG_SYNONYM))
1932 if (inverse != NULL) {
1933 if ((parm_table[parm1].type == P_BOOLREV) &&
1934 (parm_table[parm2].type == P_BOOL))
1936 *inverse = true;
1937 } else {
1938 *inverse = false;
1941 return true;
1943 return false;
1946 /***************************************************************************
1947 Show one parameter's name, type, [values,] and flags.
1948 (helper functions for show_parameter_list)
1949 ***************************************************************************/
1951 static void show_parameter(int parmIndex)
1953 size_t enumIndex, flagIndex;
1954 size_t parmIndex2;
1955 bool hadFlag;
1956 bool hadSyn;
1957 bool inverse;
1958 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1959 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1960 "P_ENUM", "P_BYTES", "P_CMDLIST" };
1961 unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
1962 const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
1964 printf("%s=%s", parm_table[parmIndex].label,
1965 type[parm_table[parmIndex].type]);
1966 if (parm_table[parmIndex].type == P_ENUM) {
1967 printf(",");
1968 for (enumIndex=0;
1969 parm_table[parmIndex].enum_list[enumIndex].name;
1970 enumIndex++)
1972 printf("%s%s",
1973 enumIndex ? "|" : "",
1974 parm_table[parmIndex].enum_list[enumIndex].name);
1977 printf(",");
1978 hadFlag = false;
1979 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1980 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1981 printf("%s%s",
1982 hadFlag ? "|" : "",
1983 flag_names[flagIndex]);
1984 hadFlag = true;
1988 /* output synonyms */
1989 hadSyn = false;
1990 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1991 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1992 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1993 parm_table[parmIndex2].label);
1994 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1995 if (!hadSyn) {
1996 printf(" (synonyms: ");
1997 hadSyn = true;
1998 } else {
1999 printf(", ");
2001 printf("%s%s", parm_table[parmIndex2].label,
2002 inverse ? "[i]" : "");
2005 if (hadSyn) {
2006 printf(")");
2009 printf("\n");
2013 * Check the value for a P_ENUM
2015 static bool check_enum_parameter(struct parm_struct *parm, const char *value)
2017 int i;
2019 for (i = 0; parm->enum_list[i].name; i++) {
2020 if (strwicmp(value, parm->enum_list[i].name) == 0) {
2021 return true;
2024 return false;
2027 /**************************************************************************
2028 Check whether the given value is valid for the given parameter name.
2029 **************************************************************************/
2031 static bool lp_parameter_value_is_valid(const char *parm_name, const char *val)
2033 bool ret = false, tmp_bool;
2034 int num = lpcfg_map_parameter(parm_name), tmp_int;
2035 uint64_t tmp_int64 = 0;
2036 struct parm_struct *parm;
2038 /* parametric options (parameter names containing a colon) cannot
2039 be checked and are therefore considered valid. */
2040 if (strchr(parm_name, ':') != NULL) {
2041 return true;
2044 if (num >= 0) {
2045 parm = &parm_table[num];
2046 switch (parm->type) {
2047 case P_BOOL:
2048 case P_BOOLREV:
2049 ret = set_boolean(val, &tmp_bool);
2050 break;
2052 case P_INTEGER:
2053 ret = (sscanf(val, "%d", &tmp_int) == 1);
2054 break;
2056 case P_OCTAL:
2057 ret = (sscanf(val, "%o", &tmp_int) == 1);
2058 break;
2060 case P_ENUM:
2061 ret = check_enum_parameter(parm, val);
2062 break;
2064 case P_BYTES:
2065 if (conv_str_size_error(val, &tmp_int64) &&
2066 tmp_int64 <= INT_MAX) {
2067 ret = true;
2069 break;
2071 case P_CHAR:
2072 case P_LIST:
2073 case P_STRING:
2074 case P_USTRING:
2075 case P_CMDLIST:
2076 ret = true;
2077 break;
2080 return ret;
2083 /***************************************************************************
2084 Show all parameter's name, type, [values,] and flags.
2085 ***************************************************************************/
2087 void show_parameter_list(void)
2089 int classIndex, parmIndex;
2090 const char *section_names[] = { "local", "global", NULL};
2092 for (classIndex=0; section_names[classIndex]; classIndex++) {
2093 printf("[%s]\n", section_names[classIndex]);
2094 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2095 if (parm_table[parmIndex].p_class == classIndex) {
2096 show_parameter(parmIndex);
2102 /***************************************************************************
2103 Get the standard string representation of a boolean value ("yes" or "no")
2104 ***************************************************************************/
2106 static const char *get_boolean(bool bool_value)
2108 static const char *yes_str = "yes";
2109 static const char *no_str = "no";
2111 return (bool_value ? yes_str : no_str);
2114 /***************************************************************************
2115 Provide the string of the negated boolean value associated to the boolean
2116 given as a string. Returns false if the passed string does not correctly
2117 represent a boolean.
2118 ***************************************************************************/
2120 bool lp_invert_boolean(const char *str, const char **inverse_str)
2122 bool val;
2124 if (!set_boolean(str, &val)) {
2125 return false;
2128 *inverse_str = get_boolean(!val);
2129 return true;
2132 /***************************************************************************
2133 Provide the canonical string representation of a boolean value given
2134 as a string. Return true on success, false if the string given does
2135 not correctly represent a boolean.
2136 ***************************************************************************/
2138 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2140 bool val;
2142 if (!set_boolean(str, &val)) {
2143 return false;
2146 *canon_str = get_boolean(val);
2147 return true;
2150 /***************************************************************************
2151 Find a service by name. Otherwise works like get_service.
2152 ***************************************************************************/
2154 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2156 int iService = -1;
2157 char *canon_name;
2158 TDB_DATA data;
2159 NTSTATUS status;
2161 if (ServiceHash == NULL) {
2162 return -1;
2165 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2167 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2168 &data);
2170 if (NT_STATUS_IS_OK(status) &&
2171 (data.dptr != NULL) &&
2172 (data.dsize == sizeof(iService)))
2174 memcpy(&iService, data.dptr, sizeof(iService));
2177 TALLOC_FREE(canon_name);
2179 if ((iService != -1) && (LP_SNUM_OK(iService))
2180 && (pserviceDest != NULL)) {
2181 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2184 return (iService);
2187 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2188 struct loadparm_service *lp_service(const char *pszServiceName)
2190 int iService = getservicebyname(pszServiceName, NULL);
2191 if (iService == -1 || !LP_SNUM_OK(iService)) {
2192 return NULL;
2194 return ServicePtrs[iService];
2197 struct loadparm_service *lp_servicebynum(int snum)
2199 if ((snum == -1) || !LP_SNUM_OK(snum)) {
2200 return NULL;
2202 return ServicePtrs[snum];
2205 struct loadparm_service *lp_default_loadparm_service(void)
2207 return &sDefault;
2210 static struct smbconf_ctx *lp_smbconf_ctx(void)
2212 sbcErr err;
2213 static struct smbconf_ctx *conf_ctx = NULL;
2215 if (conf_ctx == NULL) {
2216 err = smbconf_init(NULL, &conf_ctx, "registry:");
2217 if (!SBC_ERROR_IS_OK(err)) {
2218 DEBUG(1, ("error initializing registry configuration: "
2219 "%s\n", sbcErrorString(err)));
2220 conf_ctx = NULL;
2224 return conf_ctx;
2227 static bool process_smbconf_service(struct smbconf_service *service)
2229 uint32_t count;
2230 bool ret;
2232 if (service == NULL) {
2233 return false;
2236 ret = lp_do_section(service->name, NULL);
2237 if (ret != true) {
2238 return false;
2240 for (count = 0; count < service->num_params; count++) {
2242 if (!bInGlobalSection && bGlobalOnly) {
2243 ret = true;
2244 } else {
2245 const char *pszParmName = service->param_names[count];
2246 const char *pszParmValue = service->param_values[count];
2248 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2250 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2251 pszParmName, pszParmValue);
2254 if (ret != true) {
2255 return false;
2258 if (iServiceIndex >= 0) {
2259 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2261 return true;
2265 * load a service from registry and activate it
2267 bool process_registry_service(const char *service_name)
2269 sbcErr err;
2270 struct smbconf_service *service = NULL;
2271 TALLOC_CTX *mem_ctx = talloc_stackframe();
2272 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2273 bool ret = false;
2275 if (conf_ctx == NULL) {
2276 goto done;
2279 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2281 if (!smbconf_share_exists(conf_ctx, service_name)) {
2283 * Registry does not contain data for this service (yet),
2284 * but make sure lp_load doesn't return false.
2286 ret = true;
2287 goto done;
2290 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2291 if (!SBC_ERROR_IS_OK(err)) {
2292 goto done;
2295 ret = process_smbconf_service(service);
2296 if (!ret) {
2297 goto done;
2300 /* store the csn */
2301 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2303 done:
2304 TALLOC_FREE(mem_ctx);
2305 return ret;
2309 * process_registry_globals
2311 static bool process_registry_globals(void)
2313 bool ret;
2315 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2317 if (!bInGlobalSection && bGlobalOnly) {
2318 ret = true;
2319 } else {
2320 const char *pszParmName = "registry shares";
2321 const char *pszParmValue = "yes";
2323 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2325 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2326 pszParmName, pszParmValue);
2329 if (!ret) {
2330 return ret;
2333 return process_registry_service(GLOBAL_NAME);
2336 bool process_registry_shares(void)
2338 sbcErr err;
2339 uint32_t count;
2340 struct smbconf_service **service = NULL;
2341 uint32_t num_shares = 0;
2342 TALLOC_CTX *mem_ctx = talloc_stackframe();
2343 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2344 bool ret = false;
2346 if (conf_ctx == NULL) {
2347 goto done;
2350 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2351 if (!SBC_ERROR_IS_OK(err)) {
2352 goto done;
2355 ret = true;
2357 for (count = 0; count < num_shares; count++) {
2358 if (strequal(service[count]->name, GLOBAL_NAME)) {
2359 continue;
2361 ret = process_smbconf_service(service[count]);
2362 if (!ret) {
2363 goto done;
2367 /* store the csn */
2368 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2370 done:
2371 TALLOC_FREE(mem_ctx);
2372 return ret;
2376 * reload those shares from registry that are already
2377 * activated in the services array.
2379 static bool reload_registry_shares(void)
2381 int i;
2382 bool ret = true;
2384 for (i = 0; i < iNumServices; i++) {
2385 if (!VALID(i)) {
2386 continue;
2389 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2390 continue;
2393 ret = process_registry_service(ServicePtrs[i]->szService);
2394 if (!ret) {
2395 goto done;
2399 done:
2400 return ret;
2404 #define MAX_INCLUDE_DEPTH 100
2406 static uint8_t include_depth;
2409 * Free the file lists
2411 static void free_file_list(void)
2413 struct file_lists *f;
2414 struct file_lists *next;
2416 f = file_lists;
2417 while( f ) {
2418 next = f->next;
2419 TALLOC_FREE( f );
2420 f = next;
2422 file_lists = NULL;
2427 * Utility function for outsiders to check if we're running on registry.
2429 bool lp_config_backend_is_registry(void)
2431 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2435 * Utility function to check if the config backend is FILE.
2437 bool lp_config_backend_is_file(void)
2439 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2442 /*******************************************************************
2443 Check if a config file has changed date.
2444 ********************************************************************/
2446 bool lp_file_list_changed(void)
2448 struct file_lists *f = file_lists;
2450 DEBUG(6, ("lp_file_list_changed()\n"));
2452 while (f) {
2453 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2454 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2456 if (conf_ctx == NULL) {
2457 return false;
2459 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2460 NULL))
2462 DEBUGADD(6, ("registry config changed\n"));
2463 return true;
2465 } else {
2466 struct timespec mod_time = {
2467 .tv_sec = 0,
2469 struct timeval_buf tbuf = {
2470 .buf = {0},
2472 char *n2 = NULL;
2473 struct stat sb = {0};
2474 int rc;
2476 n2 = talloc_sub_basic(talloc_tos(),
2477 get_current_username(),
2478 get_current_user_info_domain(),
2479 f->name);
2480 if (!n2) {
2481 return false;
2483 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2484 f->name, n2,
2485 timespec_string_buf(&f->modtime,
2486 true,
2487 &tbuf)));
2489 rc = stat(n2, &sb);
2490 if (rc == 0) {
2491 mod_time = get_mtimespec(&sb);
2494 if (mod_time.tv_sec > 0 &&
2495 ((timespec_compare(&mod_time, &f->modtime) != 0) ||
2496 (f->subfname == NULL) ||
2497 (strcmp(n2, f->subfname) != 0)))
2499 f->modtime = mod_time;
2501 DEBUGADD(6,
2502 ("file %s modified: %s\n", n2,
2503 timespec_string_buf(&f->modtime,
2504 true,
2505 &tbuf)));
2507 TALLOC_FREE(f->subfname);
2508 f->subfname = talloc_strdup(f, n2);
2509 if (f->subfname == NULL) {
2510 smb_panic("talloc_strdup failed");
2512 TALLOC_FREE(n2);
2513 return true;
2515 TALLOC_FREE(n2);
2517 f = f->next;
2519 return false;
2524 * Initialize iconv conversion descriptors.
2526 * This is called the first time it is needed, and also called again
2527 * every time the configuration is reloaded, because the charset or
2528 * codepage might have changed.
2530 static void init_iconv(void)
2532 struct smb_iconv_handle *ret = NULL;
2534 ret = reinit_iconv_handle(NULL,
2535 lp_dos_charset(),
2536 lp_unix_charset());
2537 if (ret == NULL) {
2538 smb_panic("reinit_iconv_handle failed");
2542 /***************************************************************************
2543 Handle the include operation.
2544 ***************************************************************************/
2545 static bool bAllowIncludeRegistry = true;
2547 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2548 const char *pszParmValue, char **ptr)
2550 char *fname;
2552 if (include_depth >= MAX_INCLUDE_DEPTH) {
2553 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2554 include_depth));
2555 return false;
2558 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2559 if (!bAllowIncludeRegistry) {
2560 return true;
2562 if (lp_ctx->bInGlobalSection) {
2563 bool ret;
2564 include_depth++;
2565 ret = process_registry_globals();
2566 include_depth--;
2567 return ret;
2568 } else {
2569 DEBUG(1, ("\"include = registry\" only effective "
2570 "in %s section\n", GLOBAL_NAME));
2571 return false;
2575 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2576 get_current_user_info_domain(),
2577 pszParmValue);
2579 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2581 if (service == NULL) {
2582 lpcfg_string_set(Globals.ctx, ptr, fname);
2583 } else {
2584 lpcfg_string_set(service, ptr, fname);
2587 if (file_exist(fname)) {
2588 bool ret;
2589 include_depth++;
2590 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2591 include_depth--;
2592 TALLOC_FREE(fname);
2593 return ret;
2596 DEBUG(2, ("Can't find include file %s\n", fname));
2597 TALLOC_FREE(fname);
2598 return true;
2601 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2603 char *config_option = NULL;
2604 const char *range = NULL;
2605 bool ret = false;
2607 SMB_ASSERT(low != NULL);
2608 SMB_ASSERT(high != NULL);
2610 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2611 domain_name = "*";
2614 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2615 domain_name);
2616 if (config_option == NULL) {
2617 DEBUG(0, ("out of memory\n"));
2618 return false;
2621 range = lp_parm_const_string(-1, config_option, "range", NULL);
2622 if (range == NULL) {
2623 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2624 goto done;
2627 if (sscanf(range, "%u - %u", low, high) != 2) {
2628 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2629 range, domain_name));
2630 goto done;
2633 ret = true;
2635 done:
2636 talloc_free(config_option);
2637 return ret;
2641 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2643 return lp_idmap_range("*", low, high);
2646 const char *lp_idmap_backend(const char *domain_name)
2648 char *config_option = NULL;
2649 const char *backend = NULL;
2651 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2652 domain_name = "*";
2655 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2656 domain_name);
2657 if (config_option == NULL) {
2658 DEBUG(0, ("out of memory\n"));
2659 return false;
2662 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2663 if (backend == NULL) {
2664 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2665 goto done;
2668 done:
2669 talloc_free(config_option);
2670 return backend;
2673 const char *lp_idmap_default_backend(void)
2675 return lp_idmap_backend("*");
2678 /***************************************************************************
2679 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2680 ***************************************************************************/
2682 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2684 const char *suffix_string;
2686 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2687 Globals.ldap_suffix );
2688 if ( !suffix_string ) {
2689 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2690 return "";
2693 return suffix_string;
2696 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2698 if (Globals._ldap_machine_suffix[0])
2699 return append_ldap_suffix(ctx, Globals._ldap_machine_suffix);
2701 return talloc_strdup(ctx, Globals.ldap_suffix);
2704 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2706 if (Globals._ldap_user_suffix[0])
2707 return append_ldap_suffix(ctx, Globals._ldap_user_suffix);
2709 return talloc_strdup(ctx, Globals.ldap_suffix);
2712 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2714 if (Globals._ldap_group_suffix[0])
2715 return append_ldap_suffix(ctx, Globals._ldap_group_suffix);
2717 return talloc_strdup(ctx, Globals.ldap_suffix);
2720 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2722 if (Globals._ldap_idmap_suffix[0])
2723 return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix);
2725 return talloc_strdup(ctx, Globals.ldap_suffix);
2729 return the parameter pointer for a parameter
2731 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2733 if (service == NULL) {
2734 if (parm->p_class == P_LOCAL)
2735 return (void *)(((char *)&sDefault)+parm->offset);
2736 else if (parm->p_class == P_GLOBAL)
2737 return (void *)(((char *)&Globals)+parm->offset);
2738 else return NULL;
2739 } else {
2740 return (void *)(((char *)service) + parm->offset);
2744 /***************************************************************************
2745 Process a parameter for a particular service number. If snum < 0
2746 then assume we are in the globals.
2747 ***************************************************************************/
2749 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2751 TALLOC_CTX *frame = talloc_stackframe();
2752 struct loadparm_context *lp_ctx;
2753 bool ok;
2755 lp_ctx = setup_lp_context(frame);
2756 if (lp_ctx == NULL) {
2757 TALLOC_FREE(frame);
2758 return false;
2761 if (snum < 0) {
2762 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2763 } else {
2764 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2765 pszParmName, pszParmValue);
2768 TALLOC_FREE(frame);
2770 return ok;
2773 /***************************************************************************
2774 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2775 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2776 ***************************************************************************/
2778 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2780 int parmnum, i;
2781 parmnum = lpcfg_map_parameter(pszParmName);
2782 if (parmnum >= 0) {
2783 flags_list[parmnum] &= ~FLAG_CMDLINE;
2784 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2785 return false;
2787 flags_list[parmnum] |= FLAG_CMDLINE;
2789 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2790 * be grouped in the table, so we don't have to search the
2791 * whole table */
2792 for (i=parmnum-1;
2793 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2794 && parm_table[i].p_class == parm_table[parmnum].p_class;
2795 i--) {
2796 flags_list[i] |= FLAG_CMDLINE;
2798 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2799 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2800 flags_list[i] |= FLAG_CMDLINE;
2803 return true;
2806 /* it might be parametric */
2807 if (strchr(pszParmName, ':') != NULL) {
2808 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2809 return true;
2812 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2813 return false;
2816 /***************************************************************************
2817 Process a parameter.
2818 ***************************************************************************/
2820 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2821 void *userdata)
2823 if (!bInGlobalSection && bGlobalOnly)
2824 return true;
2826 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2828 if (bInGlobalSection) {
2829 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2830 } else {
2831 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2832 pszParmName, pszParmValue);
2837 static const char *ad_dc_req_vfs_mods[] = {"dfs_samba4", "acl_xattr", NULL};
2840 * check that @vfs_objects includes all vfs modules required by an AD DC.
2842 static bool check_ad_dc_required_mods(const char **vfs_objects)
2844 int i;
2845 int j;
2846 int got_req;
2848 for (i = 0; ad_dc_req_vfs_mods[i] != NULL; i++) {
2849 got_req = false;
2850 for (j = 0; vfs_objects[j] != NULL; j++) {
2851 if (!strwicmp(ad_dc_req_vfs_mods[i], vfs_objects[j])) {
2852 got_req = true;
2853 break;
2856 if (!got_req) {
2857 DEBUG(0, ("vfs objects specified without required AD "
2858 "DC module: %s\n", ad_dc_req_vfs_mods[i]));
2859 return false;
2863 DEBUG(6, ("vfs objects specified with all required AD DC modules\n"));
2864 return true;
2868 /***************************************************************************
2869 Initialize any local variables in the sDefault table, after parsing a
2870 [globals] section.
2871 ***************************************************************************/
2873 static void init_locals(void)
2876 * We run this check once the [globals] is parsed, to force
2877 * the VFS objects and other per-share settings we need for
2878 * the standard way a AD DC is operated. We may change these
2879 * as our code evolves, which is why we force these settings.
2881 * We can't do this at the end of lp_load_ex(), as by that
2882 * point the services have been loaded and they will already
2883 * have "" as their vfs objects.
2885 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2886 const char **vfs_objects = lp_vfs_objects(-1);
2887 if (vfs_objects != NULL) {
2888 /* ignore return, only warn if modules are missing */
2889 check_ad_dc_required_mods(vfs_objects);
2890 } else {
2891 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2892 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2893 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2894 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2895 } else {
2896 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2900 lp_do_parameter(-1, "map hidden", "no");
2901 lp_do_parameter(-1, "map system", "no");
2902 lp_do_parameter(-1, "map readonly", "no");
2903 lp_do_parameter(-1, "map archive", "no");
2904 lp_do_parameter(-1, "store dos attributes", "yes");
2908 /***************************************************************************
2909 Process a new section (service). At this stage all sections are services.
2910 Later we'll have special sections that permit server parameters to be set.
2911 Returns true on success, false on failure.
2912 ***************************************************************************/
2914 bool lp_do_section(const char *pszSectionName, void *userdata)
2916 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2917 bool bRetval;
2918 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2919 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2921 /* if we were in a global section then do the local inits */
2922 if (bInGlobalSection && !isglobal)
2923 init_locals();
2925 /* if we've just struck a global section, note the fact. */
2926 bInGlobalSection = isglobal;
2927 if (lp_ctx != NULL) {
2928 lp_ctx->bInGlobalSection = isglobal;
2931 /* check for multiple global sections */
2932 if (bInGlobalSection) {
2933 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2934 return true;
2937 if (!bInGlobalSection && bGlobalOnly)
2938 return true;
2940 /* if we have a current service, tidy it up before moving on */
2941 bRetval = true;
2943 if ((iServiceIndex >= 0) && (ServicePtrs[iServiceIndex] != NULL))
2944 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2946 /* if all is still well, move to the next record in the services array */
2947 if (bRetval) {
2948 /* We put this here to avoid an odd message order if messages are */
2949 /* issued by the post-processing of a previous section. */
2950 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2952 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2953 if (iServiceIndex < 0) {
2954 DEBUG(0, ("Failed to add a new service\n"));
2955 return false;
2957 /* Clean all parametric options for service */
2958 /* They will be added during parsing again */
2959 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2962 return bRetval;
2965 /***************************************************************************
2966 Display the contents of a parameter of a single services record.
2967 ***************************************************************************/
2969 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2971 bool result = false;
2972 struct loadparm_context *lp_ctx;
2974 lp_ctx = setup_lp_context(talloc_tos());
2975 if (lp_ctx == NULL) {
2976 return false;
2979 if (isGlobal) {
2980 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2981 } else {
2982 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2984 TALLOC_FREE(lp_ctx);
2985 return result;
2988 #if 0
2989 /***************************************************************************
2990 Display the contents of a single copy structure.
2991 ***************************************************************************/
2992 static void dump_copy_map(bool *pcopymap)
2994 int i;
2995 if (!pcopymap)
2996 return;
2998 printf("\n\tNon-Copied parameters:\n");
3000 for (i = 0; parm_table[i].label; i++)
3001 if (parm_table[i].p_class == P_LOCAL &&
3002 parm_table[i].ptr && !pcopymap[i] &&
3003 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3005 printf("\t\t%s\n", parm_table[i].label);
3008 #endif
3010 /***************************************************************************
3011 Return TRUE if the passed service number is within range.
3012 ***************************************************************************/
3014 bool lp_snum_ok(int iService)
3016 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->available);
3019 /***************************************************************************
3020 Auto-load some home services.
3021 ***************************************************************************/
3023 static void lp_add_auto_services(const char *str)
3025 char *s;
3026 char *p;
3027 int homes;
3028 char *saveptr;
3030 if (!str)
3031 return;
3033 s = talloc_strdup(talloc_tos(), str);
3034 if (!s) {
3035 smb_panic("talloc_strdup failed");
3036 return;
3039 homes = lp_servicenumber(HOMES_NAME);
3041 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3042 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3043 char *home;
3045 if (lp_servicenumber(p) >= 0)
3046 continue;
3048 home = get_user_home_dir(talloc_tos(), p);
3050 if (home && home[0] && homes >= 0)
3051 lp_add_home(p, homes, p, home);
3053 TALLOC_FREE(home);
3055 TALLOC_FREE(s);
3058 /***************************************************************************
3059 Auto-load one printer.
3060 ***************************************************************************/
3062 void lp_add_one_printer(const char *name, const char *comment,
3063 const char *location, void *pdata)
3065 int printers = lp_servicenumber(PRINTERS_NAME);
3066 int i;
3068 if (lp_servicenumber(name) < 0) {
3069 lp_add_printer(name, printers);
3070 if ((i = lp_servicenumber(name)) >= 0) {
3071 lpcfg_string_set(ServicePtrs[i],
3072 &ServicePtrs[i]->comment, comment);
3073 ServicePtrs[i]->autoloaded = true;
3078 /***************************************************************************
3079 Have we loaded a services file yet?
3080 ***************************************************************************/
3082 bool lp_loaded(void)
3084 return (b_loaded);
3087 /***************************************************************************
3088 Unload unused services.
3089 ***************************************************************************/
3091 void lp_killunused(struct smbd_server_connection *sconn,
3092 bool (*snumused) (struct smbd_server_connection *, int))
3094 int i;
3095 for (i = 0; i < iNumServices; i++) {
3096 if (!VALID(i))
3097 continue;
3099 /* don't kill autoloaded or usershare services */
3100 if ( ServicePtrs[i]->autoloaded ||
3101 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3102 continue;
3105 if (!snumused || !snumused(sconn, i)) {
3106 free_service_byindex(i);
3112 * Kill all except autoloaded and usershare services - convenience wrapper
3114 void lp_kill_all_services(void)
3116 lp_killunused(NULL, NULL);
3119 /***************************************************************************
3120 Unload a service.
3121 ***************************************************************************/
3123 void lp_killservice(int iServiceIn)
3125 if (VALID(iServiceIn)) {
3126 free_service_byindex(iServiceIn);
3130 /***************************************************************************
3131 Save the current values of all global and sDefault parameters into the
3132 defaults union. This allows testparm to show only the
3133 changed (ie. non-default) parameters.
3134 ***************************************************************************/
3136 static void lp_save_defaults(void)
3138 int i;
3139 struct parmlist_entry * parm;
3140 for (i = 0; parm_table[i].label; i++) {
3141 if (!(flags_list[i] & FLAG_CMDLINE)) {
3142 flags_list[i] |= FLAG_DEFAULT;
3145 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3146 && parm_table[i].p_class == parm_table[i - 1].p_class)
3147 continue;
3148 switch (parm_table[i].type) {
3149 case P_LIST:
3150 case P_CMDLIST:
3151 parm_table[i].def.lvalue = str_list_copy(
3152 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3153 break;
3154 case P_STRING:
3155 case P_USTRING:
3156 lpcfg_string_set(
3157 Globals.ctx,
3158 &parm_table[i].def.svalue,
3159 *(char **)lp_parm_ptr(
3160 NULL, &parm_table[i]));
3161 if (parm_table[i].def.svalue == NULL) {
3162 smb_panic("lpcfg_string_set() failed");
3164 break;
3165 case P_BOOL:
3166 case P_BOOLREV:
3167 parm_table[i].def.bvalue =
3168 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3169 break;
3170 case P_CHAR:
3171 parm_table[i].def.cvalue =
3172 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3173 break;
3174 case P_INTEGER:
3175 case P_OCTAL:
3176 case P_ENUM:
3177 case P_BYTES:
3178 parm_table[i].def.ivalue =
3179 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3180 break;
3184 for (parm=Globals.param_opt; parm; parm=parm->next) {
3185 if (!(parm->priority & FLAG_CMDLINE)) {
3186 parm->priority |= FLAG_DEFAULT;
3190 for (parm=sDefault.param_opt; parm; parm=parm->next) {
3191 if (!(parm->priority & FLAG_CMDLINE)) {
3192 parm->priority |= FLAG_DEFAULT;
3196 defaults_saved = true;
3199 /***********************************************************
3200 If we should send plaintext/LANMAN passwords in the client
3201 ************************************************************/
3203 static void set_allowed_client_auth(void)
3205 if (Globals.client_ntlmv2_auth) {
3206 Globals.client_lanman_auth = false;
3208 if (!Globals.client_lanman_auth) {
3209 Globals.client_plaintext_auth = false;
3213 /***************************************************************************
3214 JRA.
3215 The following code allows smbd to read a user defined share file.
3216 Yes, this is my intent. Yes, I'm comfortable with that...
3218 THE FOLLOWING IS SECURITY CRITICAL CODE.
3220 It washes your clothes, it cleans your house, it guards you while you sleep...
3221 Do not f%^k with it....
3222 ***************************************************************************/
3224 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3226 /***************************************************************************
3227 Check allowed stat state of a usershare file.
3228 Ensure we print out who is dicking with us so the admin can
3229 get their sorry ass fired.
3230 ***************************************************************************/
3232 static bool check_usershare_stat(const char *fname,
3233 const SMB_STRUCT_STAT *psbuf)
3235 if (!S_ISREG(psbuf->st_ex_mode)) {
3236 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3237 "not a regular file\n",
3238 fname, (unsigned int)psbuf->st_ex_uid ));
3239 return false;
3242 /* Ensure this doesn't have the other write bit set. */
3243 if (psbuf->st_ex_mode & S_IWOTH) {
3244 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3245 "public write. Refusing to allow as a usershare file.\n",
3246 fname, (unsigned int)psbuf->st_ex_uid ));
3247 return false;
3250 /* Should be 10k or less. */
3251 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3252 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3253 "too large (%u) to be a user share file.\n",
3254 fname, (unsigned int)psbuf->st_ex_uid,
3255 (unsigned int)psbuf->st_ex_size ));
3256 return false;
3259 return true;
3262 /***************************************************************************
3263 Parse the contents of a usershare file.
3264 ***************************************************************************/
3266 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3267 SMB_STRUCT_STAT *psbuf,
3268 const char *servicename,
3269 int snum,
3270 char **lines,
3271 int numlines,
3272 char **pp_sharepath,
3273 char **pp_comment,
3274 char **pp_cp_servicename,
3275 struct security_descriptor **ppsd,
3276 bool *pallow_guest)
3278 const char **prefixallowlist = lp_usershare_prefix_allow_list();
3279 const char **prefixdenylist = lp_usershare_prefix_deny_list();
3280 int us_vers;
3281 DIR *dp;
3282 SMB_STRUCT_STAT sbuf;
3283 char *sharepath = NULL;
3284 char *comment = NULL;
3286 *pp_sharepath = NULL;
3287 *pp_comment = NULL;
3289 *pallow_guest = false;
3291 if (numlines < 4) {
3292 return USERSHARE_MALFORMED_FILE;
3295 if (strcmp(lines[0], "#VERSION 1") == 0) {
3296 us_vers = 1;
3297 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3298 us_vers = 2;
3299 if (numlines < 5) {
3300 return USERSHARE_MALFORMED_FILE;
3302 } else {
3303 return USERSHARE_BAD_VERSION;
3306 if (strncmp(lines[1], "path=", 5) != 0) {
3307 return USERSHARE_MALFORMED_PATH;
3310 sharepath = talloc_strdup(ctx, &lines[1][5]);
3311 if (!sharepath) {
3312 return USERSHARE_POSIX_ERR;
3314 trim_string(sharepath, " ", " ");
3316 if (strncmp(lines[2], "comment=", 8) != 0) {
3317 return USERSHARE_MALFORMED_COMMENT_DEF;
3320 comment = talloc_strdup(ctx, &lines[2][8]);
3321 if (!comment) {
3322 return USERSHARE_POSIX_ERR;
3324 trim_string(comment, " ", " ");
3325 trim_char(comment, '"', '"');
3327 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3328 return USERSHARE_MALFORMED_ACL_DEF;
3331 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3332 return USERSHARE_ACL_ERR;
3335 if (us_vers == 2) {
3336 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3337 return USERSHARE_MALFORMED_ACL_DEF;
3339 if (lines[4][9] == 'y') {
3340 *pallow_guest = true;
3343 /* Backwards compatible extension to file version #2. */
3344 if (numlines > 5) {
3345 if (strncmp(lines[5], "sharename=", 10) != 0) {
3346 return USERSHARE_MALFORMED_SHARENAME_DEF;
3348 if (!strequal(&lines[5][10], servicename)) {
3349 return USERSHARE_BAD_SHARENAME;
3351 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3352 if (!*pp_cp_servicename) {
3353 return USERSHARE_POSIX_ERR;
3358 if (*pp_cp_servicename == NULL) {
3359 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3360 if (!*pp_cp_servicename) {
3361 return USERSHARE_POSIX_ERR;
3365 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3366 /* Path didn't change, no checks needed. */
3367 *pp_sharepath = sharepath;
3368 *pp_comment = comment;
3369 return USERSHARE_OK;
3372 /* The path *must* be absolute. */
3373 if (sharepath[0] != '/') {
3374 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3375 servicename, sharepath));
3376 return USERSHARE_PATH_NOT_ABSOLUTE;
3379 /* If there is a usershare prefix deny list ensure one of these paths
3380 doesn't match the start of the user given path. */
3381 if (prefixdenylist) {
3382 int i;
3383 for ( i=0; prefixdenylist[i]; i++ ) {
3384 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3385 servicename, i, prefixdenylist[i], sharepath ));
3386 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3387 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3388 "usershare prefix deny list entries.\n",
3389 servicename, sharepath));
3390 return USERSHARE_PATH_IS_DENIED;
3395 /* If there is a usershare prefix allow list ensure one of these paths
3396 does match the start of the user given path. */
3398 if (prefixallowlist) {
3399 int i;
3400 for ( i=0; prefixallowlist[i]; i++ ) {
3401 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3402 servicename, i, prefixallowlist[i], sharepath ));
3403 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3404 break;
3407 if (prefixallowlist[i] == NULL) {
3408 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3409 "usershare prefix allow list entries.\n",
3410 servicename, sharepath));
3411 return USERSHARE_PATH_NOT_ALLOWED;
3415 /* Ensure this is pointing to a directory. */
3416 dp = opendir(sharepath);
3418 if (!dp) {
3419 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3420 servicename, sharepath));
3421 return USERSHARE_PATH_NOT_DIRECTORY;
3424 /* Ensure the owner of the usershare file has permission to share
3425 this directory. */
3427 if (sys_stat(sharepath, &sbuf, false) == -1) {
3428 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3429 servicename, sharepath, strerror(errno) ));
3430 closedir(dp);
3431 return USERSHARE_POSIX_ERR;
3434 closedir(dp);
3436 if (!S_ISDIR(sbuf.st_ex_mode)) {
3437 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3438 servicename, sharepath ));
3439 return USERSHARE_PATH_NOT_DIRECTORY;
3442 /* Check if sharing is restricted to owner-only. */
3443 /* psbuf is the stat of the usershare definition file,
3444 sbuf is the stat of the target directory to be shared. */
3446 if (lp_usershare_owner_only()) {
3447 /* root can share anything. */
3448 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3449 return USERSHARE_PATH_NOT_ALLOWED;
3453 *pp_sharepath = sharepath;
3454 *pp_comment = comment;
3455 return USERSHARE_OK;
3458 /***************************************************************************
3459 Deal with a usershare file.
3460 Returns:
3461 >= 0 - snum
3462 -1 - Bad name, invalid contents.
3463 - service name already existed and not a usershare, problem
3464 with permissions to share directory etc.
3465 ***************************************************************************/
3467 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3469 SMB_STRUCT_STAT sbuf;
3470 SMB_STRUCT_STAT lsbuf;
3471 char *fname = NULL;
3472 char *sharepath = NULL;
3473 char *comment = NULL;
3474 char *cp_service_name = NULL;
3475 char **lines = NULL;
3476 int numlines = 0;
3477 int fd = -1;
3478 int iService = -1;
3479 TALLOC_CTX *ctx = talloc_stackframe();
3480 struct security_descriptor *psd = NULL;
3481 bool guest_ok = false;
3482 char *canon_name = NULL;
3483 bool added_service = false;
3484 int ret = -1;
3485 NTSTATUS status;
3487 /* Ensure share name doesn't contain invalid characters. */
3488 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3489 DEBUG(0,("process_usershare_file: share name %s contains "
3490 "invalid characters (any of %s)\n",
3491 file_name, INVALID_SHARENAME_CHARS ));
3492 goto out;
3495 canon_name = canonicalize_servicename(ctx, file_name);
3496 if (!canon_name) {
3497 goto out;
3500 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3501 if (!fname) {
3502 goto out;
3505 /* Minimize the race condition by doing an lstat before we
3506 open and fstat. Ensure this isn't a symlink link. */
3508 if (sys_lstat(fname, &lsbuf, false) != 0) {
3509 if (errno == ENOENT) {
3510 /* Unknown share requested. Just ignore. */
3511 goto out;
3513 /* Only log messages for meaningful problems. */
3514 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3515 fname, strerror(errno) ));
3516 goto out;
3519 /* This must be a regular file, not a symlink, directory or
3520 other strange filetype. */
3521 if (!check_usershare_stat(fname, &lsbuf)) {
3522 goto out;
3526 TDB_DATA data;
3528 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3529 canon_name, &data);
3531 iService = -1;
3533 if (NT_STATUS_IS_OK(status) &&
3534 (data.dptr != NULL) &&
3535 (data.dsize == sizeof(iService))) {
3536 memcpy(&iService, data.dptr, sizeof(iService));
3540 if (iService != -1 &&
3541 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3542 &lsbuf.st_ex_mtime) == 0) {
3543 /* Nothing changed - Mark valid and return. */
3544 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3545 canon_name ));
3546 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3547 ret = iService;
3548 goto out;
3551 /* Try and open the file read only - no symlinks allowed. */
3552 #ifdef O_NOFOLLOW
3553 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3554 #else
3555 fd = open(fname, O_RDONLY, 0);
3556 #endif
3558 if (fd == -1) {
3559 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3560 fname, strerror(errno) ));
3561 goto out;
3564 /* Now fstat to be *SURE* it's a regular file. */
3565 if (sys_fstat(fd, &sbuf, false) != 0) {
3566 close(fd);
3567 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3568 fname, strerror(errno) ));
3569 goto out;
3572 /* Is it the same dev/inode as was lstated ? */
3573 if (!check_same_stat(&lsbuf, &sbuf)) {
3574 close(fd);
3575 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3576 "Symlink spoofing going on ?\n", fname ));
3577 goto out;
3580 /* This must be a regular file, not a symlink, directory or
3581 other strange filetype. */
3582 if (!check_usershare_stat(fname, &sbuf)) {
3583 close(fd);
3584 goto out;
3587 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3589 close(fd);
3590 if (lines == NULL) {
3591 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3592 fname, (unsigned int)sbuf.st_ex_uid ));
3593 goto out;
3596 if (parse_usershare_file(ctx, &sbuf, file_name,
3597 iService, lines, numlines, &sharepath,
3598 &comment, &cp_service_name,
3599 &psd, &guest_ok) != USERSHARE_OK) {
3600 goto out;
3603 /* Everything ok - add the service possibly using a template. */
3604 if (iService < 0) {
3605 const struct loadparm_service *sp = &sDefault;
3606 if (snum_template != -1) {
3607 sp = ServicePtrs[snum_template];
3610 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3611 DEBUG(0, ("process_usershare_file: Failed to add "
3612 "new service %s\n", cp_service_name));
3613 goto out;
3616 added_service = true;
3618 /* Read only is controlled by usershare ACL below. */
3619 ServicePtrs[iService]->read_only = false;
3622 /* Write the ACL of the new/modified share. */
3623 status = set_share_security(canon_name, psd);
3624 if (!NT_STATUS_IS_OK(status)) {
3625 DEBUG(0, ("process_usershare_file: Failed to set share "
3626 "security for user share %s\n",
3627 canon_name ));
3628 goto out;
3631 /* If from a template it may be marked invalid. */
3632 ServicePtrs[iService]->valid = true;
3634 /* Set the service as a valid usershare. */
3635 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3637 /* Set guest access. */
3638 if (lp_usershare_allow_guests()) {
3639 ServicePtrs[iService]->guest_ok = guest_ok;
3642 /* And note when it was loaded. */
3643 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3644 lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path,
3645 sharepath);
3646 lpcfg_string_set(ServicePtrs[iService],
3647 &ServicePtrs[iService]->comment, comment);
3649 ret = iService;
3651 out:
3653 if (ret == -1 && iService != -1 && added_service) {
3654 lp_remove_service(iService);
3657 TALLOC_FREE(lines);
3658 TALLOC_FREE(ctx);
3659 return ret;
3662 /***************************************************************************
3663 Checks if a usershare entry has been modified since last load.
3664 ***************************************************************************/
3666 static bool usershare_exists(int iService, struct timespec *last_mod)
3668 SMB_STRUCT_STAT lsbuf;
3669 const char *usersharepath = Globals.usershare_path;
3670 char *fname;
3672 fname = talloc_asprintf(talloc_tos(),
3673 "%s/%s",
3674 usersharepath,
3675 ServicePtrs[iService]->szService);
3676 if (fname == NULL) {
3677 return false;
3680 if (sys_lstat(fname, &lsbuf, false) != 0) {
3681 TALLOC_FREE(fname);
3682 return false;
3685 if (!S_ISREG(lsbuf.st_ex_mode)) {
3686 TALLOC_FREE(fname);
3687 return false;
3690 TALLOC_FREE(fname);
3691 *last_mod = lsbuf.st_ex_mtime;
3692 return true;
3695 static bool usershare_directory_is_root(uid_t uid)
3697 if (uid == 0) {
3698 return true;
3701 if (uid_wrapper_enabled()) {
3702 return true;
3705 return false;
3708 /***************************************************************************
3709 Load a usershare service by name. Returns a valid servicenumber or -1.
3710 ***************************************************************************/
3712 int load_usershare_service(const char *servicename)
3714 SMB_STRUCT_STAT sbuf;
3715 const char *usersharepath = Globals.usershare_path;
3716 int max_user_shares = Globals.usershare_max_shares;
3717 int snum_template = -1;
3719 if (servicename[0] == '\0') {
3720 /* Invalid service name. */
3721 return -1;
3724 if (*usersharepath == 0 || max_user_shares == 0) {
3725 return -1;
3728 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3729 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3730 usersharepath, strerror(errno) ));
3731 return -1;
3734 if (!S_ISDIR(sbuf.st_ex_mode)) {
3735 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3736 usersharepath ));
3737 return -1;
3741 * This directory must be owned by root, and have the 't' bit set.
3742 * It also must not be writable by "other".
3745 #ifdef S_ISVTX
3746 if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3747 !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3748 #else
3749 if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3750 (sbuf.st_ex_mode & S_IWOTH)) {
3751 #endif
3752 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3753 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3754 usersharepath ));
3755 return -1;
3758 /* Ensure the template share exists if it's set. */
3759 if (Globals.usershare_template_share[0]) {
3760 /* We can't use lp_servicenumber here as we are recommending that
3761 template shares have -valid=false set. */
3762 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3763 if (ServicePtrs[snum_template]->szService &&
3764 strequal(ServicePtrs[snum_template]->szService,
3765 Globals.usershare_template_share)) {
3766 break;
3770 if (snum_template == -1) {
3771 DEBUG(0,("load_usershare_service: usershare template share %s "
3772 "does not exist.\n",
3773 Globals.usershare_template_share ));
3774 return -1;
3778 return process_usershare_file(usersharepath, servicename, snum_template);
3781 /***************************************************************************
3782 Load all user defined shares from the user share directory.
3783 We only do this if we're enumerating the share list.
3784 This is the function that can delete usershares that have
3785 been removed.
3786 ***************************************************************************/
3788 int load_usershare_shares(struct smbd_server_connection *sconn,
3789 bool (*snumused) (struct smbd_server_connection *, int))
3791 DIR *dp;
3792 SMB_STRUCT_STAT sbuf;
3793 struct dirent *de;
3794 int num_usershares = 0;
3795 int max_user_shares = Globals.usershare_max_shares;
3796 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3797 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3798 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3799 int iService;
3800 int snum_template = -1;
3801 const char *usersharepath = Globals.usershare_path;
3802 int ret = lp_numservices();
3803 TALLOC_CTX *tmp_ctx;
3805 if (max_user_shares == 0 || *usersharepath == '\0') {
3806 return lp_numservices();
3809 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3810 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3811 usersharepath, strerror(errno) ));
3812 return ret;
3816 * This directory must be owned by root, and have the 't' bit set.
3817 * It also must not be writable by "other".
3820 #ifdef S_ISVTX
3821 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3822 #else
3823 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3824 #endif
3825 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3826 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3827 usersharepath ));
3828 return ret;
3831 /* Ensure the template share exists if it's set. */
3832 if (Globals.usershare_template_share[0]) {
3833 /* We can't use lp_servicenumber here as we are recommending that
3834 template shares have -valid=false set. */
3835 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3836 if (ServicePtrs[snum_template]->szService &&
3837 strequal(ServicePtrs[snum_template]->szService,
3838 Globals.usershare_template_share)) {
3839 break;
3843 if (snum_template == -1) {
3844 DEBUG(0,("load_usershare_shares: usershare template share %s "
3845 "does not exist.\n",
3846 Globals.usershare_template_share ));
3847 return ret;
3851 /* Mark all existing usershares as pending delete. */
3852 for (iService = iNumServices - 1; iService >= 0; iService--) {
3853 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3854 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3858 dp = opendir(usersharepath);
3859 if (!dp) {
3860 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3861 usersharepath, strerror(errno) ));
3862 return ret;
3865 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3866 (de = readdir(dp));
3867 num_dir_entries++ ) {
3868 int r;
3869 const char *n = de->d_name;
3871 /* Ignore . and .. */
3872 if (*n == '.') {
3873 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3874 continue;
3878 if (n[0] == ':') {
3879 /* Temporary file used when creating a share. */
3880 num_tmp_dir_entries++;
3883 /* Allow 20% tmp entries. */
3884 if (num_tmp_dir_entries > allowed_tmp_entries) {
3885 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3886 "in directory %s\n",
3887 num_tmp_dir_entries, usersharepath));
3888 break;
3891 r = process_usershare_file(usersharepath, n, snum_template);
3892 if (r == 0) {
3893 /* Update the services count. */
3894 num_usershares++;
3895 if (num_usershares >= max_user_shares) {
3896 DEBUG(0,("load_usershare_shares: max user shares reached "
3897 "on file %s in directory %s\n",
3898 n, usersharepath ));
3899 break;
3901 } else if (r == -1) {
3902 num_bad_dir_entries++;
3905 /* Allow 20% bad entries. */
3906 if (num_bad_dir_entries > allowed_bad_entries) {
3907 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3908 "in directory %s\n",
3909 num_bad_dir_entries, usersharepath));
3910 break;
3913 /* Allow 20% bad entries. */
3914 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3915 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3916 "in directory %s\n",
3917 num_dir_entries, usersharepath));
3918 break;
3922 closedir(dp);
3924 /* Sweep through and delete any non-refreshed usershares that are
3925 not currently in use. */
3926 tmp_ctx = talloc_stackframe();
3927 for (iService = iNumServices - 1; iService >= 0; iService--) {
3928 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3929 const struct loadparm_substitution *lp_sub =
3930 loadparm_s3_global_substitution();
3931 char *servname;
3933 if (snumused && snumused(sconn, iService)) {
3934 continue;
3937 servname = lp_servicename(tmp_ctx, lp_sub, iService);
3939 /* Remove from the share ACL db. */
3940 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3941 servname ));
3942 delete_share_security(servname);
3943 free_service_byindex(iService);
3946 talloc_free(tmp_ctx);
3948 return lp_numservices();
3951 /********************************************************
3952 Destroy global resources allocated in this file
3953 ********************************************************/
3955 void gfree_loadparm(void)
3957 int i;
3959 free_file_list();
3961 /* Free resources allocated to services */
3963 for ( i = 0; i < iNumServices; i++ ) {
3964 if ( VALID(i) ) {
3965 free_service_byindex(i);
3969 TALLOC_FREE( ServicePtrs );
3970 iNumServices = 0;
3972 /* Now release all resources allocated to global
3973 parameters and the default service */
3975 free_global_parameters();
3979 /***************************************************************************
3980 Allow client apps to specify that they are a client
3981 ***************************************************************************/
3982 static void lp_set_in_client(bool b)
3984 in_client = b;
3988 /***************************************************************************
3989 Determine if we're running in a client app
3990 ***************************************************************************/
3991 static bool lp_is_in_client(void)
3993 return in_client;
3996 static void lp_enforce_ad_dc_settings(void)
3998 lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3999 lp_do_parameter(GLOBAL_SECTION_SNUM,
4000 "winbindd:use external pipes", "true");
4001 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
4002 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
4003 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
4004 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
4005 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
4006 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
4007 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
4008 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
4009 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
4012 /***************************************************************************
4013 Load the services array from the services file. Return true on success,
4014 false on failure.
4015 ***************************************************************************/
4017 static bool lp_load_ex(const char *pszFname,
4018 bool global_only,
4019 bool save_defaults,
4020 bool add_ipc,
4021 bool reinit_globals,
4022 bool allow_include_registry,
4023 bool load_all_shares)
4025 char *n2 = NULL;
4026 bool bRetval;
4027 TALLOC_CTX *frame = talloc_stackframe();
4028 struct loadparm_context *lp_ctx;
4029 int max_protocol, min_protocol;
4031 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4033 bInGlobalSection = true;
4034 bGlobalOnly = global_only;
4035 bAllowIncludeRegistry = allow_include_registry;
4036 sDefault = _sDefault;
4038 lp_ctx = setup_lp_context(talloc_tos());
4040 loadparm_s3_init_globals(lp_ctx, reinit_globals);
4042 free_file_list();
4044 if (save_defaults) {
4045 init_locals();
4046 lp_save_defaults();
4049 if (!reinit_globals) {
4050 free_param_opts(&Globals.param_opt);
4051 apply_lp_set_cmdline();
4054 lp_do_parameter(-1, "idmap config * : backend", Globals.idmap_backend);
4056 /* We get sections first, so have to start 'behind' to make up */
4057 iServiceIndex = -1;
4059 if (lp_config_backend_is_file()) {
4060 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4061 get_current_user_info_domain(),
4062 pszFname);
4063 if (!n2) {
4064 smb_panic("lp_load_ex: out of memory");
4067 add_to_file_list(NULL, &file_lists, pszFname, n2);
4069 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
4070 TALLOC_FREE(n2);
4072 /* finish up the last section */
4073 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4074 if (bRetval) {
4075 if (iServiceIndex >= 0) {
4076 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
4080 if (lp_config_backend_is_registry()) {
4081 bool ok;
4082 /* config backend changed to registry in config file */
4084 * We need to use this extra global variable here to
4085 * survive restart: init_globals uses this as a default
4086 * for config_backend. Otherwise, init_globals would
4087 * send us into an endless loop here.
4090 config_backend = CONFIG_BACKEND_REGISTRY;
4091 /* start over */
4092 DEBUG(1, ("lp_load_ex: changing to config backend "
4093 "registry\n"));
4094 loadparm_s3_init_globals(lp_ctx, true);
4096 TALLOC_FREE(lp_ctx);
4098 lp_kill_all_services();
4099 ok = lp_load_ex(pszFname, global_only, save_defaults,
4100 add_ipc, reinit_globals,
4101 allow_include_registry,
4102 load_all_shares);
4103 TALLOC_FREE(frame);
4104 return ok;
4106 } else if (lp_config_backend_is_registry()) {
4107 bRetval = process_registry_globals();
4108 } else {
4109 DEBUG(0, ("Illegal config backend given: %d\n",
4110 lp_config_backend()));
4111 bRetval = false;
4114 if (bRetval && lp_registry_shares()) {
4115 if (load_all_shares) {
4116 bRetval = process_registry_shares();
4117 } else {
4118 bRetval = reload_registry_shares();
4123 const struct loadparm_substitution *lp_sub =
4124 loadparm_s3_global_substitution();
4125 char *serv = lp_auto_services(talloc_tos(), lp_sub);
4126 lp_add_auto_services(serv);
4127 TALLOC_FREE(serv);
4130 if (add_ipc) {
4131 /* When 'restrict anonymous = 2' guest connections to ipc$
4132 are denied */
4133 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4134 if ( lp_enable_asu_support() ) {
4135 lp_add_ipc("ADMIN$", false);
4139 set_allowed_client_auth();
4141 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4142 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4143 lp_password_server()));
4146 b_loaded = true;
4148 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4149 /* if we_are_a_wins_server is true and we are in the client */
4150 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4151 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4154 init_iconv();
4156 fault_configure(smb_panic_s3);
4159 * We run this check once the whole smb.conf is parsed, to
4160 * force some settings for the standard way a AD DC is
4161 * operated. We may change these as our code evolves, which
4162 * is why we force these settings.
4164 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4165 lp_enforce_ad_dc_settings();
4168 bAllowIncludeRegistry = true;
4170 /* Check if command line max protocol < min protocol, if so
4171 * report a warning to the user.
4173 max_protocol = lp_client_max_protocol();
4174 min_protocol = lp_client_min_protocol();
4175 if (max_protocol < min_protocol) {
4176 const char *max_protocolp, *min_protocolp;
4177 max_protocolp = lpcfg_get_smb_protocol(max_protocol);
4178 min_protocolp = lpcfg_get_smb_protocol(min_protocol);
4179 DBG_ERR("Max protocol %s is less than min protocol %s.\n",
4180 max_protocolp, min_protocolp);
4183 TALLOC_FREE(frame);
4184 return (bRetval);
4187 static bool lp_load(const char *pszFname,
4188 bool global_only,
4189 bool save_defaults,
4190 bool add_ipc,
4191 bool reinit_globals)
4193 return lp_load_ex(pszFname,
4194 global_only,
4195 save_defaults,
4196 add_ipc,
4197 reinit_globals,
4198 true, /* allow_include_registry */
4199 false); /* load_all_shares*/
4202 bool lp_load_initial_only(const char *pszFname)
4204 return lp_load_ex(pszFname,
4205 true, /* global only */
4206 true, /* save_defaults */
4207 false, /* add_ipc */
4208 true, /* reinit_globals */
4209 false, /* allow_include_registry */
4210 false); /* load_all_shares*/
4214 * most common lp_load wrapper, loading only the globals
4216 * If this is used in a daemon or client utility it should be called
4217 * after processing popt.
4219 bool lp_load_global(const char *file_name)
4221 return lp_load(file_name,
4222 true, /* global_only */
4223 false, /* save_defaults */
4224 false, /* add_ipc */
4225 true); /* reinit_globals */
4229 * The typical lp_load wrapper with shares, loads global and
4230 * shares, including IPC, but does not force immediate
4231 * loading of all shares from registry.
4233 bool lp_load_with_shares(const char *file_name)
4235 return lp_load(file_name,
4236 false, /* global_only */
4237 false, /* save_defaults */
4238 true, /* add_ipc */
4239 true); /* reinit_globals */
4243 * lp_load wrapper, especially for clients
4245 bool lp_load_client(const char *file_name)
4247 lp_set_in_client(true);
4249 return lp_load_global(file_name);
4253 * lp_load wrapper, loading only globals, but intended
4254 * for subsequent calls, not reinitializing the globals
4255 * to default values
4257 bool lp_load_global_no_reinit(const char *file_name)
4259 return lp_load(file_name,
4260 true, /* global_only */
4261 false, /* save_defaults */
4262 false, /* add_ipc */
4263 false); /* reinit_globals */
4267 * lp_load wrapper, loading globals and shares,
4268 * intended for subsequent calls, i.e. not reinitializing
4269 * the globals to default values.
4271 bool lp_load_no_reinit(const char *file_name)
4273 return lp_load(file_name,
4274 false, /* global_only */
4275 false, /* save_defaults */
4276 false, /* add_ipc */
4277 false); /* reinit_globals */
4282 * lp_load wrapper, especially for clients, no reinitialization
4284 bool lp_load_client_no_reinit(const char *file_name)
4286 lp_set_in_client(true);
4288 return lp_load_global_no_reinit(file_name);
4291 bool lp_load_with_registry_shares(const char *pszFname)
4293 return lp_load_ex(pszFname,
4294 false, /* global_only */
4295 true, /* save_defaults */
4296 false, /* add_ipc */
4297 true, /* reinit_globals */
4298 true, /* allow_include_registry */
4299 true); /* load_all_shares*/
4302 bool lp_load_with_registry_without_shares(const char *pszFname)
4304 return lp_load_ex(pszFname,
4305 false, /* global_only */
4306 true, /* save_defaults */
4307 false, /* add_ipc */
4308 true, /* reinit_globals */
4309 true, /* allow_include_registry */
4310 false); /* load_all_shares*/
4313 /***************************************************************************
4314 Return the max number of services.
4315 ***************************************************************************/
4317 int lp_numservices(void)
4319 return (iNumServices);
4322 /***************************************************************************
4323 Display the contents of the services array in human-readable form.
4324 ***************************************************************************/
4326 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4328 int iService;
4329 struct loadparm_context *lp_ctx;
4331 if (show_defaults)
4332 defaults_saved = false;
4334 lp_ctx = setup_lp_context(talloc_tos());
4335 if (lp_ctx == NULL) {
4336 return;
4339 lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
4341 lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
4343 for (iService = 0; iService < maxtoprint; iService++) {
4344 fprintf(f,"\n");
4345 lp_dump_one(f, show_defaults, iService);
4347 TALLOC_FREE(lp_ctx);
4350 /***************************************************************************
4351 Display the contents of one service in human-readable form.
4352 ***************************************************************************/
4354 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4356 if (VALID(snum)) {
4357 if (ServicePtrs[snum]->szService[0] == '\0')
4358 return;
4359 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
4360 flags_list, show_defaults);
4364 /***************************************************************************
4365 Return the number of the service with the given name, or -1 if it doesn't
4366 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4367 getservicebyname()! This works ONLY if all services have been loaded, and
4368 does not copy the found service.
4369 ***************************************************************************/
4371 int lp_servicenumber(const char *pszServiceName)
4373 int iService;
4374 fstring serviceName;
4376 if (!pszServiceName) {
4377 return GLOBAL_SECTION_SNUM;
4380 for (iService = iNumServices - 1; iService >= 0; iService--) {
4381 if (VALID(iService) && ServicePtrs[iService]->szService) {
4383 * The substitution here is used to support %U in
4384 * service names
4386 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4387 standard_sub_basic(get_current_username(),
4388 get_current_user_info_domain(),
4389 serviceName,sizeof(serviceName));
4390 if (strequal(serviceName, pszServiceName)) {
4391 break;
4396 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4397 struct timespec last_mod;
4399 if (!usershare_exists(iService, &last_mod)) {
4400 /* Remove the share security tdb entry for it. */
4401 delete_share_security(lp_const_servicename(iService));
4402 /* Remove it from the array. */
4403 free_service_byindex(iService);
4404 /* Doesn't exist anymore. */
4405 return GLOBAL_SECTION_SNUM;
4408 /* Has it been modified ? If so delete and reload. */
4409 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4410 &last_mod) < 0) {
4411 /* Remove it from the array. */
4412 free_service_byindex(iService);
4413 /* and now reload it. */
4414 iService = load_usershare_service(pszServiceName);
4418 if (iService < 0) {
4419 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4420 return GLOBAL_SECTION_SNUM;
4423 return (iService);
4426 /*******************************************************************
4427 A useful volume label function.
4428 ********************************************************************/
4430 const char *volume_label(TALLOC_CTX *ctx, int snum)
4432 const struct loadparm_substitution *lp_sub =
4433 loadparm_s3_global_substitution();
4434 char *ret;
4435 const char *label = lp_volume(ctx, lp_sub, snum);
4436 size_t end = 32;
4438 if (!*label) {
4439 label = lp_servicename(ctx, lp_sub, snum);
4443 * Volume label can be a max of 32 bytes. Make sure to truncate
4444 * it at a codepoint boundary if it's longer than 32 and contains
4445 * multibyte characters. Windows insists on a volume label being
4446 * a valid mb sequence, and errors out if not.
4448 if (strlen(label) > 32) {
4450 * A MB char can be a max of 5 bytes, thus
4451 * we should have a valid mb character at a
4452 * minimum position of (32-5) = 27.
4454 while (end >= 27) {
4456 * Check if a codepoint starting from next byte
4457 * is valid. If yes, then the current byte is the
4458 * end of a MB or ascii sequence and the label can
4459 * be safely truncated here. If not, keep going
4460 * backwards till a valid codepoint is found.
4462 size_t len = 0;
4463 const char *s = &label[end];
4464 codepoint_t c = next_codepoint(s, &len);
4465 if (c != INVALID_CODEPOINT) {
4466 break;
4468 end--;
4472 /* This returns a max of 33 byte guaranteed null terminated string. */
4473 ret = talloc_strndup(ctx, label, end);
4474 if (!ret) {
4475 return "";
4477 return ret;
4480 /*******************************************************************
4481 Get the default server type we will announce as via nmbd.
4482 ********************************************************************/
4484 int lp_default_server_announce(void)
4486 int default_server_announce = 0;
4487 default_server_announce |= SV_TYPE_WORKSTATION;
4488 default_server_announce |= SV_TYPE_SERVER;
4489 default_server_announce |= SV_TYPE_SERVER_UNIX;
4491 /* note that the flag should be set only if we have a
4492 printer service but nmbd doesn't actually load the
4493 services so we can't tell --jerry */
4495 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4497 default_server_announce |= SV_TYPE_SERVER_NT;
4498 default_server_announce |= SV_TYPE_NT;
4500 switch (lp_server_role()) {
4501 case ROLE_DOMAIN_MEMBER:
4502 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4503 break;
4504 case ROLE_DOMAIN_PDC:
4505 case ROLE_IPA_DC:
4506 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4507 break;
4508 case ROLE_DOMAIN_BDC:
4509 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4510 break;
4511 case ROLE_STANDALONE:
4512 default:
4513 break;
4515 if (lp_time_server())
4516 default_server_announce |= SV_TYPE_TIME_SOURCE;
4518 if (lp_host_msdfs())
4519 default_server_announce |= SV_TYPE_DFS_SERVER;
4521 return default_server_announce;
4524 /***********************************************************
4525 If we are PDC then prefer us as DMB
4526 ************************************************************/
4528 bool lp_domain_master(void)
4530 if (Globals._domain_master == Auto)
4531 return (lp_server_role() == ROLE_DOMAIN_PDC ||
4532 lp_server_role() == ROLE_IPA_DC);
4534 return (bool)Globals._domain_master;
4537 /***********************************************************
4538 If we are PDC then prefer us as DMB
4539 ************************************************************/
4541 static bool lp_domain_master_true_or_auto(void)
4543 if (Globals._domain_master) /* auto or yes */
4544 return true;
4546 return false;
4549 /***********************************************************
4550 If we are DMB then prefer us as LMB
4551 ************************************************************/
4553 bool lp_preferred_master(void)
4555 int preferred_master = lp__preferred_master();
4557 if (preferred_master == Auto)
4558 return (lp_local_master() && lp_domain_master());
4560 return (bool)preferred_master;
4563 /*******************************************************************
4564 Remove a service.
4565 ********************************************************************/
4567 void lp_remove_service(int snum)
4569 ServicePtrs[snum]->valid = false;
4572 const char *lp_printername(TALLOC_CTX *ctx,
4573 const struct loadparm_substitution *lp_sub,
4574 int snum)
4576 const char *ret = lp__printername(ctx, lp_sub, snum);
4578 if (ret == NULL || *ret == '\0') {
4579 ret = lp_const_servicename(snum);
4582 return ret;
4586 /***********************************************************
4587 Allow daemons such as winbindd to fix their logfile name.
4588 ************************************************************/
4590 void lp_set_logfile(const char *name)
4592 lpcfg_string_set(Globals.ctx, &Globals.logfile, name);
4593 debug_set_logfile(name);
4596 /*******************************************************************
4597 Return the max print jobs per queue.
4598 ********************************************************************/
4600 int lp_maxprintjobs(int snum)
4602 int maxjobs = lp_max_print_jobs(snum);
4604 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4605 maxjobs = PRINT_MAX_JOBID - 1;
4607 return maxjobs;
4610 const char *lp_printcapname(void)
4612 const char *printcap_name = lp_printcap_name();
4614 if ((printcap_name != NULL) &&
4615 (printcap_name[0] != '\0'))
4616 return printcap_name;
4618 if (sDefault.printing == PRINT_CUPS) {
4619 return "cups";
4622 if (sDefault.printing == PRINT_BSD)
4623 return "/etc/printcap";
4625 return PRINTCAP_NAME;
4628 static uint32_t spoolss_state;
4630 bool lp_disable_spoolss( void )
4632 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4633 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4635 return spoolss_state == SVCCTL_STOPPED ? true : false;
4638 void lp_set_spoolss_state( uint32_t state )
4640 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4642 spoolss_state = state;
4645 uint32_t lp_get_spoolss_state( void )
4647 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4650 /*******************************************************************
4651 Turn off sendfile if we find the underlying OS doesn't support it.
4652 ********************************************************************/
4654 void set_use_sendfile(int snum, bool val)
4656 if (LP_SNUM_OK(snum))
4657 ServicePtrs[snum]->_use_sendfile = val;
4658 else
4659 sDefault._use_sendfile = val;
4662 void lp_set_mangling_method(const char *new_method)
4664 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method);
4667 /*******************************************************************
4668 Global state for POSIX pathname processing.
4669 ********************************************************************/
4671 static bool posix_pathnames;
4673 bool lp_posix_pathnames(void)
4675 return posix_pathnames;
4678 /*******************************************************************
4679 Change everything needed to ensure POSIX pathname processing (currently
4680 not much).
4681 ********************************************************************/
4683 void lp_set_posix_pathnames(void)
4685 posix_pathnames = true;
4688 /*******************************************************************
4689 Global state for POSIX lock processing - CIFS unix extensions.
4690 ********************************************************************/
4692 bool posix_default_lock_was_set;
4693 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4695 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4697 if (posix_default_lock_was_set) {
4698 return posix_cifsx_locktype;
4699 } else {
4700 return fsp->fsp_flags.posix_open ?
4701 POSIX_LOCK : WINDOWS_LOCK;
4705 /*******************************************************************
4706 ********************************************************************/
4708 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4710 posix_default_lock_was_set = true;
4711 posix_cifsx_locktype = val;
4714 int lp_min_receive_file_size(void)
4716 int min_receivefile_size = lp_min_receivefile_size();
4718 if (min_receivefile_size < 0) {
4719 return 0;
4721 return min_receivefile_size;
4724 /*******************************************************************
4725 Safe wide links checks.
4726 This helper function always verify the validity of wide links,
4727 even after a configuration file reload.
4728 ********************************************************************/
4730 void widelinks_warning(int snum)
4732 if (lp_allow_insecure_wide_links()) {
4733 return;
4736 if (lp_wide_links(snum)) {
4737 if (lp_smb1_unix_extensions()) {
4738 DBG_ERR("Share '%s' has wide links and SMB1 unix "
4739 "extensions enabled. "
4740 "These parameters are incompatible. "
4741 "Wide links will be disabled for this share.\n",
4742 lp_const_servicename(snum));
4743 } else if (lp_smb3_unix_extensions(snum)) {
4744 DBG_ERR("Share '%s' has wide links and SMB3 Unix "
4745 "extensions enabled. "
4746 "These parameters are incompatible. "
4747 "Wide links will be disabled for this share.\n",
4748 lp_const_servicename(snum));
4753 bool lp_widelinks(int snum)
4755 /* wide links is always incompatible with unix extensions */
4756 if (lp_smb1_unix_extensions() || lp_smb3_unix_extensions(snum)) {
4758 * Unless we have "allow insecure widelinks"
4759 * turned on.
4761 if (!lp_allow_insecure_wide_links()) {
4762 return false;
4766 return lp_wide_links(snum);
4769 int lp_server_role(void)
4771 return lp_find_server_role(lp__server_role(),
4772 lp__security(),
4773 lp__domain_logons(),
4774 lp_domain_master_true_or_auto());
4777 int lp_security(void)
4779 return lp_find_security(lp__server_role(),
4780 lp__security());
4783 int lp_client_max_protocol(void)
4785 int client_max_protocol = lp__client_max_protocol();
4786 if (client_max_protocol == PROTOCOL_DEFAULT) {
4787 return PROTOCOL_LATEST;
4789 return client_max_protocol;
4792 int lp_client_ipc_min_protocol(void)
4794 int client_ipc_min_protocol = lp__client_ipc_min_protocol();
4795 if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
4796 client_ipc_min_protocol = lp_client_min_protocol();
4798 if (client_ipc_min_protocol < PROTOCOL_NT1) {
4799 return PROTOCOL_NT1;
4801 return client_ipc_min_protocol;
4804 int lp_client_ipc_max_protocol(void)
4806 int client_ipc_max_protocol = lp__client_ipc_max_protocol();
4807 if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
4808 return PROTOCOL_LATEST;
4810 if (client_ipc_max_protocol < PROTOCOL_NT1) {
4811 return PROTOCOL_NT1;
4813 return client_ipc_max_protocol;
4816 int lp_client_ipc_signing(void)
4818 int client_ipc_signing = lp__client_ipc_signing();
4819 if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
4820 return SMB_SIGNING_REQUIRED;
4822 return client_ipc_signing;
4825 enum credentials_use_kerberos lp_client_use_kerberos(void)
4827 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
4828 return CRED_USE_KERBEROS_REQUIRED;
4831 return lp__client_use_kerberos();
4835 int lp_rpc_low_port(void)
4837 return Globals.rpc_low_port;
4840 int lp_rpc_high_port(void)
4842 return Globals.rpc_high_port;
4845 const char *lp_dns_hostname(void)
4847 const char *dns_hostname = lp__dns_hostname();
4848 const char *dns_domain = lp_dnsdomain();
4849 char *netbios_name = NULL;
4850 bool ok;
4852 if (dns_hostname != NULL && dns_hostname[0] != '\0') {
4853 return dns_hostname;
4856 netbios_name = talloc_strdup(talloc_tos(), lp_netbios_name());
4857 if (netbios_name == NULL) {
4858 return NULL;
4860 ok = strlower_m(netbios_name);
4861 if (!ok) {
4862 return NULL;
4865 /* If it isn't set, try to initialize with [netbios name].[realm] */
4866 if (dns_domain != NULL && dns_domain[0] != '\0') {
4867 Globals._dns_hostname = talloc_asprintf(Globals.ctx,
4868 "%s.%s",
4869 netbios_name,
4870 dns_domain);
4871 } else {
4872 Globals._dns_hostname = talloc_strdup(Globals.ctx,
4873 netbios_name);
4875 TALLOC_FREE(netbios_name);
4876 if (Globals._dns_hostname == NULL) {
4877 return NULL;
4879 dns_hostname = Globals._dns_hostname;
4881 return dns_hostname;
4885 * Do not allow LanMan auth if unless NTLMv1 is also allowed
4887 * This also ensures it is disabled if NTLM is totally disabled
4889 bool lp_lanman_auth(void)
4891 enum ntlm_auth_level ntlm_auth_level = lp_ntlm_auth();
4893 if (ntlm_auth_level == NTLM_AUTH_ON) {
4894 return lp__lanman_auth();
4895 } else {
4896 return false;
4900 struct loadparm_global * get_globals(void)
4902 return &Globals;
4905 unsigned int * get_flags(void)
4907 if (flags_list == NULL) {
4908 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
4911 return flags_list;
4914 enum samba_weak_crypto lp_weak_crypto(void)
4916 if (Globals.weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) {
4917 Globals.weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED;
4919 if (samba_gnutls_weak_crypto_allowed()) {
4920 Globals.weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED;
4924 return Globals.weak_crypto;
4927 uint32_t lp_get_async_dns_timeout(void)
4930 * Clamp minimum async dns timeout to 1 second
4931 * as per the man page.
4933 return MAX(Globals.async_dns_timeout, 1);
4936 bool lp_strict_rename(int snum)
4938 if (lp_smb3_directory_leases()){
4939 return true;
4941 return lp__strict_rename(snum);
4944 int lp_smb3_directory_leases(void)
4946 bool dirleases = lp__smb3_directory_leases();
4948 if (lp__smb3_directory_leases() == Auto) {
4949 dirleases &= !lp_clustering();
4952 dirleases &= lp_smb2_leases();
4953 dirleases &= lp_oplocks(GLOBAL_SECTION_SNUM);
4954 dirleases &= !lp_kernel_oplocks(GLOBAL_SECTION_SNUM);
4955 return dirleases;