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"
74 #ifdef HAVE_SYS_SYSCTL_H
75 #include <sys/sysctl.h>
80 extern userdom_struct current_user_info;
82 /* the special value for the include parameter
83 * to be interpreted not as a file name but to
84 * trigger loading of the global smb.conf options
86 #ifndef INCLUDE_REGISTRY_NAME
87 #define INCLUDE_REGISTRY_NAME "registry"
90 static bool in_client = false; /* Not in the client by default */
91 static struct smbconf_csn conf_last_csn;
93 static int config_backend = CONFIG_BACKEND_FILE;
95 /* some helpful bits */
96 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
97 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
99 #define USERSHARE_VALID 1
100 #define USERSHARE_PENDING_DELETE 2
102 static bool defaults_saved = false;
104 #include "lib/param/param_global.h"
106 static struct loadparm_global Globals;
108 /* This is a default service used to prime a services structure */
109 static struct loadparm_service sDefault =
114 .usershare_last_mod = {0, 0},
118 .invalid_users = NULL,
125 .root_preexec = NULL,
126 .root_postexec = NULL,
127 .cups_options = NULL,
128 .print_command = NULL,
130 .lprm_command = NULL,
131 .lppause_command = NULL,
132 .lpresume_command = NULL,
133 .queuepause_command = NULL,
134 .queueresume_command = NULL,
135 ._printername = NULL,
136 .printjob_username = NULL,
137 .dont_descend = NULL,
140 .magic_script = NULL,
141 .magic_output = NULL,
144 .veto_oplock_files = NULL,
154 .aio_write_behind = NULL,
155 .dfree_command = NULL,
156 .min_print_space = 0,
157 .max_print_jobs = 1000,
158 .max_reported_print_jobs = 0,
159 .write_cache_size = 0,
161 .force_create_mode = 0,
162 .directory_mask = 0755,
163 .force_directory_mode = 0,
164 .max_connections = 0,
165 .default_case = CASE_LOWER,
166 .printing = DEFAULT_PRINTING,
167 .oplock_contention_limit = 2,
170 .dfree_cache_time = 0,
171 .preexec_close = false,
172 .root_preexec_close = false,
173 .case_sensitive = Auto,
174 .preserve_case = true,
175 .short_preserve_case = true,
176 .hide_dot_files = true,
177 .hide_special_files = false,
178 .hide_unreadable = false,
179 .hide_unwriteable_files = false,
181 .access_based_share_enum = false,
186 .administrative_share = false,
189 .print_notify_backchannel = false,
193 .store_dos_attributes = false,
194 .dmapi_support = false,
196 .strict_locking = Auto,
197 .posix_locking = true,
199 .kernel_oplocks = false,
200 .level2_oplocks = true,
202 .mangled_names = true,
204 .follow_symlinks = true,
205 .sync_always = false,
206 .strict_allocate = false,
207 .strict_rename = false,
208 .strict_sync = false,
209 .mangling_char = '~',
211 .delete_readonly = false,
212 .fake_oplocks = false,
213 .delete_veto_files = false,
214 .dos_filemode = false,
215 .dos_filetimes = true,
216 .dos_filetime_resolution = false,
217 .fake_directory_create_times = false,
218 .blocking_locks = true,
219 .inherit_permissions = false,
220 .inherit_acls = false,
221 .inherit_owner = false,
223 .msdfs_shuffle_referrals = false,
224 .use_client_driver = false,
225 .default_devmode = true,
226 .force_printername = false,
227 .nt_acl_support = true,
228 .force_unknown_acl_user = false,
229 ._use_sendfile = false,
230 .profile_acls = false,
231 .map_acl_inherit = false,
234 .acl_check_permissions = true,
235 .acl_map_full_control = true,
236 .acl_group_control = false,
237 .acl_allow_execute_always = false,
238 .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
241 .map_readonly = MAP_READONLY_YES,
242 .directory_name_cache_size = 100,
243 .smb_encrypt = SMB_SIGNING_DEFAULT,
244 .kernel_share_modes = true,
245 .durable_handles = true,
250 /* local variables */
251 static struct loadparm_service **ServicePtrs = NULL;
252 static int iNumServices = 0;
253 static int iServiceIndex = 0;
254 static struct db_context *ServiceHash;
255 static bool bInGlobalSection = true;
256 static bool bGlobalOnly = false;
257 static struct file_lists *file_lists = NULL;
258 static unsigned int *flags_list = NULL;
260 static void set_allowed_client_auth(void);
262 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
263 static void free_param_opts(struct parmlist_entry **popts);
266 * Function to return the default value for the maximum number of open
267 * file descriptors permitted. This function tries to consult the
268 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
269 * the smaller of those.
271 static int max_open_files(void)
273 int sysctl_max = MAX_OPEN_FILES;
274 int rlimit_max = MAX_OPEN_FILES;
276 #ifdef HAVE_SYSCTLBYNAME
278 size_t size = sizeof(sysctl_max);
279 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
284 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
290 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
291 rlimit_max = rl.rlim_cur;
293 #if defined(RLIM_INFINITY)
294 if(rl.rlim_cur == RLIM_INFINITY)
295 rlimit_max = MAX_OPEN_FILES;
300 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
301 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
302 "minimum Windows limit (%d)\n",
304 MIN_OPEN_FILES_WINDOWS));
305 sysctl_max = MIN_OPEN_FILES_WINDOWS;
308 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
309 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
310 "minimum Windows limit (%d)\n",
312 MIN_OPEN_FILES_WINDOWS));
313 rlimit_max = MIN_OPEN_FILES_WINDOWS;
316 return MIN(sysctl_max, rlimit_max);
320 * Common part of freeing allocated data for one parameter.
322 static void free_one_parameter_common(void *parm_ptr,
323 struct parm_struct parm)
325 if ((parm.type == P_STRING) ||
326 (parm.type == P_USTRING))
328 lpcfg_string_free((char**)parm_ptr);
329 } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
330 TALLOC_FREE(*((char***)parm_ptr));
335 * Free the allocated data for one parameter for a share
336 * given as a service struct.
338 static void free_one_parameter(struct loadparm_service *service,
339 struct parm_struct parm)
343 if (parm.p_class != P_LOCAL) {
347 parm_ptr = lp_parm_ptr(service, &parm);
349 free_one_parameter_common(parm_ptr, parm);
353 * Free the allocated parameter data of a share given
354 * as a service struct.
356 static void free_parameters(struct loadparm_service *service)
360 for (i=0; parm_table[i].label; i++) {
361 free_one_parameter(service, parm_table[i]);
366 * Free the allocated data for one parameter for a given share
367 * specified by an snum.
369 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
374 parm_ptr = lp_parm_ptr(NULL, &parm);
375 } else if (parm.p_class != P_LOCAL) {
378 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
381 free_one_parameter_common(parm_ptr, parm);
385 * Free the allocated parameter data for a share specified
388 static void free_parameters_by_snum(int snum)
392 for (i=0; parm_table[i].label; i++) {
393 free_one_parameter_by_snum(snum, parm_table[i]);
398 * Free the allocated global parameters.
400 static void free_global_parameters(void)
402 free_param_opts(&Globals.param_opt);
403 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
404 TALLOC_FREE(Globals.ctx);
407 struct lp_stored_option {
408 struct lp_stored_option *prev, *next;
413 static struct lp_stored_option *stored_options;
416 save options set by lp_set_cmdline() into a list. This list is
417 re-applied when we do a globals reset, so that cmdline set options
418 are sticky across reloads of smb.conf
420 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
422 struct lp_stored_option *entry, *entry_next;
423 for (entry = stored_options; entry != NULL; entry = entry_next) {
424 entry_next = entry->next;
425 if (strcmp(pszParmName, entry->label) == 0) {
426 DLIST_REMOVE(stored_options, entry);
432 entry = talloc(NULL, struct lp_stored_option);
437 entry->label = talloc_strdup(entry, pszParmName);
443 entry->value = talloc_strdup(entry, pszParmValue);
449 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
454 static bool apply_lp_set_cmdline(void)
456 struct lp_stored_option *entry = NULL;
457 for (entry = stored_options; entry != NULL; entry = entry->next) {
458 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
459 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
460 entry->label, entry->value));
467 /***************************************************************************
468 Initialise the global parameter structure.
469 ***************************************************************************/
471 static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
473 static bool done_init = false;
477 /* If requested to initialize only once and we've already done it... */
478 if (!reinit_globals && done_init) {
479 /* ... then we have nothing more to do */
484 /* The logfile can be set before this is invoked. Free it if so. */
485 lpcfg_string_free(&Globals.logfile);
488 free_global_parameters();
491 /* This memset and the free_global_parameters() above will
492 * wipe out smb.conf options set with lp_set_cmdline(). The
493 * apply_lp_set_cmdline() call puts these values back in the
494 * table once the defaults are set */
495 ZERO_STRUCT(Globals);
497 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
499 /* Initialize the flags list if necessary */
500 if (flags_list == NULL) {
504 for (i = 0; parm_table[i].label; i++) {
505 if ((parm_table[i].type == P_STRING ||
506 parm_table[i].type == P_USTRING))
510 (char **)lp_parm_ptr(NULL, &parm_table[i]),
516 lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
517 lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U");
519 init_printer_values(lp_ctx, Globals.ctx, &sDefault);
521 sDefault.ntvfs_handler = str_list_make_v3_const(NULL, "unixuid default", NULL);
523 DEBUG(3, ("Initialising global parameters\n"));
525 /* Must manually force to upper case here, as this does not go via the handler */
526 lpcfg_string_set(Globals.ctx, &Globals.netbios_name,
529 lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file,
530 get_dyn_SMB_PASSWD_FILE());
531 lpcfg_string_set(Globals.ctx, &Globals.private_dir,
532 get_dyn_PRIVATE_DIR());
534 /* use the new 'hash2' method by default, with a prefix of 1 */
535 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
536 Globals.mangle_prefix = 1;
538 lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
540 /* using UTF8 by default allows us to support all chars */
541 lpcfg_string_set(Globals.ctx, &Globals.unix_charset,
542 DEFAULT_UNIX_CHARSET);
544 /* Use codepage 850 as a default for the dos character set */
545 lpcfg_string_set(Globals.ctx, &Globals.dos_charset,
546 DEFAULT_DOS_CHARSET);
549 * Allow the default PASSWD_CHAT to be overridden in local.h.
551 lpcfg_string_set(Globals.ctx, &Globals.passwd_chat,
552 DEFAULT_PASSWD_CHAT);
554 lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
556 lpcfg_string_set(Globals.ctx, &Globals.passwd_program, "");
557 lpcfg_string_set(Globals.ctx, &Globals.lock_directory,
559 lpcfg_string_set(Globals.ctx, &Globals.state_directory,
561 lpcfg_string_set(Globals.ctx, &Globals.cache_directory,
563 lpcfg_string_set(Globals.ctx, &Globals.pid_directory,
565 lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address,
568 * By default support explicit binding to broadcast
571 Globals.nmbd_bind_explicit_broadcast = true;
573 s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
575 smb_panic("init_globals: ENOMEM");
577 lpcfg_string_set(Globals.ctx, &Globals.server_string, s);
580 lpcfg_string_set(Globals.ctx, &Globals.panic_action,
581 "/bin/sleep 999999999");
584 lpcfg_string_set(Globals.ctx, &Globals.socket_options,
585 DEFAULT_SOCKET_OPTIONS);
587 lpcfg_string_set(Globals.ctx, &Globals.logon_drive, "");
588 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
589 lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
590 lpcfg_string_set(Globals.ctx, &Globals.logon_path,
591 "\\\\%N\\%U\\profile");
593 Globals.name_resolve_order = str_list_make_v3_const(NULL, "lmhosts wins host bcast", NULL);
594 lpcfg_string_set(Globals.ctx, &Globals.password_server, "*");
596 Globals.algorithmic_rid_base = BASE_RID;
598 Globals.load_printers = true;
599 Globals.printcap_cache_time = 750; /* 12.5 minutes */
601 Globals.config_backend = config_backend;
602 Globals._server_role = ROLE_AUTO;
604 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
605 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
606 Globals.max_xmit = 0x4104;
607 Globals.max_mux = 50; /* This is *needed* for profile support. */
608 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
609 Globals._disable_spoolss = false;
610 Globals.max_smbd_processes = 0;/* no limit specified */
611 Globals.username_level = 0;
612 Globals.deadtime = 0;
613 Globals.getwd_cache = true;
614 Globals.large_readwrite = true;
615 Globals.max_log_size = 5000;
616 Globals.max_open_files = max_open_files();
617 Globals.server_max_protocol = PROTOCOL_SMB3_11;
618 Globals.server_min_protocol = PROTOCOL_LANMAN1;
619 Globals._client_max_protocol = PROTOCOL_DEFAULT;
620 Globals.client_min_protocol = PROTOCOL_CORE;
621 Globals._security = SEC_AUTO;
622 Globals.encrypt_passwords = true;
623 Globals.client_schannel = Auto;
624 Globals.winbind_sealed_pipes = true;
625 Globals.require_strong_key = true;
626 Globals.server_schannel = Auto;
627 Globals.read_raw = true;
628 Globals.write_raw = true;
629 Globals.null_passwords = false;
630 Globals.old_password_allowed_period = 60;
631 Globals.obey_pam_restrictions = false;
633 Globals.syslog_only = false;
634 Globals.timestamp_logs = true;
635 lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
636 Globals.debug_prefix_timestamp = false;
637 Globals.debug_hires_timestamp = true;
638 Globals.debug_pid = false;
639 Globals.debug_uid = false;
640 Globals.debug_class = false;
641 Globals.enable_core_files = true;
642 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
643 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
644 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
645 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
646 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
647 Globals.lm_interval = 60;
648 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
649 Globals.nis_homedir = false;
650 #ifdef WITH_NISPLUS_HOME
651 lpcfg_string_set(Globals.ctx, &Globals.homedir_map,
652 "auto_home.org_dir");
654 lpcfg_string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
657 Globals.time_server = false;
658 Globals.bind_interfaces_only = false;
659 Globals.unix_password_sync = false;
660 Globals.pam_password_change = false;
661 Globals.passwd_chat_debug = false;
662 Globals.passwd_chat_timeout = 2; /* 2 second default. */
663 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
664 Globals.nt_status_support = true; /* Use NT status by default. */
665 Globals.smbd_profiling_level = 0;
666 Globals.stat_cache = true; /* use stat cache by default */
667 Globals.max_stat_cache_size = 256; /* 256k by default */
668 Globals.restrict_anonymous = 0;
669 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
670 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
671 Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
672 Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
673 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 */
674 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
676 Globals.map_to_guest = 0; /* By Default, "Never" */
677 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
678 Globals.enhanced_browsing = true;
679 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
680 #ifdef MMAP_BLACKLIST
681 Globals.use_mmap = false;
683 Globals.use_mmap = true;
685 Globals.unicode = true;
686 Globals.unix_extensions = true;
687 Globals.reset_on_zero_vc = false;
688 Globals.log_writeable_files_on_exit = false;
689 Globals.create_krb5_conf = true;
690 Globals._winbind_max_domain_connections = 1;
692 /* hostname lookups can be very expensive and are broken on
693 a large number of sites (tridge) */
694 Globals.hostname_lookups = false;
696 Globals.change_notify = true,
697 Globals.kernel_change_notify = true,
699 lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
700 lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, "");
701 lpcfg_string_set(Globals.ctx, &Globals._ldap_machine_suffix, "");
702 lpcfg_string_set(Globals.ctx, &Globals._ldap_user_suffix, "");
703 lpcfg_string_set(Globals.ctx, &Globals._ldap_group_suffix, "");
704 lpcfg_string_set(Globals.ctx, &Globals._ldap_idmap_suffix, "");
706 lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
707 Globals.ldap_ssl = LDAP_SSL_START_TLS;
708 Globals.ldap_ssl_ads = false;
709 Globals.ldap_deref = -1;
710 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
711 Globals.ldap_delete_dn = false;
712 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
713 Globals.ldap_follow_referral = Auto;
714 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
715 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
716 Globals.ldap_page_size = LDAP_PAGE_SIZE;
718 Globals.ldap_debug_level = 0;
719 Globals.ldap_debug_threshold = 10;
721 Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
723 /* This is what we tell the afs client. in reality we set the token
724 * to never expire, though, when this runs out the afs client will
725 * forget the token. Set to 0 to get NEVERDATE.*/
726 Globals.afs_token_lifetime = 604800;
727 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
729 /* these parameters are set to defaults that are more appropriate
730 for the increasing samba install base:
732 as a member of the workgroup, that will possibly become a
733 _local_ master browser (lm = true). this is opposed to a forced
734 local master browser startup (pm = true).
736 doesn't provide WINS server service by default (wsupp = false),
737 and doesn't provide domain master browser services by default, either.
741 Globals.show_add_printer_wizard = true;
742 Globals.os_level = 20;
743 Globals.local_master = true;
744 Globals._domain_master = Auto; /* depending on _domain_logons */
745 Globals._domain_logons = false;
746 Globals.browse_list = true;
747 Globals.we_are_a_wins_server = false;
748 Globals.wins_proxy = false;
750 TALLOC_FREE(Globals.init_logon_delayed_hosts);
751 Globals.init_logon_delay = 100; /* 100 ms default delay */
753 Globals.wins_dns_proxy = true;
755 Globals.allow_trusted_domains = true;
756 lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb");
758 lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
759 lpcfg_string_set(Globals.ctx, &Globals.template_homedir,
761 lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\");
762 lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory,
763 dyn_WINBINDD_SOCKET_DIR);
765 lpcfg_string_set(Globals.ctx, &Globals.cups_server, "");
766 lpcfg_string_set(Globals.ctx, &Globals.iprint_server, "");
768 lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, "");
770 Globals.cluster_addresses = NULL;
771 Globals.clustering = false;
772 Globals.ctdb_timeout = 0;
773 Globals.ctdb_locktime_warn_threshold = 0;
775 Globals.winbind_cache_time = 300; /* 5 minutes */
776 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
777 Globals.winbind_request_timeout = 60; /* 60 seconds */
778 Globals.winbind_max_clients = 200;
779 Globals.winbind_enum_users = false;
780 Globals.winbind_enum_groups = false;
781 Globals.winbind_use_default_domain = false;
782 Globals.winbind_trusted_domains_only = false;
783 Globals.winbind_nested_groups = true;
784 Globals.winbind_expand_groups = 0;
785 Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
786 Globals.winbind_refresh_tickets = false;
787 Globals.winbind_offline_logon = false;
789 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
790 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
792 Globals.passdb_expand_explicit = false;
794 Globals.name_cache_timeout = 660; /* In seconds */
796 Globals.use_spnego = true;
797 Globals.client_use_spnego = true;
799 Globals.client_signing = SMB_SIGNING_DEFAULT;
800 Globals.server_signing = SMB_SIGNING_DEFAULT;
802 Globals.defer_sharing_violations = true;
803 Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
805 Globals.enable_privileges = true;
806 Globals.host_msdfs = true;
807 Globals.enable_asu_support = false;
809 /* User defined shares. */
810 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
812 smb_panic("init_globals: ENOMEM");
814 lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s);
816 lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, "");
817 Globals.usershare_max_shares = 0;
818 /* By default disallow sharing of directories not owned by the sharer. */
819 Globals.usershare_owner_only = true;
820 /* By default disallow guest access to usershares. */
821 Globals.usershare_allow_guests = false;
823 Globals.keepalive = DEFAULT_KEEPALIVE;
825 /* By default no shares out of the registry */
826 Globals.registry_shares = false;
828 Globals.min_receivefile_size = 0;
830 Globals.map_untrusted_to_domain = false;
831 Globals.multicast_dns_register = true;
833 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
834 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
835 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
836 Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
837 Globals.smb2_leases = false;
839 lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir,
840 get_dyn_NCALRPCDIR());
842 Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
844 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);
846 Globals.tls_enabled = true;
848 lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
849 lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
850 lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
851 lpcfg_string_set(Globals.ctx, &Globals.tls_priority,
852 "NORMAL:-VERS-SSL3.0");
854 lpcfg_string_set(Globals.ctx, &Globals.share_backend, "classic");
856 Globals._preferred_master = Auto;
858 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
860 lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
861 get_dyn_NTP_SIGND_SOCKET_DIR());
863 lpcfg_string_set(Globals.ctx,
864 &Globals.winbindd_privileged_socket_directory,
865 get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
867 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
869 smb_panic("init_globals: ENOMEM");
871 Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
874 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
876 smb_panic("init_globals: ENOMEM");
878 Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
881 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
883 smb_panic("init_globals: ENOMEM");
885 Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
888 Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
890 Globals.rndc_command = str_list_make_v3_const(NULL, "/usr/sbin/rndc", NULL);
892 Globals.cldap_port = 389;
894 Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
896 Globals.nbt_port = NBT_NAME_SERVICE_PORT;
898 Globals.krb5_port = 88;
900 Globals.kpasswd_port = 464;
902 Globals.web_port = 901;
904 Globals.aio_max_threads = 100;
906 /* Now put back the settings that were set with lp_set_cmdline() */
907 apply_lp_set_cmdline();
910 /* Convenience routine to setup an lp_context with additional s3 variables */
911 static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
913 struct loadparm_context *lp_ctx;
915 lp_ctx = loadparm_init_s3(mem_ctx,
916 loadparm_s3_helpers());
917 if (lp_ctx == NULL) {
918 DEBUG(0, ("loadparm_init_s3 failed\n"));
922 lp_ctx->sDefault = &sDefault;
923 lp_ctx->services = NULL; /* We do not want to access this directly */
924 lp_ctx->bInGlobalSection = bInGlobalSection;
925 lp_ctx->flags = flags_list;
930 /*******************************************************************
931 Convenience routine to grab string parameters into talloced memory
932 and run standard_sub_basic on them. The buffers can be written to by
933 callers without affecting the source string.
934 ********************************************************************/
936 char *lp_string(TALLOC_CTX *ctx, const char *s)
940 /* The follow debug is useful for tracking down memory problems
941 especially if you have an inner loop that is calling a lp_*()
942 function that returns a string. Perhaps this debug should be
943 present all the time? */
946 DEBUG(10, ("lp_string(%s)\n", s));
952 ret = talloc_sub_basic(ctx,
953 get_current_username(),
954 current_user_info.domain,
956 if (trim_char(ret, '\"', '\"')) {
957 if (strchr(ret,'\"') != NULL) {
959 ret = talloc_sub_basic(ctx,
960 get_current_username(),
961 current_user_info.domain,
969 In this section all the functions that are used to access the
970 parameters from the rest of the program are defined
973 #define FN_GLOBAL_STRING(fn_name,ptr) \
974 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
975 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
976 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
977 #define FN_GLOBAL_LIST(fn_name,ptr) \
978 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
979 #define FN_GLOBAL_BOOL(fn_name,ptr) \
980 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
981 #define FN_GLOBAL_CHAR(fn_name,ptr) \
982 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
983 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
984 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
986 #define FN_LOCAL_STRING(fn_name,val) \
987 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));}
988 #define FN_LOCAL_CONST_STRING(fn_name,val) \
989 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
990 #define FN_LOCAL_LIST(fn_name,val) \
991 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
992 #define FN_LOCAL_BOOL(fn_name,val) \
993 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
994 #define FN_LOCAL_INTEGER(fn_name,val) \
995 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
997 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
998 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
999 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1000 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1001 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1002 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1004 int lp_winbind_max_domain_connections(void)
1006 if (lp_winbind_offline_logon() &&
1007 lp__winbind_max_domain_connections() > 1) {
1008 DEBUG(1, ("offline logons active, restricting max domain "
1009 "connections to 1\n"));
1012 return MAX(1, lp__winbind_max_domain_connections());
1015 /* These functions remain in source3/param for now */
1017 #include "lib/param/param_functions.c"
1019 FN_LOCAL_STRING(servicename, szService)
1020 FN_LOCAL_CONST_STRING(const_servicename, szService)
1022 /* These functions cannot be auto-generated */
1023 FN_LOCAL_BOOL(autoloaded, autoloaded)
1024 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1026 /* local prototypes */
1028 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1029 static const char *get_boolean(bool bool_value);
1030 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1032 static bool hash_a_service(const char *name, int number);
1033 static void free_service_byindex(int iService);
1034 static void show_parameter(int parmIndex);
1035 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1038 * This is a helper function for parametrical options support. It returns a
1039 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1040 * parametrical functions are quite simple
1042 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1045 if (snum >= iNumServices) return NULL;
1048 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1050 return get_parametric_helper(ServicePtrs[snum],
1051 type, option, Globals.param_opt);
1055 static void discard_whitespace(char *str)
1057 size_t len = strlen(str);
1061 if (isspace(str[i])) {
1062 memmove(&str[i], &str[i+1], len-i);
1071 * @brief Go through all global parametric parameters
1073 * @param regex_str A regular expression to scan param for
1074 * @param max_matches Max number of submatches the regexp expects
1075 * @param cb Function to call on match. Should return true
1076 * when it wants wi_scan_global_parametrics to stop
1078 * @param private_data Anonymous pointer passed to cb
1080 * @return 0: success, regcomp/regexec return value on error.
1081 * See "man regexec" for possible errors
1084 int lp_wi_scan_global_parametrics(
1085 const char *regex_str, size_t max_matches,
1086 bool (*cb)(const char *string, regmatch_t matches[],
1087 void *private_data),
1090 struct parmlist_entry *data;
1094 ret = regcomp(®ex, regex_str, REG_ICASE);
1099 for (data = Globals.param_opt; data != NULL; data = data->next) {
1100 size_t keylen = strlen(data->key);
1102 regmatch_t matches[max_matches];
1105 memcpy(key, data->key, sizeof(key));
1106 discard_whitespace(key);
1108 ret = regexec(®ex, key, max_matches, matches, 0);
1109 if (ret == REG_NOMATCH) {
1116 stop = cb(key, matches, private_data);
1129 #define MISSING_PARAMETER(name) \
1130 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1132 /*******************************************************************
1133 convenience routine to return enum parameters.
1134 ********************************************************************/
1135 static int lp_enum(const char *s,const struct enum_list *_enum)
1139 if (!s || !*s || !_enum) {
1140 MISSING_PARAMETER(lp_enum);
1144 for (i=0; _enum[i].name; i++) {
1145 if (strequal(_enum[i].name,s))
1146 return _enum[i].value;
1149 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1153 #undef MISSING_PARAMETER
1155 /* Return parametric option from a given service. Type is a part of option before ':' */
1156 /* Parametric option has following syntax: 'Type: option = value' */
1157 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1159 struct parmlist_entry *data = get_parametrics(snum, type, option);
1161 if (data == NULL||data->value==NULL) {
1163 return lp_string(ctx, def);
1169 return lp_string(ctx, data->value);
1172 /* Return parametric option from a given service. Type is a part of option before ':' */
1173 /* Parametric option has following syntax: 'Type: option = value' */
1174 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1176 struct parmlist_entry *data = get_parametrics(snum, type, option);
1178 if (data == NULL||data->value==NULL)
1185 /* Return parametric option from a given service. Type is a part of option before ':' */
1186 /* Parametric option has following syntax: 'Type: option = value' */
1188 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1190 struct parmlist_entry *data = get_parametrics(snum, type, option);
1192 if (data == NULL||data->value==NULL)
1193 return (const char **)def;
1195 if (data->list==NULL) {
1196 data->list = str_list_make_v3(NULL, data->value, NULL);
1199 return discard_const_p(const char *, data->list);
1202 /* Return parametric option from a given service. Type is a part of option before ':' */
1203 /* Parametric option has following syntax: 'Type: option = value' */
1205 int lp_parm_int(int snum, const char *type, const char *option, int def)
1207 struct parmlist_entry *data = get_parametrics(snum, type, option);
1209 if (data && data->value && *data->value)
1210 return lp_int(data->value);
1215 /* Return parametric option from a given service. Type is a part of option before ':' */
1216 /* Parametric option has following syntax: 'Type: option = value' */
1218 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1220 struct parmlist_entry *data = get_parametrics(snum, type, option);
1222 if (data && data->value && *data->value)
1223 return lp_ulong(data->value);
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 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1233 struct parmlist_entry *data = get_parametrics(snum, type, option);
1235 if (data && data->value && *data->value)
1236 return lp_bool(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 int lp_parm_enum(int snum, const char *type, const char *option,
1245 const struct enum_list *_enum, int def)
1247 struct parmlist_entry *data = get_parametrics(snum, type, option);
1249 if (data && data->value && *data->value && _enum)
1250 return lp_enum(data->value, _enum);
1256 * free a param_opts structure.
1257 * param_opts handling should be moved to talloc;
1258 * then this whole functions reduces to a TALLOC_FREE().
1261 static void free_param_opts(struct parmlist_entry **popts)
1263 struct parmlist_entry *opt, *next_opt;
1265 if (*popts != NULL) {
1266 DEBUG(5, ("Freeing parametrics:\n"));
1269 while (opt != NULL) {
1270 lpcfg_string_free(&opt->key);
1271 lpcfg_string_free(&opt->value);
1272 TALLOC_FREE(opt->list);
1273 next_opt = opt->next;
1280 /***************************************************************************
1281 Free the dynamically allocated parts of a service struct.
1282 ***************************************************************************/
1284 static void free_service(struct loadparm_service *pservice)
1289 if (pservice->szService)
1290 DEBUG(5, ("free_service: Freeing service %s\n",
1291 pservice->szService));
1293 free_parameters(pservice);
1295 lpcfg_string_free(&pservice->szService);
1296 TALLOC_FREE(pservice->copymap);
1298 free_param_opts(&pservice->param_opt);
1300 ZERO_STRUCTP(pservice);
1304 /***************************************************************************
1305 remove a service indexed in the ServicePtrs array from the ServiceHash
1306 and free the dynamically allocated parts
1307 ***************************************************************************/
1309 static void free_service_byindex(int idx)
1311 if ( !LP_SNUM_OK(idx) )
1314 ServicePtrs[idx]->valid = false;
1316 /* we have to cleanup the hash record */
1318 if (ServicePtrs[idx]->szService) {
1319 char *canon_name = canonicalize_servicename(
1321 ServicePtrs[idx]->szService );
1323 dbwrap_delete_bystring(ServiceHash, canon_name );
1324 TALLOC_FREE(canon_name);
1327 free_service(ServicePtrs[idx]);
1328 talloc_free_children(ServicePtrs[idx]);
1331 /***************************************************************************
1332 Add a new service to the services array initialising it with the given
1334 ***************************************************************************/
1336 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1339 int num_to_alloc = iNumServices + 1;
1340 struct loadparm_service **tsp = NULL;
1342 /* it might already exist */
1344 i = getservicebyname(name, NULL);
1350 /* if not, then create one */
1352 tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
1354 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1358 ServicePtrs[iNumServices] = talloc_zero(NULL, struct loadparm_service);
1359 if (!ServicePtrs[iNumServices]) {
1360 DEBUG(0,("add_a_service: out of memory!\n"));
1365 ServicePtrs[i]->valid = true;
1367 copy_service(ServicePtrs[i], pservice, NULL);
1369 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
1372 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1373 i, ServicePtrs[i]->szService));
1375 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1382 /***************************************************************************
1383 Convert a string to uppercase and remove whitespaces.
1384 ***************************************************************************/
1386 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1391 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1395 result = talloc_strdup(ctx, src);
1396 SMB_ASSERT(result != NULL);
1398 if (!strlower_m(result)) {
1399 TALLOC_FREE(result);
1405 /***************************************************************************
1406 Add a name/index pair for the services array to the hash table.
1407 ***************************************************************************/
1409 static bool hash_a_service(const char *name, int idx)
1413 if ( !ServiceHash ) {
1414 DEBUG(10,("hash_a_service: creating servicehash\n"));
1415 ServiceHash = db_open_rbt(NULL);
1416 if ( !ServiceHash ) {
1417 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1422 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1425 canon_name = canonicalize_servicename(talloc_tos(), name );
1427 dbwrap_store_bystring(ServiceHash, canon_name,
1428 make_tdb_data((uint8_t *)&idx, sizeof(idx)),
1431 TALLOC_FREE(canon_name);
1436 /***************************************************************************
1437 Add a new home service, with the specified home directory, defaults coming
1439 ***************************************************************************/
1441 bool lp_add_home(const char *pszHomename, int iDefaultService,
1442 const char *user, const char *pszHomedir)
1446 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1447 pszHomedir[0] == '\0') {
1451 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1456 if (!(*(ServicePtrs[iDefaultService]->path))
1457 || strequal(ServicePtrs[iDefaultService]->path,
1458 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1459 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
1463 if (!(*(ServicePtrs[i]->comment))) {
1464 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1465 if (comment == NULL) {
1468 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment,
1470 TALLOC_FREE(comment);
1473 /* set the browseable flag from the global default */
1475 ServicePtrs[i]->browseable = sDefault.browseable;
1476 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1478 ServicePtrs[i]->autoloaded = true;
1480 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1481 user, ServicePtrs[i]->path ));
1486 /***************************************************************************
1487 Add a new service, based on an old one.
1488 ***************************************************************************/
1490 int lp_add_service(const char *pszService, int iDefaultService)
1492 if (iDefaultService < 0) {
1493 return add_a_service(&sDefault, pszService);
1496 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1499 /***************************************************************************
1500 Add the IPC service.
1501 ***************************************************************************/
1503 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1505 char *comment = NULL;
1506 int i = add_a_service(&sDefault, ipc_name);
1511 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1512 Globals.server_string);
1513 if (comment == NULL) {
1517 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1518 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
1519 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1520 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1521 ServicePtrs[i]->max_connections = 0;
1522 ServicePtrs[i]->available = true;
1523 ServicePtrs[i]->read_only = true;
1524 ServicePtrs[i]->guest_only = false;
1525 ServicePtrs[i]->administrative_share = true;
1526 ServicePtrs[i]->guest_ok = guest_ok;
1527 ServicePtrs[i]->printable = false;
1528 ServicePtrs[i]->browseable = sDefault.browseable;
1530 DEBUG(3, ("adding IPC service\n"));
1532 TALLOC_FREE(comment);
1536 /***************************************************************************
1537 Add a new printer service, with defaults coming from service iFrom.
1538 ***************************************************************************/
1540 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1542 const char *comment = "From Printcap";
1543 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1548 /* note that we do NOT default the availability flag to true - */
1549 /* we take it from the default service passed. This allows all */
1550 /* dynamic printers to be disabled by disabling the [printers] */
1551 /* entry (if/when the 'available' keyword is implemented!). */
1553 /* the printer name is set to the service name. */
1554 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername,
1556 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1558 /* set the browseable flag from the gloabl default */
1559 ServicePtrs[i]->browseable = sDefault.browseable;
1561 /* Printers cannot be read_only. */
1562 ServicePtrs[i]->read_only = false;
1563 /* No oplocks on printer services. */
1564 ServicePtrs[i]->oplocks = false;
1565 /* Printer services must be printable. */
1566 ServicePtrs[i]->printable = true;
1568 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1574 /***************************************************************************
1575 Check whether the given parameter name is valid.
1576 Parametric options (names containing a colon) are considered valid.
1577 ***************************************************************************/
1579 bool lp_parameter_is_valid(const char *pszParmName)
1581 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1582 (strchr(pszParmName, ':') != NULL));
1585 /***************************************************************************
1586 Check whether the given name is the name of a global parameter.
1587 Returns true for strings belonging to parameters of class
1588 P_GLOBAL, false for all other strings, also for parametric options
1589 and strings not belonging to any option.
1590 ***************************************************************************/
1592 bool lp_parameter_is_global(const char *pszParmName)
1594 int num = lpcfg_map_parameter(pszParmName);
1597 return (parm_table[num].p_class == P_GLOBAL);
1603 /**************************************************************************
1604 Determine the canonical name for a parameter.
1605 Indicate when it is an inverse (boolean) synonym instead of a
1607 **************************************************************************/
1609 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1614 if (!lp_parameter_is_valid(parm_name)) {
1619 num = map_parameter_canonical(parm_name, inverse);
1621 /* parametric option */
1622 *canon_parm = parm_name;
1624 *canon_parm = parm_table[num].label;
1631 /**************************************************************************
1632 Determine the canonical name for a parameter.
1633 Turn the value given into the inverse boolean expression when
1634 the synonym is an invers boolean synonym.
1636 Return true if parm_name is a valid parameter name and
1637 in case it is an invers boolean synonym, if the val string could
1638 successfully be converted to the reverse bool.
1639 Return false in all other cases.
1640 **************************************************************************/
1642 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1644 const char **canon_parm,
1645 const char **canon_val)
1650 if (!lp_parameter_is_valid(parm_name)) {
1656 num = map_parameter_canonical(parm_name, &inverse);
1658 /* parametric option */
1659 *canon_parm = parm_name;
1662 *canon_parm = parm_table[num].label;
1664 if (!lp_invert_boolean(val, canon_val)) {
1676 /***************************************************************************
1677 Map a parameter's string representation to the index of the canonical
1678 form of the parameter (it might be a synonym).
1679 Returns -1 if the parameter string is not recognised.
1680 ***************************************************************************/
1682 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1684 int parm_num, canon_num;
1685 bool loc_inverse = false;
1687 parm_num = lpcfg_map_parameter(pszParmName);
1688 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
1689 /* invalid, parametric or no canidate for synonyms ... */
1693 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1694 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1695 parm_num = canon_num;
1701 if (inverse != NULL) {
1702 *inverse = loc_inverse;
1707 /***************************************************************************
1708 return true if parameter number parm1 is a synonym of parameter
1709 number parm2 (parm2 being the principal name).
1710 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1712 ***************************************************************************/
1714 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1716 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1717 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1718 (parm_table[parm1].flags & FLAG_SYNONYM) &&
1719 !(parm_table[parm2].flags & FLAG_SYNONYM))
1721 if (inverse != NULL) {
1722 if ((parm_table[parm1].type == P_BOOLREV) &&
1723 (parm_table[parm2].type == P_BOOL))
1735 /***************************************************************************
1736 Show one parameter's name, type, [values,] and flags.
1737 (helper functions for show_parameter_list)
1738 ***************************************************************************/
1740 static void show_parameter(int parmIndex)
1742 int enumIndex, flagIndex;
1747 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1748 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1749 "P_ENUM", "P_BYTES", "P_CMDLIST" };
1750 unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
1751 const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
1753 printf("%s=%s", parm_table[parmIndex].label,
1754 type[parm_table[parmIndex].type]);
1755 if (parm_table[parmIndex].type == P_ENUM) {
1758 parm_table[parmIndex].enum_list[enumIndex].name;
1762 enumIndex ? "|" : "",
1763 parm_table[parmIndex].enum_list[enumIndex].name);
1768 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1769 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1772 flag_names[flagIndex]);
1777 /* output synonyms */
1779 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1780 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1781 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1782 parm_table[parmIndex2].label);
1783 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1785 printf(" (synonyms: ");
1790 printf("%s%s", parm_table[parmIndex2].label,
1791 inverse ? "[i]" : "");
1801 /***************************************************************************
1802 Show all parameter's name, type, [values,] and flags.
1803 ***************************************************************************/
1805 void show_parameter_list(void)
1807 int classIndex, parmIndex;
1808 const char *section_names[] = { "local", "global", NULL};
1810 for (classIndex=0; section_names[classIndex]; classIndex++) {
1811 printf("[%s]\n", section_names[classIndex]);
1812 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
1813 if (parm_table[parmIndex].p_class == classIndex) {
1814 show_parameter(parmIndex);
1820 /***************************************************************************
1821 Get the standard string representation of a boolean value ("yes" or "no")
1822 ***************************************************************************/
1824 static const char *get_boolean(bool bool_value)
1826 static const char *yes_str = "yes";
1827 static const char *no_str = "no";
1829 return (bool_value ? yes_str : no_str);
1832 /***************************************************************************
1833 Provide the string of the negated boolean value associated to the boolean
1834 given as a string. Returns false if the passed string does not correctly
1835 represent a boolean.
1836 ***************************************************************************/
1838 bool lp_invert_boolean(const char *str, const char **inverse_str)
1842 if (!set_boolean(str, &val)) {
1846 *inverse_str = get_boolean(!val);
1850 /***************************************************************************
1851 Provide the canonical string representation of a boolean value given
1852 as a string. Return true on success, false if the string given does
1853 not correctly represent a boolean.
1854 ***************************************************************************/
1856 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
1860 if (!set_boolean(str, &val)) {
1864 *canon_str = get_boolean(val);
1868 /***************************************************************************
1869 Find a service by name. Otherwise works like get_service.
1870 ***************************************************************************/
1872 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
1879 if (ServiceHash == NULL) {
1883 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
1885 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
1888 if (NT_STATUS_IS_OK(status) &&
1889 (data.dptr != NULL) &&
1890 (data.dsize == sizeof(iService)))
1892 iService = *(int *)data.dptr;
1895 TALLOC_FREE(canon_name);
1897 if ((iService != -1) && (LP_SNUM_OK(iService))
1898 && (pserviceDest != NULL)) {
1899 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1905 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
1906 struct loadparm_service *lp_service(const char *pszServiceName)
1908 int iService = getservicebyname(pszServiceName, NULL);
1909 if (iService == -1 || !LP_SNUM_OK(iService)) {
1912 return ServicePtrs[iService];
1915 struct loadparm_service *lp_servicebynum(int snum)
1917 if ((snum == -1) || !LP_SNUM_OK(snum)) {
1920 return ServicePtrs[snum];
1923 struct loadparm_service *lp_default_loadparm_service()
1928 static struct smbconf_ctx *lp_smbconf_ctx(void)
1931 static struct smbconf_ctx *conf_ctx = NULL;
1933 if (conf_ctx == NULL) {
1934 err = smbconf_init(NULL, &conf_ctx, "registry:");
1935 if (!SBC_ERROR_IS_OK(err)) {
1936 DEBUG(1, ("error initializing registry configuration: "
1937 "%s\n", sbcErrorString(err)));
1945 static bool process_smbconf_service(struct smbconf_service *service)
1950 if (service == NULL) {
1954 ret = lp_do_section(service->name, NULL);
1958 for (count = 0; count < service->num_params; count++) {
1960 if (!bInGlobalSection && bGlobalOnly) {
1963 const char *pszParmName = service->param_names[count];
1964 const char *pszParmValue = service->param_values[count];
1966 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
1968 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1969 pszParmName, pszParmValue);
1976 if (iServiceIndex >= 0) {
1977 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
1983 * load a service from registry and activate it
1985 bool process_registry_service(const char *service_name)
1988 struct smbconf_service *service = NULL;
1989 TALLOC_CTX *mem_ctx = talloc_stackframe();
1990 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
1993 if (conf_ctx == NULL) {
1997 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
1999 if (!smbconf_share_exists(conf_ctx, service_name)) {
2001 * Registry does not contain data for this service (yet),
2002 * but make sure lp_load doesn't return false.
2008 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2009 if (!SBC_ERROR_IS_OK(err)) {
2013 ret = process_smbconf_service(service);
2019 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2022 TALLOC_FREE(mem_ctx);
2027 * process_registry_globals
2029 static bool process_registry_globals(void)
2033 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2035 if (!bInGlobalSection && bGlobalOnly) {
2038 const char *pszParmName = "registry shares";
2039 const char *pszParmValue = "yes";
2041 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2043 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2044 pszParmName, pszParmValue);
2051 return process_registry_service(GLOBAL_NAME);
2054 bool process_registry_shares(void)
2058 struct smbconf_service **service = NULL;
2059 uint32_t num_shares = 0;
2060 TALLOC_CTX *mem_ctx = talloc_stackframe();
2061 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2064 if (conf_ctx == NULL) {
2068 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2069 if (!SBC_ERROR_IS_OK(err)) {
2075 for (count = 0; count < num_shares; count++) {
2076 if (strequal(service[count]->name, GLOBAL_NAME)) {
2079 ret = process_smbconf_service(service[count]);
2086 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2089 TALLOC_FREE(mem_ctx);
2094 * reload those shares from registry that are already
2095 * activated in the services array.
2097 static bool reload_registry_shares(void)
2102 for (i = 0; i < iNumServices; i++) {
2107 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2111 ret = process_registry_service(ServicePtrs[i]->szService);
2122 #define MAX_INCLUDE_DEPTH 100
2124 static uint8_t include_depth;
2127 * Free the file lists
2129 static void free_file_list(void)
2131 struct file_lists *f;
2132 struct file_lists *next;
2145 * Utility function for outsiders to check if we're running on registry.
2147 bool lp_config_backend_is_registry(void)
2149 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2153 * Utility function to check if the config backend is FILE.
2155 bool lp_config_backend_is_file(void)
2157 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2160 /*******************************************************************
2161 Check if a config file has changed date.
2162 ********************************************************************/
2164 bool lp_file_list_changed(void)
2166 struct file_lists *f = file_lists;
2168 DEBUG(6, ("lp_file_list_changed()\n"));
2171 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2172 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2174 if (conf_ctx == NULL) {
2177 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2180 DEBUGADD(6, ("registry config changed\n"));
2187 n2 = talloc_sub_basic(talloc_tos(),
2188 get_current_username(),
2189 current_user_info.domain,
2194 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2195 f->name, n2, ctime(&f->modtime)));
2197 mod_time = file_modtime(n2);
2200 ((f->modtime != mod_time) ||
2201 (f->subfname == NULL) ||
2202 (strcmp(n2, f->subfname) != 0)))
2205 ("file %s modified: %s\n", n2,
2207 f->modtime = mod_time;
2208 TALLOC_FREE(f->subfname);
2209 f->subfname = talloc_strdup(f, n2);
2210 if (f->subfname == NULL) {
2211 smb_panic("talloc_strdup failed");
2225 * Initialize iconv conversion descriptors.
2227 * This is called the first time it is needed, and also called again
2228 * every time the configuration is reloaded, because the charset or
2229 * codepage might have changed.
2231 static void init_iconv(void)
2233 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2235 true, global_iconv_handle);
2238 /***************************************************************************
2239 Handle the include operation.
2240 ***************************************************************************/
2241 static bool bAllowIncludeRegistry = true;
2243 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2244 const char *pszParmValue, char **ptr)
2248 if (include_depth >= MAX_INCLUDE_DEPTH) {
2249 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2254 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2255 if (!bAllowIncludeRegistry) {
2258 if (lp_ctx->bInGlobalSection) {
2261 ret = process_registry_globals();
2265 DEBUG(1, ("\"include = registry\" only effective "
2266 "in %s section\n", GLOBAL_NAME));
2271 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2272 current_user_info.domain,
2275 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2277 if (service == NULL) {
2278 lpcfg_string_set(Globals.ctx, ptr, fname);
2280 lpcfg_string_set(service, ptr, fname);
2283 if (file_exist(fname)) {
2286 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2292 DEBUG(2, ("Can't find include file %s\n", fname));
2297 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2299 char *config_option = NULL;
2300 const char *range = NULL;
2303 SMB_ASSERT(low != NULL);
2304 SMB_ASSERT(high != NULL);
2306 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2310 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2312 if (config_option == NULL) {
2313 DEBUG(0, ("out of memory\n"));
2317 range = lp_parm_const_string(-1, config_option, "range", NULL);
2318 if (range == NULL) {
2319 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2323 if (sscanf(range, "%u - %u", low, high) != 2) {
2324 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2325 range, domain_name));
2332 talloc_free(config_option);
2337 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2339 return lp_idmap_range("*", low, high);
2342 const char *lp_idmap_backend(const char *domain_name)
2344 char *config_option = NULL;
2345 const char *backend = NULL;
2347 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2351 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2353 if (config_option == NULL) {
2354 DEBUG(0, ("out of memory\n"));
2358 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2359 if (backend == NULL) {
2360 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2365 talloc_free(config_option);
2369 const char *lp_idmap_default_backend(void)
2371 return lp_idmap_backend("*");
2374 /***************************************************************************
2375 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2376 ***************************************************************************/
2378 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2380 const char *suffix_string;
2382 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2383 Globals.ldap_suffix );
2384 if ( !suffix_string ) {
2385 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2389 return suffix_string;
2392 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2394 if (Globals._ldap_machine_suffix[0])
2395 return append_ldap_suffix(ctx, Globals._ldap_machine_suffix);
2397 return lp_string(ctx, Globals.ldap_suffix);
2400 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2402 if (Globals._ldap_user_suffix[0])
2403 return append_ldap_suffix(ctx, Globals._ldap_user_suffix);
2405 return lp_string(ctx, Globals.ldap_suffix);
2408 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2410 if (Globals._ldap_group_suffix[0])
2411 return append_ldap_suffix(ctx, Globals._ldap_group_suffix);
2413 return lp_string(ctx, Globals.ldap_suffix);
2416 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2418 if (Globals._ldap_idmap_suffix[0])
2419 return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix);
2421 return lp_string(ctx, Globals.ldap_suffix);
2425 return the parameter pointer for a parameter
2427 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2429 if (service == NULL) {
2430 if (parm->p_class == P_LOCAL)
2431 return (void *)(((char *)&sDefault)+parm->offset);
2432 else if (parm->p_class == P_GLOBAL)
2433 return (void *)(((char *)&Globals)+parm->offset);
2436 return (void *)(((char *)service) + parm->offset);
2440 /***************************************************************************
2441 Process a parameter for a particular service number. If snum < 0
2442 then assume we are in the globals.
2443 ***************************************************************************/
2445 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2447 TALLOC_CTX *frame = talloc_stackframe();
2448 struct loadparm_context *lp_ctx;
2451 lp_ctx = setup_lp_context(frame);
2452 if (lp_ctx == NULL) {
2458 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2460 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2461 pszParmName, pszParmValue);
2469 /***************************************************************************
2470 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2471 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2472 ***************************************************************************/
2474 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2477 parmnum = lpcfg_map_parameter(pszParmName);
2479 flags_list[parmnum] &= ~FLAG_CMDLINE;
2480 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2483 flags_list[parmnum] |= FLAG_CMDLINE;
2485 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2486 * be grouped in the table, so we don't have to search the
2489 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2490 && parm_table[i].p_class == parm_table[parmnum].p_class;
2492 flags_list[i] |= FLAG_CMDLINE;
2494 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2495 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2496 flags_list[i] |= FLAG_CMDLINE;
2502 /* it might be parametric */
2503 if (strchr(pszParmName, ':') != NULL) {
2504 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2508 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2512 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2515 TALLOC_CTX *frame = talloc_stackframe();
2516 struct loadparm_context *lp_ctx;
2518 lp_ctx = setup_lp_context(frame);
2519 if (lp_ctx == NULL) {
2524 ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
2530 /***************************************************************************
2531 Process a parameter.
2532 ***************************************************************************/
2534 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2537 if (!bInGlobalSection && bGlobalOnly)
2540 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2542 if (bInGlobalSection) {
2543 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2545 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2546 pszParmName, pszParmValue);
2550 /***************************************************************************
2551 Initialize any local variables in the sDefault table, after parsing a
2553 ***************************************************************************/
2555 static void init_locals(void)
2558 * We run this check once the [globals] is parsed, to force
2559 * the VFS objects and other per-share settings we need for
2560 * the standard way a AD DC is operated. We may change these
2561 * as our code evolves, which is why we force these settings.
2563 * We can't do this at the end of lp_load_ex(), as by that
2564 * point the services have been loaded and they will already
2565 * have "" as their vfs objects.
2567 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2568 const char **vfs_objects = lp_vfs_objects(-1);
2569 if (!vfs_objects || !vfs_objects[0]) {
2570 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2571 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2572 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2573 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2575 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2579 lp_do_parameter(-1, "map hidden", "no");
2580 lp_do_parameter(-1, "map system", "no");
2581 lp_do_parameter(-1, "map readonly", "no");
2582 lp_do_parameter(-1, "map archive", "no");
2583 lp_do_parameter(-1, "store dos attributes", "yes");
2587 /***************************************************************************
2588 Process a new section (service). At this stage all sections are services.
2589 Later we'll have special sections that permit server parameters to be set.
2590 Returns true on success, false on failure.
2591 ***************************************************************************/
2593 bool lp_do_section(const char *pszSectionName, void *userdata)
2595 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2597 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2598 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2601 /* if we were in a global section then do the local inits */
2602 if (bInGlobalSection && !isglobal)
2605 /* if we've just struck a global section, note the fact. */
2606 bInGlobalSection = isglobal;
2607 if (lp_ctx != NULL) {
2608 lp_ctx->bInGlobalSection = isglobal;
2611 /* check for multiple global sections */
2612 if (bInGlobalSection) {
2613 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2617 if (!bInGlobalSection && bGlobalOnly)
2620 /* if we have a current service, tidy it up before moving on */
2623 if (iServiceIndex >= 0)
2624 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2626 /* if all is still well, move to the next record in the services array */
2628 /* We put this here to avoid an odd message order if messages are */
2629 /* issued by the post-processing of a previous section. */
2630 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2632 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2633 if (iServiceIndex < 0) {
2634 DEBUG(0, ("Failed to add a new service\n"));
2637 /* Clean all parametric options for service */
2638 /* They will be added during parsing again */
2639 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2645 /***************************************************************************
2646 Display the contents of a parameter of a single services record.
2647 ***************************************************************************/
2649 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2651 bool result = false;
2652 struct loadparm_context *lp_ctx;
2654 lp_ctx = setup_lp_context(talloc_tos());
2655 if (lp_ctx == NULL) {
2660 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2662 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2664 TALLOC_FREE(lp_ctx);
2669 /***************************************************************************
2670 Display the contents of a single copy structure.
2671 ***************************************************************************/
2672 static void dump_copy_map(bool *pcopymap)
2678 printf("\n\tNon-Copied parameters:\n");
2680 for (i = 0; parm_table[i].label; i++)
2681 if (parm_table[i].p_class == P_LOCAL &&
2682 parm_table[i].ptr && !pcopymap[i] &&
2683 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2685 printf("\t\t%s\n", parm_table[i].label);
2690 /***************************************************************************
2691 Return TRUE if the passed service number is within range.
2692 ***************************************************************************/
2694 bool lp_snum_ok(int iService)
2696 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->available);
2699 /***************************************************************************
2700 Auto-load some home services.
2701 ***************************************************************************/
2703 static void lp_add_auto_services(char *str)
2713 s = talloc_strdup(talloc_tos(), str);
2715 smb_panic("talloc_strdup failed");
2719 homes = lp_servicenumber(HOMES_NAME);
2721 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2722 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2725 if (lp_servicenumber(p) >= 0)
2728 home = get_user_home_dir(talloc_tos(), p);
2730 if (home && home[0] && homes >= 0)
2731 lp_add_home(p, homes, p, home);
2738 /***************************************************************************
2739 Auto-load one printer.
2740 ***************************************************************************/
2742 void lp_add_one_printer(const char *name, const char *comment,
2743 const char *location, void *pdata)
2745 int printers = lp_servicenumber(PRINTERS_NAME);
2748 if (lp_servicenumber(name) < 0) {
2749 lp_add_printer(name, printers);
2750 if ((i = lp_servicenumber(name)) >= 0) {
2751 lpcfg_string_set(ServicePtrs[i],
2752 &ServicePtrs[i]->comment, comment);
2753 ServicePtrs[i]->autoloaded = true;
2758 /***************************************************************************
2759 Have we loaded a services file yet?
2760 ***************************************************************************/
2762 bool lp_loaded(void)
2767 /***************************************************************************
2768 Unload unused services.
2769 ***************************************************************************/
2771 void lp_killunused(struct smbd_server_connection *sconn,
2772 bool (*snumused) (struct smbd_server_connection *, int))
2775 for (i = 0; i < iNumServices; i++) {
2779 /* don't kill autoloaded or usershare services */
2780 if ( ServicePtrs[i]->autoloaded ||
2781 ServicePtrs[i]->usershare == USERSHARE_VALID) {
2785 if (!snumused || !snumused(sconn, i)) {
2786 free_service_byindex(i);
2792 * Kill all except autoloaded and usershare services - convenience wrapper
2794 void lp_kill_all_services(void)
2796 lp_killunused(NULL, NULL);
2799 /***************************************************************************
2801 ***************************************************************************/
2803 void lp_killservice(int iServiceIn)
2805 if (VALID(iServiceIn)) {
2806 free_service_byindex(iServiceIn);
2810 /***************************************************************************
2811 Save the curent values of all global and sDefault parameters into the
2812 defaults union. This allows testparm to show only the
2813 changed (ie. non-default) parameters.
2814 ***************************************************************************/
2816 static void lp_save_defaults(void)
2819 struct parmlist_entry * parm;
2820 for (i = 0; parm_table[i].label; i++) {
2821 if (!(flags_list[i] & FLAG_CMDLINE)) {
2822 flags_list[i] |= FLAG_DEFAULT;
2825 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
2826 && parm_table[i].p_class == parm_table[i - 1].p_class)
2828 switch (parm_table[i].type) {
2831 parm_table[i].def.lvalue = str_list_copy(
2832 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
2838 &parm_table[i].def.svalue,
2839 *(char **)lp_parm_ptr(
2840 NULL, &parm_table[i]));
2841 if (parm_table[i].def.svalue == NULL) {
2842 smb_panic("lpcfg_string_set() failed");
2847 parm_table[i].def.bvalue =
2848 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
2851 parm_table[i].def.cvalue =
2852 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
2858 parm_table[i].def.ivalue =
2859 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
2864 for (parm=Globals.param_opt; parm; parm=parm->next) {
2865 if (!(parm->priority & FLAG_CMDLINE)) {
2866 parm->priority |= FLAG_DEFAULT;
2870 for (parm=sDefault.param_opt; parm; parm=parm->next) {
2871 if (!(parm->priority & FLAG_CMDLINE)) {
2872 parm->priority |= FLAG_DEFAULT;
2876 defaults_saved = true;
2879 /***********************************************************
2880 If we should send plaintext/LANMAN passwords in the clinet
2881 ************************************************************/
2883 static void set_allowed_client_auth(void)
2885 if (Globals.client_ntlmv2_auth) {
2886 Globals.client_lanman_auth = false;
2888 if (!Globals.client_lanman_auth) {
2889 Globals.client_plaintext_auth = false;
2893 /***************************************************************************
2895 The following code allows smbd to read a user defined share file.
2896 Yes, this is my intent. Yes, I'm comfortable with that...
2898 THE FOLLOWING IS SECURITY CRITICAL CODE.
2900 It washes your clothes, it cleans your house, it guards you while you sleep...
2901 Do not f%^k with it....
2902 ***************************************************************************/
2904 #define MAX_USERSHARE_FILE_SIZE (10*1024)
2906 /***************************************************************************
2907 Check allowed stat state of a usershare file.
2908 Ensure we print out who is dicking with us so the admin can
2909 get their sorry ass fired.
2910 ***************************************************************************/
2912 static bool check_usershare_stat(const char *fname,
2913 const SMB_STRUCT_STAT *psbuf)
2915 if (!S_ISREG(psbuf->st_ex_mode)) {
2916 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2917 "not a regular file\n",
2918 fname, (unsigned int)psbuf->st_ex_uid ));
2922 /* Ensure this doesn't have the other write bit set. */
2923 if (psbuf->st_ex_mode & S_IWOTH) {
2924 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
2925 "public write. Refusing to allow as a usershare file.\n",
2926 fname, (unsigned int)psbuf->st_ex_uid ));
2930 /* Should be 10k or less. */
2931 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
2932 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2933 "too large (%u) to be a user share file.\n",
2934 fname, (unsigned int)psbuf->st_ex_uid,
2935 (unsigned int)psbuf->st_ex_size ));
2942 /***************************************************************************
2943 Parse the contents of a usershare file.
2944 ***************************************************************************/
2946 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
2947 SMB_STRUCT_STAT *psbuf,
2948 const char *servicename,
2952 char **pp_sharepath,
2954 char **pp_cp_servicename,
2955 struct security_descriptor **ppsd,
2958 const char **prefixallowlist = lp_usershare_prefix_allow_list();
2959 const char **prefixdenylist = lp_usershare_prefix_deny_list();
2962 SMB_STRUCT_STAT sbuf;
2963 char *sharepath = NULL;
2964 char *comment = NULL;
2966 *pp_sharepath = NULL;
2969 *pallow_guest = false;
2972 return USERSHARE_MALFORMED_FILE;
2975 if (strcmp(lines[0], "#VERSION 1") == 0) {
2977 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
2980 return USERSHARE_MALFORMED_FILE;
2983 return USERSHARE_BAD_VERSION;
2986 if (strncmp(lines[1], "path=", 5) != 0) {
2987 return USERSHARE_MALFORMED_PATH;
2990 sharepath = talloc_strdup(ctx, &lines[1][5]);
2992 return USERSHARE_POSIX_ERR;
2994 trim_string(sharepath, " ", " ");
2996 if (strncmp(lines[2], "comment=", 8) != 0) {
2997 return USERSHARE_MALFORMED_COMMENT_DEF;
3000 comment = talloc_strdup(ctx, &lines[2][8]);
3002 return USERSHARE_POSIX_ERR;
3004 trim_string(comment, " ", " ");
3005 trim_char(comment, '"', '"');
3007 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3008 return USERSHARE_MALFORMED_ACL_DEF;
3011 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3012 return USERSHARE_ACL_ERR;
3016 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3017 return USERSHARE_MALFORMED_ACL_DEF;
3019 if (lines[4][9] == 'y') {
3020 *pallow_guest = true;
3023 /* Backwards compatible extension to file version #2. */
3025 if (strncmp(lines[5], "sharename=", 10) != 0) {
3026 return USERSHARE_MALFORMED_SHARENAME_DEF;
3028 if (!strequal(&lines[5][10], servicename)) {
3029 return USERSHARE_BAD_SHARENAME;
3031 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3032 if (!*pp_cp_servicename) {
3033 return USERSHARE_POSIX_ERR;
3038 if (*pp_cp_servicename == NULL) {
3039 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3040 if (!*pp_cp_servicename) {
3041 return USERSHARE_POSIX_ERR;
3045 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3046 /* Path didn't change, no checks needed. */
3047 *pp_sharepath = sharepath;
3048 *pp_comment = comment;
3049 return USERSHARE_OK;
3052 /* The path *must* be absolute. */
3053 if (sharepath[0] != '/') {
3054 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3055 servicename, sharepath));
3056 return USERSHARE_PATH_NOT_ABSOLUTE;
3059 /* If there is a usershare prefix deny list ensure one of these paths
3060 doesn't match the start of the user given path. */
3061 if (prefixdenylist) {
3063 for ( i=0; prefixdenylist[i]; i++ ) {
3064 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3065 servicename, i, prefixdenylist[i], sharepath ));
3066 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3067 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3068 "usershare prefix deny list entries.\n",
3069 servicename, sharepath));
3070 return USERSHARE_PATH_IS_DENIED;
3075 /* If there is a usershare prefix allow list ensure one of these paths
3076 does match the start of the user given path. */
3078 if (prefixallowlist) {
3080 for ( i=0; prefixallowlist[i]; i++ ) {
3081 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3082 servicename, i, prefixallowlist[i], sharepath ));
3083 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3087 if (prefixallowlist[i] == NULL) {
3088 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3089 "usershare prefix allow list entries.\n",
3090 servicename, sharepath));
3091 return USERSHARE_PATH_NOT_ALLOWED;
3095 /* Ensure this is pointing to a directory. */
3096 dp = opendir(sharepath);
3099 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3100 servicename, sharepath));
3101 return USERSHARE_PATH_NOT_DIRECTORY;
3104 /* Ensure the owner of the usershare file has permission to share
3107 if (sys_stat(sharepath, &sbuf, false) == -1) {
3108 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3109 servicename, sharepath, strerror(errno) ));
3111 return USERSHARE_POSIX_ERR;
3116 if (!S_ISDIR(sbuf.st_ex_mode)) {
3117 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3118 servicename, sharepath ));
3119 return USERSHARE_PATH_NOT_DIRECTORY;
3122 /* Check if sharing is restricted to owner-only. */
3123 /* psbuf is the stat of the usershare definition file,
3124 sbuf is the stat of the target directory to be shared. */
3126 if (lp_usershare_owner_only()) {
3127 /* root can share anything. */
3128 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3129 return USERSHARE_PATH_NOT_ALLOWED;
3133 *pp_sharepath = sharepath;
3134 *pp_comment = comment;
3135 return USERSHARE_OK;
3138 /***************************************************************************
3139 Deal with a usershare file.
3142 -1 - Bad name, invalid contents.
3143 - service name already existed and not a usershare, problem
3144 with permissions to share directory etc.
3145 ***************************************************************************/
3147 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3149 SMB_STRUCT_STAT sbuf;
3150 SMB_STRUCT_STAT lsbuf;
3152 char *sharepath = NULL;
3153 char *comment = NULL;
3154 char *cp_service_name = NULL;
3155 char **lines = NULL;
3159 TALLOC_CTX *ctx = talloc_stackframe();
3160 struct security_descriptor *psd = NULL;
3161 bool guest_ok = false;
3162 char *canon_name = NULL;
3163 bool added_service = false;
3166 /* Ensure share name doesn't contain invalid characters. */
3167 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3168 DEBUG(0,("process_usershare_file: share name %s contains "
3169 "invalid characters (any of %s)\n",
3170 file_name, INVALID_SHARENAME_CHARS ));
3174 canon_name = canonicalize_servicename(ctx, file_name);
3179 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3184 /* Minimize the race condition by doing an lstat before we
3185 open and fstat. Ensure this isn't a symlink link. */
3187 if (sys_lstat(fname, &lsbuf, false) != 0) {
3188 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3189 fname, strerror(errno) ));
3193 /* This must be a regular file, not a symlink, directory or
3194 other strange filetype. */
3195 if (!check_usershare_stat(fname, &lsbuf)) {
3203 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3208 if (NT_STATUS_IS_OK(status) &&
3209 (data.dptr != NULL) &&
3210 (data.dsize == sizeof(iService))) {
3211 memcpy(&iService, data.dptr, sizeof(iService));
3215 if (iService != -1 &&
3216 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3217 &lsbuf.st_ex_mtime) == 0) {
3218 /* Nothing changed - Mark valid and return. */
3219 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3221 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3226 /* Try and open the file read only - no symlinks allowed. */
3228 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3230 fd = open(fname, O_RDONLY, 0);
3234 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3235 fname, strerror(errno) ));
3239 /* Now fstat to be *SURE* it's a regular file. */
3240 if (sys_fstat(fd, &sbuf, false) != 0) {
3242 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3243 fname, strerror(errno) ));
3247 /* Is it the same dev/inode as was lstated ? */
3248 if (!check_same_stat(&lsbuf, &sbuf)) {
3250 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3251 "Symlink spoofing going on ?\n", fname ));
3255 /* This must be a regular file, not a symlink, directory or
3256 other strange filetype. */
3257 if (!check_usershare_stat(fname, &sbuf)) {
3262 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3265 if (lines == NULL) {
3266 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3267 fname, (unsigned int)sbuf.st_ex_uid ));
3271 if (parse_usershare_file(ctx, &sbuf, file_name,
3272 iService, lines, numlines, &sharepath,
3273 &comment, &cp_service_name,
3274 &psd, &guest_ok) != USERSHARE_OK) {
3278 /* Everything ok - add the service possibly using a template. */
3280 const struct loadparm_service *sp = &sDefault;
3281 if (snum_template != -1) {
3282 sp = ServicePtrs[snum_template];
3285 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3286 DEBUG(0, ("process_usershare_file: Failed to add "
3287 "new service %s\n", cp_service_name));
3291 added_service = true;
3293 /* Read only is controlled by usershare ACL below. */
3294 ServicePtrs[iService]->read_only = false;
3297 /* Write the ACL of the new/modified share. */
3298 if (!set_share_security(canon_name, psd)) {
3299 DEBUG(0, ("process_usershare_file: Failed to set share "
3300 "security for user share %s\n",
3305 /* If from a template it may be marked invalid. */
3306 ServicePtrs[iService]->valid = true;
3308 /* Set the service as a valid usershare. */
3309 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3311 /* Set guest access. */
3312 if (lp_usershare_allow_guests()) {
3313 ServicePtrs[iService]->guest_ok = guest_ok;
3316 /* And note when it was loaded. */
3317 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3318 lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path,
3320 lpcfg_string_set(ServicePtrs[iService],
3321 &ServicePtrs[iService]->comment, comment);
3327 if (ret == -1 && iService != -1 && added_service) {
3328 lp_remove_service(iService);
3336 /***************************************************************************
3337 Checks if a usershare entry has been modified since last load.
3338 ***************************************************************************/
3340 static bool usershare_exists(int iService, struct timespec *last_mod)
3342 SMB_STRUCT_STAT lsbuf;
3343 const char *usersharepath = Globals.usershare_path;
3346 fname = talloc_asprintf(talloc_tos(),
3349 ServicePtrs[iService]->szService);
3350 if (fname == NULL) {
3354 if (sys_lstat(fname, &lsbuf, false) != 0) {
3359 if (!S_ISREG(lsbuf.st_ex_mode)) {
3365 *last_mod = lsbuf.st_ex_mtime;
3369 /***************************************************************************
3370 Load a usershare service by name. Returns a valid servicenumber or -1.
3371 ***************************************************************************/
3373 int load_usershare_service(const char *servicename)
3375 SMB_STRUCT_STAT sbuf;
3376 const char *usersharepath = Globals.usershare_path;
3377 int max_user_shares = Globals.usershare_max_shares;
3378 int snum_template = -1;
3380 if (*usersharepath == 0 || max_user_shares == 0) {
3384 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3385 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3386 usersharepath, strerror(errno) ));
3390 if (!S_ISDIR(sbuf.st_ex_mode)) {
3391 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3397 * This directory must be owned by root, and have the 't' bit set.
3398 * It also must not be writable by "other".
3402 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3404 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3406 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3407 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3412 /* Ensure the template share exists if it's set. */
3413 if (Globals.usershare_template_share[0]) {
3414 /* We can't use lp_servicenumber here as we are recommending that
3415 template shares have -valid=false set. */
3416 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3417 if (ServicePtrs[snum_template]->szService &&
3418 strequal(ServicePtrs[snum_template]->szService,
3419 Globals.usershare_template_share)) {
3424 if (snum_template == -1) {
3425 DEBUG(0,("load_usershare_service: usershare template share %s "
3426 "does not exist.\n",
3427 Globals.usershare_template_share ));
3432 return process_usershare_file(usersharepath, servicename, snum_template);
3435 /***************************************************************************
3436 Load all user defined shares from the user share directory.
3437 We only do this if we're enumerating the share list.
3438 This is the function that can delete usershares that have
3440 ***************************************************************************/
3442 int load_usershare_shares(struct smbd_server_connection *sconn,
3443 bool (*snumused) (struct smbd_server_connection *, int))
3446 SMB_STRUCT_STAT sbuf;
3448 int num_usershares = 0;
3449 int max_user_shares = Globals.usershare_max_shares;
3450 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3451 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3452 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3454 int snum_template = -1;
3455 const char *usersharepath = Globals.usershare_path;
3456 int ret = lp_numservices();
3457 TALLOC_CTX *tmp_ctx;
3459 if (max_user_shares == 0 || *usersharepath == '\0') {
3460 return lp_numservices();
3463 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3464 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3465 usersharepath, strerror(errno) ));
3470 * This directory must be owned by root, and have the 't' bit set.
3471 * It also must not be writable by "other".
3475 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3477 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3479 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3480 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3485 /* Ensure the template share exists if it's set. */
3486 if (Globals.usershare_template_share[0]) {
3487 /* We can't use lp_servicenumber here as we are recommending that
3488 template shares have -valid=false set. */
3489 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3490 if (ServicePtrs[snum_template]->szService &&
3491 strequal(ServicePtrs[snum_template]->szService,
3492 Globals.usershare_template_share)) {
3497 if (snum_template == -1) {
3498 DEBUG(0,("load_usershare_shares: usershare template share %s "
3499 "does not exist.\n",
3500 Globals.usershare_template_share ));
3505 /* Mark all existing usershares as pending delete. */
3506 for (iService = iNumServices - 1; iService >= 0; iService--) {
3507 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3508 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3512 dp = opendir(usersharepath);
3514 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3515 usersharepath, strerror(errno) ));
3519 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3521 num_dir_entries++ ) {
3523 const char *n = de->d_name;
3525 /* Ignore . and .. */
3527 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3533 /* Temporary file used when creating a share. */
3534 num_tmp_dir_entries++;
3537 /* Allow 20% tmp entries. */
3538 if (num_tmp_dir_entries > allowed_tmp_entries) {
3539 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3540 "in directory %s\n",
3541 num_tmp_dir_entries, usersharepath));
3545 r = process_usershare_file(usersharepath, n, snum_template);
3547 /* Update the services count. */
3549 if (num_usershares >= max_user_shares) {
3550 DEBUG(0,("load_usershare_shares: max user shares reached "
3551 "on file %s in directory %s\n",
3552 n, usersharepath ));
3555 } else if (r == -1) {
3556 num_bad_dir_entries++;
3559 /* Allow 20% bad entries. */
3560 if (num_bad_dir_entries > allowed_bad_entries) {
3561 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3562 "in directory %s\n",
3563 num_bad_dir_entries, usersharepath));
3567 /* Allow 20% bad entries. */
3568 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3569 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3570 "in directory %s\n",
3571 num_dir_entries, usersharepath));
3578 /* Sweep through and delete any non-refreshed usershares that are
3579 not currently in use. */
3580 tmp_ctx = talloc_stackframe();
3581 for (iService = iNumServices - 1; iService >= 0; iService--) {
3582 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3585 if (snumused && snumused(sconn, iService)) {
3589 servname = lp_servicename(tmp_ctx, iService);
3591 /* Remove from the share ACL db. */
3592 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3594 delete_share_security(servname);
3595 free_service_byindex(iService);
3598 talloc_free(tmp_ctx);
3600 return lp_numservices();
3603 /********************************************************
3604 Destroy global resources allocated in this file
3605 ********************************************************/
3607 void gfree_loadparm(void)
3613 /* Free resources allocated to services */
3615 for ( i = 0; i < iNumServices; i++ ) {
3617 free_service_byindex(i);
3621 TALLOC_FREE( ServicePtrs );
3624 /* Now release all resources allocated to global
3625 parameters and the default service */
3627 free_global_parameters();
3631 /***************************************************************************
3632 Allow client apps to specify that they are a client
3633 ***************************************************************************/
3634 static void lp_set_in_client(bool b)
3640 /***************************************************************************
3641 Determine if we're running in a client app
3642 ***************************************************************************/
3643 static bool lp_is_in_client(void)
3648 static void lp_enforce_ad_dc_settings(void)
3650 lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3651 lp_do_parameter(GLOBAL_SECTION_SNUM,
3652 "winbindd:use external pipes", "true");
3653 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
3654 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
3655 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
3656 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
3657 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
3658 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
3659 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
3660 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
3661 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
3664 /***************************************************************************
3665 Load the services array from the services file. Return true on success,
3667 ***************************************************************************/
3669 static bool lp_load_ex(const char *pszFname,
3673 bool reinit_globals,
3674 bool allow_include_registry,
3675 bool load_all_shares)
3679 TALLOC_CTX *frame = talloc_stackframe();
3680 struct loadparm_context *lp_ctx;
3684 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3686 bInGlobalSection = true;
3687 bGlobalOnly = global_only;
3688 bAllowIncludeRegistry = allow_include_registry;
3690 lp_ctx = setup_lp_context(talloc_tos());
3692 init_globals(lp_ctx, reinit_globals);
3696 if (save_defaults) {
3701 if (!reinit_globals) {
3702 free_param_opts(&Globals.param_opt);
3703 apply_lp_set_cmdline();
3706 lp_do_parameter(-1, "idmap config * : backend", Globals.idmap_backend);
3708 /* We get sections first, so have to start 'behind' to make up */
3711 if (lp_config_backend_is_file()) {
3712 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
3713 current_user_info.domain,
3716 smb_panic("lp_load_ex: out of memory");
3719 add_to_file_list(NULL, &file_lists, pszFname, n2);
3721 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
3724 /* finish up the last section */
3725 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3727 if (iServiceIndex >= 0) {
3728 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
3732 if (lp_config_backend_is_registry()) {
3734 /* config backend changed to registry in config file */
3736 * We need to use this extra global variable here to
3737 * survive restart: init_globals uses this as a default
3738 * for config_backend. Otherwise, init_globals would
3739 * send us into an endless loop here.
3742 config_backend = CONFIG_BACKEND_REGISTRY;
3744 DEBUG(1, ("lp_load_ex: changing to config backend "
3746 init_globals(lp_ctx, true);
3748 TALLOC_FREE(lp_ctx);
3750 lp_kill_all_services();
3751 ok = lp_load_ex(pszFname, global_only, save_defaults,
3752 add_ipc, reinit_globals,
3753 allow_include_registry,
3758 } else if (lp_config_backend_is_registry()) {
3759 bRetval = process_registry_globals();
3761 DEBUG(0, ("Illegal config backend given: %d\n",
3762 lp_config_backend()));
3766 if (bRetval && lp_registry_shares()) {
3767 if (load_all_shares) {
3768 bRetval = process_registry_shares();
3770 bRetval = reload_registry_shares();
3775 char *serv = lp_auto_services(talloc_tos());
3776 lp_add_auto_services(serv);
3781 /* When 'restrict anonymous = 2' guest connections to ipc$
3783 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3784 if ( lp_enable_asu_support() ) {
3785 lp_add_ipc("ADMIN$", false);
3789 set_allowed_client_auth();
3791 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
3792 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
3793 lp_password_server()));
3798 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
3799 /* if we_are_a_wins_server is true and we are in the client */
3800 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
3801 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3806 fault_configure(smb_panic_s3);
3809 * We run this check once the whole smb.conf is parsed, to
3810 * force some settings for the standard way a AD DC is
3811 * operated. We may change these as our code evolves, which
3812 * is why we force these settings.
3814 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3815 lp_enforce_ad_dc_settings();
3818 bAllowIncludeRegistry = true;
3824 static bool lp_load(const char *pszFname,
3828 bool reinit_globals)
3830 return lp_load_ex(pszFname,
3835 true, /* allow_include_registry */
3836 false); /* load_all_shares*/
3839 bool lp_load_initial_only(const char *pszFname)
3841 return lp_load_ex(pszFname,
3842 true, /* global only */
3843 true, /* save_defaults */
3844 false, /* add_ipc */
3845 true, /* reinit_globals */
3846 false, /* allow_include_registry */
3847 false); /* load_all_shares*/
3851 * most common lp_load wrapper, loading only the globals
3853 bool lp_load_global(const char *file_name)
3855 return lp_load(file_name,
3856 true, /* global_only */
3857 false, /* save_defaults */
3858 false, /* add_ipc */
3859 true); /* reinit_globals */
3863 * The typical lp_load wrapper with shares, loads global and
3864 * shares, including IPC, but does not force immediate
3865 * loading of all shares from registry.
3867 bool lp_load_with_shares(const char *file_name)
3869 return lp_load(file_name,
3870 false, /* global_only */
3871 false, /* save_defaults */
3873 true); /* reinit_globals */
3877 * lp_load wrapper, especially for clients
3879 bool lp_load_client(const char *file_name)
3881 lp_set_in_client(true);
3883 return lp_load_global(file_name);
3887 * lp_load wrapper, loading only globals, but intended
3888 * for subsequent calls, not reinitializing the globals
3891 bool lp_load_global_no_reinit(const char *file_name)
3893 return lp_load(file_name,
3894 true, /* global_only */
3895 false, /* save_defaults */
3896 false, /* add_ipc */
3897 false); /* reinit_globals */
3901 * lp_load wrapper, loading globals and shares,
3902 * intended for subsequent calls, i.e. not reinitializing
3903 * the globals to default values.
3905 bool lp_load_no_reinit(const char *file_name)
3907 return lp_load(file_name,
3908 false, /* global_only */
3909 false, /* save_defaults */
3910 false, /* add_ipc */
3911 false); /* reinit_globals */
3916 * lp_load wrapper, especially for clients, no reinitialization
3918 bool lp_load_client_no_reinit(const char *file_name)
3920 lp_set_in_client(true);
3922 return lp_load_global_no_reinit(file_name);
3925 bool lp_load_with_registry_shares(const char *pszFname)
3927 return lp_load_ex(pszFname,
3928 false, /* global_only */
3929 true, /* save_defaults */
3930 false, /* add_ipc */
3931 false, /* reinit_globals */
3932 true, /* allow_include_registry */
3933 true); /* load_all_shares*/
3936 /***************************************************************************
3937 Return the max number of services.
3938 ***************************************************************************/
3940 int lp_numservices(void)
3942 return (iNumServices);
3945 /***************************************************************************
3946 Display the contents of the services array in human-readable form.
3947 ***************************************************************************/
3949 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
3952 struct loadparm_context *lp_ctx;
3955 defaults_saved = false;
3957 lp_ctx = setup_lp_context(talloc_tos());
3958 if (lp_ctx == NULL) {
3962 lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
3964 lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
3966 for (iService = 0; iService < maxtoprint; iService++) {
3968 lp_dump_one(f, show_defaults, iService);
3972 /***************************************************************************
3973 Display the contents of one service in human-readable form.
3974 ***************************************************************************/
3976 void lp_dump_one(FILE * f, bool show_defaults, int snum)
3979 if (ServicePtrs[snum]->szService[0] == '\0')
3981 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
3982 flags_list, show_defaults);
3986 /***************************************************************************
3987 Return the number of the service with the given name, or -1 if it doesn't
3988 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3989 getservicebyname()! This works ONLY if all services have been loaded, and
3990 does not copy the found service.
3991 ***************************************************************************/
3993 int lp_servicenumber(const char *pszServiceName)
3996 fstring serviceName;
3998 if (!pszServiceName) {
3999 return GLOBAL_SECTION_SNUM;
4002 for (iService = iNumServices - 1; iService >= 0; iService--) {
4003 if (VALID(iService) && ServicePtrs[iService]->szService) {
4005 * The substitution here is used to support %U in
4008 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4009 standard_sub_basic(get_current_username(),
4010 current_user_info.domain,
4011 serviceName,sizeof(serviceName));
4012 if (strequal(serviceName, pszServiceName)) {
4018 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4019 struct timespec last_mod;
4021 if (!usershare_exists(iService, &last_mod)) {
4022 /* Remove the share security tdb entry for it. */
4023 delete_share_security(lp_servicename(talloc_tos(), iService));
4024 /* Remove it from the array. */
4025 free_service_byindex(iService);
4026 /* Doesn't exist anymore. */
4027 return GLOBAL_SECTION_SNUM;
4030 /* Has it been modified ? If so delete and reload. */
4031 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4033 /* Remove it from the array. */
4034 free_service_byindex(iService);
4035 /* and now reload it. */
4036 iService = load_usershare_service(pszServiceName);
4041 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4042 return GLOBAL_SECTION_SNUM;
4048 /*******************************************************************
4049 A useful volume label function.
4050 ********************************************************************/
4052 const char *volume_label(TALLOC_CTX *ctx, int snum)
4055 const char *label = lp_volume(ctx, snum);
4057 label = lp_servicename(ctx, snum);
4060 /* This returns a 33 byte guarenteed null terminated string. */
4061 ret = talloc_strndup(ctx, label, 32);
4068 /*******************************************************************
4069 Get the default server type we will announce as via nmbd.
4070 ********************************************************************/
4072 int lp_default_server_announce(void)
4074 int default_server_announce = 0;
4075 default_server_announce |= SV_TYPE_WORKSTATION;
4076 default_server_announce |= SV_TYPE_SERVER;
4077 default_server_announce |= SV_TYPE_SERVER_UNIX;
4079 /* note that the flag should be set only if we have a
4080 printer service but nmbd doesn't actually load the
4081 services so we can't tell --jerry */
4083 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4085 default_server_announce |= SV_TYPE_SERVER_NT;
4086 default_server_announce |= SV_TYPE_NT;
4088 switch (lp_server_role()) {
4089 case ROLE_DOMAIN_MEMBER:
4090 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4092 case ROLE_DOMAIN_PDC:
4093 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4095 case ROLE_DOMAIN_BDC:
4096 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4098 case ROLE_STANDALONE:
4102 if (lp_time_server())
4103 default_server_announce |= SV_TYPE_TIME_SOURCE;
4105 if (lp_host_msdfs())
4106 default_server_announce |= SV_TYPE_DFS_SERVER;
4108 return default_server_announce;
4111 /***********************************************************
4112 If we are PDC then prefer us as DMB
4113 ************************************************************/
4115 bool lp_domain_master(void)
4117 if (Globals._domain_master == Auto)
4118 return (lp_server_role() == ROLE_DOMAIN_PDC);
4120 return (bool)Globals._domain_master;
4123 /***********************************************************
4124 If we are PDC then prefer us as DMB
4125 ************************************************************/
4127 static bool lp_domain_master_true_or_auto(void)
4129 if (Globals._domain_master) /* auto or yes */
4135 /***********************************************************
4136 If we are DMB then prefer us as LMB
4137 ************************************************************/
4139 bool lp_preferred_master(void)
4141 int preferred_master = lp__preferred_master();
4143 if (preferred_master == Auto)
4144 return (lp_local_master() && lp_domain_master());
4146 return (bool)preferred_master;
4149 /*******************************************************************
4151 ********************************************************************/
4153 void lp_remove_service(int snum)
4155 ServicePtrs[snum]->valid = false;
4158 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4160 const char *ret = lp__printername(ctx, snum);
4161 if (ret == NULL || *ret == '\0') {
4162 ret = lp_const_servicename(snum);
4169 /***********************************************************
4170 Allow daemons such as winbindd to fix their logfile name.
4171 ************************************************************/
4173 void lp_set_logfile(const char *name)
4175 lpcfg_string_set(Globals.ctx, &Globals.logfile, name);
4176 debug_set_logfile(name);
4179 /*******************************************************************
4180 Return the max print jobs per queue.
4181 ********************************************************************/
4183 int lp_maxprintjobs(int snum)
4185 int maxjobs = lp_max_print_jobs(snum);
4187 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4188 maxjobs = PRINT_MAX_JOBID - 1;
4193 const char *lp_printcapname(void)
4195 const char *printcap_name = lp_printcap_name();
4197 if ((printcap_name != NULL) &&
4198 (printcap_name[0] != '\0'))
4199 return printcap_name;
4201 if (sDefault.printing == PRINT_CUPS) {
4205 if (sDefault.printing == PRINT_BSD)
4206 return "/etc/printcap";
4208 return PRINTCAP_NAME;
4211 static uint32_t spoolss_state;
4213 bool lp_disable_spoolss( void )
4215 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4216 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4218 return spoolss_state == SVCCTL_STOPPED ? true : false;
4221 void lp_set_spoolss_state( uint32_t state )
4223 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4225 spoolss_state = state;
4228 uint32_t lp_get_spoolss_state( void )
4230 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4233 /*******************************************************************
4234 Ensure we don't use sendfile if server smb signing is active.
4235 ********************************************************************/
4237 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4239 bool sign_active = false;
4241 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4242 if (get_Protocol() < PROTOCOL_NT1) {
4245 if (signing_state) {
4246 sign_active = smb_signing_is_active(signing_state);
4248 return (lp__use_sendfile(snum) &&
4249 (get_remote_arch() != RA_WIN95) &&
4253 /*******************************************************************
4254 Turn off sendfile if we find the underlying OS doesn't support it.
4255 ********************************************************************/
4257 void set_use_sendfile(int snum, bool val)
4259 if (LP_SNUM_OK(snum))
4260 ServicePtrs[snum]->_use_sendfile = val;
4262 sDefault._use_sendfile = val;
4265 /*******************************************************************
4266 Turn off storing DOS attributes if this share doesn't support it.
4267 ********************************************************************/
4269 void set_store_dos_attributes(int snum, bool val)
4271 if (!LP_SNUM_OK(snum))
4273 ServicePtrs[(snum)]->store_dos_attributes = val;
4276 void lp_set_mangling_method(const char *new_method)
4278 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method);
4281 /*******************************************************************
4282 Global state for POSIX pathname processing.
4283 ********************************************************************/
4285 static bool posix_pathnames;
4287 bool lp_posix_pathnames(void)
4289 return posix_pathnames;
4292 /*******************************************************************
4293 Change everything needed to ensure POSIX pathname processing (currently
4295 ********************************************************************/
4297 void lp_set_posix_pathnames(void)
4299 posix_pathnames = true;
4302 /*******************************************************************
4303 Global state for POSIX lock processing - CIFS unix extensions.
4304 ********************************************************************/
4306 bool posix_default_lock_was_set;
4307 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4309 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4311 if (posix_default_lock_was_set) {
4312 return posix_cifsx_locktype;
4314 return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
4315 POSIX_LOCK : WINDOWS_LOCK;
4319 /*******************************************************************
4320 ********************************************************************/
4322 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4324 posix_default_lock_was_set = true;
4325 posix_cifsx_locktype = val;
4328 int lp_min_receive_file_size(void)
4330 int min_receivefile_size = lp_min_receivefile_size();
4332 if (min_receivefile_size < 0) {
4335 return min_receivefile_size;
4338 /*******************************************************************
4339 Safe wide links checks.
4340 This helper function always verify the validity of wide links,
4341 even after a configuration file reload.
4342 ********************************************************************/
4344 void widelinks_warning(int snum)
4346 if (lp_allow_insecure_wide_links()) {
4350 if (lp_unix_extensions() && lp_wide_links(snum)) {
4351 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4352 "These parameters are incompatible. "
4353 "Wide links will be disabled for this share.\n",
4354 lp_servicename(talloc_tos(), snum) ));
4358 bool lp_widelinks(int snum)
4360 /* wide links is always incompatible with unix extensions */
4361 if (lp_unix_extensions()) {
4363 * Unless we have "allow insecure widelinks"
4366 if (!lp_allow_insecure_wide_links()) {
4371 return lp_wide_links(snum);
4374 int lp_server_role(void)
4376 return lp_find_server_role(lp__server_role(),
4378 lp__domain_logons(),
4379 lp_domain_master_true_or_auto());
4382 int lp_security(void)
4384 return lp_find_security(lp__server_role(),
4388 int lp_client_max_protocol(void)
4390 int client_max_protocol = lp__client_max_protocol();
4391 if (client_max_protocol == PROTOCOL_DEFAULT) {
4392 return PROTOCOL_NT1;
4394 return client_max_protocol;
4397 int lp_winbindd_max_protocol(void)
4399 int client_max_protocol = lp__client_max_protocol();
4400 if (client_max_protocol == PROTOCOL_DEFAULT) {
4401 return PROTOCOL_LATEST;
4403 return client_max_protocol;
4406 struct loadparm_global * get_globals(void)
4411 unsigned int * get_flags(void)
4413 if (flags_list == NULL) {
4414 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());