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>
78 #ifdef HAVE_HTTPCONNECTENCRYPT
79 #include <cups/http.h>
84 extern userdom_struct current_user_info;
86 /* the special value for the include parameter
87 * to be interpreted not as a file name but to
88 * trigger loading of the global smb.conf options
90 #ifndef INCLUDE_REGISTRY_NAME
91 #define INCLUDE_REGISTRY_NAME "registry"
94 static bool in_client = false; /* Not in the client by default */
95 static struct smbconf_csn conf_last_csn;
97 static int config_backend = CONFIG_BACKEND_FILE;
99 /* some helpful bits */
100 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
101 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
103 #define USERSHARE_VALID 1
104 #define USERSHARE_PENDING_DELETE 2
106 static bool defaults_saved = false;
108 #include "lib/param/param_global.h"
110 static struct loadparm_global Globals;
112 /* This is a default service used to prime a services structure */
113 static struct loadparm_service sDefault =
118 .usershare_last_mod = {0, 0},
122 .invalid_users = NULL,
129 .root_preexec = NULL,
130 .root_postexec = NULL,
131 .cups_options = NULL,
132 .print_command = NULL,
134 .lprm_command = NULL,
135 .lppause_command = NULL,
136 .lpresume_command = NULL,
137 .queuepause_command = NULL,
138 .queueresume_command = NULL,
139 ._printername = NULL,
140 .printjob_username = NULL,
141 .dont_descend = NULL,
144 .magic_script = NULL,
145 .magic_output = NULL,
148 .veto_oplock_files = NULL,
158 .aio_write_behind = NULL,
159 .dfree_command = NULL,
160 .min_print_space = 0,
161 .iMaxPrintJobs = 1000,
162 .max_reported_print_jobs = 0,
163 .write_cache_size = 0,
165 .force_create_mode = 0,
166 .directory_mask = 0755,
167 .force_directory_mode = 0,
168 .max_connections = 0,
169 .default_case = CASE_LOWER,
170 .printing = DEFAULT_PRINTING,
171 .oplock_contention_limit = 2,
174 .dfree_cache_time = 0,
175 .preexec_close = false,
176 .root_preexec_close = false,
177 .case_sensitive = Auto,
178 .preserve_case = true,
179 .short_preserve_case = true,
180 .hide_dot_files = true,
181 .hide_special_files = false,
182 .hide_unreadable = false,
183 .hide_unwriteable_files = false,
185 .access_based_share_enum = false,
190 .administrative_share = false,
193 .print_notify_backchannel = false,
197 .store_dos_attributes = false,
198 .dmapi_support = false,
200 .strict_locking = Auto,
201 .posix_locking = true,
203 .kernel_oplocks = false,
204 .level2_oplocks = true,
206 .mangled_names = true,
208 .follow_symlinks = true,
209 .sync_always = false,
210 .strict_allocate = false,
211 .strict_rename = false,
212 .strict_sync = false,
213 .mangling_char = '~',
215 .delete_readonly = false,
216 .fake_oplocks = false,
217 .delete_veto_files = false,
218 .dos_filemode = false,
219 .dos_filetimes = true,
220 .dos_filetime_resolution = false,
221 .fake_directory_create_times = false,
222 .blocking_locks = true,
223 .inherit_permissions = false,
224 .inherit_acls = false,
225 .inherit_owner = false,
227 .msdfs_shuffle_referrals = false,
228 .use_client_driver = false,
229 .default_devmode = true,
230 .force_printername = false,
231 .nt_acl_support = true,
232 .force_unknown_acl_user = false,
233 ._use_sendfile = false,
234 .profile_acls = false,
235 .map_acl_inherit = false,
238 .acl_check_permissions = true,
239 .acl_map_full_control = true,
240 .acl_group_control = false,
241 .acl_allow_execute_always = false,
242 .change_notify = true,
243 .kernel_change_notify = true,
244 .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
247 .map_readonly = MAP_READONLY_YES,
248 .directory_name_cache_size = 100,
249 .smb_encrypt = SMB_SIGNING_DEFAULT,
250 .kernel_share_modes = true,
251 .durable_handles = true,
256 /* local variables */
257 static struct loadparm_service **ServicePtrs = NULL;
258 static int iNumServices = 0;
259 static int iServiceIndex = 0;
260 static struct db_context *ServiceHash;
261 static bool bInGlobalSection = true;
262 static bool bGlobalOnly = false;
263 static struct file_lists *file_lists = NULL;
264 static unsigned int *flags_list = NULL;
266 static void set_allowed_client_auth(void);
268 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
269 static void free_param_opts(struct parmlist_entry **popts);
271 /* this is used to prevent lots of mallocs of size 1 */
272 static const char null_string[] = "";
278 static void string_free(char **s)
282 if (*s == null_string)
288 Set a string value, deallocating any existing space, and allocing the space
292 static bool string_set(TALLOC_CTX *mem_ctx, char **dest,const char *src)
300 (*dest) = talloc_strdup(mem_ctx, src);
301 if ((*dest) == NULL) {
302 DEBUG(0,("Out of memory in string_init\n"));
310 * Function to return the default value for the maximum number of open
311 * file descriptors permitted. This function tries to consult the
312 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
313 * the smaller of those.
315 static int max_open_files(void)
317 int sysctl_max = MAX_OPEN_FILES;
318 int rlimit_max = MAX_OPEN_FILES;
320 #ifdef HAVE_SYSCTLBYNAME
322 size_t size = sizeof(sysctl_max);
323 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
328 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
334 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
335 rlimit_max = rl.rlim_cur;
337 #if defined(RLIM_INFINITY)
338 if(rl.rlim_cur == RLIM_INFINITY)
339 rlimit_max = MAX_OPEN_FILES;
344 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
345 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
346 "minimum Windows limit (%d)\n",
348 MIN_OPEN_FILES_WINDOWS));
349 sysctl_max = MIN_OPEN_FILES_WINDOWS;
352 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
353 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
354 "minimum Windows limit (%d)\n",
356 MIN_OPEN_FILES_WINDOWS));
357 rlimit_max = MIN_OPEN_FILES_WINDOWS;
360 return MIN(sysctl_max, rlimit_max);
364 * Common part of freeing allocated data for one parameter.
366 static void free_one_parameter_common(void *parm_ptr,
367 struct parm_struct parm)
369 if ((parm.type == P_STRING) ||
370 (parm.type == P_USTRING))
372 string_free((char**)parm_ptr);
373 } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
374 TALLOC_FREE(*((char***)parm_ptr));
379 * Free the allocated data for one parameter for a share
380 * given as a service struct.
382 static void free_one_parameter(struct loadparm_service *service,
383 struct parm_struct parm)
387 if (parm.p_class != P_LOCAL) {
391 parm_ptr = lp_parm_ptr(service, &parm);
393 free_one_parameter_common(parm_ptr, parm);
397 * Free the allocated parameter data of a share given
398 * as a service struct.
400 static void free_parameters(struct loadparm_service *service)
404 for (i=0; parm_table[i].label; i++) {
405 free_one_parameter(service, parm_table[i]);
410 * Free the allocated data for one parameter for a given share
411 * specified by an snum.
413 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
418 parm_ptr = lp_parm_ptr(NULL, &parm);
419 } else if (parm.p_class != P_LOCAL) {
422 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
425 free_one_parameter_common(parm_ptr, parm);
429 * Free the allocated parameter data for a share specified
432 static void free_parameters_by_snum(int snum)
436 for (i=0; parm_table[i].label; i++) {
437 free_one_parameter_by_snum(snum, parm_table[i]);
442 * Free the allocated global parameters.
444 static void free_global_parameters(void)
446 free_param_opts(&Globals.param_opt);
447 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
448 TALLOC_FREE(Globals.ctx);
451 struct lp_stored_option {
452 struct lp_stored_option *prev, *next;
457 static struct lp_stored_option *stored_options;
460 save options set by lp_set_cmdline() into a list. This list is
461 re-applied when we do a globals reset, so that cmdline set options
462 are sticky across reloads of smb.conf
464 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
466 struct lp_stored_option *entry, *entry_next;
467 for (entry = stored_options; entry != NULL; entry = entry_next) {
468 entry_next = entry->next;
469 if (strcmp(pszParmName, entry->label) == 0) {
470 DLIST_REMOVE(stored_options, entry);
476 entry = talloc(NULL, struct lp_stored_option);
481 entry->label = talloc_strdup(entry, pszParmName);
487 entry->value = talloc_strdup(entry, pszParmValue);
493 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
498 static bool apply_lp_set_cmdline(void)
500 struct lp_stored_option *entry = NULL;
501 for (entry = stored_options; entry != NULL; entry = entry->next) {
502 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
503 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
504 entry->label, entry->value));
511 /***************************************************************************
512 Initialise the global parameter structure.
513 ***************************************************************************/
515 static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
517 static bool done_init = false;
521 /* If requested to initialize only once and we've already done it... */
522 if (!reinit_globals && done_init) {
523 /* ... then we have nothing more to do */
528 /* The logfile can be set before this is invoked. Free it if so. */
529 if (Globals.logfile != NULL) {
530 string_free(&Globals.logfile);
531 Globals.logfile = NULL;
535 free_global_parameters();
538 /* This memset and the free_global_parameters() above will
539 * wipe out smb.conf options set with lp_set_cmdline(). The
540 * apply_lp_set_cmdline() call puts these values back in the
541 * table once the defaults are set */
542 ZERO_STRUCT(Globals);
544 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
546 /* Initialize the flags list if necessary */
547 if (flags_list == NULL) {
551 for (i = 0; parm_table[i].label; i++) {
552 if ((parm_table[i].type == P_STRING ||
553 parm_table[i].type == P_USTRING))
555 string_set(Globals.ctx, (char **)lp_parm_ptr(NULL, &parm_table[i]), "");
560 string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
561 string_set(Globals.ctx, &sDefault.printjob_username, "%U");
563 init_printer_values(lp_ctx, Globals.ctx, &sDefault);
565 sDefault.ntvfs_handler = str_list_make_v3_const(NULL, "unixuid default", NULL);
567 DEBUG(3, ("Initialising global parameters\n"));
569 /* Must manually force to upper case here, as this does not go via the handler */
570 string_set(Globals.ctx, &Globals.netbios_name, myhostname_upper());
572 string_set(Globals.ctx, &Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
573 string_set(Globals.ctx, &Globals.private_dir, get_dyn_PRIVATE_DIR());
575 /* use the new 'hash2' method by default, with a prefix of 1 */
576 string_set(Globals.ctx, &Globals.mangling_method, "hash2");
577 Globals.mangle_prefix = 1;
579 string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
581 /* using UTF8 by default allows us to support all chars */
582 string_set(Globals.ctx, &Globals.unix_charset, DEFAULT_UNIX_CHARSET);
584 /* Use codepage 850 as a default for the dos character set */
585 string_set(Globals.ctx, &Globals.dos_charset, DEFAULT_DOS_CHARSET);
588 * Allow the default PASSWD_CHAT to be overridden in local.h.
590 string_set(Globals.ctx, &Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
592 string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
594 string_set(Globals.ctx, &Globals.passwd_program, "");
595 string_set(Globals.ctx, &Globals.lock_directory, get_dyn_LOCKDIR());
596 string_set(Globals.ctx, &Globals.state_directory, get_dyn_STATEDIR());
597 string_set(Globals.ctx, &Globals.cache_directory, get_dyn_CACHEDIR());
598 string_set(Globals.ctx, &Globals.pid_directory, get_dyn_PIDDIR());
599 string_set(Globals.ctx, &Globals.nbt_client_socket_address, "0.0.0.0");
601 * By default support explicit binding to broadcast
604 Globals.nmbd_bind_explicit_broadcast = true;
606 s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
608 smb_panic("init_globals: ENOMEM");
610 string_set(Globals.ctx, &Globals.server_string, s);
613 string_set(Globals.ctx, &Globals.panic_action, "/bin/sleep 999999999");
616 string_set(Globals.ctx, &Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
618 string_set(Globals.ctx, &Globals.logon_drive, "");
619 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
620 string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
621 string_set(Globals.ctx, &Globals.logon_path, "\\\\%N\\%U\\profile");
623 Globals.name_resolve_order = str_list_make_v3_const(NULL, "lmhosts wins host bcast", NULL);
624 string_set(Globals.ctx, &Globals.password_server, "*");
626 Globals.algorithmic_rid_base = BASE_RID;
628 Globals.load_printers = true;
629 Globals.printcap_cache_time = 750; /* 12.5 minutes */
631 Globals.config_backend = config_backend;
632 Globals._server_role = ROLE_AUTO;
634 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
635 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
636 Globals.max_xmit = 0x4104;
637 Globals.max_mux = 50; /* This is *needed* for profile support. */
638 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
639 Globals._disable_spoolss = false;
640 Globals.max_smbd_processes = 0;/* no limit specified */
641 Globals.username_level = 0;
642 Globals.deadtime = 0;
643 Globals.getwd_cache = true;
644 Globals.large_readwrite = true;
645 Globals.max_log_size = 5000;
646 Globals.max_open_files = max_open_files();
647 Globals.server_max_protocol = PROTOCOL_SMB3_11;
648 Globals.server_min_protocol = PROTOCOL_LANMAN1;
649 Globals._client_max_protocol = PROTOCOL_DEFAULT;
650 Globals.client_min_protocol = PROTOCOL_CORE;
651 Globals._security = SEC_AUTO;
652 Globals.encrypt_passwords = true;
653 Globals.client_schannel = Auto;
654 Globals.winbind_sealed_pipes = true;
655 Globals.require_strong_key = true;
656 Globals.server_schannel = Auto;
657 Globals.read_raw = true;
658 Globals.write_raw = true;
659 Globals.null_passwords = false;
660 Globals.old_password_allowed_period = 60;
661 Globals.obey_pam_restrictions = false;
663 Globals.syslog_only = false;
664 Globals.timestamp_logs = true;
665 string_set(Globals.ctx, &Globals.log_level, "0");
666 Globals.debug_prefix_timestamp = false;
667 Globals.debug_hires_timestamp = true;
668 Globals.debug_pid = false;
669 Globals.debug_uid = false;
670 Globals.debug_class = false;
671 Globals.enable_core_files = true;
672 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
673 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
674 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
675 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
676 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
677 Globals.lm_interval = 60;
678 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
679 Globals.nis_homedir = false;
680 #ifdef WITH_NISPLUS_HOME
681 string_set(Globals.ctx, &Globals.homedir_map, "auto_home.org_dir");
683 string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
686 Globals.time_server = false;
687 Globals.bind_interfaces_only = false;
688 Globals.unix_password_sync = false;
689 Globals.pam_password_change = false;
690 Globals.passwd_chat_debug = false;
691 Globals.passwd_chat_timeout = 2; /* 2 second default. */
692 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
693 Globals.nt_status_support = true; /* Use NT status by default. */
694 Globals.smbd_profiling_level = 0;
695 Globals.stat_cache = true; /* use stat cache by default */
696 Globals.max_stat_cache_size = 256; /* 256k by default */
697 Globals.restrict_anonymous = 0;
698 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
699 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
700 Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
701 Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
702 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 */
703 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
705 Globals.map_to_guest = 0; /* By Default, "Never" */
706 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
707 Globals.enhanced_browsing = true;
708 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
709 #ifdef MMAP_BLACKLIST
710 Globals.use_mmap = false;
712 Globals.use_mmap = true;
714 Globals.unicode = true;
715 Globals.unix_extensions = true;
716 Globals.reset_on_zero_vc = false;
717 Globals.log_writeable_files_on_exit = false;
718 Globals.create_krb5_conf = true;
719 Globals.winbindMaxDomainConnections = 1;
721 /* hostname lookups can be very expensive and are broken on
722 a large number of sites (tridge) */
723 Globals.hostname_lookups = false;
725 string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
726 string_set(Globals.ctx, &Globals.ldap_suffix, "");
727 string_set(Globals.ctx, &Globals.szLdapMachineSuffix, "");
728 string_set(Globals.ctx, &Globals.szLdapUserSuffix, "");
729 string_set(Globals.ctx, &Globals.szLdapGroupSuffix, "");
730 string_set(Globals.ctx, &Globals.szLdapIdmapSuffix, "");
732 string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
733 Globals.ldap_ssl = LDAP_SSL_START_TLS;
734 Globals.ldap_ssl_ads = false;
735 Globals.ldap_deref = -1;
736 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
737 Globals.ldap_delete_dn = false;
738 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
739 Globals.ldap_follow_referral = Auto;
740 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
741 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
742 Globals.ldap_page_size = LDAP_PAGE_SIZE;
744 Globals.ldap_debug_level = 0;
745 Globals.ldap_debug_threshold = 10;
747 Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
749 /* This is what we tell the afs client. in reality we set the token
750 * to never expire, though, when this runs out the afs client will
751 * forget the token. Set to 0 to get NEVERDATE.*/
752 Globals.afs_token_lifetime = 604800;
753 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
755 /* these parameters are set to defaults that are more appropriate
756 for the increasing samba install base:
758 as a member of the workgroup, that will possibly become a
759 _local_ master browser (lm = true). this is opposed to a forced
760 local master browser startup (pm = true).
762 doesn't provide WINS server service by default (wsupp = false),
763 and doesn't provide domain master browser services by default, either.
767 Globals.show_add_printer_wizard = true;
768 Globals.os_level = 20;
769 Globals.local_master = true;
770 Globals._domain_master = Auto; /* depending on _domain_logons */
771 Globals._domain_logons = false;
772 Globals.browse_list = true;
773 Globals.we_are_a_wins_server = false;
774 Globals.wins_proxy = false;
776 TALLOC_FREE(Globals.init_logon_delayed_hosts);
777 Globals.init_logon_delay = 100; /* 100 ms default delay */
779 Globals.wins_dns_proxy = true;
781 Globals.allow_trusted_domains = true;
782 string_set(Globals.ctx, &Globals.szIdmapBackend, "tdb");
784 string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
785 string_set(Globals.ctx, &Globals.template_homedir, "/home/%D/%U");
786 string_set(Globals.ctx, &Globals.winbind_separator, "\\");
787 string_set(Globals.ctx, &Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
789 string_set(Globals.ctx, &Globals.cups_server, "");
790 string_set(Globals.ctx, &Globals.iprint_server, "");
792 string_set(Globals.ctx, &Globals._ctdbd_socket, "");
794 Globals.cluster_addresses = NULL;
795 Globals.clustering = false;
796 Globals.ctdb_timeout = 0;
797 Globals.ctdb_locktime_warn_threshold = 0;
799 Globals.winbind_cache_time = 300; /* 5 minutes */
800 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
801 Globals.winbind_request_timeout = 60; /* 60 seconds */
802 Globals.winbind_max_clients = 200;
803 Globals.winbind_enum_users = false;
804 Globals.winbind_enum_groups = false;
805 Globals.winbind_use_default_domain = false;
806 Globals.winbind_trusted_domains_only = false;
807 Globals.winbind_nested_groups = true;
808 Globals.winbind_expand_groups = 0;
809 Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
810 Globals.winbind_refresh_tickets = false;
811 Globals.winbind_offline_logon = false;
813 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
814 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
816 Globals.passdb_expand_explicit = false;
818 Globals.name_cache_timeout = 660; /* In seconds */
820 Globals.use_spnego = true;
821 Globals.client_use_spnego = true;
823 Globals.client_signing = SMB_SIGNING_DEFAULT;
824 Globals.server_signing = SMB_SIGNING_DEFAULT;
826 Globals.defer_sharing_violations = true;
827 Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
829 Globals.enable_privileges = true;
830 Globals.host_msdfs = true;
831 Globals.enable_asu_support = false;
833 /* User defined shares. */
834 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
836 smb_panic("init_globals: ENOMEM");
838 string_set(Globals.ctx, &Globals.usershare_path, s);
840 string_set(Globals.ctx, &Globals.usershare_template_share, "");
841 Globals.usershare_max_shares = 0;
842 /* By default disallow sharing of directories not owned by the sharer. */
843 Globals.usershare_owner_only = true;
844 /* By default disallow guest access to usershares. */
845 Globals.usershare_allow_guests = false;
847 Globals.keepalive = DEFAULT_KEEPALIVE;
849 /* By default no shares out of the registry */
850 Globals.registry_shares = false;
852 Globals.iminreceivefile = 0;
854 Globals.map_untrusted_to_domain = false;
855 Globals.multicast_dns_register = true;
857 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
858 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
859 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
860 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
861 Globals.smb2_leases = false;
863 string_set(Globals.ctx, &Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
865 Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
867 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);
869 Globals.tls_enabled = true;
871 string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
872 string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
873 string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
875 string_set(Globals.ctx, &Globals.share_backend, "classic");
877 Globals.iPreferredMaster = Auto;
879 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
881 string_set(Globals.ctx, &Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
883 string_set(Globals.ctx, &Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
885 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
887 smb_panic("init_globals: ENOMEM");
889 Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
892 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
894 smb_panic("init_globals: ENOMEM");
896 Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
899 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
901 smb_panic("init_globals: ENOMEM");
903 Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
906 Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
908 Globals.rndc_command = str_list_make_v3_const(NULL, "/usr/sbin/rndc", NULL);
910 Globals.cldap_port = 389;
912 Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
914 Globals.nbt_port = NBT_NAME_SERVICE_PORT;
916 Globals.krb5_port = 88;
918 Globals.kpasswd_port = 464;
920 Globals.web_port = 901;
922 /* Now put back the settings that were set with lp_set_cmdline() */
923 apply_lp_set_cmdline();
926 /* Convenience routine to setup an lp_context with additional s3 variables */
927 static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
929 struct loadparm_context *lp_ctx;
931 lp_ctx = loadparm_init_s3(mem_ctx,
932 loadparm_s3_helpers());
933 if (lp_ctx == NULL) {
934 DEBUG(0, ("loadparm_init_s3 failed\n"));
938 lp_ctx->sDefault = &sDefault;
939 lp_ctx->services = NULL; /* We do not want to access this directly */
940 lp_ctx->bInGlobalSection = bInGlobalSection;
941 lp_ctx->flags = flags_list;
946 /*******************************************************************
947 Convenience routine to grab string parameters into talloced memory
948 and run standard_sub_basic on them. The buffers can be written to by
949 callers without affecting the source string.
950 ********************************************************************/
952 char *lp_string(TALLOC_CTX *ctx, const char *s)
956 /* The follow debug is useful for tracking down memory problems
957 especially if you have an inner loop that is calling a lp_*()
958 function that returns a string. Perhaps this debug should be
959 present all the time? */
962 DEBUG(10, ("lp_string(%s)\n", s));
968 ret = talloc_sub_basic(ctx,
969 get_current_username(),
970 current_user_info.domain,
972 if (trim_char(ret, '\"', '\"')) {
973 if (strchr(ret,'\"') != NULL) {
975 ret = talloc_sub_basic(ctx,
976 get_current_username(),
977 current_user_info.domain,
985 In this section all the functions that are used to access the
986 parameters from the rest of the program are defined
989 #define FN_GLOBAL_STRING(fn_name,ptr) \
990 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
991 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
992 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
993 #define FN_GLOBAL_LIST(fn_name,ptr) \
994 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
995 #define FN_GLOBAL_BOOL(fn_name,ptr) \
996 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
997 #define FN_GLOBAL_CHAR(fn_name,ptr) \
998 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
999 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1000 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1002 #define FN_LOCAL_STRING(fn_name,val) \
1003 char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1004 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1005 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1006 #define FN_LOCAL_LIST(fn_name,val) \
1007 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1008 #define FN_LOCAL_BOOL(fn_name,val) \
1009 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1010 #define FN_LOCAL_INTEGER(fn_name,val) \
1011 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1013 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1014 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1015 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1016 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1017 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1018 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1020 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
1021 winbindMaxDomainConnections)
1023 int lp_winbind_max_domain_connections(void)
1025 if (lp_winbind_offline_logon() &&
1026 lp_winbind_max_domain_connections_int() > 1) {
1027 DEBUG(1, ("offline logons active, restricting max domain "
1028 "connections to 1\n"));
1031 return MAX(1, lp_winbind_max_domain_connections_int());
1034 int lp_smb2_max_credits(void)
1036 if (Globals.ismb2_max_credits == 0) {
1037 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1039 return Globals.ismb2_max_credits;
1041 int lp_cups_encrypt(void)
1044 #ifdef HAVE_HTTPCONNECTENCRYPT
1045 switch (Globals.CupsEncrypt) {
1047 result = HTTP_ENCRYPT_REQUIRED;
1050 result = HTTP_ENCRYPT_ALWAYS;
1053 result = HTTP_ENCRYPT_NEVER;
1060 /* These functions remain in source3/param for now */
1062 #include "lib/param/param_functions.c"
1064 FN_LOCAL_STRING(servicename, szService)
1065 FN_LOCAL_CONST_STRING(const_servicename, szService)
1067 /* These functions cannot be auto-generated */
1068 FN_LOCAL_BOOL(autoloaded, autoloaded)
1069 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1071 /* local prototypes */
1073 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1074 static const char *get_boolean(bool bool_value);
1075 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1077 static bool hash_a_service(const char *name, int number);
1078 static void free_service_byindex(int iService);
1079 static void show_parameter(int parmIndex);
1080 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1083 * This is a helper function for parametrical options support. It returns a
1084 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1085 * parametrical functions are quite simple
1087 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1090 if (snum >= iNumServices) return NULL;
1093 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1095 return get_parametric_helper(ServicePtrs[snum],
1096 type, option, Globals.param_opt);
1101 #define MISSING_PARAMETER(name) \
1102 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1104 /*******************************************************************
1105 convenience routine to return enum parameters.
1106 ********************************************************************/
1107 static int lp_enum(const char *s,const struct enum_list *_enum)
1111 if (!s || !*s || !_enum) {
1112 MISSING_PARAMETER(lp_enum);
1116 for (i=0; _enum[i].name; i++) {
1117 if (strequal(_enum[i].name,s))
1118 return _enum[i].value;
1121 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1125 #undef MISSING_PARAMETER
1127 /* Return parametric option from a given service. Type is a part of option before ':' */
1128 /* Parametric option has following syntax: 'Type: option = value' */
1129 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1131 struct parmlist_entry *data = get_parametrics(snum, type, option);
1133 if (data == NULL||data->value==NULL) {
1135 return lp_string(ctx, def);
1141 return lp_string(ctx, data->value);
1144 /* Return parametric option from a given service. Type is a part of option before ':' */
1145 /* Parametric option has following syntax: 'Type: option = value' */
1146 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1148 struct parmlist_entry *data = get_parametrics(snum, type, option);
1150 if (data == NULL||data->value==NULL)
1157 /* Return parametric option from a given service. Type is a part of option before ':' */
1158 /* Parametric option has following syntax: 'Type: option = value' */
1160 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1162 struct parmlist_entry *data = get_parametrics(snum, type, option);
1164 if (data == NULL||data->value==NULL)
1165 return (const char **)def;
1167 if (data->list==NULL) {
1168 data->list = str_list_make_v3(NULL, data->value, NULL);
1171 return discard_const_p(const char *, data->list);
1174 /* Return parametric option from a given service. Type is a part of option before ':' */
1175 /* Parametric option has following syntax: 'Type: option = value' */
1177 int lp_parm_int(int snum, const char *type, const char *option, int def)
1179 struct parmlist_entry *data = get_parametrics(snum, type, option);
1181 if (data && data->value && *data->value)
1182 return lp_int(data->value);
1187 /* Return parametric option from a given service. Type is a part of option before ':' */
1188 /* Parametric option has following syntax: 'Type: option = value' */
1190 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1192 struct parmlist_entry *data = get_parametrics(snum, type, option);
1194 if (data && data->value && *data->value)
1195 return lp_ulong(data->value);
1200 /* Return parametric option from a given service. Type is a part of option before ':' */
1201 /* Parametric option has following syntax: 'Type: option = value' */
1203 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1205 struct parmlist_entry *data = get_parametrics(snum, type, option);
1207 if (data && data->value && *data->value)
1208 return lp_bool(data->value);
1213 /* Return parametric option from a given service. Type is a part of option before ':' */
1214 /* Parametric option has following syntax: 'Type: option = value' */
1216 int lp_parm_enum(int snum, const char *type, const char *option,
1217 const struct enum_list *_enum, int def)
1219 struct parmlist_entry *data = get_parametrics(snum, type, option);
1221 if (data && data->value && *data->value && _enum)
1222 return lp_enum(data->value, _enum);
1228 * free a param_opts structure.
1229 * param_opts handling should be moved to talloc;
1230 * then this whole functions reduces to a TALLOC_FREE().
1233 static void free_param_opts(struct parmlist_entry **popts)
1235 struct parmlist_entry *opt, *next_opt;
1237 if (*popts != NULL) {
1238 DEBUG(5, ("Freeing parametrics:\n"));
1241 while (opt != NULL) {
1242 string_free(&opt->key);
1243 string_free(&opt->value);
1244 TALLOC_FREE(opt->list);
1245 next_opt = opt->next;
1252 /***************************************************************************
1253 Free the dynamically allocated parts of a service struct.
1254 ***************************************************************************/
1256 static void free_service(struct loadparm_service *pservice)
1261 if (pservice->szService)
1262 DEBUG(5, ("free_service: Freeing service %s\n",
1263 pservice->szService));
1265 free_parameters(pservice);
1267 string_free(&pservice->szService);
1268 TALLOC_FREE(pservice->copymap);
1270 free_param_opts(&pservice->param_opt);
1272 ZERO_STRUCTP(pservice);
1276 /***************************************************************************
1277 remove a service indexed in the ServicePtrs array from the ServiceHash
1278 and free the dynamically allocated parts
1279 ***************************************************************************/
1281 static void free_service_byindex(int idx)
1283 if ( !LP_SNUM_OK(idx) )
1286 ServicePtrs[idx]->valid = false;
1288 /* we have to cleanup the hash record */
1290 if (ServicePtrs[idx]->szService) {
1291 char *canon_name = canonicalize_servicename(
1293 ServicePtrs[idx]->szService );
1295 dbwrap_delete_bystring(ServiceHash, canon_name );
1296 TALLOC_FREE(canon_name);
1299 free_service(ServicePtrs[idx]);
1300 talloc_free_children(ServicePtrs[idx]);
1303 /***************************************************************************
1304 Add a new service to the services array initialising it with the given
1306 ***************************************************************************/
1308 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1311 int num_to_alloc = iNumServices + 1;
1312 struct loadparm_service **tsp = NULL;
1314 /* it might already exist */
1316 i = getservicebyname(name, NULL);
1322 /* if not, then create one */
1324 tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
1326 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1330 ServicePtrs[iNumServices] = talloc_zero(NULL, struct loadparm_service);
1331 if (!ServicePtrs[iNumServices]) {
1332 DEBUG(0,("add_a_service: out of memory!\n"));
1337 ServicePtrs[i]->valid = true;
1339 copy_service(ServicePtrs[i], pservice, NULL);
1341 string_set(ServicePtrs[i], &ServicePtrs[i]->szService, name);
1343 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1344 i, ServicePtrs[i]->szService));
1346 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1353 /***************************************************************************
1354 Convert a string to uppercase and remove whitespaces.
1355 ***************************************************************************/
1357 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1362 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1366 result = talloc_strdup(ctx, src);
1367 SMB_ASSERT(result != NULL);
1369 if (!strlower_m(result)) {
1370 TALLOC_FREE(result);
1376 /***************************************************************************
1377 Add a name/index pair for the services array to the hash table.
1378 ***************************************************************************/
1380 static bool hash_a_service(const char *name, int idx)
1384 if ( !ServiceHash ) {
1385 DEBUG(10,("hash_a_service: creating servicehash\n"));
1386 ServiceHash = db_open_rbt(NULL);
1387 if ( !ServiceHash ) {
1388 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1393 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1396 canon_name = canonicalize_servicename(talloc_tos(), name );
1398 dbwrap_store_bystring(ServiceHash, canon_name,
1399 make_tdb_data((uint8_t *)&idx, sizeof(idx)),
1402 TALLOC_FREE(canon_name);
1407 /***************************************************************************
1408 Add a new home service, with the specified home directory, defaults coming
1410 ***************************************************************************/
1412 bool lp_add_home(const char *pszHomename, int iDefaultService,
1413 const char *user, const char *pszHomedir)
1417 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1418 pszHomedir[0] == '\0') {
1422 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1427 if (!(*(ServicePtrs[iDefaultService]->path))
1428 || strequal(ServicePtrs[iDefaultService]->path,
1429 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1430 string_set(ServicePtrs[i], &ServicePtrs[i]->path, pszHomedir);
1433 if (!(*(ServicePtrs[i]->comment))) {
1434 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1435 if (comment == NULL) {
1438 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1439 TALLOC_FREE(comment);
1442 /* set the browseable flag from the global default */
1444 ServicePtrs[i]->browseable = sDefault.browseable;
1445 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1447 ServicePtrs[i]->autoloaded = true;
1449 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1450 user, ServicePtrs[i]->path ));
1455 /***************************************************************************
1456 Add a new service, based on an old one.
1457 ***************************************************************************/
1459 int lp_add_service(const char *pszService, int iDefaultService)
1461 if (iDefaultService < 0) {
1462 return add_a_service(&sDefault, pszService);
1465 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1468 /***************************************************************************
1469 Add the IPC service.
1470 ***************************************************************************/
1472 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1474 char *comment = NULL;
1475 int i = add_a_service(&sDefault, ipc_name);
1480 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1481 Globals.server_string);
1482 if (comment == NULL) {
1486 string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1487 string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
1488 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1489 string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1490 ServicePtrs[i]->max_connections = 0;
1491 ServicePtrs[i]->bAvailable = true;
1492 ServicePtrs[i]->read_only = true;
1493 ServicePtrs[i]->guest_only = false;
1494 ServicePtrs[i]->administrative_share = true;
1495 ServicePtrs[i]->guest_ok = guest_ok;
1496 ServicePtrs[i]->printable = false;
1497 ServicePtrs[i]->browseable = sDefault.browseable;
1499 DEBUG(3, ("adding IPC service\n"));
1501 TALLOC_FREE(comment);
1505 /***************************************************************************
1506 Add a new printer service, with defaults coming from service iFrom.
1507 ***************************************************************************/
1509 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1511 const char *comment = "From Printcap";
1512 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1517 /* note that we do NOT default the availability flag to true - */
1518 /* we take it from the default service passed. This allows all */
1519 /* dynamic printers to be disabled by disabling the [printers] */
1520 /* entry (if/when the 'available' keyword is implemented!). */
1522 /* the printer name is set to the service name. */
1523 string_set(ServicePtrs[i], &ServicePtrs[i]->_printername, pszPrintername);
1524 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1526 /* set the browseable flag from the gloabl default */
1527 ServicePtrs[i]->browseable = sDefault.browseable;
1529 /* Printers cannot be read_only. */
1530 ServicePtrs[i]->read_only = false;
1531 /* No oplocks on printer services. */
1532 ServicePtrs[i]->oplocks = false;
1533 /* Printer services must be printable. */
1534 ServicePtrs[i]->printable = true;
1536 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1542 /***************************************************************************
1543 Check whether the given parameter name is valid.
1544 Parametric options (names containing a colon) are considered valid.
1545 ***************************************************************************/
1547 bool lp_parameter_is_valid(const char *pszParmName)
1549 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1550 (strchr(pszParmName, ':') != NULL));
1553 /***************************************************************************
1554 Check whether the given name is the name of a global parameter.
1555 Returns true for strings belonging to parameters of class
1556 P_GLOBAL, false for all other strings, also for parametric options
1557 and strings not belonging to any option.
1558 ***************************************************************************/
1560 bool lp_parameter_is_global(const char *pszParmName)
1562 int num = lpcfg_map_parameter(pszParmName);
1565 return (parm_table[num].p_class == P_GLOBAL);
1571 /**************************************************************************
1572 Determine the canonical name for a parameter.
1573 Indicate when it is an inverse (boolean) synonym instead of a
1575 **************************************************************************/
1577 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1582 if (!lp_parameter_is_valid(parm_name)) {
1587 num = map_parameter_canonical(parm_name, inverse);
1589 /* parametric option */
1590 *canon_parm = parm_name;
1592 *canon_parm = parm_table[num].label;
1599 /**************************************************************************
1600 Determine the canonical name for a parameter.
1601 Turn the value given into the inverse boolean expression when
1602 the synonym is an invers boolean synonym.
1604 Return true if parm_name is a valid parameter name and
1605 in case it is an invers boolean synonym, if the val string could
1606 successfully be converted to the reverse bool.
1607 Return false in all other cases.
1608 **************************************************************************/
1610 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1612 const char **canon_parm,
1613 const char **canon_val)
1618 if (!lp_parameter_is_valid(parm_name)) {
1624 num = map_parameter_canonical(parm_name, &inverse);
1626 /* parametric option */
1627 *canon_parm = parm_name;
1630 *canon_parm = parm_table[num].label;
1632 if (!lp_invert_boolean(val, canon_val)) {
1644 /***************************************************************************
1645 Map a parameter's string representation to the index of the canonical
1646 form of the parameter (it might be a synonym).
1647 Returns -1 if the parameter string is not recognised.
1648 ***************************************************************************/
1650 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1652 int parm_num, canon_num;
1653 bool loc_inverse = false;
1655 parm_num = lpcfg_map_parameter(pszParmName);
1656 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
1657 /* invalid, parametric or no canidate for synonyms ... */
1661 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1662 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1663 parm_num = canon_num;
1669 if (inverse != NULL) {
1670 *inverse = loc_inverse;
1675 /***************************************************************************
1676 return true if parameter number parm1 is a synonym of parameter
1677 number parm2 (parm2 being the principal name).
1678 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1680 ***************************************************************************/
1682 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1684 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1685 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1686 (parm_table[parm1].flags & FLAG_SYNONYM) &&
1687 !(parm_table[parm2].flags & FLAG_SYNONYM))
1689 if (inverse != NULL) {
1690 if ((parm_table[parm1].type == P_BOOLREV) &&
1691 (parm_table[parm2].type == P_BOOL))
1703 /***************************************************************************
1704 Show one parameter's name, type, [values,] and flags.
1705 (helper functions for show_parameter_list)
1706 ***************************************************************************/
1708 static void show_parameter(int parmIndex)
1710 int enumIndex, flagIndex;
1715 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1716 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1717 "P_ENUM", "P_BYTES", "P_CMDLIST" };
1718 unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
1719 const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
1721 printf("%s=%s", parm_table[parmIndex].label,
1722 type[parm_table[parmIndex].type]);
1723 if (parm_table[parmIndex].type == P_ENUM) {
1726 parm_table[parmIndex].enum_list[enumIndex].name;
1730 enumIndex ? "|" : "",
1731 parm_table[parmIndex].enum_list[enumIndex].name);
1736 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1737 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1740 flag_names[flagIndex]);
1745 /* output synonyms */
1747 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1748 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1749 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1750 parm_table[parmIndex2].label);
1751 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1753 printf(" (synonyms: ");
1758 printf("%s%s", parm_table[parmIndex2].label,
1759 inverse ? "[i]" : "");
1769 /***************************************************************************
1770 Show all parameter's name, type, [values,] and flags.
1771 ***************************************************************************/
1773 void show_parameter_list(void)
1775 int classIndex, parmIndex;
1776 const char *section_names[] = { "local", "global", NULL};
1778 for (classIndex=0; section_names[classIndex]; classIndex++) {
1779 printf("[%s]\n", section_names[classIndex]);
1780 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
1781 if (parm_table[parmIndex].p_class == classIndex) {
1782 show_parameter(parmIndex);
1788 /***************************************************************************
1789 Get the standard string representation of a boolean value ("yes" or "no")
1790 ***************************************************************************/
1792 static const char *get_boolean(bool bool_value)
1794 static const char *yes_str = "yes";
1795 static const char *no_str = "no";
1797 return (bool_value ? yes_str : no_str);
1800 /***************************************************************************
1801 Provide the string of the negated boolean value associated to the boolean
1802 given as a string. Returns false if the passed string does not correctly
1803 represent a boolean.
1804 ***************************************************************************/
1806 bool lp_invert_boolean(const char *str, const char **inverse_str)
1810 if (!set_boolean(str, &val)) {
1814 *inverse_str = get_boolean(!val);
1818 /***************************************************************************
1819 Provide the canonical string representation of a boolean value given
1820 as a string. Return true on success, false if the string given does
1821 not correctly represent a boolean.
1822 ***************************************************************************/
1824 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
1828 if (!set_boolean(str, &val)) {
1832 *canon_str = get_boolean(val);
1836 /***************************************************************************
1837 Find a service by name. Otherwise works like get_service.
1838 ***************************************************************************/
1840 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
1847 if (ServiceHash == NULL) {
1851 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
1853 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
1856 if (NT_STATUS_IS_OK(status) &&
1857 (data.dptr != NULL) &&
1858 (data.dsize == sizeof(iService)))
1860 iService = *(int *)data.dptr;
1863 TALLOC_FREE(canon_name);
1865 if ((iService != -1) && (LP_SNUM_OK(iService))
1866 && (pserviceDest != NULL)) {
1867 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1873 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
1874 struct loadparm_service *lp_service(const char *pszServiceName)
1876 int iService = getservicebyname(pszServiceName, NULL);
1877 if (iService == -1 || !LP_SNUM_OK(iService)) {
1880 return ServicePtrs[iService];
1883 struct loadparm_service *lp_servicebynum(int snum)
1885 if ((snum == -1) || !LP_SNUM_OK(snum)) {
1888 return ServicePtrs[snum];
1891 struct loadparm_service *lp_default_loadparm_service()
1896 static struct smbconf_ctx *lp_smbconf_ctx(void)
1899 static struct smbconf_ctx *conf_ctx = NULL;
1901 if (conf_ctx == NULL) {
1902 err = smbconf_init(NULL, &conf_ctx, "registry:");
1903 if (!SBC_ERROR_IS_OK(err)) {
1904 DEBUG(1, ("error initializing registry configuration: "
1905 "%s\n", sbcErrorString(err)));
1913 static bool process_smbconf_service(struct smbconf_service *service)
1918 if (service == NULL) {
1922 ret = lp_do_section(service->name, NULL);
1926 for (count = 0; count < service->num_params; count++) {
1928 if (!bInGlobalSection && bGlobalOnly) {
1931 const char *pszParmName = service->param_names[count];
1932 const char *pszParmValue = service->param_values[count];
1934 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
1936 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1937 pszParmName, pszParmValue);
1944 if (iServiceIndex >= 0) {
1945 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
1951 * load a service from registry and activate it
1953 bool process_registry_service(const char *service_name)
1956 struct smbconf_service *service = NULL;
1957 TALLOC_CTX *mem_ctx = talloc_stackframe();
1958 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
1961 if (conf_ctx == NULL) {
1965 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
1967 if (!smbconf_share_exists(conf_ctx, service_name)) {
1969 * Registry does not contain data for this service (yet),
1970 * but make sure lp_load doesn't return false.
1976 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
1977 if (!SBC_ERROR_IS_OK(err)) {
1981 ret = process_smbconf_service(service);
1987 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
1990 TALLOC_FREE(mem_ctx);
1995 * process_registry_globals
1997 static bool process_registry_globals(void)
2001 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2003 if (!bInGlobalSection && bGlobalOnly) {
2006 const char *pszParmName = "registry shares";
2007 const char *pszParmValue = "yes";
2009 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2011 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2012 pszParmName, pszParmValue);
2019 return process_registry_service(GLOBAL_NAME);
2022 bool process_registry_shares(void)
2026 struct smbconf_service **service = NULL;
2027 uint32_t num_shares = 0;
2028 TALLOC_CTX *mem_ctx = talloc_stackframe();
2029 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2032 if (conf_ctx == NULL) {
2036 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2037 if (!SBC_ERROR_IS_OK(err)) {
2043 for (count = 0; count < num_shares; count++) {
2044 if (strequal(service[count]->name, GLOBAL_NAME)) {
2047 ret = process_smbconf_service(service[count]);
2054 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2057 TALLOC_FREE(mem_ctx);
2062 * reload those shares from registry that are already
2063 * activated in the services array.
2065 static bool reload_registry_shares(void)
2070 for (i = 0; i < iNumServices; i++) {
2075 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2079 ret = process_registry_service(ServicePtrs[i]->szService);
2090 #define MAX_INCLUDE_DEPTH 100
2092 static uint8_t include_depth;
2095 * Free the file lists
2097 static void free_file_list(void)
2099 struct file_lists *f;
2100 struct file_lists *next;
2113 * Utility function for outsiders to check if we're running on registry.
2115 bool lp_config_backend_is_registry(void)
2117 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2121 * Utility function to check if the config backend is FILE.
2123 bool lp_config_backend_is_file(void)
2125 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2128 /*******************************************************************
2129 Check if a config file has changed date.
2130 ********************************************************************/
2132 bool lp_file_list_changed(void)
2134 struct file_lists *f = file_lists;
2136 DEBUG(6, ("lp_file_list_changed()\n"));
2139 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2140 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2142 if (conf_ctx == NULL) {
2145 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2148 DEBUGADD(6, ("registry config changed\n"));
2155 n2 = talloc_sub_basic(talloc_tos(),
2156 get_current_username(),
2157 current_user_info.domain,
2162 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2163 f->name, n2, ctime(&f->modtime)));
2165 mod_time = file_modtime(n2);
2168 ((f->modtime != mod_time) ||
2169 (f->subfname == NULL) ||
2170 (strcmp(n2, f->subfname) != 0)))
2173 ("file %s modified: %s\n", n2,
2175 f->modtime = mod_time;
2176 TALLOC_FREE(f->subfname);
2177 f->subfname = talloc_strdup(f, n2);
2178 if (f->subfname == NULL) {
2179 smb_panic("talloc_strdup failed");
2193 * Initialize iconv conversion descriptors.
2195 * This is called the first time it is needed, and also called again
2196 * every time the configuration is reloaded, because the charset or
2197 * codepage might have changed.
2199 static void init_iconv(void)
2201 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2203 true, global_iconv_handle);
2206 /***************************************************************************
2207 Handle the include operation.
2208 ***************************************************************************/
2209 static bool bAllowIncludeRegistry = true;
2211 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2212 const char *pszParmValue, char **ptr)
2216 if (include_depth >= MAX_INCLUDE_DEPTH) {
2217 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2222 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2223 if (!bAllowIncludeRegistry) {
2226 if (lp_ctx->bInGlobalSection) {
2229 ret = process_registry_globals();
2233 DEBUG(1, ("\"include = registry\" only effective "
2234 "in %s section\n", GLOBAL_NAME));
2239 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2240 current_user_info.domain,
2243 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2245 if (service == NULL) {
2246 string_set(Globals.ctx, ptr, fname);
2248 string_set(service, ptr, fname);
2251 if (file_exist(fname)) {
2254 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2260 DEBUG(2, ("Can't find include file %s\n", fname));
2265 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2267 char *config_option = NULL;
2268 const char *range = NULL;
2271 SMB_ASSERT(low != NULL);
2272 SMB_ASSERT(high != NULL);
2274 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2278 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2280 if (config_option == NULL) {
2281 DEBUG(0, ("out of memory\n"));
2285 range = lp_parm_const_string(-1, config_option, "range", NULL);
2286 if (range == NULL) {
2287 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2291 if (sscanf(range, "%u - %u", low, high) != 2) {
2292 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2293 range, domain_name));
2300 talloc_free(config_option);
2305 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2307 return lp_idmap_range("*", low, high);
2310 const char *lp_idmap_backend(const char *domain_name)
2312 char *config_option = NULL;
2313 const char *backend = NULL;
2315 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2319 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2321 if (config_option == NULL) {
2322 DEBUG(0, ("out of memory\n"));
2326 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2327 if (backend == NULL) {
2328 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2333 talloc_free(config_option);
2337 const char *lp_idmap_default_backend(void)
2339 return lp_idmap_backend("*");
2342 /***************************************************************************
2343 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2344 ***************************************************************************/
2346 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2348 const char *suffix_string;
2350 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2351 Globals.ldap_suffix );
2352 if ( !suffix_string ) {
2353 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2357 return suffix_string;
2360 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2362 if (Globals.szLdapMachineSuffix[0])
2363 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
2365 return lp_string(ctx, Globals.ldap_suffix);
2368 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2370 if (Globals.szLdapUserSuffix[0])
2371 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
2373 return lp_string(ctx, Globals.ldap_suffix);
2376 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2378 if (Globals.szLdapGroupSuffix[0])
2379 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
2381 return lp_string(ctx, Globals.ldap_suffix);
2384 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2386 if (Globals.szLdapIdmapSuffix[0])
2387 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
2389 return lp_string(ctx, Globals.ldap_suffix);
2393 return the parameter pointer for a parameter
2395 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2397 if (service == NULL) {
2398 if (parm->p_class == P_LOCAL)
2399 return (void *)(((char *)&sDefault)+parm->offset);
2400 else if (parm->p_class == P_GLOBAL)
2401 return (void *)(((char *)&Globals)+parm->offset);
2404 return (void *)(((char *)service) + parm->offset);
2408 /***************************************************************************
2409 Process a parameter for a particular service number. If snum < 0
2410 then assume we are in the globals.
2411 ***************************************************************************/
2413 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2415 TALLOC_CTX *frame = talloc_stackframe();
2416 struct loadparm_context *lp_ctx;
2419 lp_ctx = setup_lp_context(frame);
2420 if (lp_ctx == NULL) {
2426 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2428 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2429 pszParmName, pszParmValue);
2437 /***************************************************************************
2438 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2439 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2440 ***************************************************************************/
2442 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2445 parmnum = lpcfg_map_parameter(pszParmName);
2447 flags_list[parmnum] &= ~FLAG_CMDLINE;
2448 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2451 flags_list[parmnum] |= FLAG_CMDLINE;
2453 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2454 * be grouped in the table, so we don't have to search the
2457 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2458 && parm_table[i].p_class == parm_table[parmnum].p_class;
2460 flags_list[i] |= FLAG_CMDLINE;
2462 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2463 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2464 flags_list[i] |= FLAG_CMDLINE;
2470 /* it might be parametric */
2471 if (strchr(pszParmName, ':') != NULL) {
2472 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2476 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2480 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2483 TALLOC_CTX *frame = talloc_stackframe();
2484 struct loadparm_context *lp_ctx;
2486 lp_ctx = setup_lp_context(frame);
2487 if (lp_ctx == NULL) {
2492 ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
2498 /***************************************************************************
2499 Process a parameter.
2500 ***************************************************************************/
2502 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2505 if (!bInGlobalSection && bGlobalOnly)
2508 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2510 if (bInGlobalSection) {
2511 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2513 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2514 pszParmName, pszParmValue);
2518 /***************************************************************************
2519 Initialize any local variables in the sDefault table, after parsing a
2521 ***************************************************************************/
2523 static void init_locals(void)
2526 * We run this check once the [globals] is parsed, to force
2527 * the VFS objects and other per-share settings we need for
2528 * the standard way a AD DC is operated. We may change these
2529 * as our code evolves, which is why we force these settings.
2531 * We can't do this at the end of lp_load_ex(), as by that
2532 * point the services have been loaded and they will already
2533 * have "" as their vfs objects.
2535 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2536 const char **vfs_objects = lp_vfs_objects(-1);
2537 if (!vfs_objects || !vfs_objects[0]) {
2538 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2539 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2540 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2541 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2543 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2547 lp_do_parameter(-1, "map hidden", "no");
2548 lp_do_parameter(-1, "map system", "no");
2549 lp_do_parameter(-1, "map readonly", "no");
2550 lp_do_parameter(-1, "map archive", "no");
2551 lp_do_parameter(-1, "store dos attributes", "yes");
2555 /***************************************************************************
2556 Process a new section (service). At this stage all sections are services.
2557 Later we'll have special sections that permit server parameters to be set.
2558 Returns true on success, false on failure.
2559 ***************************************************************************/
2561 bool lp_do_section(const char *pszSectionName, void *userdata)
2563 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2565 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2566 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2569 /* if we were in a global section then do the local inits */
2570 if (bInGlobalSection && !isglobal)
2573 /* if we've just struck a global section, note the fact. */
2574 bInGlobalSection = isglobal;
2575 if (lp_ctx != NULL) {
2576 lp_ctx->bInGlobalSection = isglobal;
2579 /* check for multiple global sections */
2580 if (bInGlobalSection) {
2581 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2585 if (!bInGlobalSection && bGlobalOnly)
2588 /* if we have a current service, tidy it up before moving on */
2591 if (iServiceIndex >= 0)
2592 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2594 /* if all is still well, move to the next record in the services array */
2596 /* We put this here to avoid an odd message order if messages are */
2597 /* issued by the post-processing of a previous section. */
2598 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2600 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2601 if (iServiceIndex < 0) {
2602 DEBUG(0, ("Failed to add a new service\n"));
2605 /* Clean all parametric options for service */
2606 /* They will be added during parsing again */
2607 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2613 /***************************************************************************
2614 Display the contents of a parameter of a single services record.
2615 ***************************************************************************/
2617 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2619 bool result = false;
2620 struct loadparm_context *lp_ctx;
2622 lp_ctx = setup_lp_context(talloc_tos());
2623 if (lp_ctx == NULL) {
2628 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2630 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2632 TALLOC_FREE(lp_ctx);
2637 /***************************************************************************
2638 Display the contents of a single copy structure.
2639 ***************************************************************************/
2640 static void dump_copy_map(bool *pcopymap)
2646 printf("\n\tNon-Copied parameters:\n");
2648 for (i = 0; parm_table[i].label; i++)
2649 if (parm_table[i].p_class == P_LOCAL &&
2650 parm_table[i].ptr && !pcopymap[i] &&
2651 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2653 printf("\t\t%s\n", parm_table[i].label);
2658 /***************************************************************************
2659 Return TRUE if the passed service number is within range.
2660 ***************************************************************************/
2662 bool lp_snum_ok(int iService)
2664 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2667 /***************************************************************************
2668 Auto-load some home services.
2669 ***************************************************************************/
2671 static void lp_add_auto_services(char *str)
2681 s = talloc_strdup(talloc_tos(), str);
2683 smb_panic("talloc_strdup failed");
2687 homes = lp_servicenumber(HOMES_NAME);
2689 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2690 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2693 if (lp_servicenumber(p) >= 0)
2696 home = get_user_home_dir(talloc_tos(), p);
2698 if (home && home[0] && homes >= 0)
2699 lp_add_home(p, homes, p, home);
2706 /***************************************************************************
2707 Auto-load one printer.
2708 ***************************************************************************/
2710 void lp_add_one_printer(const char *name, const char *comment,
2711 const char *location, void *pdata)
2713 int printers = lp_servicenumber(PRINTERS_NAME);
2716 if (lp_servicenumber(name) < 0) {
2717 lp_add_printer(name, printers);
2718 if ((i = lp_servicenumber(name)) >= 0) {
2719 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
2720 ServicePtrs[i]->autoloaded = true;
2725 /***************************************************************************
2726 Have we loaded a services file yet?
2727 ***************************************************************************/
2729 bool lp_loaded(void)
2734 /***************************************************************************
2735 Unload unused services.
2736 ***************************************************************************/
2738 void lp_killunused(struct smbd_server_connection *sconn,
2739 bool (*snumused) (struct smbd_server_connection *, int))
2742 for (i = 0; i < iNumServices; i++) {
2746 /* don't kill autoloaded or usershare services */
2747 if ( ServicePtrs[i]->autoloaded ||
2748 ServicePtrs[i]->usershare == USERSHARE_VALID) {
2752 if (!snumused || !snumused(sconn, i)) {
2753 free_service_byindex(i);
2759 * Kill all except autoloaded and usershare services - convenience wrapper
2761 void lp_kill_all_services(void)
2763 lp_killunused(NULL, NULL);
2766 /***************************************************************************
2768 ***************************************************************************/
2770 void lp_killservice(int iServiceIn)
2772 if (VALID(iServiceIn)) {
2773 free_service_byindex(iServiceIn);
2777 /***************************************************************************
2778 Save the curent values of all global and sDefault parameters into the
2779 defaults union. This allows testparm to show only the
2780 changed (ie. non-default) parameters.
2781 ***************************************************************************/
2783 static void lp_save_defaults(void)
2786 struct parmlist_entry * parm;
2787 for (i = 0; parm_table[i].label; i++) {
2788 if (!(flags_list[i] & FLAG_CMDLINE)) {
2789 flags_list[i] |= FLAG_DEFAULT;
2792 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
2793 && parm_table[i].p_class == parm_table[i - 1].p_class)
2795 switch (parm_table[i].type) {
2798 parm_table[i].def.lvalue = str_list_copy(
2799 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
2803 parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i]));
2804 if (parm_table[i].def.svalue == NULL) {
2805 smb_panic("talloc_strdup failed");
2810 parm_table[i].def.bvalue =
2811 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
2814 parm_table[i].def.cvalue =
2815 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
2821 parm_table[i].def.ivalue =
2822 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
2827 for (parm=Globals.param_opt; parm; parm=parm->next) {
2828 if (!(parm->priority & FLAG_CMDLINE)) {
2829 parm->priority |= FLAG_DEFAULT;
2833 for (parm=sDefault.param_opt; parm; parm=parm->next) {
2834 if (!(parm->priority & FLAG_CMDLINE)) {
2835 parm->priority |= FLAG_DEFAULT;
2839 defaults_saved = true;
2842 /***********************************************************
2843 If we should send plaintext/LANMAN passwords in the clinet
2844 ************************************************************/
2846 static void set_allowed_client_auth(void)
2848 if (Globals.client_ntlmv2_auth) {
2849 Globals.client_lanman_auth = false;
2851 if (!Globals.client_lanman_auth) {
2852 Globals.client_plaintext_auth = false;
2856 /***************************************************************************
2858 The following code allows smbd to read a user defined share file.
2859 Yes, this is my intent. Yes, I'm comfortable with that...
2861 THE FOLLOWING IS SECURITY CRITICAL CODE.
2863 It washes your clothes, it cleans your house, it guards you while you sleep...
2864 Do not f%^k with it....
2865 ***************************************************************************/
2867 #define MAX_USERSHARE_FILE_SIZE (10*1024)
2869 /***************************************************************************
2870 Check allowed stat state of a usershare file.
2871 Ensure we print out who is dicking with us so the admin can
2872 get their sorry ass fired.
2873 ***************************************************************************/
2875 static bool check_usershare_stat(const char *fname,
2876 const SMB_STRUCT_STAT *psbuf)
2878 if (!S_ISREG(psbuf->st_ex_mode)) {
2879 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2880 "not a regular file\n",
2881 fname, (unsigned int)psbuf->st_ex_uid ));
2885 /* Ensure this doesn't have the other write bit set. */
2886 if (psbuf->st_ex_mode & S_IWOTH) {
2887 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
2888 "public write. Refusing to allow as a usershare file.\n",
2889 fname, (unsigned int)psbuf->st_ex_uid ));
2893 /* Should be 10k or less. */
2894 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
2895 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2896 "too large (%u) to be a user share file.\n",
2897 fname, (unsigned int)psbuf->st_ex_uid,
2898 (unsigned int)psbuf->st_ex_size ));
2905 /***************************************************************************
2906 Parse the contents of a usershare file.
2907 ***************************************************************************/
2909 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
2910 SMB_STRUCT_STAT *psbuf,
2911 const char *servicename,
2915 char **pp_sharepath,
2917 char **pp_cp_servicename,
2918 struct security_descriptor **ppsd,
2921 const char **prefixallowlist = lp_usershare_prefix_allow_list();
2922 const char **prefixdenylist = lp_usershare_prefix_deny_list();
2925 SMB_STRUCT_STAT sbuf;
2926 char *sharepath = NULL;
2927 char *comment = NULL;
2929 *pp_sharepath = NULL;
2932 *pallow_guest = false;
2935 return USERSHARE_MALFORMED_FILE;
2938 if (strcmp(lines[0], "#VERSION 1") == 0) {
2940 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
2943 return USERSHARE_MALFORMED_FILE;
2946 return USERSHARE_BAD_VERSION;
2949 if (strncmp(lines[1], "path=", 5) != 0) {
2950 return USERSHARE_MALFORMED_PATH;
2953 sharepath = talloc_strdup(ctx, &lines[1][5]);
2955 return USERSHARE_POSIX_ERR;
2957 trim_string(sharepath, " ", " ");
2959 if (strncmp(lines[2], "comment=", 8) != 0) {
2960 return USERSHARE_MALFORMED_COMMENT_DEF;
2963 comment = talloc_strdup(ctx, &lines[2][8]);
2965 return USERSHARE_POSIX_ERR;
2967 trim_string(comment, " ", " ");
2968 trim_char(comment, '"', '"');
2970 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
2971 return USERSHARE_MALFORMED_ACL_DEF;
2974 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
2975 return USERSHARE_ACL_ERR;
2979 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
2980 return USERSHARE_MALFORMED_ACL_DEF;
2982 if (lines[4][9] == 'y') {
2983 *pallow_guest = true;
2986 /* Backwards compatible extension to file version #2. */
2988 if (strncmp(lines[5], "sharename=", 10) != 0) {
2989 return USERSHARE_MALFORMED_SHARENAME_DEF;
2991 if (!strequal(&lines[5][10], servicename)) {
2992 return USERSHARE_BAD_SHARENAME;
2994 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
2995 if (!*pp_cp_servicename) {
2996 return USERSHARE_POSIX_ERR;
3001 if (*pp_cp_servicename == NULL) {
3002 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3003 if (!*pp_cp_servicename) {
3004 return USERSHARE_POSIX_ERR;
3008 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3009 /* Path didn't change, no checks needed. */
3010 *pp_sharepath = sharepath;
3011 *pp_comment = comment;
3012 return USERSHARE_OK;
3015 /* The path *must* be absolute. */
3016 if (sharepath[0] != '/') {
3017 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3018 servicename, sharepath));
3019 return USERSHARE_PATH_NOT_ABSOLUTE;
3022 /* If there is a usershare prefix deny list ensure one of these paths
3023 doesn't match the start of the user given path. */
3024 if (prefixdenylist) {
3026 for ( i=0; prefixdenylist[i]; i++ ) {
3027 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3028 servicename, i, prefixdenylist[i], sharepath ));
3029 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3030 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3031 "usershare prefix deny list entries.\n",
3032 servicename, sharepath));
3033 return USERSHARE_PATH_IS_DENIED;
3038 /* If there is a usershare prefix allow list ensure one of these paths
3039 does match the start of the user given path. */
3041 if (prefixallowlist) {
3043 for ( i=0; prefixallowlist[i]; i++ ) {
3044 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3045 servicename, i, prefixallowlist[i], sharepath ));
3046 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3050 if (prefixallowlist[i] == NULL) {
3051 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3052 "usershare prefix allow list entries.\n",
3053 servicename, sharepath));
3054 return USERSHARE_PATH_NOT_ALLOWED;
3058 /* Ensure this is pointing to a directory. */
3059 dp = opendir(sharepath);
3062 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3063 servicename, sharepath));
3064 return USERSHARE_PATH_NOT_DIRECTORY;
3067 /* Ensure the owner of the usershare file has permission to share
3070 if (sys_stat(sharepath, &sbuf, false) == -1) {
3071 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3072 servicename, sharepath, strerror(errno) ));
3074 return USERSHARE_POSIX_ERR;
3079 if (!S_ISDIR(sbuf.st_ex_mode)) {
3080 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3081 servicename, sharepath ));
3082 return USERSHARE_PATH_NOT_DIRECTORY;
3085 /* Check if sharing is restricted to owner-only. */
3086 /* psbuf is the stat of the usershare definition file,
3087 sbuf is the stat of the target directory to be shared. */
3089 if (lp_usershare_owner_only()) {
3090 /* root can share anything. */
3091 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3092 return USERSHARE_PATH_NOT_ALLOWED;
3096 *pp_sharepath = sharepath;
3097 *pp_comment = comment;
3098 return USERSHARE_OK;
3101 /***************************************************************************
3102 Deal with a usershare file.
3105 -1 - Bad name, invalid contents.
3106 - service name already existed and not a usershare, problem
3107 with permissions to share directory etc.
3108 ***************************************************************************/
3110 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3112 SMB_STRUCT_STAT sbuf;
3113 SMB_STRUCT_STAT lsbuf;
3115 char *sharepath = NULL;
3116 char *comment = NULL;
3117 char *cp_service_name = NULL;
3118 char **lines = NULL;
3122 TALLOC_CTX *ctx = talloc_stackframe();
3123 struct security_descriptor *psd = NULL;
3124 bool guest_ok = false;
3125 char *canon_name = NULL;
3126 bool added_service = false;
3129 /* Ensure share name doesn't contain invalid characters. */
3130 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3131 DEBUG(0,("process_usershare_file: share name %s contains "
3132 "invalid characters (any of %s)\n",
3133 file_name, INVALID_SHARENAME_CHARS ));
3137 canon_name = canonicalize_servicename(ctx, file_name);
3142 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3147 /* Minimize the race condition by doing an lstat before we
3148 open and fstat. Ensure this isn't a symlink link. */
3150 if (sys_lstat(fname, &lsbuf, false) != 0) {
3151 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3152 fname, strerror(errno) ));
3156 /* This must be a regular file, not a symlink, directory or
3157 other strange filetype. */
3158 if (!check_usershare_stat(fname, &lsbuf)) {
3166 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3171 if (NT_STATUS_IS_OK(status) &&
3172 (data.dptr != NULL) &&
3173 (data.dsize == sizeof(iService))) {
3174 memcpy(&iService, data.dptr, sizeof(iService));
3178 if (iService != -1 &&
3179 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3180 &lsbuf.st_ex_mtime) == 0) {
3181 /* Nothing changed - Mark valid and return. */
3182 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3184 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3189 /* Try and open the file read only - no symlinks allowed. */
3191 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3193 fd = open(fname, O_RDONLY, 0);
3197 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3198 fname, strerror(errno) ));
3202 /* Now fstat to be *SURE* it's a regular file. */
3203 if (sys_fstat(fd, &sbuf, false) != 0) {
3205 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3206 fname, strerror(errno) ));
3210 /* Is it the same dev/inode as was lstated ? */
3211 if (!check_same_stat(&lsbuf, &sbuf)) {
3213 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3214 "Symlink spoofing going on ?\n", fname ));
3218 /* This must be a regular file, not a symlink, directory or
3219 other strange filetype. */
3220 if (!check_usershare_stat(fname, &sbuf)) {
3225 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3228 if (lines == NULL) {
3229 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3230 fname, (unsigned int)sbuf.st_ex_uid ));
3234 if (parse_usershare_file(ctx, &sbuf, file_name,
3235 iService, lines, numlines, &sharepath,
3236 &comment, &cp_service_name,
3237 &psd, &guest_ok) != USERSHARE_OK) {
3241 /* Everything ok - add the service possibly using a template. */
3243 const struct loadparm_service *sp = &sDefault;
3244 if (snum_template != -1) {
3245 sp = ServicePtrs[snum_template];
3248 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3249 DEBUG(0, ("process_usershare_file: Failed to add "
3250 "new service %s\n", cp_service_name));
3254 added_service = true;
3256 /* Read only is controlled by usershare ACL below. */
3257 ServicePtrs[iService]->read_only = false;
3260 /* Write the ACL of the new/modified share. */
3261 if (!set_share_security(canon_name, psd)) {
3262 DEBUG(0, ("process_usershare_file: Failed to set share "
3263 "security for user share %s\n",
3268 /* If from a template it may be marked invalid. */
3269 ServicePtrs[iService]->valid = true;
3271 /* Set the service as a valid usershare. */
3272 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3274 /* Set guest access. */
3275 if (lp_usershare_allow_guests()) {
3276 ServicePtrs[iService]->guest_ok = guest_ok;
3279 /* And note when it was loaded. */
3280 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3281 string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath);
3282 string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment);
3288 if (ret == -1 && iService != -1 && added_service) {
3289 lp_remove_service(iService);
3297 /***************************************************************************
3298 Checks if a usershare entry has been modified since last load.
3299 ***************************************************************************/
3301 static bool usershare_exists(int iService, struct timespec *last_mod)
3303 SMB_STRUCT_STAT lsbuf;
3304 const char *usersharepath = Globals.usershare_path;
3307 fname = talloc_asprintf(talloc_tos(),
3310 ServicePtrs[iService]->szService);
3311 if (fname == NULL) {
3315 if (sys_lstat(fname, &lsbuf, false) != 0) {
3320 if (!S_ISREG(lsbuf.st_ex_mode)) {
3326 *last_mod = lsbuf.st_ex_mtime;
3330 /***************************************************************************
3331 Load a usershare service by name. Returns a valid servicenumber or -1.
3332 ***************************************************************************/
3334 int load_usershare_service(const char *servicename)
3336 SMB_STRUCT_STAT sbuf;
3337 const char *usersharepath = Globals.usershare_path;
3338 int max_user_shares = Globals.usershare_max_shares;
3339 int snum_template = -1;
3341 if (*usersharepath == 0 || max_user_shares == 0) {
3345 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3346 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3347 usersharepath, strerror(errno) ));
3351 if (!S_ISDIR(sbuf.st_ex_mode)) {
3352 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3358 * This directory must be owned by root, and have the 't' bit set.
3359 * It also must not be writable by "other".
3363 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3365 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3367 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3368 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3373 /* Ensure the template share exists if it's set. */
3374 if (Globals.usershare_template_share[0]) {
3375 /* We can't use lp_servicenumber here as we are recommending that
3376 template shares have -valid=false set. */
3377 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3378 if (ServicePtrs[snum_template]->szService &&
3379 strequal(ServicePtrs[snum_template]->szService,
3380 Globals.usershare_template_share)) {
3385 if (snum_template == -1) {
3386 DEBUG(0,("load_usershare_service: usershare template share %s "
3387 "does not exist.\n",
3388 Globals.usershare_template_share ));
3393 return process_usershare_file(usersharepath, servicename, snum_template);
3396 /***************************************************************************
3397 Load all user defined shares from the user share directory.
3398 We only do this if we're enumerating the share list.
3399 This is the function that can delete usershares that have
3401 ***************************************************************************/
3403 int load_usershare_shares(struct smbd_server_connection *sconn,
3404 bool (*snumused) (struct smbd_server_connection *, int))
3407 SMB_STRUCT_STAT sbuf;
3409 int num_usershares = 0;
3410 int max_user_shares = Globals.usershare_max_shares;
3411 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3412 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3413 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3415 int snum_template = -1;
3416 const char *usersharepath = Globals.usershare_path;
3417 int ret = lp_numservices();
3418 TALLOC_CTX *tmp_ctx;
3420 if (max_user_shares == 0 || *usersharepath == '\0') {
3421 return lp_numservices();
3424 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3425 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3426 usersharepath, strerror(errno) ));
3431 * This directory must be owned by root, and have the 't' bit set.
3432 * It also must not be writable by "other".
3436 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3438 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3440 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3441 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3446 /* Ensure the template share exists if it's set. */
3447 if (Globals.usershare_template_share[0]) {
3448 /* We can't use lp_servicenumber here as we are recommending that
3449 template shares have -valid=false set. */
3450 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3451 if (ServicePtrs[snum_template]->szService &&
3452 strequal(ServicePtrs[snum_template]->szService,
3453 Globals.usershare_template_share)) {
3458 if (snum_template == -1) {
3459 DEBUG(0,("load_usershare_shares: usershare template share %s "
3460 "does not exist.\n",
3461 Globals.usershare_template_share ));
3466 /* Mark all existing usershares as pending delete. */
3467 for (iService = iNumServices - 1; iService >= 0; iService--) {
3468 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3469 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3473 dp = opendir(usersharepath);
3475 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3476 usersharepath, strerror(errno) ));
3480 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3482 num_dir_entries++ ) {
3484 const char *n = de->d_name;
3486 /* Ignore . and .. */
3488 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3494 /* Temporary file used when creating a share. */
3495 num_tmp_dir_entries++;
3498 /* Allow 20% tmp entries. */
3499 if (num_tmp_dir_entries > allowed_tmp_entries) {
3500 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3501 "in directory %s\n",
3502 num_tmp_dir_entries, usersharepath));
3506 r = process_usershare_file(usersharepath, n, snum_template);
3508 /* Update the services count. */
3510 if (num_usershares >= max_user_shares) {
3511 DEBUG(0,("load_usershare_shares: max user shares reached "
3512 "on file %s in directory %s\n",
3513 n, usersharepath ));
3516 } else if (r == -1) {
3517 num_bad_dir_entries++;
3520 /* Allow 20% bad entries. */
3521 if (num_bad_dir_entries > allowed_bad_entries) {
3522 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3523 "in directory %s\n",
3524 num_bad_dir_entries, usersharepath));
3528 /* Allow 20% bad entries. */
3529 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3530 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3531 "in directory %s\n",
3532 num_dir_entries, usersharepath));
3539 /* Sweep through and delete any non-refreshed usershares that are
3540 not currently in use. */
3541 tmp_ctx = talloc_stackframe();
3542 for (iService = iNumServices - 1; iService >= 0; iService--) {
3543 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3546 if (snumused && snumused(sconn, iService)) {
3550 servname = lp_servicename(tmp_ctx, iService);
3552 /* Remove from the share ACL db. */
3553 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3555 delete_share_security(servname);
3556 free_service_byindex(iService);
3559 talloc_free(tmp_ctx);
3561 return lp_numservices();
3564 /********************************************************
3565 Destroy global resources allocated in this file
3566 ********************************************************/
3568 void gfree_loadparm(void)
3574 /* Free resources allocated to services */
3576 for ( i = 0; i < iNumServices; i++ ) {
3578 free_service_byindex(i);
3582 TALLOC_FREE( ServicePtrs );
3585 /* Now release all resources allocated to global
3586 parameters and the default service */
3588 free_global_parameters();
3592 /***************************************************************************
3593 Allow client apps to specify that they are a client
3594 ***************************************************************************/
3595 static void lp_set_in_client(bool b)
3601 /***************************************************************************
3602 Determine if we're running in a client app
3603 ***************************************************************************/
3604 static bool lp_is_in_client(void)
3609 static void lp_enforce_ad_dc_settings(void)
3611 lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3612 lp_do_parameter(GLOBAL_SECTION_SNUM,
3613 "winbindd:use external pipes", "true");
3614 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
3615 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
3616 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
3617 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
3618 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
3619 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
3620 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
3621 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
3622 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
3625 /***************************************************************************
3626 Load the services array from the services file. Return true on success,
3628 ***************************************************************************/
3630 static bool lp_load_ex(const char *pszFname,
3634 bool reinit_globals,
3635 bool allow_include_registry,
3636 bool load_all_shares)
3640 TALLOC_CTX *frame = talloc_stackframe();
3641 struct loadparm_context *lp_ctx;
3645 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3647 bInGlobalSection = true;
3648 bGlobalOnly = global_only;
3649 bAllowIncludeRegistry = allow_include_registry;
3651 lp_ctx = setup_lp_context(talloc_tos());
3653 init_globals(lp_ctx, reinit_globals);
3657 if (save_defaults) {
3662 if (!reinit_globals) {
3663 free_param_opts(&Globals.param_opt);
3664 apply_lp_set_cmdline();
3667 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
3669 /* We get sections first, so have to start 'behind' to make up */
3672 if (lp_config_backend_is_file()) {
3673 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
3674 current_user_info.domain,
3677 smb_panic("lp_load_ex: out of memory");
3680 add_to_file_list(NULL, &file_lists, pszFname, n2);
3682 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
3685 /* finish up the last section */
3686 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3688 if (iServiceIndex >= 0) {
3689 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
3693 if (lp_config_backend_is_registry()) {
3695 /* config backend changed to registry in config file */
3697 * We need to use this extra global variable here to
3698 * survive restart: init_globals uses this as a default
3699 * for config_backend. Otherwise, init_globals would
3700 * send us into an endless loop here.
3703 config_backend = CONFIG_BACKEND_REGISTRY;
3705 DEBUG(1, ("lp_load_ex: changing to config backend "
3707 init_globals(lp_ctx, true);
3709 TALLOC_FREE(lp_ctx);
3711 lp_kill_all_services();
3712 ok = lp_load_ex(pszFname, global_only, save_defaults,
3713 add_ipc, reinit_globals,
3714 allow_include_registry,
3719 } else if (lp_config_backend_is_registry()) {
3720 bRetval = process_registry_globals();
3722 DEBUG(0, ("Illegal config backend given: %d\n",
3723 lp_config_backend()));
3727 if (bRetval && lp_registry_shares()) {
3728 if (load_all_shares) {
3729 bRetval = process_registry_shares();
3731 bRetval = reload_registry_shares();
3736 char *serv = lp_auto_services(talloc_tos());
3737 lp_add_auto_services(serv);
3742 /* When 'restrict anonymous = 2' guest connections to ipc$
3744 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3745 if ( lp_enable_asu_support() ) {
3746 lp_add_ipc("ADMIN$", false);
3750 set_allowed_client_auth();
3752 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
3753 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
3754 lp_password_server()));
3759 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
3760 /* if we_are_a_wins_server is true and we are in the client */
3761 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
3762 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3767 fault_configure(smb_panic_s3);
3770 * We run this check once the whole smb.conf is parsed, to
3771 * force some settings for the standard way a AD DC is
3772 * operated. We may change these as our code evolves, which
3773 * is why we force these settings.
3775 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3776 lp_enforce_ad_dc_settings();
3779 bAllowIncludeRegistry = true;
3785 static bool lp_load(const char *pszFname,
3789 bool reinit_globals)
3791 return lp_load_ex(pszFname,
3796 true, /* allow_include_registry */
3797 false); /* load_all_shares*/
3800 bool lp_load_initial_only(const char *pszFname)
3802 return lp_load_ex(pszFname,
3803 true, /* global only */
3804 true, /* save_defaults */
3805 false, /* add_ipc */
3806 true, /* reinit_globals */
3807 false, /* allow_include_registry */
3808 false); /* load_all_shares*/
3812 * most common lp_load wrapper, loading only the globals
3814 bool lp_load_global(const char *file_name)
3816 return lp_load(file_name,
3817 true, /* global_only */
3818 false, /* save_defaults */
3819 false, /* add_ipc */
3820 true); /* reinit_globals */
3824 * The typical lp_load wrapper with shares, loads global and
3825 * shares, including IPC, but does not force immediate
3826 * loading of all shares from registry.
3828 bool lp_load_with_shares(const char *file_name)
3830 return lp_load(file_name,
3831 false, /* global_only */
3832 false, /* save_defaults */
3834 true); /* reinit_globals */
3838 * lp_load wrapper, especially for clients
3840 bool lp_load_client(const char *file_name)
3842 lp_set_in_client(true);
3844 return lp_load_global(file_name);
3848 * lp_load wrapper, loading only globals, but intended
3849 * for subsequent calls, not reinitializing the globals
3852 bool lp_load_global_no_reinit(const char *file_name)
3854 return lp_load(file_name,
3855 true, /* global_only */
3856 false, /* save_defaults */
3857 false, /* add_ipc */
3858 false); /* reinit_globals */
3862 * lp_load wrapper, loading globals and shares,
3863 * intended for subsequent calls, i.e. not reinitializing
3864 * the globals to default values.
3866 bool lp_load_no_reinit(const char *file_name)
3868 return lp_load(file_name,
3869 false, /* global_only */
3870 false, /* save_defaults */
3871 false, /* add_ipc */
3872 false); /* reinit_globals */
3877 * lp_load wrapper, especially for clients, no reinitialization
3879 bool lp_load_client_no_reinit(const char *file_name)
3881 lp_set_in_client(true);
3883 return lp_load_global_no_reinit(file_name);
3886 bool lp_load_with_registry_shares(const char *pszFname)
3888 return lp_load_ex(pszFname,
3889 false, /* global_only */
3890 true, /* save_defaults */
3891 false, /* add_ipc */
3892 false, /* reinit_globals */
3893 true, /* allow_include_registry */
3894 true); /* load_all_shares*/
3897 /***************************************************************************
3898 Return the max number of services.
3899 ***************************************************************************/
3901 int lp_numservices(void)
3903 return (iNumServices);
3906 /***************************************************************************
3907 Display the contents of the services array in human-readable form.
3908 ***************************************************************************/
3910 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
3913 struct loadparm_context *lp_ctx;
3916 defaults_saved = false;
3918 lp_ctx = setup_lp_context(talloc_tos());
3919 if (lp_ctx == NULL) {
3923 lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
3925 lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
3927 for (iService = 0; iService < maxtoprint; iService++) {
3929 lp_dump_one(f, show_defaults, iService);
3933 /***************************************************************************
3934 Display the contents of one service in human-readable form.
3935 ***************************************************************************/
3937 void lp_dump_one(FILE * f, bool show_defaults, int snum)
3940 if (ServicePtrs[snum]->szService[0] == '\0')
3942 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
3943 flags_list, show_defaults);
3947 /***************************************************************************
3948 Return the number of the service with the given name, or -1 if it doesn't
3949 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3950 getservicebyname()! This works ONLY if all services have been loaded, and
3951 does not copy the found service.
3952 ***************************************************************************/
3954 int lp_servicenumber(const char *pszServiceName)
3957 fstring serviceName;
3959 if (!pszServiceName) {
3960 return GLOBAL_SECTION_SNUM;
3963 for (iService = iNumServices - 1; iService >= 0; iService--) {
3964 if (VALID(iService) && ServicePtrs[iService]->szService) {
3966 * The substitution here is used to support %U in
3969 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3970 standard_sub_basic(get_current_username(),
3971 current_user_info.domain,
3972 serviceName,sizeof(serviceName));
3973 if (strequal(serviceName, pszServiceName)) {
3979 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
3980 struct timespec last_mod;
3982 if (!usershare_exists(iService, &last_mod)) {
3983 /* Remove the share security tdb entry for it. */
3984 delete_share_security(lp_servicename(talloc_tos(), iService));
3985 /* Remove it from the array. */
3986 free_service_byindex(iService);
3987 /* Doesn't exist anymore. */
3988 return GLOBAL_SECTION_SNUM;
3991 /* Has it been modified ? If so delete and reload. */
3992 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3994 /* Remove it from the array. */
3995 free_service_byindex(iService);
3996 /* and now reload it. */
3997 iService = load_usershare_service(pszServiceName);
4002 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4003 return GLOBAL_SECTION_SNUM;
4009 /*******************************************************************
4010 A useful volume label function.
4011 ********************************************************************/
4013 const char *volume_label(TALLOC_CTX *ctx, int snum)
4016 const char *label = lp_volume(ctx, snum);
4018 label = lp_servicename(ctx, snum);
4021 /* This returns a 33 byte guarenteed null terminated string. */
4022 ret = talloc_strndup(ctx, label, 32);
4029 /*******************************************************************
4030 Get the default server type we will announce as via nmbd.
4031 ********************************************************************/
4033 int lp_default_server_announce(void)
4035 int default_server_announce = 0;
4036 default_server_announce |= SV_TYPE_WORKSTATION;
4037 default_server_announce |= SV_TYPE_SERVER;
4038 default_server_announce |= SV_TYPE_SERVER_UNIX;
4040 /* note that the flag should be set only if we have a
4041 printer service but nmbd doesn't actually load the
4042 services so we can't tell --jerry */
4044 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4046 default_server_announce |= SV_TYPE_SERVER_NT;
4047 default_server_announce |= SV_TYPE_NT;
4049 switch (lp_server_role()) {
4050 case ROLE_DOMAIN_MEMBER:
4051 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4053 case ROLE_DOMAIN_PDC:
4054 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4056 case ROLE_DOMAIN_BDC:
4057 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4059 case ROLE_STANDALONE:
4063 if (lp_time_server())
4064 default_server_announce |= SV_TYPE_TIME_SOURCE;
4066 if (lp_host_msdfs())
4067 default_server_announce |= SV_TYPE_DFS_SERVER;
4069 return default_server_announce;
4072 /***********************************************************
4073 If we are PDC then prefer us as DMB
4074 ************************************************************/
4076 bool lp_domain_master(void)
4078 if (Globals._domain_master == Auto)
4079 return (lp_server_role() == ROLE_DOMAIN_PDC);
4081 return (bool)Globals._domain_master;
4084 /***********************************************************
4085 If we are PDC then prefer us as DMB
4086 ************************************************************/
4088 static bool lp_domain_master_true_or_auto(void)
4090 if (Globals._domain_master) /* auto or yes */
4096 /***********************************************************
4097 If we are DMB then prefer us as LMB
4098 ************************************************************/
4100 bool lp_preferred_master(void)
4102 if (Globals.iPreferredMaster == Auto)
4103 return (lp_local_master() && lp_domain_master());
4105 return (bool)Globals.iPreferredMaster;
4108 /*******************************************************************
4110 ********************************************************************/
4112 void lp_remove_service(int snum)
4114 ServicePtrs[snum]->valid = false;
4117 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4119 const char *ret = lp__printername(ctx, snum);
4120 if (ret == NULL || *ret == '\0') {
4121 ret = lp_const_servicename(snum);
4128 /***********************************************************
4129 Allow daemons such as winbindd to fix their logfile name.
4130 ************************************************************/
4132 void lp_set_logfile(const char *name)
4134 string_set(Globals.ctx, &Globals.logfile, name);
4135 debug_set_logfile(name);
4138 /*******************************************************************
4139 Return the max print jobs per queue.
4140 ********************************************************************/
4142 int lp_maxprintjobs(int snum)
4144 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4145 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4146 maxjobs = PRINT_MAX_JOBID - 1;
4151 const char *lp_printcapname(void)
4153 if ((Globals.szPrintcapname != NULL) &&
4154 (Globals.szPrintcapname[0] != '\0'))
4155 return Globals.szPrintcapname;
4157 if (sDefault.printing == PRINT_CUPS) {
4161 if (sDefault.printing == PRINT_BSD)
4162 return "/etc/printcap";
4164 return PRINTCAP_NAME;
4167 static uint32_t spoolss_state;
4169 bool lp_disable_spoolss( void )
4171 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4172 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4174 return spoolss_state == SVCCTL_STOPPED ? true : false;
4177 void lp_set_spoolss_state( uint32_t state )
4179 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4181 spoolss_state = state;
4184 uint32_t lp_get_spoolss_state( void )
4186 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4189 /*******************************************************************
4190 Ensure we don't use sendfile if server smb signing is active.
4191 ********************************************************************/
4193 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4195 bool sign_active = false;
4197 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4198 if (get_Protocol() < PROTOCOL_NT1) {
4201 if (signing_state) {
4202 sign_active = smb_signing_is_active(signing_state);
4204 return (lp__use_sendfile(snum) &&
4205 (get_remote_arch() != RA_WIN95) &&
4209 /*******************************************************************
4210 Turn off sendfile if we find the underlying OS doesn't support it.
4211 ********************************************************************/
4213 void set_use_sendfile(int snum, bool val)
4215 if (LP_SNUM_OK(snum))
4216 ServicePtrs[snum]->_use_sendfile = val;
4218 sDefault._use_sendfile = val;
4221 /*******************************************************************
4222 Turn off storing DOS attributes if this share doesn't support it.
4223 ********************************************************************/
4225 void set_store_dos_attributes(int snum, bool val)
4227 if (!LP_SNUM_OK(snum))
4229 ServicePtrs[(snum)]->store_dos_attributes = val;
4232 void lp_set_mangling_method(const char *new_method)
4234 string_set(Globals.ctx, &Globals.mangling_method, new_method);
4237 /*******************************************************************
4238 Global state for POSIX pathname processing.
4239 ********************************************************************/
4241 static bool posix_pathnames;
4243 bool lp_posix_pathnames(void)
4245 return posix_pathnames;
4248 /*******************************************************************
4249 Change everything needed to ensure POSIX pathname processing (currently
4251 ********************************************************************/
4253 void lp_set_posix_pathnames(void)
4255 posix_pathnames = true;
4258 /*******************************************************************
4259 Global state for POSIX lock processing - CIFS unix extensions.
4260 ********************************************************************/
4262 bool posix_default_lock_was_set;
4263 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4265 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4267 if (posix_default_lock_was_set) {
4268 return posix_cifsx_locktype;
4270 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
4274 /*******************************************************************
4275 ********************************************************************/
4277 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4279 posix_default_lock_was_set = true;
4280 posix_cifsx_locktype = val;
4283 int lp_min_receive_file_size(void)
4285 if (Globals.iminreceivefile < 0) {
4288 return Globals.iminreceivefile;
4291 /*******************************************************************
4292 Safe wide links checks.
4293 This helper function always verify the validity of wide links,
4294 even after a configuration file reload.
4295 ********************************************************************/
4297 static bool lp_widelinks_internal(int snum)
4299 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
4300 sDefault.bWidelinks);
4303 void widelinks_warning(int snum)
4305 if (lp_allow_insecure_wide_links()) {
4309 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
4310 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4311 "These parameters are incompatible. "
4312 "Wide links will be disabled for this share.\n",
4313 lp_servicename(talloc_tos(), snum) ));
4317 bool lp_widelinks(int snum)
4319 /* wide links is always incompatible with unix extensions */
4320 if (lp_unix_extensions()) {
4322 * Unless we have "allow insecure widelinks"
4325 if (!lp_allow_insecure_wide_links()) {
4330 return lp_widelinks_internal(snum);
4333 int lp_server_role(void)
4335 return lp_find_server_role(lp__server_role(),
4337 lp__domain_logons(),
4338 lp_domain_master_true_or_auto());
4341 int lp_security(void)
4343 return lp_find_security(lp__server_role(),
4347 int lp_client_max_protocol(void)
4349 int client_max_protocol = lp__client_max_protocol();
4350 if (client_max_protocol == PROTOCOL_DEFAULT) {
4351 return PROTOCOL_NT1;
4353 return client_max_protocol;
4356 int lp_winbindd_max_protocol(void)
4358 int client_max_protocol = lp__client_max_protocol();
4359 if (client_max_protocol == PROTOCOL_DEFAULT) {
4360 return PROTOCOL_LATEST;
4362 return client_max_protocol;
4365 struct loadparm_global * get_globals(void)
4370 unsigned int * get_flags(void)
4372 if (flags_list == NULL) {
4373 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());