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/>.
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.
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
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
57 #include "system/filesys.h"
59 #include "lib/param/loadparm.h"
60 #include "lib/param/param.h"
62 #include "lib/smbconf/smbconf.h"
63 #include "lib/smbconf/smbconf_init.h"
66 #include "../librpc/gen_ndr/svcctl.h"
68 #include "../libcli/smb/smb_signing.h"
69 #include "dbwrap/dbwrap.h"
70 #include "dbwrap/dbwrap_rbt.h"
71 #include "../lib/util/bitmap.h"
72 #include "librpc/gen_ndr/nbt.h"
73 #include "source4/lib/tls/tls.h"
75 #ifdef HAVE_SYS_SYSCTL_H
76 #include <sys/sysctl.h>
81 extern userdom_struct current_user_info;
83 /* the special value for the include parameter
84 * to be interpreted not as a file name but to
85 * trigger loading of the global smb.conf options
87 #ifndef INCLUDE_REGISTRY_NAME
88 #define INCLUDE_REGISTRY_NAME "registry"
91 static bool in_client = false; /* Not in the client by default */
92 static struct smbconf_csn conf_last_csn;
94 static int config_backend = CONFIG_BACKEND_FILE;
96 /* some helpful bits */
97 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && \
98 (ServicePtrs != NULL) && \
99 (ServicePtrs[(i)] != NULL) && ServicePtrs[(i)]->valid)
100 #define VALID(i) ((ServicePtrs != NULL) && (ServicePtrs[i]!= NULL) && \
101 ServicePtrs[i]->valid)
103 #define USERSHARE_VALID 1
104 #define USERSHARE_PENDING_DELETE 2
106 static bool defaults_saved = false;
108 #include "lib/param/param_global.h"
110 static struct loadparm_global Globals;
112 /* This is a default service used to prime a services structure */
113 static struct loadparm_service sDefault =
118 .usershare_last_mod = {0, 0},
122 .invalid_users = NULL,
129 .root_preexec = NULL,
130 .root_postexec = NULL,
131 .cups_options = NULL,
132 .print_command = NULL,
134 .lprm_command = NULL,
135 .lppause_command = NULL,
136 .lpresume_command = NULL,
137 .queuepause_command = NULL,
138 .queueresume_command = NULL,
139 ._printername = NULL,
140 .printjob_username = NULL,
141 .dont_descend = NULL,
144 .magic_script = NULL,
145 .magic_output = NULL,
148 .veto_oplock_files = NULL,
158 .aio_write_behind = NULL,
159 .dfree_command = NULL,
160 .min_print_space = 0,
161 .max_print_jobs = 1000,
162 .max_reported_print_jobs = 0,
163 .write_cache_size = 0,
165 .force_create_mode = 0,
166 .directory_mask = 0755,
167 .force_directory_mode = 0,
168 .max_connections = 0,
169 .default_case = CASE_LOWER,
170 .printing = DEFAULT_PRINTING,
171 .oplock_contention_limit = 2,
174 .dfree_cache_time = 0,
175 .preexec_close = false,
176 .root_preexec_close = false,
177 .case_sensitive = Auto,
178 .preserve_case = true,
179 .short_preserve_case = true,
180 .hide_dot_files = true,
181 .hide_special_files = false,
182 .hide_unreadable = false,
183 .hide_unwriteable_files = false,
185 .access_based_share_enum = false,
190 .administrative_share = false,
193 .print_notify_backchannel = false,
197 .store_dos_attributes = false,
198 .dmapi_support = false,
200 .strict_locking = Auto,
201 .posix_locking = true,
203 .kernel_oplocks = false,
204 .level2_oplocks = true,
206 .mangled_names = true,
208 .follow_symlinks = true,
209 .sync_always = false,
210 .strict_allocate = false,
211 .strict_rename = false,
212 .strict_sync = false,
213 .mangling_char = '~',
215 .delete_readonly = false,
216 .fake_oplocks = false,
217 .delete_veto_files = false,
218 .dos_filemode = false,
219 .dos_filetimes = true,
220 .dos_filetime_resolution = false,
221 .fake_directory_create_times = false,
222 .blocking_locks = true,
223 .inherit_permissions = false,
224 .inherit_acls = false,
225 .inherit_owner = false,
227 .msdfs_shuffle_referrals = false,
228 .use_client_driver = false,
229 .default_devmode = true,
230 .force_printername = false,
231 .nt_acl_support = true,
232 .force_unknown_acl_user = false,
233 ._use_sendfile = false,
234 .profile_acls = false,
235 .map_acl_inherit = false,
238 .acl_check_permissions = true,
239 .acl_map_full_control = true,
240 .acl_group_control = false,
241 .acl_allow_execute_always = false,
242 .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
245 .map_readonly = MAP_READONLY_YES,
246 .directory_name_cache_size = 100,
247 .smb_encrypt = SMB_SIGNING_DEFAULT,
248 .kernel_share_modes = true,
249 .durable_handles = true,
254 /* local variables */
255 static struct loadparm_service **ServicePtrs = NULL;
256 static int iNumServices = 0;
257 static int iServiceIndex = 0;
258 static struct db_context *ServiceHash;
259 static bool bInGlobalSection = true;
260 static bool bGlobalOnly = false;
261 static struct file_lists *file_lists = NULL;
262 static unsigned int *flags_list = NULL;
264 static void set_allowed_client_auth(void);
266 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
267 static void free_param_opts(struct parmlist_entry **popts);
270 * Function to return the default value for the maximum number of open
271 * file descriptors permitted. This function tries to consult the
272 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
273 * the smaller of those.
275 static int max_open_files(void)
277 int sysctl_max = MAX_OPEN_FILES;
278 int rlimit_max = MAX_OPEN_FILES;
280 #ifdef HAVE_SYSCTLBYNAME
282 size_t size = sizeof(sysctl_max);
283 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
288 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
294 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
295 rlimit_max = rl.rlim_cur;
297 #if defined(RLIM_INFINITY)
298 if(rl.rlim_cur == RLIM_INFINITY)
299 rlimit_max = MAX_OPEN_FILES;
304 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
305 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
306 "minimum Windows limit (%d)\n",
308 MIN_OPEN_FILES_WINDOWS));
309 sysctl_max = MIN_OPEN_FILES_WINDOWS;
312 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
313 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
314 "minimum Windows limit (%d)\n",
316 MIN_OPEN_FILES_WINDOWS));
317 rlimit_max = MIN_OPEN_FILES_WINDOWS;
320 return MIN(sysctl_max, rlimit_max);
324 * Common part of freeing allocated data for one parameter.
326 static void free_one_parameter_common(void *parm_ptr,
327 struct parm_struct parm)
329 if ((parm.type == P_STRING) ||
330 (parm.type == P_USTRING))
332 lpcfg_string_free((char**)parm_ptr);
333 } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
334 TALLOC_FREE(*((char***)parm_ptr));
339 * Free the allocated data for one parameter for a share
340 * given as a service struct.
342 static void free_one_parameter(struct loadparm_service *service,
343 struct parm_struct parm)
347 if (parm.p_class != P_LOCAL) {
351 parm_ptr = lp_parm_ptr(service, &parm);
353 free_one_parameter_common(parm_ptr, parm);
357 * Free the allocated parameter data of a share given
358 * as a service struct.
360 static void free_parameters(struct loadparm_service *service)
364 for (i=0; parm_table[i].label; i++) {
365 free_one_parameter(service, parm_table[i]);
370 * Free the allocated data for one parameter for a given share
371 * specified by an snum.
373 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
378 parm_ptr = lp_parm_ptr(NULL, &parm);
379 } else if (parm.p_class != P_LOCAL) {
382 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
385 free_one_parameter_common(parm_ptr, parm);
389 * Free the allocated parameter data for a share specified
392 static void free_parameters_by_snum(int snum)
396 for (i=0; parm_table[i].label; i++) {
397 free_one_parameter_by_snum(snum, parm_table[i]);
402 * Free the allocated global parameters.
404 static void free_global_parameters(void)
407 struct parm_struct *parm;
409 free_param_opts(&Globals.param_opt);
410 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
412 /* Reset references in the defaults because the context is going to be freed */
413 for (i=0; parm_table[i].label; i++) {
414 parm = &parm_table[i];
415 if ((parm->type == P_STRING) ||
416 (parm->type == P_USTRING)) {
417 if ((parm->def.svalue != NULL) &&
418 (*(parm->def.svalue) != '\0')) {
419 if (talloc_parent(parm->def.svalue) == Globals.ctx) {
420 parm->def.svalue = NULL;
425 TALLOC_FREE(Globals.ctx);
428 struct lp_stored_option {
429 struct lp_stored_option *prev, *next;
434 static struct lp_stored_option *stored_options;
437 save options set by lp_set_cmdline() into a list. This list is
438 re-applied when we do a globals reset, so that cmdline set options
439 are sticky across reloads of smb.conf
441 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
443 struct lp_stored_option *entry, *entry_next;
444 for (entry = stored_options; entry != NULL; entry = entry_next) {
445 entry_next = entry->next;
446 if (strcmp(pszParmName, entry->label) == 0) {
447 DLIST_REMOVE(stored_options, entry);
453 entry = talloc(NULL, struct lp_stored_option);
458 entry->label = talloc_strdup(entry, pszParmName);
464 entry->value = talloc_strdup(entry, pszParmValue);
470 DLIST_ADD_END(stored_options, entry);
475 static bool apply_lp_set_cmdline(void)
477 struct lp_stored_option *entry = NULL;
478 for (entry = stored_options; entry != NULL; entry = entry->next) {
479 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
480 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
481 entry->label, entry->value));
488 /***************************************************************************
489 Initialise the global parameter structure.
490 ***************************************************************************/
492 static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
494 static bool done_init = false;
498 /* If requested to initialize only once and we've already done it... */
499 if (!reinit_globals && done_init) {
500 /* ... then we have nothing more to do */
505 /* The logfile can be set before this is invoked. Free it if so. */
506 lpcfg_string_free(&Globals.logfile);
509 free_global_parameters();
512 /* This memset and the free_global_parameters() above will
513 * wipe out smb.conf options set with lp_set_cmdline(). The
514 * apply_lp_set_cmdline() call puts these values back in the
515 * table once the defaults are set */
516 ZERO_STRUCT(Globals);
518 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
520 /* Initialize the flags list if necessary */
521 if (flags_list == NULL) {
525 for (i = 0; parm_table[i].label; i++) {
526 if ((parm_table[i].type == P_STRING ||
527 parm_table[i].type == P_USTRING))
531 (char **)lp_parm_ptr(NULL, &parm_table[i]),
537 lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
538 lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U");
540 init_printer_values(lp_ctx, Globals.ctx, &sDefault);
542 sDefault.ntvfs_handler = str_list_make_v3_const(NULL, "unixuid default", NULL);
544 DEBUG(3, ("Initialising global parameters\n"));
546 /* Must manually force to upper case here, as this does not go via the handler */
547 lpcfg_string_set(Globals.ctx, &Globals.netbios_name,
550 lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file,
551 get_dyn_SMB_PASSWD_FILE());
552 lpcfg_string_set(Globals.ctx, &Globals.private_dir,
553 get_dyn_PRIVATE_DIR());
555 /* use the new 'hash2' method by default, with a prefix of 1 */
556 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
557 Globals.mangle_prefix = 1;
559 lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
561 /* using UTF8 by default allows us to support all chars */
562 lpcfg_string_set(Globals.ctx, &Globals.unix_charset,
563 DEFAULT_UNIX_CHARSET);
565 /* Use codepage 850 as a default for the dos character set */
566 lpcfg_string_set(Globals.ctx, &Globals.dos_charset,
567 DEFAULT_DOS_CHARSET);
570 * Allow the default PASSWD_CHAT to be overridden in local.h.
572 lpcfg_string_set(Globals.ctx, &Globals.passwd_chat,
573 DEFAULT_PASSWD_CHAT);
575 lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
577 lpcfg_string_set(Globals.ctx, &Globals.passwd_program, "");
578 lpcfg_string_set(Globals.ctx, &Globals.lock_directory,
580 lpcfg_string_set(Globals.ctx, &Globals.state_directory,
582 lpcfg_string_set(Globals.ctx, &Globals.cache_directory,
584 lpcfg_string_set(Globals.ctx, &Globals.pid_directory,
586 lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address,
589 * By default support explicit binding to broadcast
592 Globals.nmbd_bind_explicit_broadcast = true;
594 s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
596 smb_panic("init_globals: ENOMEM");
598 lpcfg_string_set(Globals.ctx, &Globals.server_string, s);
601 lpcfg_string_set(Globals.ctx, &Globals.panic_action,
602 "/bin/sleep 999999999");
605 lpcfg_string_set(Globals.ctx, &Globals.socket_options,
606 DEFAULT_SOCKET_OPTIONS);
608 lpcfg_string_set(Globals.ctx, &Globals.logon_drive, "");
609 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
610 lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
611 lpcfg_string_set(Globals.ctx, &Globals.logon_path,
612 "\\\\%N\\%U\\profile");
614 Globals.name_resolve_order = str_list_make_v3_const(NULL, "lmhosts wins host bcast", NULL);
615 lpcfg_string_set(Globals.ctx, &Globals.password_server, "*");
617 Globals.algorithmic_rid_base = BASE_RID;
619 Globals.load_printers = true;
620 Globals.printcap_cache_time = 750; /* 12.5 minutes */
622 Globals.config_backend = config_backend;
623 Globals._server_role = ROLE_AUTO;
625 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
626 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
627 Globals.max_xmit = 0x4104;
628 Globals.max_mux = 50; /* This is *needed* for profile support. */
629 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
630 Globals._disable_spoolss = false;
631 Globals.max_smbd_processes = 0;/* no limit specified */
632 Globals.username_level = 0;
633 Globals.deadtime = 0;
634 Globals.getwd_cache = true;
635 Globals.large_readwrite = true;
636 Globals.max_log_size = 5000;
637 Globals.max_open_files = max_open_files();
638 Globals.server_max_protocol = PROTOCOL_SMB3_11;
639 Globals.server_min_protocol = PROTOCOL_LANMAN1;
640 Globals._client_max_protocol = PROTOCOL_DEFAULT;
641 Globals.client_min_protocol = PROTOCOL_CORE;
642 Globals._security = SEC_AUTO;
643 Globals.encrypt_passwords = true;
644 Globals.client_schannel = Auto;
645 Globals.winbind_sealed_pipes = true;
646 Globals.require_strong_key = true;
647 Globals.server_schannel = Auto;
648 Globals.read_raw = true;
649 Globals.write_raw = true;
650 Globals.null_passwords = false;
651 Globals.old_password_allowed_period = 60;
652 Globals.obey_pam_restrictions = false;
654 Globals.syslog_only = false;
655 Globals.timestamp_logs = true;
656 lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
657 Globals.debug_prefix_timestamp = false;
658 Globals.debug_hires_timestamp = true;
659 Globals.debug_pid = false;
660 Globals.debug_uid = false;
661 Globals.debug_class = false;
662 Globals.enable_core_files = true;
663 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
664 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
665 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
666 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
667 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
668 Globals.lm_interval = 60;
669 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
670 Globals.nis_homedir = false;
671 #ifdef WITH_NISPLUS_HOME
672 lpcfg_string_set(Globals.ctx, &Globals.homedir_map,
673 "auto_home.org_dir");
675 lpcfg_string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
678 Globals.time_server = false;
679 Globals.bind_interfaces_only = false;
680 Globals.unix_password_sync = false;
681 Globals.pam_password_change = false;
682 Globals.passwd_chat_debug = false;
683 Globals.passwd_chat_timeout = 2; /* 2 second default. */
684 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
685 Globals.nt_status_support = true; /* Use NT status by default. */
686 Globals.smbd_profiling_level = 0;
687 Globals.stat_cache = true; /* use stat cache by default */
688 Globals.max_stat_cache_size = 256; /* 256k by default */
689 Globals.restrict_anonymous = 0;
690 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
691 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
692 Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
693 Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
694 Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */
695 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 */
696 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
698 Globals.map_to_guest = 0; /* By Default, "Never" */
699 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
700 Globals.enhanced_browsing = true;
701 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
702 #ifdef MMAP_BLACKLIST
703 Globals.use_mmap = false;
705 Globals.use_mmap = true;
707 Globals.unicode = true;
708 Globals.unix_extensions = true;
709 Globals.reset_on_zero_vc = false;
710 Globals.log_writeable_files_on_exit = false;
711 Globals.create_krb5_conf = true;
712 Globals._winbind_max_domain_connections = 1;
714 /* hostname lookups can be very expensive and are broken on
715 a large number of sites (tridge) */
716 Globals.hostname_lookups = false;
718 Globals.change_notify = true,
719 Globals.kernel_change_notify = true,
721 lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
722 lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, "");
723 lpcfg_string_set(Globals.ctx, &Globals._ldap_machine_suffix, "");
724 lpcfg_string_set(Globals.ctx, &Globals._ldap_user_suffix, "");
725 lpcfg_string_set(Globals.ctx, &Globals._ldap_group_suffix, "");
726 lpcfg_string_set(Globals.ctx, &Globals._ldap_idmap_suffix, "");
728 lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
729 Globals.ldap_ssl = LDAP_SSL_START_TLS;
730 Globals.ldap_ssl_ads = false;
731 Globals.ldap_deref = -1;
732 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
733 Globals.ldap_delete_dn = false;
734 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
735 Globals.ldap_follow_referral = Auto;
736 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
737 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
738 Globals.ldap_page_size = LDAP_PAGE_SIZE;
740 Globals.ldap_debug_level = 0;
741 Globals.ldap_debug_threshold = 10;
743 Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
745 Globals.ldap_server_require_strong_auth =
746 LDAP_SERVER_REQUIRE_STRONG_AUTH_YES;
748 /* This is what we tell the afs client. in reality we set the token
749 * to never expire, though, when this runs out the afs client will
750 * forget the token. Set to 0 to get NEVERDATE.*/
751 Globals.afs_token_lifetime = 604800;
752 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
754 /* these parameters are set to defaults that are more appropriate
755 for the increasing samba install base:
757 as a member of the workgroup, that will possibly become a
758 _local_ master browser (lm = true). this is opposed to a forced
759 local master browser startup (pm = true).
761 doesn't provide WINS server service by default (wsupp = false),
762 and doesn't provide domain master browser services by default, either.
766 Globals.show_add_printer_wizard = true;
767 Globals.os_level = 20;
768 Globals.local_master = true;
769 Globals._domain_master = Auto; /* depending on _domain_logons */
770 Globals._domain_logons = false;
771 Globals.browse_list = true;
772 Globals.we_are_a_wins_server = false;
773 Globals.wins_proxy = false;
775 TALLOC_FREE(Globals.init_logon_delayed_hosts);
776 Globals.init_logon_delay = 100; /* 100 ms default delay */
778 Globals.wins_dns_proxy = true;
780 Globals.allow_trusted_domains = true;
781 lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb");
783 lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
784 lpcfg_string_set(Globals.ctx, &Globals.template_homedir,
786 lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\");
787 lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory,
788 dyn_WINBINDD_SOCKET_DIR);
790 lpcfg_string_set(Globals.ctx, &Globals.cups_server, "");
791 lpcfg_string_set(Globals.ctx, &Globals.iprint_server, "");
793 lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, "");
795 Globals.cluster_addresses = NULL;
796 Globals.clustering = false;
797 Globals.ctdb_timeout = 0;
798 Globals.ctdb_locktime_warn_threshold = 0;
800 Globals.winbind_cache_time = 300; /* 5 minutes */
801 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
802 Globals.winbind_request_timeout = 60; /* 60 seconds */
803 Globals.winbind_max_clients = 200;
804 Globals.winbind_enum_users = false;
805 Globals.winbind_enum_groups = false;
806 Globals.winbind_use_default_domain = false;
807 Globals.winbind_trusted_domains_only = false;
808 Globals.winbind_nested_groups = true;
809 Globals.winbind_expand_groups = 0;
810 Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
811 Globals.winbind_refresh_tickets = false;
812 Globals.winbind_offline_logon = false;
814 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
815 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
817 Globals.passdb_expand_explicit = false;
819 Globals.name_cache_timeout = 660; /* In seconds */
821 Globals.use_spnego = true;
822 Globals.client_use_spnego = true;
824 Globals.client_signing = SMB_SIGNING_DEFAULT;
825 Globals.server_signing = SMB_SIGNING_DEFAULT;
827 Globals.defer_sharing_violations = true;
828 Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
830 Globals.enable_privileges = true;
831 Globals.host_msdfs = true;
832 Globals.enable_asu_support = false;
834 /* User defined shares. */
835 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
837 smb_panic("init_globals: ENOMEM");
839 lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s);
841 lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, "");
842 Globals.usershare_max_shares = 0;
843 /* By default disallow sharing of directories not owned by the sharer. */
844 Globals.usershare_owner_only = true;
845 /* By default disallow guest access to usershares. */
846 Globals.usershare_allow_guests = false;
848 Globals.keepalive = DEFAULT_KEEPALIVE;
850 /* By default no shares out of the registry */
851 Globals.registry_shares = false;
853 Globals.min_receivefile_size = 0;
855 Globals.map_untrusted_to_domain = false;
856 Globals.multicast_dns_register = true;
858 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
859 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
860 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
861 Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
862 Globals.smb2_leases = false;
864 lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir,
865 get_dyn_NCALRPCDIR());
867 Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
869 Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
871 Globals.tls_enabled = true;
872 Globals.tls_verify_peer = TLS_VERIFY_PEER_NO_CHECK;
874 lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
875 lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
876 lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
877 lpcfg_string_set(Globals.ctx, &Globals.tls_priority,
878 "NORMAL:-VERS-SSL3.0");
880 lpcfg_string_set(Globals.ctx, &Globals.share_backend, "classic");
882 Globals._preferred_master = Auto;
884 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
886 lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
887 get_dyn_NTP_SIGND_SOCKET_DIR());
889 lpcfg_string_set(Globals.ctx,
890 &Globals.winbindd_privileged_socket_directory,
891 get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
893 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
895 smb_panic("init_globals: ENOMEM");
897 Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
900 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
902 smb_panic("init_globals: ENOMEM");
904 Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
907 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
909 smb_panic("init_globals: ENOMEM");
911 Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
914 Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
916 Globals.rndc_command = str_list_make_v3_const(NULL, "/usr/sbin/rndc", NULL);
918 Globals.cldap_port = 389;
920 Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
922 Globals.nbt_port = NBT_NAME_SERVICE_PORT;
924 Globals.krb5_port = 88;
926 Globals.kpasswd_port = 464;
928 Globals.web_port = 901;
930 Globals.aio_max_threads = 100;
932 /* Now put back the settings that were set with lp_set_cmdline() */
933 apply_lp_set_cmdline();
936 /* Convenience routine to setup an lp_context with additional s3 variables */
937 static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
939 struct loadparm_context *lp_ctx;
941 lp_ctx = loadparm_init_s3(mem_ctx,
942 loadparm_s3_helpers());
943 if (lp_ctx == NULL) {
944 DEBUG(0, ("loadparm_init_s3 failed\n"));
948 lp_ctx->sDefault = &sDefault;
949 lp_ctx->services = NULL; /* We do not want to access this directly */
950 lp_ctx->bInGlobalSection = bInGlobalSection;
951 lp_ctx->flags = flags_list;
956 /*******************************************************************
957 Convenience routine to grab string parameters into talloced memory
958 and run standard_sub_basic on them. The buffers can be written to by
959 callers without affecting the source string.
960 ********************************************************************/
962 char *lp_string(TALLOC_CTX *ctx, const char *s)
966 /* The follow debug is useful for tracking down memory problems
967 especially if you have an inner loop that is calling a lp_*()
968 function that returns a string. Perhaps this debug should be
969 present all the time? */
972 DEBUG(10, ("lp_string(%s)\n", s));
978 ret = talloc_sub_basic(ctx,
979 get_current_username(),
980 current_user_info.domain,
982 if (trim_char(ret, '\"', '\"')) {
983 if (strchr(ret,'\"') != NULL) {
985 ret = talloc_sub_basic(ctx,
986 get_current_username(),
987 current_user_info.domain,
995 In this section all the functions that are used to access the
996 parameters from the rest of the program are defined
999 #define FN_GLOBAL_STRING(fn_name,ptr) \
1000 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1001 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1002 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1003 #define FN_GLOBAL_LIST(fn_name,ptr) \
1004 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1005 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1006 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1007 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1008 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1009 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1010 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1012 #define FN_LOCAL_STRING(fn_name,val) \
1013 char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1014 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1015 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1016 #define FN_LOCAL_LIST(fn_name,val) \
1017 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1018 #define FN_LOCAL_BOOL(fn_name,val) \
1019 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1020 #define FN_LOCAL_INTEGER(fn_name,val) \
1021 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1023 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1024 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1025 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1026 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1027 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1028 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1030 int lp_winbind_max_domain_connections(void)
1032 if (lp_winbind_offline_logon() &&
1033 lp__winbind_max_domain_connections() > 1) {
1034 DEBUG(1, ("offline logons active, restricting max domain "
1035 "connections to 1\n"));
1038 return MAX(1, lp__winbind_max_domain_connections());
1041 /* These functions remain in source3/param for now */
1043 #include "lib/param/param_functions.c"
1045 FN_LOCAL_STRING(servicename, szService)
1046 FN_LOCAL_CONST_STRING(const_servicename, szService)
1048 /* These functions cannot be auto-generated */
1049 FN_LOCAL_BOOL(autoloaded, autoloaded)
1050 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1052 /* local prototypes */
1054 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1055 static const char *get_boolean(bool bool_value);
1056 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1058 static bool hash_a_service(const char *name, int number);
1059 static void free_service_byindex(int iService);
1060 static void show_parameter(int parmIndex);
1061 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1064 * This is a helper function for parametrical options support. It returns a
1065 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1066 * parametrical functions are quite simple
1068 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1071 if (snum >= iNumServices) return NULL;
1074 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1076 return get_parametric_helper(ServicePtrs[snum],
1077 type, option, Globals.param_opt);
1081 static void discard_whitespace(char *str)
1083 size_t len = strlen(str);
1087 if (isspace(str[i])) {
1088 memmove(&str[i], &str[i+1], len-i);
1097 * @brief Go through all global parametric parameters
1099 * @param regex_str A regular expression to scan param for
1100 * @param max_matches Max number of submatches the regexp expects
1101 * @param cb Function to call on match. Should return true
1102 * when it wants wi_scan_global_parametrics to stop
1104 * @param private_data Anonymous pointer passed to cb
1106 * @return 0: success, regcomp/regexec return value on error.
1107 * See "man regexec" for possible errors
1110 int lp_wi_scan_global_parametrics(
1111 const char *regex_str, size_t max_matches,
1112 bool (*cb)(const char *string, regmatch_t matches[],
1113 void *private_data),
1116 struct parmlist_entry *data;
1120 ret = regcomp(®ex, regex_str, REG_ICASE);
1125 for (data = Globals.param_opt; data != NULL; data = data->next) {
1126 size_t keylen = strlen(data->key);
1128 regmatch_t matches[max_matches];
1131 memcpy(key, data->key, sizeof(key));
1132 discard_whitespace(key);
1134 ret = regexec(®ex, key, max_matches, matches, 0);
1135 if (ret == REG_NOMATCH) {
1142 stop = cb(key, matches, private_data);
1155 #define MISSING_PARAMETER(name) \
1156 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1158 /*******************************************************************
1159 convenience routine to return enum parameters.
1160 ********************************************************************/
1161 static int lp_enum(const char *s,const struct enum_list *_enum)
1165 if (!s || !*s || !_enum) {
1166 MISSING_PARAMETER(lp_enum);
1170 for (i=0; _enum[i].name; i++) {
1171 if (strequal(_enum[i].name,s))
1172 return _enum[i].value;
1175 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1179 #undef MISSING_PARAMETER
1181 /* Return parametric option from a given service. Type is a part of option before ':' */
1182 /* Parametric option has following syntax: 'Type: option = value' */
1183 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1185 struct parmlist_entry *data = get_parametrics(snum, type, option);
1187 if (data == NULL||data->value==NULL) {
1189 return lp_string(ctx, def);
1195 return lp_string(ctx, data->value);
1198 /* Return parametric option from a given service. Type is a part of option before ':' */
1199 /* Parametric option has following syntax: 'Type: option = value' */
1200 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1202 struct parmlist_entry *data = get_parametrics(snum, type, option);
1204 if (data == NULL||data->value==NULL)
1211 /* Return parametric option from a given service. Type is a part of option before ':' */
1212 /* Parametric option has following syntax: 'Type: option = value' */
1214 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1216 struct parmlist_entry *data = get_parametrics(snum, type, option);
1218 if (data == NULL||data->value==NULL)
1219 return (const char **)def;
1221 if (data->list==NULL) {
1222 data->list = str_list_make_v3(NULL, data->value, NULL);
1225 return discard_const_p(const char *, data->list);
1228 /* Return parametric option from a given service. Type is a part of option before ':' */
1229 /* Parametric option has following syntax: 'Type: option = value' */
1231 int lp_parm_int(int snum, const char *type, const char *option, int def)
1233 struct parmlist_entry *data = get_parametrics(snum, type, option);
1235 if (data && data->value && *data->value)
1236 return lp_int(data->value);
1241 /* Return parametric option from a given service. Type is a part of option before ':' */
1242 /* Parametric option has following syntax: 'Type: option = value' */
1244 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1246 struct parmlist_entry *data = get_parametrics(snum, type, option);
1248 if (data && data->value && *data->value)
1249 return lp_ulong(data->value);
1254 /* Return parametric option from a given service. Type is a part of option before ':' */
1255 /* Parametric option has following syntax: 'Type: option = value' */
1257 unsigned long long lp_parm_ulonglong(int snum, const char *type,
1258 const char *option, unsigned long long def)
1260 struct parmlist_entry *data = get_parametrics(snum, type, option);
1262 if (data && data->value && *data->value) {
1263 return lp_ulonglong(data->value);
1269 /* Return parametric option from a given service. Type is a part of option
1271 /* Parametric option has following syntax: 'Type: option = value' */
1273 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1275 struct parmlist_entry *data = get_parametrics(snum, type, option);
1277 if (data && data->value && *data->value)
1278 return lp_bool(data->value);
1283 /* Return parametric option from a given service. Type is a part of option before ':' */
1284 /* Parametric option has following syntax: 'Type: option = value' */
1286 int lp_parm_enum(int snum, const char *type, const char *option,
1287 const struct enum_list *_enum, int def)
1289 struct parmlist_entry *data = get_parametrics(snum, type, option);
1291 if (data && data->value && *data->value && _enum)
1292 return lp_enum(data->value, _enum);
1298 * free a param_opts structure.
1299 * param_opts handling should be moved to talloc;
1300 * then this whole functions reduces to a TALLOC_FREE().
1303 static void free_param_opts(struct parmlist_entry **popts)
1305 struct parmlist_entry *opt, *next_opt;
1307 if (*popts != NULL) {
1308 DEBUG(5, ("Freeing parametrics:\n"));
1311 while (opt != NULL) {
1312 lpcfg_string_free(&opt->key);
1313 lpcfg_string_free(&opt->value);
1314 TALLOC_FREE(opt->list);
1315 next_opt = opt->next;
1322 /***************************************************************************
1323 Free the dynamically allocated parts of a service struct.
1324 ***************************************************************************/
1326 static void free_service(struct loadparm_service *pservice)
1331 if (pservice->szService)
1332 DEBUG(5, ("free_service: Freeing service %s\n",
1333 pservice->szService));
1335 free_parameters(pservice);
1337 lpcfg_string_free(&pservice->szService);
1338 TALLOC_FREE(pservice->copymap);
1340 free_param_opts(&pservice->param_opt);
1342 ZERO_STRUCTP(pservice);
1346 /***************************************************************************
1347 remove a service indexed in the ServicePtrs array from the ServiceHash
1348 and free the dynamically allocated parts
1349 ***************************************************************************/
1351 static void free_service_byindex(int idx)
1353 if ( !LP_SNUM_OK(idx) )
1356 ServicePtrs[idx]->valid = false;
1358 /* we have to cleanup the hash record */
1360 if (ServicePtrs[idx]->szService) {
1361 char *canon_name = canonicalize_servicename(
1363 ServicePtrs[idx]->szService );
1365 dbwrap_delete_bystring(ServiceHash, canon_name );
1366 TALLOC_FREE(canon_name);
1369 free_service(ServicePtrs[idx]);
1370 TALLOC_FREE(ServicePtrs[idx]);
1373 /***************************************************************************
1374 Add a new service to the services array initialising it with the given
1376 ***************************************************************************/
1378 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1381 struct loadparm_service **tsp = NULL;
1383 /* it might already exist */
1385 i = getservicebyname(name, NULL);
1391 /* Re use empty slots if any before allocating new one.*/
1392 for (i=0; i < iNumServices; i++) {
1393 if (ServicePtrs[i] == NULL) {
1397 if (i == iNumServices) {
1398 /* if not, then create one */
1399 tsp = talloc_realloc(NULL, ServicePtrs,
1400 struct loadparm_service *,
1403 DEBUG(0, ("add_a_service: failed to enlarge "
1410 ServicePtrs[i] = talloc_zero(ServicePtrs, struct loadparm_service);
1411 if (!ServicePtrs[i]) {
1412 DEBUG(0,("add_a_service: out of memory!\n"));
1416 ServicePtrs[i]->valid = true;
1418 copy_service(ServicePtrs[i], pservice, NULL);
1420 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
1423 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1424 i, ServicePtrs[i]->szService));
1426 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1433 /***************************************************************************
1434 Convert a string to uppercase and remove whitespaces.
1435 ***************************************************************************/
1437 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1442 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1446 result = talloc_strdup(ctx, src);
1447 SMB_ASSERT(result != NULL);
1449 if (!strlower_m(result)) {
1450 TALLOC_FREE(result);
1456 /***************************************************************************
1457 Add a name/index pair for the services array to the hash table.
1458 ***************************************************************************/
1460 static bool hash_a_service(const char *name, int idx)
1464 if ( !ServiceHash ) {
1465 DEBUG(10,("hash_a_service: creating servicehash\n"));
1466 ServiceHash = db_open_rbt(NULL);
1467 if ( !ServiceHash ) {
1468 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1473 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1476 canon_name = canonicalize_servicename(talloc_tos(), name );
1478 dbwrap_store_bystring(ServiceHash, canon_name,
1479 make_tdb_data((uint8_t *)&idx, sizeof(idx)),
1482 TALLOC_FREE(canon_name);
1487 /***************************************************************************
1488 Add a new home service, with the specified home directory, defaults coming
1490 ***************************************************************************/
1492 bool lp_add_home(const char *pszHomename, int iDefaultService,
1493 const char *user, const char *pszHomedir)
1497 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1498 pszHomedir[0] == '\0') {
1502 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1507 if (!(*(ServicePtrs[iDefaultService]->path))
1508 || strequal(ServicePtrs[iDefaultService]->path,
1509 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1510 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
1514 if (!(*(ServicePtrs[i]->comment))) {
1515 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1516 if (comment == NULL) {
1519 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment,
1521 TALLOC_FREE(comment);
1524 /* set the browseable flag from the global default */
1526 ServicePtrs[i]->browseable = sDefault.browseable;
1527 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1529 ServicePtrs[i]->autoloaded = true;
1531 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1532 user, ServicePtrs[i]->path ));
1537 /***************************************************************************
1538 Add a new service, based on an old one.
1539 ***************************************************************************/
1541 int lp_add_service(const char *pszService, int iDefaultService)
1543 if (iDefaultService < 0) {
1544 return add_a_service(&sDefault, pszService);
1547 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1550 /***************************************************************************
1551 Add the IPC service.
1552 ***************************************************************************/
1554 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1556 char *comment = NULL;
1557 int i = add_a_service(&sDefault, ipc_name);
1562 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1563 Globals.server_string);
1564 if (comment == NULL) {
1568 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1569 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
1570 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1571 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1572 ServicePtrs[i]->max_connections = 0;
1573 ServicePtrs[i]->available = true;
1574 ServicePtrs[i]->read_only = true;
1575 ServicePtrs[i]->guest_only = false;
1576 ServicePtrs[i]->administrative_share = true;
1577 ServicePtrs[i]->guest_ok = guest_ok;
1578 ServicePtrs[i]->printable = false;
1579 ServicePtrs[i]->browseable = sDefault.browseable;
1580 ServicePtrs[i]->autoloaded = true;
1582 DEBUG(3, ("adding IPC service\n"));
1584 TALLOC_FREE(comment);
1588 /***************************************************************************
1589 Add a new printer service, with defaults coming from service iFrom.
1590 ***************************************************************************/
1592 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1594 const char *comment = "From Printcap";
1595 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1600 /* note that we do NOT default the availability flag to true - */
1601 /* we take it from the default service passed. This allows all */
1602 /* dynamic printers to be disabled by disabling the [printers] */
1603 /* entry (if/when the 'available' keyword is implemented!). */
1605 /* the printer name is set to the service name. */
1606 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername,
1608 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1610 /* set the browseable flag from the gloabl default */
1611 ServicePtrs[i]->browseable = sDefault.browseable;
1613 /* Printers cannot be read_only. */
1614 ServicePtrs[i]->read_only = false;
1615 /* No oplocks on printer services. */
1616 ServicePtrs[i]->oplocks = false;
1617 /* Printer services must be printable. */
1618 ServicePtrs[i]->printable = true;
1620 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1626 /***************************************************************************
1627 Check whether the given parameter name is valid.
1628 Parametric options (names containing a colon) are considered valid.
1629 ***************************************************************************/
1631 bool lp_parameter_is_valid(const char *pszParmName)
1633 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1634 (strchr(pszParmName, ':') != NULL));
1637 /***************************************************************************
1638 Check whether the given name is the name of a global parameter.
1639 Returns true for strings belonging to parameters of class
1640 P_GLOBAL, false for all other strings, also for parametric options
1641 and strings not belonging to any option.
1642 ***************************************************************************/
1644 bool lp_parameter_is_global(const char *pszParmName)
1646 int num = lpcfg_map_parameter(pszParmName);
1649 return (parm_table[num].p_class == P_GLOBAL);
1655 /**************************************************************************
1656 Determine the canonical name for a parameter.
1657 Indicate when it is an inverse (boolean) synonym instead of a
1659 **************************************************************************/
1661 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1666 if (!lp_parameter_is_valid(parm_name)) {
1671 num = map_parameter_canonical(parm_name, inverse);
1673 /* parametric option */
1674 *canon_parm = parm_name;
1676 *canon_parm = parm_table[num].label;
1683 /**************************************************************************
1684 Determine the canonical name for a parameter.
1685 Turn the value given into the inverse boolean expression when
1686 the synonym is an invers boolean synonym.
1688 Return true if parm_name is a valid parameter name and
1689 in case it is an invers boolean synonym, if the val string could
1690 successfully be converted to the reverse bool.
1691 Return false in all other cases.
1692 **************************************************************************/
1694 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1696 const char **canon_parm,
1697 const char **canon_val)
1702 if (!lp_parameter_is_valid(parm_name)) {
1708 num = map_parameter_canonical(parm_name, &inverse);
1710 /* parametric option */
1711 *canon_parm = parm_name;
1714 *canon_parm = parm_table[num].label;
1716 if (!lp_invert_boolean(val, canon_val)) {
1728 /***************************************************************************
1729 Map a parameter's string representation to the index of the canonical
1730 form of the parameter (it might be a synonym).
1731 Returns -1 if the parameter string is not recognised.
1732 ***************************************************************************/
1734 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1736 int parm_num, canon_num;
1737 bool loc_inverse = false;
1739 parm_num = lpcfg_map_parameter(pszParmName);
1740 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
1741 /* invalid, parametric or no canidate for synonyms ... */
1745 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1746 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1747 parm_num = canon_num;
1753 if (inverse != NULL) {
1754 *inverse = loc_inverse;
1759 /***************************************************************************
1760 return true if parameter number parm1 is a synonym of parameter
1761 number parm2 (parm2 being the principal name).
1762 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1764 ***************************************************************************/
1766 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1768 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1769 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1770 (parm_table[parm1].flags & FLAG_SYNONYM) &&
1771 !(parm_table[parm2].flags & FLAG_SYNONYM))
1773 if (inverse != NULL) {
1774 if ((parm_table[parm1].type == P_BOOLREV) &&
1775 (parm_table[parm2].type == P_BOOL))
1787 /***************************************************************************
1788 Show one parameter's name, type, [values,] and flags.
1789 (helper functions for show_parameter_list)
1790 ***************************************************************************/
1792 static void show_parameter(int parmIndex)
1794 int enumIndex, flagIndex;
1799 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1800 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1801 "P_ENUM", "P_BYTES", "P_CMDLIST" };
1802 unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
1803 const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
1805 printf("%s=%s", parm_table[parmIndex].label,
1806 type[parm_table[parmIndex].type]);
1807 if (parm_table[parmIndex].type == P_ENUM) {
1810 parm_table[parmIndex].enum_list[enumIndex].name;
1814 enumIndex ? "|" : "",
1815 parm_table[parmIndex].enum_list[enumIndex].name);
1820 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1821 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1824 flag_names[flagIndex]);
1829 /* output synonyms */
1831 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1832 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1833 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1834 parm_table[parmIndex2].label);
1835 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1837 printf(" (synonyms: ");
1842 printf("%s%s", parm_table[parmIndex2].label,
1843 inverse ? "[i]" : "");
1853 /***************************************************************************
1854 Show all parameter's name, type, [values,] and flags.
1855 ***************************************************************************/
1857 void show_parameter_list(void)
1859 int classIndex, parmIndex;
1860 const char *section_names[] = { "local", "global", NULL};
1862 for (classIndex=0; section_names[classIndex]; classIndex++) {
1863 printf("[%s]\n", section_names[classIndex]);
1864 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
1865 if (parm_table[parmIndex].p_class == classIndex) {
1866 show_parameter(parmIndex);
1872 /***************************************************************************
1873 Get the standard string representation of a boolean value ("yes" or "no")
1874 ***************************************************************************/
1876 static const char *get_boolean(bool bool_value)
1878 static const char *yes_str = "yes";
1879 static const char *no_str = "no";
1881 return (bool_value ? yes_str : no_str);
1884 /***************************************************************************
1885 Provide the string of the negated boolean value associated to the boolean
1886 given as a string. Returns false if the passed string does not correctly
1887 represent a boolean.
1888 ***************************************************************************/
1890 bool lp_invert_boolean(const char *str, const char **inverse_str)
1894 if (!set_boolean(str, &val)) {
1898 *inverse_str = get_boolean(!val);
1902 /***************************************************************************
1903 Provide the canonical string representation of a boolean value given
1904 as a string. Return true on success, false if the string given does
1905 not correctly represent a boolean.
1906 ***************************************************************************/
1908 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
1912 if (!set_boolean(str, &val)) {
1916 *canon_str = get_boolean(val);
1920 /***************************************************************************
1921 Find a service by name. Otherwise works like get_service.
1922 ***************************************************************************/
1924 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
1931 if (ServiceHash == NULL) {
1935 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
1937 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
1940 if (NT_STATUS_IS_OK(status) &&
1941 (data.dptr != NULL) &&
1942 (data.dsize == sizeof(iService)))
1944 iService = *(int *)data.dptr;
1947 TALLOC_FREE(canon_name);
1949 if ((iService != -1) && (LP_SNUM_OK(iService))
1950 && (pserviceDest != NULL)) {
1951 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1957 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
1958 struct loadparm_service *lp_service(const char *pszServiceName)
1960 int iService = getservicebyname(pszServiceName, NULL);
1961 if (iService == -1 || !LP_SNUM_OK(iService)) {
1964 return ServicePtrs[iService];
1967 struct loadparm_service *lp_servicebynum(int snum)
1969 if ((snum == -1) || !LP_SNUM_OK(snum)) {
1972 return ServicePtrs[snum];
1975 struct loadparm_service *lp_default_loadparm_service()
1980 static struct smbconf_ctx *lp_smbconf_ctx(void)
1983 static struct smbconf_ctx *conf_ctx = NULL;
1985 if (conf_ctx == NULL) {
1986 err = smbconf_init(NULL, &conf_ctx, "registry:");
1987 if (!SBC_ERROR_IS_OK(err)) {
1988 DEBUG(1, ("error initializing registry configuration: "
1989 "%s\n", sbcErrorString(err)));
1997 static bool process_smbconf_service(struct smbconf_service *service)
2002 if (service == NULL) {
2006 ret = lp_do_section(service->name, NULL);
2010 for (count = 0; count < service->num_params; count++) {
2012 if (!bInGlobalSection && bGlobalOnly) {
2015 const char *pszParmName = service->param_names[count];
2016 const char *pszParmValue = service->param_values[count];
2018 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2020 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2021 pszParmName, pszParmValue);
2028 if (iServiceIndex >= 0) {
2029 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2035 * load a service from registry and activate it
2037 bool process_registry_service(const char *service_name)
2040 struct smbconf_service *service = NULL;
2041 TALLOC_CTX *mem_ctx = talloc_stackframe();
2042 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2045 if (conf_ctx == NULL) {
2049 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2051 if (!smbconf_share_exists(conf_ctx, service_name)) {
2053 * Registry does not contain data for this service (yet),
2054 * but make sure lp_load doesn't return false.
2060 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2061 if (!SBC_ERROR_IS_OK(err)) {
2065 ret = process_smbconf_service(service);
2071 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2074 TALLOC_FREE(mem_ctx);
2079 * process_registry_globals
2081 static bool process_registry_globals(void)
2085 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2087 if (!bInGlobalSection && bGlobalOnly) {
2090 const char *pszParmName = "registry shares";
2091 const char *pszParmValue = "yes";
2093 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2095 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2096 pszParmName, pszParmValue);
2103 return process_registry_service(GLOBAL_NAME);
2106 bool process_registry_shares(void)
2110 struct smbconf_service **service = NULL;
2111 uint32_t num_shares = 0;
2112 TALLOC_CTX *mem_ctx = talloc_stackframe();
2113 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2116 if (conf_ctx == NULL) {
2120 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2121 if (!SBC_ERROR_IS_OK(err)) {
2127 for (count = 0; count < num_shares; count++) {
2128 if (strequal(service[count]->name, GLOBAL_NAME)) {
2131 ret = process_smbconf_service(service[count]);
2138 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2141 TALLOC_FREE(mem_ctx);
2146 * reload those shares from registry that are already
2147 * activated in the services array.
2149 static bool reload_registry_shares(void)
2154 for (i = 0; i < iNumServices; i++) {
2159 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2163 ret = process_registry_service(ServicePtrs[i]->szService);
2174 #define MAX_INCLUDE_DEPTH 100
2176 static uint8_t include_depth;
2179 * Free the file lists
2181 static void free_file_list(void)
2183 struct file_lists *f;
2184 struct file_lists *next;
2197 * Utility function for outsiders to check if we're running on registry.
2199 bool lp_config_backend_is_registry(void)
2201 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2205 * Utility function to check if the config backend is FILE.
2207 bool lp_config_backend_is_file(void)
2209 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2212 /*******************************************************************
2213 Check if a config file has changed date.
2214 ********************************************************************/
2216 bool lp_file_list_changed(void)
2218 struct file_lists *f = file_lists;
2220 DEBUG(6, ("lp_file_list_changed()\n"));
2223 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2224 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2226 if (conf_ctx == NULL) {
2229 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2232 DEBUGADD(6, ("registry config changed\n"));
2239 n2 = talloc_sub_basic(talloc_tos(),
2240 get_current_username(),
2241 current_user_info.domain,
2246 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2247 f->name, n2, ctime(&f->modtime)));
2249 mod_time = file_modtime(n2);
2252 ((f->modtime != mod_time) ||
2253 (f->subfname == NULL) ||
2254 (strcmp(n2, f->subfname) != 0)))
2257 ("file %s modified: %s\n", n2,
2259 f->modtime = mod_time;
2260 TALLOC_FREE(f->subfname);
2261 f->subfname = talloc_strdup(f, n2);
2262 if (f->subfname == NULL) {
2263 smb_panic("talloc_strdup failed");
2277 * Initialize iconv conversion descriptors.
2279 * This is called the first time it is needed, and also called again
2280 * every time the configuration is reloaded, because the charset or
2281 * codepage might have changed.
2283 static void init_iconv(void)
2285 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2287 true, global_iconv_handle);
2290 /***************************************************************************
2291 Handle the include operation.
2292 ***************************************************************************/
2293 static bool bAllowIncludeRegistry = true;
2295 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2296 const char *pszParmValue, char **ptr)
2300 if (include_depth >= MAX_INCLUDE_DEPTH) {
2301 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2306 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2307 if (!bAllowIncludeRegistry) {
2310 if (lp_ctx->bInGlobalSection) {
2313 ret = process_registry_globals();
2317 DEBUG(1, ("\"include = registry\" only effective "
2318 "in %s section\n", GLOBAL_NAME));
2323 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2324 current_user_info.domain,
2327 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2329 if (service == NULL) {
2330 lpcfg_string_set(Globals.ctx, ptr, fname);
2332 lpcfg_string_set(service, ptr, fname);
2335 if (file_exist(fname)) {
2338 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2344 DEBUG(2, ("Can't find include file %s\n", fname));
2349 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2351 char *config_option = NULL;
2352 const char *range = NULL;
2355 SMB_ASSERT(low != NULL);
2356 SMB_ASSERT(high != NULL);
2358 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2362 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2364 if (config_option == NULL) {
2365 DEBUG(0, ("out of memory\n"));
2369 range = lp_parm_const_string(-1, config_option, "range", NULL);
2370 if (range == NULL) {
2371 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2375 if (sscanf(range, "%u - %u", low, high) != 2) {
2376 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2377 range, domain_name));
2384 talloc_free(config_option);
2389 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2391 return lp_idmap_range("*", low, high);
2394 const char *lp_idmap_backend(const char *domain_name)
2396 char *config_option = NULL;
2397 const char *backend = NULL;
2399 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2403 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2405 if (config_option == NULL) {
2406 DEBUG(0, ("out of memory\n"));
2410 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2411 if (backend == NULL) {
2412 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2417 talloc_free(config_option);
2421 const char *lp_idmap_default_backend(void)
2423 return lp_idmap_backend("*");
2426 /***************************************************************************
2427 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2428 ***************************************************************************/
2430 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2432 const char *suffix_string;
2434 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2435 Globals.ldap_suffix );
2436 if ( !suffix_string ) {
2437 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2441 return suffix_string;
2444 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2446 if (Globals._ldap_machine_suffix[0])
2447 return append_ldap_suffix(ctx, Globals._ldap_machine_suffix);
2449 return lp_string(ctx, Globals.ldap_suffix);
2452 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2454 if (Globals._ldap_user_suffix[0])
2455 return append_ldap_suffix(ctx, Globals._ldap_user_suffix);
2457 return lp_string(ctx, Globals.ldap_suffix);
2460 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2462 if (Globals._ldap_group_suffix[0])
2463 return append_ldap_suffix(ctx, Globals._ldap_group_suffix);
2465 return lp_string(ctx, Globals.ldap_suffix);
2468 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2470 if (Globals._ldap_idmap_suffix[0])
2471 return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix);
2473 return lp_string(ctx, Globals.ldap_suffix);
2477 return the parameter pointer for a parameter
2479 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2481 if (service == NULL) {
2482 if (parm->p_class == P_LOCAL)
2483 return (void *)(((char *)&sDefault)+parm->offset);
2484 else if (parm->p_class == P_GLOBAL)
2485 return (void *)(((char *)&Globals)+parm->offset);
2488 return (void *)(((char *)service) + parm->offset);
2492 /***************************************************************************
2493 Process a parameter for a particular service number. If snum < 0
2494 then assume we are in the globals.
2495 ***************************************************************************/
2497 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2499 TALLOC_CTX *frame = talloc_stackframe();
2500 struct loadparm_context *lp_ctx;
2503 lp_ctx = setup_lp_context(frame);
2504 if (lp_ctx == NULL) {
2510 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2512 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2513 pszParmName, pszParmValue);
2521 /***************************************************************************
2522 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2523 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2524 ***************************************************************************/
2526 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2529 parmnum = lpcfg_map_parameter(pszParmName);
2531 flags_list[parmnum] &= ~FLAG_CMDLINE;
2532 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2535 flags_list[parmnum] |= FLAG_CMDLINE;
2537 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2538 * be grouped in the table, so we don't have to search the
2541 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2542 && parm_table[i].p_class == parm_table[parmnum].p_class;
2544 flags_list[i] |= FLAG_CMDLINE;
2546 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2547 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2548 flags_list[i] |= FLAG_CMDLINE;
2554 /* it might be parametric */
2555 if (strchr(pszParmName, ':') != NULL) {
2556 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2560 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2564 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2567 TALLOC_CTX *frame = talloc_stackframe();
2568 struct loadparm_context *lp_ctx;
2570 lp_ctx = setup_lp_context(frame);
2571 if (lp_ctx == NULL) {
2576 ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
2582 /***************************************************************************
2583 Process a parameter.
2584 ***************************************************************************/
2586 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2589 if (!bInGlobalSection && bGlobalOnly)
2592 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2594 if (bInGlobalSection) {
2595 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2597 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2598 pszParmName, pszParmValue);
2602 /***************************************************************************
2603 Initialize any local variables in the sDefault table, after parsing a
2605 ***************************************************************************/
2607 static void init_locals(void)
2610 * We run this check once the [globals] is parsed, to force
2611 * the VFS objects and other per-share settings we need for
2612 * the standard way a AD DC is operated. We may change these
2613 * as our code evolves, which is why we force these settings.
2615 * We can't do this at the end of lp_load_ex(), as by that
2616 * point the services have been loaded and they will already
2617 * have "" as their vfs objects.
2619 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2620 const char **vfs_objects = lp_vfs_objects(-1);
2621 if (!vfs_objects || !vfs_objects[0]) {
2622 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2623 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2624 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2625 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2627 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2631 lp_do_parameter(-1, "map hidden", "no");
2632 lp_do_parameter(-1, "map system", "no");
2633 lp_do_parameter(-1, "map readonly", "no");
2634 lp_do_parameter(-1, "map archive", "no");
2635 lp_do_parameter(-1, "store dos attributes", "yes");
2639 /***************************************************************************
2640 Process a new section (service). At this stage all sections are services.
2641 Later we'll have special sections that permit server parameters to be set.
2642 Returns true on success, false on failure.
2643 ***************************************************************************/
2645 bool lp_do_section(const char *pszSectionName, void *userdata)
2647 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2649 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2650 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2653 /* if we were in a global section then do the local inits */
2654 if (bInGlobalSection && !isglobal)
2657 /* if we've just struck a global section, note the fact. */
2658 bInGlobalSection = isglobal;
2659 if (lp_ctx != NULL) {
2660 lp_ctx->bInGlobalSection = isglobal;
2663 /* check for multiple global sections */
2664 if (bInGlobalSection) {
2665 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2669 if (!bInGlobalSection && bGlobalOnly)
2672 /* if we have a current service, tidy it up before moving on */
2675 if (iServiceIndex >= 0)
2676 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2678 /* if all is still well, move to the next record in the services array */
2680 /* We put this here to avoid an odd message order if messages are */
2681 /* issued by the post-processing of a previous section. */
2682 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2684 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2685 if (iServiceIndex < 0) {
2686 DEBUG(0, ("Failed to add a new service\n"));
2689 /* Clean all parametric options for service */
2690 /* They will be added during parsing again */
2691 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2697 /***************************************************************************
2698 Display the contents of a parameter of a single services record.
2699 ***************************************************************************/
2701 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2703 bool result = false;
2704 struct loadparm_context *lp_ctx;
2706 lp_ctx = setup_lp_context(talloc_tos());
2707 if (lp_ctx == NULL) {
2712 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2714 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2716 TALLOC_FREE(lp_ctx);
2721 /***************************************************************************
2722 Display the contents of a single copy structure.
2723 ***************************************************************************/
2724 static void dump_copy_map(bool *pcopymap)
2730 printf("\n\tNon-Copied parameters:\n");
2732 for (i = 0; parm_table[i].label; i++)
2733 if (parm_table[i].p_class == P_LOCAL &&
2734 parm_table[i].ptr && !pcopymap[i] &&
2735 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2737 printf("\t\t%s\n", parm_table[i].label);
2742 /***************************************************************************
2743 Return TRUE if the passed service number is within range.
2744 ***************************************************************************/
2746 bool lp_snum_ok(int iService)
2748 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->available);
2751 /***************************************************************************
2752 Auto-load some home services.
2753 ***************************************************************************/
2755 static void lp_add_auto_services(char *str)
2765 s = talloc_strdup(talloc_tos(), str);
2767 smb_panic("talloc_strdup failed");
2771 homes = lp_servicenumber(HOMES_NAME);
2773 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2774 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2777 if (lp_servicenumber(p) >= 0)
2780 home = get_user_home_dir(talloc_tos(), p);
2782 if (home && home[0] && homes >= 0)
2783 lp_add_home(p, homes, p, home);
2790 /***************************************************************************
2791 Auto-load one printer.
2792 ***************************************************************************/
2794 void lp_add_one_printer(const char *name, const char *comment,
2795 const char *location, void *pdata)
2797 int printers = lp_servicenumber(PRINTERS_NAME);
2800 if (lp_servicenumber(name) < 0) {
2801 lp_add_printer(name, printers);
2802 if ((i = lp_servicenumber(name)) >= 0) {
2803 lpcfg_string_set(ServicePtrs[i],
2804 &ServicePtrs[i]->comment, comment);
2805 ServicePtrs[i]->autoloaded = true;
2810 /***************************************************************************
2811 Have we loaded a services file yet?
2812 ***************************************************************************/
2814 bool lp_loaded(void)
2819 /***************************************************************************
2820 Unload unused services.
2821 ***************************************************************************/
2823 void lp_killunused(struct smbd_server_connection *sconn,
2824 bool (*snumused) (struct smbd_server_connection *, int))
2827 for (i = 0; i < iNumServices; i++) {
2831 /* don't kill autoloaded or usershare services */
2832 if ( ServicePtrs[i]->autoloaded ||
2833 ServicePtrs[i]->usershare == USERSHARE_VALID) {
2837 if (!snumused || !snumused(sconn, i)) {
2838 free_service_byindex(i);
2844 * Kill all except autoloaded and usershare services - convenience wrapper
2846 void lp_kill_all_services(void)
2848 lp_killunused(NULL, NULL);
2851 /***************************************************************************
2853 ***************************************************************************/
2855 void lp_killservice(int iServiceIn)
2857 if (VALID(iServiceIn)) {
2858 free_service_byindex(iServiceIn);
2862 /***************************************************************************
2863 Save the curent values of all global and sDefault parameters into the
2864 defaults union. This allows testparm to show only the
2865 changed (ie. non-default) parameters.
2866 ***************************************************************************/
2868 static void lp_save_defaults(void)
2871 struct parmlist_entry * parm;
2872 for (i = 0; parm_table[i].label; i++) {
2873 if (!(flags_list[i] & FLAG_CMDLINE)) {
2874 flags_list[i] |= FLAG_DEFAULT;
2877 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
2878 && parm_table[i].p_class == parm_table[i - 1].p_class)
2880 switch (parm_table[i].type) {
2883 parm_table[i].def.lvalue = str_list_copy(
2884 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
2890 &parm_table[i].def.svalue,
2891 *(char **)lp_parm_ptr(
2892 NULL, &parm_table[i]));
2893 if (parm_table[i].def.svalue == NULL) {
2894 smb_panic("lpcfg_string_set() failed");
2899 parm_table[i].def.bvalue =
2900 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
2903 parm_table[i].def.cvalue =
2904 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
2910 parm_table[i].def.ivalue =
2911 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
2916 for (parm=Globals.param_opt; parm; parm=parm->next) {
2917 if (!(parm->priority & FLAG_CMDLINE)) {
2918 parm->priority |= FLAG_DEFAULT;
2922 for (parm=sDefault.param_opt; parm; parm=parm->next) {
2923 if (!(parm->priority & FLAG_CMDLINE)) {
2924 parm->priority |= FLAG_DEFAULT;
2928 defaults_saved = true;
2931 /***********************************************************
2932 If we should send plaintext/LANMAN passwords in the clinet
2933 ************************************************************/
2935 static void set_allowed_client_auth(void)
2937 if (Globals.client_ntlmv2_auth) {
2938 Globals.client_lanman_auth = false;
2940 if (!Globals.client_lanman_auth) {
2941 Globals.client_plaintext_auth = false;
2945 /***************************************************************************
2947 The following code allows smbd to read a user defined share file.
2948 Yes, this is my intent. Yes, I'm comfortable with that...
2950 THE FOLLOWING IS SECURITY CRITICAL CODE.
2952 It washes your clothes, it cleans your house, it guards you while you sleep...
2953 Do not f%^k with it....
2954 ***************************************************************************/
2956 #define MAX_USERSHARE_FILE_SIZE (10*1024)
2958 /***************************************************************************
2959 Check allowed stat state of a usershare file.
2960 Ensure we print out who is dicking with us so the admin can
2961 get their sorry ass fired.
2962 ***************************************************************************/
2964 static bool check_usershare_stat(const char *fname,
2965 const SMB_STRUCT_STAT *psbuf)
2967 if (!S_ISREG(psbuf->st_ex_mode)) {
2968 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2969 "not a regular file\n",
2970 fname, (unsigned int)psbuf->st_ex_uid ));
2974 /* Ensure this doesn't have the other write bit set. */
2975 if (psbuf->st_ex_mode & S_IWOTH) {
2976 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
2977 "public write. Refusing to allow as a usershare file.\n",
2978 fname, (unsigned int)psbuf->st_ex_uid ));
2982 /* Should be 10k or less. */
2983 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
2984 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2985 "too large (%u) to be a user share file.\n",
2986 fname, (unsigned int)psbuf->st_ex_uid,
2987 (unsigned int)psbuf->st_ex_size ));
2994 /***************************************************************************
2995 Parse the contents of a usershare file.
2996 ***************************************************************************/
2998 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
2999 SMB_STRUCT_STAT *psbuf,
3000 const char *servicename,
3004 char **pp_sharepath,
3006 char **pp_cp_servicename,
3007 struct security_descriptor **ppsd,
3010 const char **prefixallowlist = lp_usershare_prefix_allow_list();
3011 const char **prefixdenylist = lp_usershare_prefix_deny_list();
3014 SMB_STRUCT_STAT sbuf;
3015 char *sharepath = NULL;
3016 char *comment = NULL;
3018 *pp_sharepath = NULL;
3021 *pallow_guest = false;
3024 return USERSHARE_MALFORMED_FILE;
3027 if (strcmp(lines[0], "#VERSION 1") == 0) {
3029 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3032 return USERSHARE_MALFORMED_FILE;
3035 return USERSHARE_BAD_VERSION;
3038 if (strncmp(lines[1], "path=", 5) != 0) {
3039 return USERSHARE_MALFORMED_PATH;
3042 sharepath = talloc_strdup(ctx, &lines[1][5]);
3044 return USERSHARE_POSIX_ERR;
3046 trim_string(sharepath, " ", " ");
3048 if (strncmp(lines[2], "comment=", 8) != 0) {
3049 return USERSHARE_MALFORMED_COMMENT_DEF;
3052 comment = talloc_strdup(ctx, &lines[2][8]);
3054 return USERSHARE_POSIX_ERR;
3056 trim_string(comment, " ", " ");
3057 trim_char(comment, '"', '"');
3059 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3060 return USERSHARE_MALFORMED_ACL_DEF;
3063 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3064 return USERSHARE_ACL_ERR;
3068 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3069 return USERSHARE_MALFORMED_ACL_DEF;
3071 if (lines[4][9] == 'y') {
3072 *pallow_guest = true;
3075 /* Backwards compatible extension to file version #2. */
3077 if (strncmp(lines[5], "sharename=", 10) != 0) {
3078 return USERSHARE_MALFORMED_SHARENAME_DEF;
3080 if (!strequal(&lines[5][10], servicename)) {
3081 return USERSHARE_BAD_SHARENAME;
3083 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3084 if (!*pp_cp_servicename) {
3085 return USERSHARE_POSIX_ERR;
3090 if (*pp_cp_servicename == NULL) {
3091 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3092 if (!*pp_cp_servicename) {
3093 return USERSHARE_POSIX_ERR;
3097 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3098 /* Path didn't change, no checks needed. */
3099 *pp_sharepath = sharepath;
3100 *pp_comment = comment;
3101 return USERSHARE_OK;
3104 /* The path *must* be absolute. */
3105 if (sharepath[0] != '/') {
3106 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3107 servicename, sharepath));
3108 return USERSHARE_PATH_NOT_ABSOLUTE;
3111 /* If there is a usershare prefix deny list ensure one of these paths
3112 doesn't match the start of the user given path. */
3113 if (prefixdenylist) {
3115 for ( i=0; prefixdenylist[i]; i++ ) {
3116 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3117 servicename, i, prefixdenylist[i], sharepath ));
3118 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3119 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3120 "usershare prefix deny list entries.\n",
3121 servicename, sharepath));
3122 return USERSHARE_PATH_IS_DENIED;
3127 /* If there is a usershare prefix allow list ensure one of these paths
3128 does match the start of the user given path. */
3130 if (prefixallowlist) {
3132 for ( i=0; prefixallowlist[i]; i++ ) {
3133 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3134 servicename, i, prefixallowlist[i], sharepath ));
3135 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3139 if (prefixallowlist[i] == NULL) {
3140 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3141 "usershare prefix allow list entries.\n",
3142 servicename, sharepath));
3143 return USERSHARE_PATH_NOT_ALLOWED;
3147 /* Ensure this is pointing to a directory. */
3148 dp = opendir(sharepath);
3151 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3152 servicename, sharepath));
3153 return USERSHARE_PATH_NOT_DIRECTORY;
3156 /* Ensure the owner of the usershare file has permission to share
3159 if (sys_stat(sharepath, &sbuf, false) == -1) {
3160 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3161 servicename, sharepath, strerror(errno) ));
3163 return USERSHARE_POSIX_ERR;
3168 if (!S_ISDIR(sbuf.st_ex_mode)) {
3169 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3170 servicename, sharepath ));
3171 return USERSHARE_PATH_NOT_DIRECTORY;
3174 /* Check if sharing is restricted to owner-only. */
3175 /* psbuf is the stat of the usershare definition file,
3176 sbuf is the stat of the target directory to be shared. */
3178 if (lp_usershare_owner_only()) {
3179 /* root can share anything. */
3180 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3181 return USERSHARE_PATH_NOT_ALLOWED;
3185 *pp_sharepath = sharepath;
3186 *pp_comment = comment;
3187 return USERSHARE_OK;
3190 /***************************************************************************
3191 Deal with a usershare file.
3194 -1 - Bad name, invalid contents.
3195 - service name already existed and not a usershare, problem
3196 with permissions to share directory etc.
3197 ***************************************************************************/
3199 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3201 SMB_STRUCT_STAT sbuf;
3202 SMB_STRUCT_STAT lsbuf;
3204 char *sharepath = NULL;
3205 char *comment = NULL;
3206 char *cp_service_name = NULL;
3207 char **lines = NULL;
3211 TALLOC_CTX *ctx = talloc_stackframe();
3212 struct security_descriptor *psd = NULL;
3213 bool guest_ok = false;
3214 char *canon_name = NULL;
3215 bool added_service = false;
3218 /* Ensure share name doesn't contain invalid characters. */
3219 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3220 DEBUG(0,("process_usershare_file: share name %s contains "
3221 "invalid characters (any of %s)\n",
3222 file_name, INVALID_SHARENAME_CHARS ));
3226 canon_name = canonicalize_servicename(ctx, file_name);
3231 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3236 /* Minimize the race condition by doing an lstat before we
3237 open and fstat. Ensure this isn't a symlink link. */
3239 if (sys_lstat(fname, &lsbuf, false) != 0) {
3240 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3241 fname, strerror(errno) ));
3245 /* This must be a regular file, not a symlink, directory or
3246 other strange filetype. */
3247 if (!check_usershare_stat(fname, &lsbuf)) {
3255 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3260 if (NT_STATUS_IS_OK(status) &&
3261 (data.dptr != NULL) &&
3262 (data.dsize == sizeof(iService))) {
3263 memcpy(&iService, data.dptr, sizeof(iService));
3267 if (iService != -1 &&
3268 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3269 &lsbuf.st_ex_mtime) == 0) {
3270 /* Nothing changed - Mark valid and return. */
3271 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3273 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3278 /* Try and open the file read only - no symlinks allowed. */
3280 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3282 fd = open(fname, O_RDONLY, 0);
3286 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3287 fname, strerror(errno) ));
3291 /* Now fstat to be *SURE* it's a regular file. */
3292 if (sys_fstat(fd, &sbuf, false) != 0) {
3294 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3295 fname, strerror(errno) ));
3299 /* Is it the same dev/inode as was lstated ? */
3300 if (!check_same_stat(&lsbuf, &sbuf)) {
3302 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3303 "Symlink spoofing going on ?\n", fname ));
3307 /* This must be a regular file, not a symlink, directory or
3308 other strange filetype. */
3309 if (!check_usershare_stat(fname, &sbuf)) {
3314 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3317 if (lines == NULL) {
3318 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3319 fname, (unsigned int)sbuf.st_ex_uid ));
3323 if (parse_usershare_file(ctx, &sbuf, file_name,
3324 iService, lines, numlines, &sharepath,
3325 &comment, &cp_service_name,
3326 &psd, &guest_ok) != USERSHARE_OK) {
3330 /* Everything ok - add the service possibly using a template. */
3332 const struct loadparm_service *sp = &sDefault;
3333 if (snum_template != -1) {
3334 sp = ServicePtrs[snum_template];
3337 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3338 DEBUG(0, ("process_usershare_file: Failed to add "
3339 "new service %s\n", cp_service_name));
3343 added_service = true;
3345 /* Read only is controlled by usershare ACL below. */
3346 ServicePtrs[iService]->read_only = false;
3349 /* Write the ACL of the new/modified share. */
3350 if (!set_share_security(canon_name, psd)) {
3351 DEBUG(0, ("process_usershare_file: Failed to set share "
3352 "security for user share %s\n",
3357 /* If from a template it may be marked invalid. */
3358 ServicePtrs[iService]->valid = true;
3360 /* Set the service as a valid usershare. */
3361 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3363 /* Set guest access. */
3364 if (lp_usershare_allow_guests()) {
3365 ServicePtrs[iService]->guest_ok = guest_ok;
3368 /* And note when it was loaded. */
3369 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3370 lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path,
3372 lpcfg_string_set(ServicePtrs[iService],
3373 &ServicePtrs[iService]->comment, comment);
3379 if (ret == -1 && iService != -1 && added_service) {
3380 lp_remove_service(iService);
3388 /***************************************************************************
3389 Checks if a usershare entry has been modified since last load.
3390 ***************************************************************************/
3392 static bool usershare_exists(int iService, struct timespec *last_mod)
3394 SMB_STRUCT_STAT lsbuf;
3395 const char *usersharepath = Globals.usershare_path;
3398 fname = talloc_asprintf(talloc_tos(),
3401 ServicePtrs[iService]->szService);
3402 if (fname == NULL) {
3406 if (sys_lstat(fname, &lsbuf, false) != 0) {
3411 if (!S_ISREG(lsbuf.st_ex_mode)) {
3417 *last_mod = lsbuf.st_ex_mtime;
3421 /***************************************************************************
3422 Load a usershare service by name. Returns a valid servicenumber or -1.
3423 ***************************************************************************/
3425 int load_usershare_service(const char *servicename)
3427 SMB_STRUCT_STAT sbuf;
3428 const char *usersharepath = Globals.usershare_path;
3429 int max_user_shares = Globals.usershare_max_shares;
3430 int snum_template = -1;
3432 if (*usersharepath == 0 || max_user_shares == 0) {
3436 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3437 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3438 usersharepath, strerror(errno) ));
3442 if (!S_ISDIR(sbuf.st_ex_mode)) {
3443 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3449 * This directory must be owned by root, and have the 't' bit set.
3450 * It also must not be writable by "other".
3454 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3456 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3458 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3459 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3464 /* Ensure the template share exists if it's set. */
3465 if (Globals.usershare_template_share[0]) {
3466 /* We can't use lp_servicenumber here as we are recommending that
3467 template shares have -valid=false set. */
3468 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3469 if (ServicePtrs[snum_template]->szService &&
3470 strequal(ServicePtrs[snum_template]->szService,
3471 Globals.usershare_template_share)) {
3476 if (snum_template == -1) {
3477 DEBUG(0,("load_usershare_service: usershare template share %s "
3478 "does not exist.\n",
3479 Globals.usershare_template_share ));
3484 return process_usershare_file(usersharepath, servicename, snum_template);
3487 /***************************************************************************
3488 Load all user defined shares from the user share directory.
3489 We only do this if we're enumerating the share list.
3490 This is the function that can delete usershares that have
3492 ***************************************************************************/
3494 int load_usershare_shares(struct smbd_server_connection *sconn,
3495 bool (*snumused) (struct smbd_server_connection *, int))
3498 SMB_STRUCT_STAT sbuf;
3500 int num_usershares = 0;
3501 int max_user_shares = Globals.usershare_max_shares;
3502 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3503 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3504 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3506 int snum_template = -1;
3507 const char *usersharepath = Globals.usershare_path;
3508 int ret = lp_numservices();
3509 TALLOC_CTX *tmp_ctx;
3511 if (max_user_shares == 0 || *usersharepath == '\0') {
3512 return lp_numservices();
3515 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3516 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3517 usersharepath, strerror(errno) ));
3522 * This directory must be owned by root, and have the 't' bit set.
3523 * It also must not be writable by "other".
3527 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3529 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3531 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3532 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3537 /* Ensure the template share exists if it's set. */
3538 if (Globals.usershare_template_share[0]) {
3539 /* We can't use lp_servicenumber here as we are recommending that
3540 template shares have -valid=false set. */
3541 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3542 if (ServicePtrs[snum_template]->szService &&
3543 strequal(ServicePtrs[snum_template]->szService,
3544 Globals.usershare_template_share)) {
3549 if (snum_template == -1) {
3550 DEBUG(0,("load_usershare_shares: usershare template share %s "
3551 "does not exist.\n",
3552 Globals.usershare_template_share ));
3557 /* Mark all existing usershares as pending delete. */
3558 for (iService = iNumServices - 1; iService >= 0; iService--) {
3559 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3560 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3564 dp = opendir(usersharepath);
3566 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3567 usersharepath, strerror(errno) ));
3571 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3573 num_dir_entries++ ) {
3575 const char *n = de->d_name;
3577 /* Ignore . and .. */
3579 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3585 /* Temporary file used when creating a share. */
3586 num_tmp_dir_entries++;
3589 /* Allow 20% tmp entries. */
3590 if (num_tmp_dir_entries > allowed_tmp_entries) {
3591 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3592 "in directory %s\n",
3593 num_tmp_dir_entries, usersharepath));
3597 r = process_usershare_file(usersharepath, n, snum_template);
3599 /* Update the services count. */
3601 if (num_usershares >= max_user_shares) {
3602 DEBUG(0,("load_usershare_shares: max user shares reached "
3603 "on file %s in directory %s\n",
3604 n, usersharepath ));
3607 } else if (r == -1) {
3608 num_bad_dir_entries++;
3611 /* Allow 20% bad entries. */
3612 if (num_bad_dir_entries > allowed_bad_entries) {
3613 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3614 "in directory %s\n",
3615 num_bad_dir_entries, usersharepath));
3619 /* Allow 20% bad entries. */
3620 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3621 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3622 "in directory %s\n",
3623 num_dir_entries, usersharepath));
3630 /* Sweep through and delete any non-refreshed usershares that are
3631 not currently in use. */
3632 tmp_ctx = talloc_stackframe();
3633 for (iService = iNumServices - 1; iService >= 0; iService--) {
3634 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3637 if (snumused && snumused(sconn, iService)) {
3641 servname = lp_servicename(tmp_ctx, iService);
3643 /* Remove from the share ACL db. */
3644 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3646 delete_share_security(servname);
3647 free_service_byindex(iService);
3650 talloc_free(tmp_ctx);
3652 return lp_numservices();
3655 /********************************************************
3656 Destroy global resources allocated in this file
3657 ********************************************************/
3659 void gfree_loadparm(void)
3665 /* Free resources allocated to services */
3667 for ( i = 0; i < iNumServices; i++ ) {
3669 free_service_byindex(i);
3673 TALLOC_FREE( ServicePtrs );
3676 /* Now release all resources allocated to global
3677 parameters and the default service */
3679 free_global_parameters();
3683 /***************************************************************************
3684 Allow client apps to specify that they are a client
3685 ***************************************************************************/
3686 static void lp_set_in_client(bool b)
3692 /***************************************************************************
3693 Determine if we're running in a client app
3694 ***************************************************************************/
3695 static bool lp_is_in_client(void)
3700 static void lp_enforce_ad_dc_settings(void)
3702 lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3703 lp_do_parameter(GLOBAL_SECTION_SNUM,
3704 "winbindd:use external pipes", "true");
3705 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
3706 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
3707 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
3708 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
3709 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
3710 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
3711 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
3712 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
3713 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
3716 /***************************************************************************
3717 Load the services array from the services file. Return true on success,
3719 ***************************************************************************/
3721 static bool lp_load_ex(const char *pszFname,
3725 bool reinit_globals,
3726 bool allow_include_registry,
3727 bool load_all_shares)
3731 TALLOC_CTX *frame = talloc_stackframe();
3732 struct loadparm_context *lp_ctx;
3736 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3738 bInGlobalSection = true;
3739 bGlobalOnly = global_only;
3740 bAllowIncludeRegistry = allow_include_registry;
3742 lp_ctx = setup_lp_context(talloc_tos());
3744 init_globals(lp_ctx, reinit_globals);
3748 if (save_defaults) {
3753 if (!reinit_globals) {
3754 free_param_opts(&Globals.param_opt);
3755 apply_lp_set_cmdline();
3758 lp_do_parameter(-1, "idmap config * : backend", Globals.idmap_backend);
3760 /* We get sections first, so have to start 'behind' to make up */
3763 if (lp_config_backend_is_file()) {
3764 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
3765 current_user_info.domain,
3768 smb_panic("lp_load_ex: out of memory");
3771 add_to_file_list(NULL, &file_lists, pszFname, n2);
3773 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
3776 /* finish up the last section */
3777 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3779 if (iServiceIndex >= 0) {
3780 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
3784 if (lp_config_backend_is_registry()) {
3786 /* config backend changed to registry in config file */
3788 * We need to use this extra global variable here to
3789 * survive restart: init_globals uses this as a default
3790 * for config_backend. Otherwise, init_globals would
3791 * send us into an endless loop here.
3794 config_backend = CONFIG_BACKEND_REGISTRY;
3796 DEBUG(1, ("lp_load_ex: changing to config backend "
3798 init_globals(lp_ctx, true);
3800 TALLOC_FREE(lp_ctx);
3802 lp_kill_all_services();
3803 ok = lp_load_ex(pszFname, global_only, save_defaults,
3804 add_ipc, reinit_globals,
3805 allow_include_registry,
3810 } else if (lp_config_backend_is_registry()) {
3811 bRetval = process_registry_globals();
3813 DEBUG(0, ("Illegal config backend given: %d\n",
3814 lp_config_backend()));
3818 if (bRetval && lp_registry_shares()) {
3819 if (load_all_shares) {
3820 bRetval = process_registry_shares();
3822 bRetval = reload_registry_shares();
3827 char *serv = lp_auto_services(talloc_tos());
3828 lp_add_auto_services(serv);
3833 /* When 'restrict anonymous = 2' guest connections to ipc$
3835 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3836 if ( lp_enable_asu_support() ) {
3837 lp_add_ipc("ADMIN$", false);
3841 set_allowed_client_auth();
3843 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
3844 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
3845 lp_password_server()));
3850 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
3851 /* if we_are_a_wins_server is true and we are in the client */
3852 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
3853 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3858 fault_configure(smb_panic_s3);
3861 * We run this check once the whole smb.conf is parsed, to
3862 * force some settings for the standard way a AD DC is
3863 * operated. We may change these as our code evolves, which
3864 * is why we force these settings.
3866 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3867 lp_enforce_ad_dc_settings();
3870 bAllowIncludeRegistry = true;
3876 static bool lp_load(const char *pszFname,
3880 bool reinit_globals)
3882 return lp_load_ex(pszFname,
3887 true, /* allow_include_registry */
3888 false); /* load_all_shares*/
3891 bool lp_load_initial_only(const char *pszFname)
3893 return lp_load_ex(pszFname,
3894 true, /* global only */
3895 true, /* save_defaults */
3896 false, /* add_ipc */
3897 true, /* reinit_globals */
3898 false, /* allow_include_registry */
3899 false); /* load_all_shares*/
3903 * most common lp_load wrapper, loading only the globals
3905 bool lp_load_global(const char *file_name)
3907 return lp_load(file_name,
3908 true, /* global_only */
3909 false, /* save_defaults */
3910 false, /* add_ipc */
3911 true); /* reinit_globals */
3915 * The typical lp_load wrapper with shares, loads global and
3916 * shares, including IPC, but does not force immediate
3917 * loading of all shares from registry.
3919 bool lp_load_with_shares(const char *file_name)
3921 return lp_load(file_name,
3922 false, /* global_only */
3923 false, /* save_defaults */
3925 true); /* reinit_globals */
3929 * lp_load wrapper, especially for clients
3931 bool lp_load_client(const char *file_name)
3933 lp_set_in_client(true);
3935 return lp_load_global(file_name);
3939 * lp_load wrapper, loading only globals, but intended
3940 * for subsequent calls, not reinitializing the globals
3943 bool lp_load_global_no_reinit(const char *file_name)
3945 return lp_load(file_name,
3946 true, /* global_only */
3947 false, /* save_defaults */
3948 false, /* add_ipc */
3949 false); /* reinit_globals */
3953 * lp_load wrapper, loading globals and shares,
3954 * intended for subsequent calls, i.e. not reinitializing
3955 * the globals to default values.
3957 bool lp_load_no_reinit(const char *file_name)
3959 return lp_load(file_name,
3960 false, /* global_only */
3961 false, /* save_defaults */
3962 false, /* add_ipc */
3963 false); /* reinit_globals */
3968 * lp_load wrapper, especially for clients, no reinitialization
3970 bool lp_load_client_no_reinit(const char *file_name)
3972 lp_set_in_client(true);
3974 return lp_load_global_no_reinit(file_name);
3977 bool lp_load_with_registry_shares(const char *pszFname)
3979 return lp_load_ex(pszFname,
3980 false, /* global_only */
3981 true, /* save_defaults */
3982 false, /* add_ipc */
3983 false, /* reinit_globals */
3984 true, /* allow_include_registry */
3985 true); /* load_all_shares*/
3988 /***************************************************************************
3989 Return the max number of services.
3990 ***************************************************************************/
3992 int lp_numservices(void)
3994 return (iNumServices);
3997 /***************************************************************************
3998 Display the contents of the services array in human-readable form.
3999 ***************************************************************************/
4001 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4004 struct loadparm_context *lp_ctx;
4007 defaults_saved = false;
4009 lp_ctx = setup_lp_context(talloc_tos());
4010 if (lp_ctx == NULL) {
4014 lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
4016 lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
4018 for (iService = 0; iService < maxtoprint; iService++) {
4020 lp_dump_one(f, show_defaults, iService);
4024 /***************************************************************************
4025 Display the contents of one service in human-readable form.
4026 ***************************************************************************/
4028 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4031 if (ServicePtrs[snum]->szService[0] == '\0')
4033 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
4034 flags_list, show_defaults);
4038 /***************************************************************************
4039 Return the number of the service with the given name, or -1 if it doesn't
4040 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4041 getservicebyname()! This works ONLY if all services have been loaded, and
4042 does not copy the found service.
4043 ***************************************************************************/
4045 int lp_servicenumber(const char *pszServiceName)
4048 fstring serviceName;
4050 if (!pszServiceName) {
4051 return GLOBAL_SECTION_SNUM;
4054 for (iService = iNumServices - 1; iService >= 0; iService--) {
4055 if (VALID(iService) && ServicePtrs[iService]->szService) {
4057 * The substitution here is used to support %U in
4060 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4061 standard_sub_basic(get_current_username(),
4062 current_user_info.domain,
4063 serviceName,sizeof(serviceName));
4064 if (strequal(serviceName, pszServiceName)) {
4070 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4071 struct timespec last_mod;
4073 if (!usershare_exists(iService, &last_mod)) {
4074 /* Remove the share security tdb entry for it. */
4075 delete_share_security(lp_servicename(talloc_tos(), iService));
4076 /* Remove it from the array. */
4077 free_service_byindex(iService);
4078 /* Doesn't exist anymore. */
4079 return GLOBAL_SECTION_SNUM;
4082 /* Has it been modified ? If so delete and reload. */
4083 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4085 /* Remove it from the array. */
4086 free_service_byindex(iService);
4087 /* and now reload it. */
4088 iService = load_usershare_service(pszServiceName);
4093 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4094 return GLOBAL_SECTION_SNUM;
4100 /*******************************************************************
4101 A useful volume label function.
4102 ********************************************************************/
4104 const char *volume_label(TALLOC_CTX *ctx, int snum)
4107 const char *label = lp_volume(ctx, snum);
4109 label = lp_servicename(ctx, snum);
4112 /* This returns a 33 byte guarenteed null terminated string. */
4113 ret = talloc_strndup(ctx, label, 32);
4120 /*******************************************************************
4121 Get the default server type we will announce as via nmbd.
4122 ********************************************************************/
4124 int lp_default_server_announce(void)
4126 int default_server_announce = 0;
4127 default_server_announce |= SV_TYPE_WORKSTATION;
4128 default_server_announce |= SV_TYPE_SERVER;
4129 default_server_announce |= SV_TYPE_SERVER_UNIX;
4131 /* note that the flag should be set only if we have a
4132 printer service but nmbd doesn't actually load the
4133 services so we can't tell --jerry */
4135 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4137 default_server_announce |= SV_TYPE_SERVER_NT;
4138 default_server_announce |= SV_TYPE_NT;
4140 switch (lp_server_role()) {
4141 case ROLE_DOMAIN_MEMBER:
4142 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4144 case ROLE_DOMAIN_PDC:
4145 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4147 case ROLE_DOMAIN_BDC:
4148 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4150 case ROLE_STANDALONE:
4154 if (lp_time_server())
4155 default_server_announce |= SV_TYPE_TIME_SOURCE;
4157 if (lp_host_msdfs())
4158 default_server_announce |= SV_TYPE_DFS_SERVER;
4160 return default_server_announce;
4163 /***********************************************************
4164 If we are PDC then prefer us as DMB
4165 ************************************************************/
4167 bool lp_domain_master(void)
4169 if (Globals._domain_master == Auto)
4170 return (lp_server_role() == ROLE_DOMAIN_PDC);
4172 return (bool)Globals._domain_master;
4175 /***********************************************************
4176 If we are PDC then prefer us as DMB
4177 ************************************************************/
4179 static bool lp_domain_master_true_or_auto(void)
4181 if (Globals._domain_master) /* auto or yes */
4187 /***********************************************************
4188 If we are DMB then prefer us as LMB
4189 ************************************************************/
4191 bool lp_preferred_master(void)
4193 int preferred_master = lp__preferred_master();
4195 if (preferred_master == Auto)
4196 return (lp_local_master() && lp_domain_master());
4198 return (bool)preferred_master;
4201 /*******************************************************************
4203 ********************************************************************/
4205 void lp_remove_service(int snum)
4207 ServicePtrs[snum]->valid = false;
4210 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4212 const char *ret = lp__printername(ctx, snum);
4213 if (ret == NULL || *ret == '\0') {
4214 ret = lp_const_servicename(snum);
4221 /***********************************************************
4222 Allow daemons such as winbindd to fix their logfile name.
4223 ************************************************************/
4225 void lp_set_logfile(const char *name)
4227 lpcfg_string_set(Globals.ctx, &Globals.logfile, name);
4228 debug_set_logfile(name);
4231 /*******************************************************************
4232 Return the max print jobs per queue.
4233 ********************************************************************/
4235 int lp_maxprintjobs(int snum)
4237 int maxjobs = lp_max_print_jobs(snum);
4239 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4240 maxjobs = PRINT_MAX_JOBID - 1;
4245 const char *lp_printcapname(void)
4247 const char *printcap_name = lp_printcap_name();
4249 if ((printcap_name != NULL) &&
4250 (printcap_name[0] != '\0'))
4251 return printcap_name;
4253 if (sDefault.printing == PRINT_CUPS) {
4257 if (sDefault.printing == PRINT_BSD)
4258 return "/etc/printcap";
4260 return PRINTCAP_NAME;
4263 static uint32_t spoolss_state;
4265 bool lp_disable_spoolss( void )
4267 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4268 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4270 return spoolss_state == SVCCTL_STOPPED ? true : false;
4273 void lp_set_spoolss_state( uint32_t state )
4275 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4277 spoolss_state = state;
4280 uint32_t lp_get_spoolss_state( void )
4282 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4285 /*******************************************************************
4286 Ensure we don't use sendfile if server smb signing is active.
4287 ********************************************************************/
4289 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4291 bool sign_active = false;
4293 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4294 if (get_Protocol() < PROTOCOL_NT1) {
4297 if (signing_state) {
4298 sign_active = smb_signing_is_active(signing_state);
4300 return (lp__use_sendfile(snum) &&
4301 (get_remote_arch() != RA_WIN95) &&
4305 /*******************************************************************
4306 Turn off sendfile if we find the underlying OS doesn't support it.
4307 ********************************************************************/
4309 void set_use_sendfile(int snum, bool val)
4311 if (LP_SNUM_OK(snum))
4312 ServicePtrs[snum]->_use_sendfile = val;
4314 sDefault._use_sendfile = val;
4317 void lp_set_mangling_method(const char *new_method)
4319 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method);
4322 /*******************************************************************
4323 Global state for POSIX pathname processing.
4324 ********************************************************************/
4326 static bool posix_pathnames;
4328 bool lp_posix_pathnames(void)
4330 return posix_pathnames;
4333 /*******************************************************************
4334 Change everything needed to ensure POSIX pathname processing (currently
4336 ********************************************************************/
4338 void lp_set_posix_pathnames(void)
4340 posix_pathnames = true;
4343 /*******************************************************************
4344 Global state for POSIX lock processing - CIFS unix extensions.
4345 ********************************************************************/
4347 bool posix_default_lock_was_set;
4348 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4350 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4352 if (posix_default_lock_was_set) {
4353 return posix_cifsx_locktype;
4355 return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
4356 POSIX_LOCK : WINDOWS_LOCK;
4360 /*******************************************************************
4361 ********************************************************************/
4363 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4365 posix_default_lock_was_set = true;
4366 posix_cifsx_locktype = val;
4369 int lp_min_receive_file_size(void)
4371 int min_receivefile_size = lp_min_receivefile_size();
4373 if (min_receivefile_size < 0) {
4376 return min_receivefile_size;
4379 /*******************************************************************
4380 Safe wide links checks.
4381 This helper function always verify the validity of wide links,
4382 even after a configuration file reload.
4383 ********************************************************************/
4385 void widelinks_warning(int snum)
4387 if (lp_allow_insecure_wide_links()) {
4391 if (lp_unix_extensions() && lp_wide_links(snum)) {
4392 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4393 "These parameters are incompatible. "
4394 "Wide links will be disabled for this share.\n",
4395 lp_servicename(talloc_tos(), snum) ));
4399 bool lp_widelinks(int snum)
4401 /* wide links is always incompatible with unix extensions */
4402 if (lp_unix_extensions()) {
4404 * Unless we have "allow insecure widelinks"
4407 if (!lp_allow_insecure_wide_links()) {
4412 return lp_wide_links(snum);
4415 int lp_server_role(void)
4417 return lp_find_server_role(lp__server_role(),
4419 lp__domain_logons(),
4420 lp_domain_master_true_or_auto());
4423 int lp_security(void)
4425 return lp_find_security(lp__server_role(),
4429 int lp_client_max_protocol(void)
4431 int client_max_protocol = lp__client_max_protocol();
4432 if (client_max_protocol == PROTOCOL_DEFAULT) {
4433 return PROTOCOL_NT1;
4435 return client_max_protocol;
4438 int lp_winbindd_max_protocol(void)
4440 int client_max_protocol = lp__client_max_protocol();
4441 if (client_max_protocol == PROTOCOL_DEFAULT) {
4442 return PROTOCOL_LATEST;
4444 return client_max_protocol;
4447 struct loadparm_global * get_globals(void)
4452 unsigned int * get_flags(void)
4454 if (flags_list == NULL) {
4455 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());