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"
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
81 #ifdef CLUSTER_SUPPORT
82 #include "ctdb_private.h"
87 extern userdom_struct current_user_info;
89 /* the special value for the include parameter
90 * to be interpreted not as a file name but to
91 * trigger loading of the global smb.conf options
93 #ifndef INCLUDE_REGISTRY_NAME
94 #define INCLUDE_REGISTRY_NAME "registry"
97 static bool in_client = false; /* Not in the client by default */
98 static struct smbconf_csn conf_last_csn;
100 static int config_backend = CONFIG_BACKEND_FILE;
102 /* some helpful bits */
103 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
104 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
106 #define USERSHARE_VALID 1
107 #define USERSHARE_PENDING_DELETE 2
109 static bool defaults_saved = false;
111 #include "lib/param/param_global.h"
113 static struct loadparm_global Globals;
115 /* This is a default service used to prime a services structure */
116 static struct loadparm_service sDefault =
121 .usershare_last_mod = {0, 0},
125 .invalid_users = NULL,
132 .root_preexec = NULL,
133 .root_postexec = NULL,
134 .cups_options = NULL,
135 .print_command = NULL,
137 .lprm_command = NULL,
138 .lppause_command = NULL,
139 .lpresume_command = NULL,
140 .queuepause_command = NULL,
141 .queueresume_command = NULL,
142 ._printername = NULL,
143 .printjob_username = NULL,
144 .dont_descend = NULL,
147 .magic_script = NULL,
148 .magic_output = NULL,
151 .veto_oplock_files = NULL,
161 .aio_write_behind = NULL,
162 .dfree_command = NULL,
163 .min_print_space = 0,
164 .iMaxPrintJobs = 1000,
165 .max_reported_print_jobs = 0,
166 .write_cache_size = 0,
168 .force_create_mode = 0,
169 .directory_mask = 0755,
170 .force_directory_mode = 0,
171 .max_connections = 0,
172 .default_case = CASE_LOWER,
173 .printing = DEFAULT_PRINTING,
174 .oplock_contention_limit = 2,
177 .dfree_cache_time = 0,
178 .preexec_close = false,
179 .root_preexec_close = false,
180 .case_sensitive = Auto,
181 .preserve_case = true,
182 .short_preserve_case = true,
183 .hide_dot_files = true,
184 .hide_special_files = false,
185 .hide_unreadable = false,
186 .hide_unwriteable_files = false,
188 .access_based_share_enum = false,
192 .administrative_share = false,
195 .print_notify_backchannel = false,
199 .store_dos_attributes = false,
200 .dmapi_support = false,
202 .strict_locking = Auto,
203 .posix_locking = true,
205 .kernel_oplocks = false,
206 .level2_oplocks = true,
208 .mangled_names = true,
210 .follow_symlinks = true,
211 .sync_always = false,
212 .strict_allocate = false,
213 .strict_sync = false,
214 .mangling_char = '~',
216 .delete_readonly = false,
217 .fake_oplocks = false,
218 .delete_veto_files = false,
219 .dos_filemode = false,
220 .dos_filetimes = true,
221 .dos_filetime_resolution = false,
222 .fake_directory_create_times = false,
223 .blocking_locks = true,
224 .inherit_permissions = false,
225 .inherit_acls = false,
226 .inherit_owner = 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;
264 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
266 /* prototypes for the special type handlers */
267 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
268 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
269 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
270 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
271 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
272 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
273 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
274 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
275 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
276 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
277 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
278 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
280 /* these are parameter handlers which are not needed in the
284 #define handle_logfile NULL
286 static void set_allowed_client_auth(void);
288 static void add_to_file_list(const char *fname, const char *subfname);
289 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
290 static void free_param_opts(struct parmlist_entry **popts);
292 #include "lib/param/param_table.c"
294 /* this is used to prevent lots of mallocs of size 1 */
295 static const char null_string[] = "";
298 Set a string value, allocing the space for the string
301 static bool string_init(char **dest,const char *src)
311 *dest = discard_const_p(char, null_string);
313 (*dest) = SMB_STRDUP(src);
314 if ((*dest) == NULL) {
315 DEBUG(0,("Out of memory in string_init\n"));
326 static void string_free(char **s)
330 if (*s == null_string)
336 Set a string value, deallocating any existing space, and allocing the space
340 static bool string_set(char **dest,const char *src)
343 return(string_init(dest,src));
346 /***************************************************************************
347 Initialise the sDefault parameter structure for the printer values.
348 ***************************************************************************/
350 static void init_printer_values(struct loadparm_service *pService)
352 /* choose defaults depending on the type of printing */
353 switch (pService->printing) {
358 string_set(&pService->lpq_command, "lpq -P'%p'");
359 string_set(&pService->lprm_command, "lprm -P'%p' %j");
360 string_set(&pService->print_command, "lpr -r -P'%p' %s");
365 string_set(&pService->lpq_command, "lpq -P'%p'");
366 string_set(&pService->lprm_command, "lprm -P'%p' %j");
367 string_set(&pService->print_command, "lpr -r -P'%p' %s");
368 string_set(&pService->queuepause_command, "lpc stop '%p'");
369 string_set(&pService->queueresume_command, "lpc start '%p'");
370 string_set(&pService->lppause_command, "lpc hold '%p' %j");
371 string_set(&pService->lpresume_command, "lpc release '%p' %j");
376 /* set the lpq command to contain the destination printer
377 name only. This is used by cups_queue_get() */
378 string_set(&pService->lpq_command, "%p");
379 string_set(&pService->lprm_command, "");
380 string_set(&pService->print_command, "");
381 string_set(&pService->lppause_command, "");
382 string_set(&pService->lpresume_command, "");
383 string_set(&pService->queuepause_command, "");
384 string_set(&pService->queueresume_command, "");
389 string_set(&pService->lpq_command, "lpstat -o%p");
390 string_set(&pService->lprm_command, "cancel %p-%j");
391 string_set(&pService->print_command, "lp -c -d%p %s; rm %s");
392 string_set(&pService->queuepause_command, "disable %p");
393 string_set(&pService->queueresume_command, "enable %p");
395 string_set(&pService->lppause_command, "lp -i %p-%j -H hold");
396 string_set(&pService->lpresume_command, "lp -i %p-%j -H resume");
401 string_set(&pService->lpq_command, "lpq -P%p");
402 string_set(&pService->lprm_command, "lprm -P%p %j");
403 string_set(&pService->print_command, "lp -r -P%p %s");
406 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
411 TALLOC_CTX *tmp_ctx = talloc_stackframe();
414 tdbfile = talloc_asprintf(
415 tmp_ctx, "tdbfile=%s",
416 lp_parm_const_string(-1, "vlp", "tdbfile",
418 if (tdbfile == NULL) {
419 tdbfile="tdbfile=/tmp/vlp.tdb";
422 tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
424 string_set(&pService->print_command,
425 tmp ? tmp : "vlp print %p %s");
427 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
429 string_set(&pService->lpq_command,
430 tmp ? tmp : "vlp lpq %p");
432 tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
434 string_set(&pService->lprm_command,
435 tmp ? tmp : "vlp lprm %p %j");
437 tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
439 string_set(&pService->lppause_command,
440 tmp ? tmp : "vlp lppause %p %j");
442 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
444 string_set(&pService->lpresume_command,
445 tmp ? tmp : "vlp lpresume %p %j");
447 tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
449 string_set(&pService->queuepause_command,
450 tmp ? tmp : "vlp queuepause %p");
452 tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
454 string_set(&pService->queueresume_command,
455 tmp ? tmp : "vlp queueresume %p");
456 TALLOC_FREE(tmp_ctx);
460 #endif /* DEVELOPER */
465 * Function to return the default value for the maximum number of open
466 * file descriptors permitted. This function tries to consult the
467 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
468 * the smaller of those.
470 static int max_open_files(void)
472 int sysctl_max = MAX_OPEN_FILES;
473 int rlimit_max = MAX_OPEN_FILES;
475 #ifdef HAVE_SYSCTLBYNAME
477 size_t size = sizeof(sysctl_max);
478 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
483 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
489 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
490 rlimit_max = rl.rlim_cur;
492 #if defined(RLIM_INFINITY)
493 if(rl.rlim_cur == RLIM_INFINITY)
494 rlimit_max = MAX_OPEN_FILES;
499 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
500 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
501 "minimum Windows limit (%d)\n",
503 MIN_OPEN_FILES_WINDOWS));
504 sysctl_max = MIN_OPEN_FILES_WINDOWS;
507 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
508 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
509 "minimum Windows limit (%d)\n",
511 MIN_OPEN_FILES_WINDOWS));
512 rlimit_max = MIN_OPEN_FILES_WINDOWS;
515 return MIN(sysctl_max, rlimit_max);
519 * Common part of freeing allocated data for one parameter.
521 static void free_one_parameter_common(void *parm_ptr,
522 struct parm_struct parm)
524 if ((parm.type == P_STRING) ||
525 (parm.type == P_USTRING))
527 string_free((char**)parm_ptr);
528 } else if (parm.type == P_LIST) {
529 TALLOC_FREE(*((char***)parm_ptr));
534 * Free the allocated data for one parameter for a share
535 * given as a service struct.
537 static void free_one_parameter(struct loadparm_service *service,
538 struct parm_struct parm)
542 if (parm.p_class != P_LOCAL) {
546 parm_ptr = lp_parm_ptr(service, &parm);
548 free_one_parameter_common(parm_ptr, parm);
552 * Free the allocated parameter data of a share given
553 * as a service struct.
555 static void free_parameters(struct loadparm_service *service)
559 for (i=0; parm_table[i].label; i++) {
560 free_one_parameter(service, parm_table[i]);
565 * Free the allocated data for one parameter for a given share
566 * specified by an snum.
568 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
573 parm_ptr = lp_parm_ptr(NULL, &parm);
574 } else if (parm.p_class != P_LOCAL) {
577 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
580 free_one_parameter_common(parm_ptr, parm);
584 * Free the allocated parameter data for a share specified
587 static void free_parameters_by_snum(int snum)
591 for (i=0; parm_table[i].label; i++) {
592 free_one_parameter_by_snum(snum, parm_table[i]);
597 * Free the allocated global parameters.
599 static void free_global_parameters(void)
601 free_param_opts(&Globals.param_opt);
602 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
603 TALLOC_FREE(Globals.ctx);
606 struct lp_stored_option {
607 struct lp_stored_option *prev, *next;
612 static struct lp_stored_option *stored_options;
615 save options set by lp_set_cmdline() into a list. This list is
616 re-applied when we do a globals reset, so that cmdline set options
617 are sticky across reloads of smb.conf
619 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
621 struct lp_stored_option *entry, *entry_next;
622 for (entry = stored_options; entry != NULL; entry = entry_next) {
623 entry_next = entry->next;
624 if (strcmp(pszParmName, entry->label) == 0) {
625 DLIST_REMOVE(stored_options, entry);
631 entry = talloc(NULL, struct lp_stored_option);
636 entry->label = talloc_strdup(entry, pszParmName);
642 entry->value = talloc_strdup(entry, pszParmValue);
648 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
653 static bool apply_lp_set_cmdline(void)
655 struct lp_stored_option *entry = NULL;
656 for (entry = stored_options; entry != NULL; entry = entry->next) {
657 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
658 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
659 entry->label, entry->value));
666 /***************************************************************************
667 Initialise the global parameter structure.
668 ***************************************************************************/
670 static void init_globals(bool reinit_globals)
672 static bool done_init = false;
676 /* If requested to initialize only once and we've already done it... */
677 if (!reinit_globals && done_init) {
678 /* ... then we have nothing more to do */
683 /* The logfile can be set before this is invoked. Free it if so. */
684 if (Globals.logfile != NULL) {
685 string_free(&Globals.logfile);
686 Globals.logfile = NULL;
690 free_global_parameters();
693 /* This memset and the free_global_parameters() above will
694 * wipe out smb.conf options set with lp_set_cmdline(). The
695 * apply_lp_set_cmdline() call puts these values back in the
696 * table once the defaults are set */
697 ZERO_STRUCT(Globals);
699 Globals.ctx = talloc_new(NULL);
701 for (i = 0; parm_table[i].label; i++) {
702 if ((parm_table[i].type == P_STRING ||
703 parm_table[i].type == P_USTRING))
705 string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
710 string_set(&sDefault.fstype, FSTYPE_STRING);
711 string_set(&sDefault.printjob_username, "%U");
713 init_printer_values(&sDefault);
715 sDefault.ntvfs_handler = (const char **)str_list_make_v3(NULL, "unixuid default", NULL);
717 DEBUG(3, ("Initialising global parameters\n"));
719 /* Must manually force to upper case here, as this does not go via the handler */
720 string_set(&Globals.netbios_name, myhostname_upper());
722 string_set(&Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
723 string_set(&Globals.private_dir, get_dyn_PRIVATE_DIR());
725 /* use the new 'hash2' method by default, with a prefix of 1 */
726 string_set(&Globals.mangling_method, "hash2");
727 Globals.mangle_prefix = 1;
729 string_set(&Globals.guest_account, GUEST_ACCOUNT);
731 /* using UTF8 by default allows us to support all chars */
732 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
734 /* Use codepage 850 as a default for the dos character set */
735 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
738 * Allow the default PASSWD_CHAT to be overridden in local.h.
740 string_set(&Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
742 string_set(&Globals.workgroup, DEFAULT_WORKGROUP);
744 string_set(&Globals.passwd_program, "");
745 string_set(&Globals.lock_directory, get_dyn_LOCKDIR());
746 string_set(&Globals.state_directory, get_dyn_STATEDIR());
747 string_set(&Globals.cache_directory, get_dyn_CACHEDIR());
748 string_set(&Globals.pid_directory, get_dyn_PIDDIR());
749 string_set(&Globals.nbt_client_socket_address, "0.0.0.0");
751 * By default support explicit binding to broadcast
754 Globals.nmbd_bind_explicit_broadcast = true;
756 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
757 smb_panic("init_globals: ENOMEM");
759 string_set(&Globals.server_string, s);
762 string_set(&Globals.panic_action, "/bin/sleep 999999999");
765 string_set(&Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
767 string_set(&Globals.logon_drive, "");
768 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
769 string_set(&Globals.logon_home, "\\\\%N\\%U");
770 string_set(&Globals.logon_path, "\\\\%N\\%U\\profile");
772 Globals.name_resolve_order = (const char **)str_list_make_v3(NULL, "lmhosts wins host bcast", NULL);
773 string_set(&Globals.password_server, "*");
775 Globals.algorithmic_rid_base = BASE_RID;
777 Globals.load_printers = true;
778 Globals.printcap_cache_time = 750; /* 12.5 minutes */
780 Globals.config_backend = config_backend;
781 Globals._server_role = ROLE_AUTO;
783 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
784 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
785 Globals.max_xmit = 0x4104;
786 Globals.max_mux = 50; /* This is *needed* for profile support. */
787 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
788 Globals._disable_spoolss = false;
789 Globals.max_smbd_processes = 0;/* no limit specified */
790 Globals.username_level = 0;
791 Globals.deadtime = 0;
792 Globals.getwd_cache = true;
793 Globals.large_readwrite = true;
794 Globals.max_log_size = 5000;
795 Globals.max_open_files = max_open_files();
796 Globals.server_max_protocol = PROTOCOL_SMB3_00;
797 Globals.server_min_protocol = PROTOCOL_LANMAN1;
798 Globals.client_max_protocol = PROTOCOL_NT1;
799 Globals.client_min_protocol = PROTOCOL_CORE;
800 Globals._security = SEC_AUTO;
801 Globals.encrypt_passwords = true;
802 Globals.client_schannel = Auto;
803 Globals.winbind_sealed_pipes = true;
804 Globals.require_strong_key = true;
805 Globals.server_schannel = Auto;
806 Globals.read_raw = true;
807 Globals.write_raw = true;
808 Globals.null_passwords = false;
809 Globals.obey_pam_restrictions = false;
811 Globals.syslog_only = false;
812 Globals.timestamp_logs = true;
813 string_set(&Globals.log_level, "0");
814 Globals.debug_prefix_timestamp = false;
815 Globals.debug_hires_timestamp = true;
816 Globals.debug_pid = false;
817 Globals.debug_uid = false;
818 Globals.debug_class = false;
819 Globals.enable_core_files = true;
820 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
821 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
822 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
823 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
824 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
825 Globals.lm_interval = 60;
826 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
827 Globals.nis_homedir = false;
828 #ifdef WITH_NISPLUS_HOME
829 string_set(&Globals.homedir_map, "auto_home.org_dir");
831 string_set(&Globals.homedir_map, "auto.home");
834 Globals.time_server = false;
835 Globals.bind_interfaces_only = false;
836 Globals.unix_password_sync = false;
837 Globals.pam_password_change = false;
838 Globals.passwd_chat_debug = false;
839 Globals.passwd_chat_timeout = 2; /* 2 second default. */
840 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
841 Globals.nt_status_support = true; /* Use NT status by default. */
842 Globals.stat_cache = true; /* use stat cache by default */
843 Globals.max_stat_cache_size = 256; /* 256k by default */
844 Globals.restrict_anonymous = 0;
845 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
846 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
847 Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
848 Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
849 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 */
850 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
852 Globals.map_to_guest = 0; /* By Default, "Never" */
853 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
854 Globals.enhanced_browsing = true;
855 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
856 #ifdef MMAP_BLACKLIST
857 Globals.use_mmap = false;
859 Globals.use_mmap = true;
861 Globals.unicode = true;
862 Globals.unix_extensions = true;
863 Globals.reset_on_zero_vc = false;
864 Globals.log_writeable_files_on_exit = false;
865 Globals.create_krb5_conf = true;
866 Globals.winbindMaxDomainConnections = 1;
868 /* hostname lookups can be very expensive and are broken on
869 a large number of sites (tridge) */
870 Globals.hostname_lookups = false;
872 string_set(&Globals.passdb_backend, "tdbsam");
873 string_set(&Globals.ldap_suffix, "");
874 string_set(&Globals.szLdapMachineSuffix, "");
875 string_set(&Globals.szLdapUserSuffix, "");
876 string_set(&Globals.szLdapGroupSuffix, "");
877 string_set(&Globals.szLdapIdmapSuffix, "");
879 string_set(&Globals.ldap_admin_dn, "");
880 Globals.ldap_ssl = LDAP_SSL_START_TLS;
881 Globals.ldap_ssl_ads = false;
882 Globals.ldap_deref = -1;
883 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
884 Globals.ldap_delete_dn = false;
885 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
886 Globals.ldap_follow_referral = Auto;
887 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
888 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
889 Globals.ldap_page_size = LDAP_PAGE_SIZE;
891 Globals.ldap_debug_level = 0;
892 Globals.ldap_debug_threshold = 10;
894 /* This is what we tell the afs client. in reality we set the token
895 * to never expire, though, when this runs out the afs client will
896 * forget the token. Set to 0 to get NEVERDATE.*/
897 Globals.afs_token_lifetime = 604800;
898 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
900 /* these parameters are set to defaults that are more appropriate
901 for the increasing samba install base:
903 as a member of the workgroup, that will possibly become a
904 _local_ master browser (lm = true). this is opposed to a forced
905 local master browser startup (pm = true).
907 doesn't provide WINS server service by default (wsupp = false),
908 and doesn't provide domain master browser services by default, either.
912 Globals.show_add_printer_wizard = true;
913 Globals.os_level = 20;
914 Globals.local_master = true;
915 Globals._domain_master = Auto; /* depending on _domain_logons */
916 Globals._domain_logons = false;
917 Globals.browse_list = true;
918 Globals.we_are_a_wins_server = false;
919 Globals.wins_proxy = false;
921 TALLOC_FREE(Globals.init_logon_delayed_hosts);
922 Globals.init_logon_delay = 100; /* 100 ms default delay */
924 Globals.wins_dns_proxy = true;
926 Globals.allow_trusted_domains = true;
927 string_set(&Globals.szIdmapBackend, "tdb");
929 string_set(&Globals.template_shell, "/bin/false");
930 string_set(&Globals.template_homedir, "/home/%D/%U");
931 string_set(&Globals.winbind_separator, "\\");
932 string_set(&Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
934 string_set(&Globals.cups_server, "");
935 string_set(&Globals.iprint_server, "");
937 #ifdef CLUSTER_SUPPORT
938 string_set(&Globals.ctdbd_socket, CTDB_PATH);
940 string_set(&Globals.ctdbd_socket, "");
943 Globals.cluster_addresses = NULL;
944 Globals.clustering = false;
945 Globals.ctdb_timeout = 0;
946 Globals.ctdb_locktime_warn_threshold = 0;
948 Globals.winbind_cache_time = 300; /* 5 minutes */
949 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
950 Globals.winbind_max_clients = 200;
951 Globals.winbind_enum_users = false;
952 Globals.winbind_enum_groups = false;
953 Globals.winbind_use_default_domain = false;
954 Globals.winbind_trusted_domains_only = false;
955 Globals.winbind_nested_groups = true;
956 Globals.winbind_expand_groups = 1;
957 Globals.winbind_nss_info = (const char **)str_list_make_v3(NULL, "template", NULL);
958 Globals.winbind_refresh_tickets = false;
959 Globals.winbind_offline_logon = false;
961 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
962 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
964 Globals.passdb_expand_explicit = false;
966 Globals.name_cache_timeout = 660; /* In seconds */
968 Globals.use_spnego = true;
969 Globals.client_use_spnego = true;
971 Globals.client_signing = SMB_SIGNING_DEFAULT;
972 Globals.server_signing = SMB_SIGNING_DEFAULT;
974 Globals.defer_sharing_violations = true;
975 Globals.smb_ports = (const char **)str_list_make_v3(NULL, SMB_PORTS, NULL);
977 Globals.enable_privileges = true;
978 Globals.host_msdfs = true;
979 Globals.enable_asu_support = false;
981 /* User defined shares. */
982 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
983 smb_panic("init_globals: ENOMEM");
985 string_set(&Globals.usershare_path, s);
987 string_set(&Globals.usershare_template_share, "");
988 Globals.usershare_max_shares = 0;
989 /* By default disallow sharing of directories not owned by the sharer. */
990 Globals.usershare_owner_only = true;
991 /* By default disallow guest access to usershares. */
992 Globals.usershare_allow_guests = false;
994 Globals.keepalive = DEFAULT_KEEPALIVE;
996 /* By default no shares out of the registry */
997 Globals.registry_shares = false;
999 Globals.iminreceivefile = 0;
1001 Globals.map_untrusted_to_domain = false;
1002 Globals.multicast_dns_register = true;
1004 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
1005 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
1006 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
1007 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1009 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
1011 Globals.server_services = (const char **)str_list_make_v3(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbind ntp_signd kcc dnsupdate dns", NULL);
1013 Globals.dcerpc_endpoint_servers = (const char **)str_list_make_v3(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
1015 Globals.tls_enabled = true;
1017 string_set(&Globals._tls_keyfile, "tls/key.pem");
1018 string_set(&Globals._tls_certfile, "tls/cert.pem");
1019 string_set(&Globals._tls_cafile, "tls/ca.pem");
1021 string_set(&Globals.share_backend, "classic");
1023 Globals.iPreferredMaster = Auto;
1025 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
1027 string_set(&Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
1029 string_set(&Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
1031 if (asprintf(&s, "%s/samba_kcc", get_dyn_SCRIPTSBINDIR()) < 0) {
1032 smb_panic("init_globals: ENOMEM");
1034 Globals.samba_kcc_command = (const char **)str_list_make_v3(NULL, s, NULL);
1037 if (asprintf(&s, "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1038 smb_panic("init_globals: ENOMEM");
1040 Globals.dns_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1043 if (asprintf(&s, "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1044 smb_panic("init_globals: ENOMEM");
1046 Globals.spn_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1049 Globals.nsupdate_command = (const char **)str_list_make_v3(NULL, "/usr/bin/nsupdate -g", NULL);
1051 Globals.rndc_command = (const char **)str_list_make_v3(NULL, "/usr/sbin/rndc", NULL);
1053 Globals.cldap_port = 389;
1055 Globals.dgram_port = 138;
1057 Globals.nbt_port = 137;
1059 Globals.krb5_port = 88;
1061 Globals.kpasswd_port = 464;
1063 Globals.web_port = 901;
1065 /* Now put back the settings that were set with lp_set_cmdline() */
1066 apply_lp_set_cmdline();
1069 /*******************************************************************
1070 Convenience routine to grab string parameters into talloced memory
1071 and run standard_sub_basic on them. The buffers can be written to by
1072 callers without affecting the source string.
1073 ********************************************************************/
1075 static char *lp_string(TALLOC_CTX *ctx, const char *s)
1079 /* The follow debug is useful for tracking down memory problems
1080 especially if you have an inner loop that is calling a lp_*()
1081 function that returns a string. Perhaps this debug should be
1082 present all the time? */
1085 DEBUG(10, ("lp_string(%s)\n", s));
1091 ret = talloc_sub_basic(ctx,
1092 get_current_username(),
1093 current_user_info.domain,
1095 if (trim_char(ret, '\"', '\"')) {
1096 if (strchr(ret,'\"') != NULL) {
1098 ret = talloc_sub_basic(ctx,
1099 get_current_username(),
1100 current_user_info.domain,
1108 In this section all the functions that are used to access the
1109 parameters from the rest of the program are defined
1112 #define FN_GLOBAL_STRING(fn_name,ptr) \
1113 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1114 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1115 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1116 #define FN_GLOBAL_LIST(fn_name,ptr) \
1117 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1118 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1119 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1120 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1121 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1122 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1123 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1125 #define FN_LOCAL_STRING(fn_name,val) \
1126 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));}
1127 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1128 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1129 #define FN_LOCAL_LIST(fn_name,val) \
1130 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1131 #define FN_LOCAL_BOOL(fn_name,val) \
1132 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1133 #define FN_LOCAL_INTEGER(fn_name,val) \
1134 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1136 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1137 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1138 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1139 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1140 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1141 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1143 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
1144 winbindMaxDomainConnections)
1146 int lp_winbind_max_domain_connections(void)
1148 if (lp_winbind_offline_logon() &&
1149 lp_winbind_max_domain_connections_int() > 1) {
1150 DEBUG(1, ("offline logons active, restricting max domain "
1151 "connections to 1\n"));
1154 return MAX(1, lp_winbind_max_domain_connections_int());
1157 int lp_smb2_max_credits(void)
1159 if (Globals.ismb2_max_credits == 0) {
1160 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1162 return Globals.ismb2_max_credits;
1164 int lp_cups_encrypt(void)
1167 #ifdef HAVE_HTTPCONNECTENCRYPT
1168 switch (Globals.CupsEncrypt) {
1170 result = HTTP_ENCRYPT_REQUIRED;
1173 result = HTTP_ENCRYPT_ALWAYS;
1176 result = HTTP_ENCRYPT_NEVER;
1183 /* These functions remain in source3/param for now */
1185 #include "lib/param/param_functions.c"
1187 FN_LOCAL_STRING(servicename, szService)
1188 FN_LOCAL_CONST_STRING(const_servicename, szService)
1190 /* These functions cannot be auto-generated */
1191 FN_LOCAL_BOOL(autoloaded, autoloaded)
1192 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1194 /* local prototypes */
1196 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1197 static const char *get_boolean(bool bool_value);
1198 static int getservicebyname(const char *pszServiceName,
1199 struct loadparm_service *pserviceDest);
1200 static void copy_service(struct loadparm_service *pserviceDest,
1201 struct loadparm_service *pserviceSource,
1202 struct bitmap *pcopymapDest);
1203 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1205 static bool do_section(const char *pszSectionName, void *userdata);
1206 static void init_copymap(struct loadparm_service *pservice);
1207 static bool hash_a_service(const char *name, int number);
1208 static void free_service_byindex(int iService);
1209 static void show_parameter(int parmIndex);
1210 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1213 * This is a helper function for parametrical options support. It returns a
1214 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1215 * parametrical functions are quite simple
1217 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
1220 bool global_section = false;
1222 struct parmlist_entry *data;
1224 if (service == NULL) {
1225 data = Globals.param_opt;
1226 global_section = true;
1228 data = service->param_opt;
1231 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
1232 DEBUG(0,("asprintf failed!\n"));
1237 if (strwicmp(data->key, param_key) == 0) {
1238 string_free(¶m_key);
1244 if (!global_section) {
1245 /* Try to fetch the same option but from globals */
1246 /* but only if we are not already working with Globals */
1247 data = Globals.param_opt;
1249 if (strwicmp(data->key, param_key) == 0) {
1250 string_free(¶m_key);
1257 string_free(¶m_key);
1263 * This is a helper function for parametrical options support. It returns a
1264 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1265 * parametrical functions are quite simple
1267 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1270 if (snum >= iNumServices) return NULL;
1273 return get_parametrics_by_service(NULL, type, option);
1275 return get_parametrics_by_service(ServicePtrs[snum], type, option);
1280 #define MISSING_PARAMETER(name) \
1281 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1283 /*******************************************************************
1284 convenience routine to return int parameters.
1285 ********************************************************************/
1286 static int lp_int(const char *s)
1290 MISSING_PARAMETER(lp_int);
1294 return (int)strtol(s, NULL, 0);
1297 /*******************************************************************
1298 convenience routine to return unsigned long parameters.
1299 ********************************************************************/
1300 static unsigned long lp_ulong(const char *s)
1304 MISSING_PARAMETER(lp_ulong);
1308 return strtoul(s, NULL, 0);
1311 /*******************************************************************
1312 convenience routine to return boolean parameters.
1313 ********************************************************************/
1314 static bool lp_bool(const char *s)
1319 MISSING_PARAMETER(lp_bool);
1323 if (!set_boolean(s, &ret)) {
1324 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1331 /*******************************************************************
1332 convenience routine to return enum parameters.
1333 ********************************************************************/
1334 static int lp_enum(const char *s,const struct enum_list *_enum)
1338 if (!s || !*s || !_enum) {
1339 MISSING_PARAMETER(lp_enum);
1343 for (i=0; _enum[i].name; i++) {
1344 if (strequal(_enum[i].name,s))
1345 return _enum[i].value;
1348 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1352 #undef MISSING_PARAMETER
1354 /* Return parametric option from a given service. Type is a part of option before ':' */
1355 /* Parametric option has following syntax: 'Type: option = value' */
1356 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1358 struct parmlist_entry *data = get_parametrics(snum, type, option);
1360 if (data == NULL||data->value==NULL) {
1362 return lp_string(ctx, def);
1368 return lp_string(ctx, data->value);
1371 /* Return parametric option from a given service. Type is a part of option before ':' */
1372 /* Parametric option has following syntax: 'Type: option = value' */
1373 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1375 struct parmlist_entry *data = get_parametrics(snum, type, option);
1377 if (data == NULL||data->value==NULL)
1383 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
1385 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
1387 if (data == NULL||data->value==NULL)
1394 /* Return parametric option from a given service. Type is a part of option before ':' */
1395 /* Parametric option has following syntax: 'Type: option = value' */
1397 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1399 struct parmlist_entry *data = get_parametrics(snum, type, option);
1401 if (data == NULL||data->value==NULL)
1402 return (const char **)def;
1404 if (data->list==NULL) {
1405 data->list = str_list_make_v3(NULL, data->value, NULL);
1408 return (const char **)data->list;
1411 /* Return parametric option from a given service. Type is a part of option before ':' */
1412 /* Parametric option has following syntax: 'Type: option = value' */
1414 int lp_parm_int(int snum, const char *type, const char *option, int def)
1416 struct parmlist_entry *data = get_parametrics(snum, type, option);
1418 if (data && data->value && *data->value)
1419 return lp_int(data->value);
1424 /* Return parametric option from a given service. Type is a part of option before ':' */
1425 /* Parametric option has following syntax: 'Type: option = value' */
1427 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1429 struct parmlist_entry *data = get_parametrics(snum, type, option);
1431 if (data && data->value && *data->value)
1432 return lp_ulong(data->value);
1437 /* Return parametric option from a given service. Type is a part of option before ':' */
1438 /* Parametric option has following syntax: 'Type: option = value' */
1440 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1442 struct parmlist_entry *data = get_parametrics(snum, type, option);
1444 if (data && data->value && *data->value)
1445 return lp_bool(data->value);
1450 /* Return parametric option from a given service. Type is a part of option before ':' */
1451 /* Parametric option has following syntax: 'Type: option = value' */
1453 int lp_parm_enum(int snum, const char *type, const char *option,
1454 const struct enum_list *_enum, int def)
1456 struct parmlist_entry *data = get_parametrics(snum, type, option);
1458 if (data && data->value && *data->value && _enum)
1459 return lp_enum(data->value, _enum);
1465 /***************************************************************************
1466 Initialise a service to the defaults.
1467 ***************************************************************************/
1469 static void init_service(struct loadparm_service *pservice)
1471 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
1472 copy_service(pservice, &sDefault, NULL);
1477 * free a param_opts structure.
1478 * param_opts handling should be moved to talloc;
1479 * then this whole functions reduces to a TALLOC_FREE().
1482 static void free_param_opts(struct parmlist_entry **popts)
1484 struct parmlist_entry *opt, *next_opt;
1486 if (*popts != NULL) {
1487 DEBUG(5, ("Freeing parametrics:\n"));
1490 while (opt != NULL) {
1491 string_free(&opt->key);
1492 string_free(&opt->value);
1493 TALLOC_FREE(opt->list);
1494 next_opt = opt->next;
1501 /***************************************************************************
1502 Free the dynamically allocated parts of a service struct.
1503 ***************************************************************************/
1505 static void free_service(struct loadparm_service *pservice)
1510 if (pservice->szService)
1511 DEBUG(5, ("free_service: Freeing service %s\n",
1512 pservice->szService));
1514 free_parameters(pservice);
1516 string_free(&pservice->szService);
1517 TALLOC_FREE(pservice->copymap);
1519 free_param_opts(&pservice->param_opt);
1521 ZERO_STRUCTP(pservice);
1525 /***************************************************************************
1526 remove a service indexed in the ServicePtrs array from the ServiceHash
1527 and free the dynamically allocated parts
1528 ***************************************************************************/
1530 static void free_service_byindex(int idx)
1532 if ( !LP_SNUM_OK(idx) )
1535 ServicePtrs[idx]->valid = false;
1537 /* we have to cleanup the hash record */
1539 if (ServicePtrs[idx]->szService) {
1540 char *canon_name = canonicalize_servicename(
1542 ServicePtrs[idx]->szService );
1544 dbwrap_delete_bystring(ServiceHash, canon_name );
1545 TALLOC_FREE(canon_name);
1548 free_service(ServicePtrs[idx]);
1549 talloc_free_children(ServicePtrs[idx]);
1552 /***************************************************************************
1553 Add a new service to the services array initialising it with the given
1555 ***************************************************************************/
1557 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1560 struct loadparm_service tservice;
1561 int num_to_alloc = iNumServices + 1;
1562 struct loadparm_service **tsp = NULL;
1564 tservice = *pservice;
1566 /* it might already exist */
1568 i = getservicebyname(name, NULL);
1574 /* if not, then create one */
1576 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
1578 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1582 ServicePtrs[iNumServices] = talloc(NULL, struct loadparm_service);
1583 if (!ServicePtrs[iNumServices]) {
1584 DEBUG(0,("add_a_service: out of memory!\n"));
1589 ServicePtrs[i]->valid = true;
1591 init_service(ServicePtrs[i]);
1592 copy_service(ServicePtrs[i], &tservice, NULL);
1594 string_set(&ServicePtrs[i]->szService, name);
1596 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1597 i, ServicePtrs[i]->szService));
1599 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1606 /***************************************************************************
1607 Convert a string to uppercase and remove whitespaces.
1608 ***************************************************************************/
1610 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1615 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1619 result = talloc_strdup(ctx, src);
1620 SMB_ASSERT(result != NULL);
1622 if (!strlower_m(result)) {
1623 TALLOC_FREE(result);
1629 /***************************************************************************
1630 Add a name/index pair for the services array to the hash table.
1631 ***************************************************************************/
1633 static bool hash_a_service(const char *name, int idx)
1637 if ( !ServiceHash ) {
1638 DEBUG(10,("hash_a_service: creating servicehash\n"));
1639 ServiceHash = db_open_rbt(NULL);
1640 if ( !ServiceHash ) {
1641 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1646 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1649 canon_name = canonicalize_servicename(talloc_tos(), name );
1651 dbwrap_store_bystring(ServiceHash, canon_name,
1652 make_tdb_data((uint8 *)&idx, sizeof(idx)),
1655 TALLOC_FREE(canon_name);
1660 /***************************************************************************
1661 Add a new home service, with the specified home directory, defaults coming
1663 ***************************************************************************/
1665 bool lp_add_home(const char *pszHomename, int iDefaultService,
1666 const char *user, const char *pszHomedir)
1670 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1671 pszHomedir[0] == '\0') {
1675 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1680 if (!(*(ServicePtrs[iDefaultService]->path))
1681 || strequal(ServicePtrs[iDefaultService]->path,
1682 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1683 string_set(&ServicePtrs[i]->path, pszHomedir);
1686 if (!(*(ServicePtrs[i]->comment))) {
1687 char *comment = NULL;
1688 if (asprintf(&comment, "Home directory of %s", user) < 0) {
1691 string_set(&ServicePtrs[i]->comment, comment);
1695 /* set the browseable flag from the global default */
1697 ServicePtrs[i]->browseable = sDefault.browseable;
1698 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1700 ServicePtrs[i]->autoloaded = true;
1702 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1703 user, ServicePtrs[i]->path ));
1708 /***************************************************************************
1709 Add a new service, based on an old one.
1710 ***************************************************************************/
1712 int lp_add_service(const char *pszService, int iDefaultService)
1714 if (iDefaultService < 0) {
1715 return add_a_service(&sDefault, pszService);
1718 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1721 /***************************************************************************
1722 Add the IPC service.
1723 ***************************************************************************/
1725 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1727 char *comment = NULL;
1728 int i = add_a_service(&sDefault, ipc_name);
1733 if (asprintf(&comment, "IPC Service (%s)",
1734 Globals.server_string) < 0) {
1738 string_set(&ServicePtrs[i]->path, tmpdir());
1739 string_set(&ServicePtrs[i]->username, "");
1740 string_set(&ServicePtrs[i]->comment, comment);
1741 string_set(&ServicePtrs[i]->fstype, "IPC");
1742 ServicePtrs[i]->max_connections = 0;
1743 ServicePtrs[i]->bAvailable = true;
1744 ServicePtrs[i]->read_only = true;
1745 ServicePtrs[i]->guest_only = false;
1746 ServicePtrs[i]->administrative_share = true;
1747 ServicePtrs[i]->guest_ok = guest_ok;
1748 ServicePtrs[i]->printable = false;
1749 ServicePtrs[i]->browseable = sDefault.browseable;
1751 DEBUG(3, ("adding IPC service\n"));
1757 /***************************************************************************
1758 Add a new printer service, with defaults coming from service iFrom.
1759 ***************************************************************************/
1761 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1763 const char *comment = "From Printcap";
1764 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1769 /* note that we do NOT default the availability flag to true - */
1770 /* we take it from the default service passed. This allows all */
1771 /* dynamic printers to be disabled by disabling the [printers] */
1772 /* entry (if/when the 'available' keyword is implemented!). */
1774 /* the printer name is set to the service name. */
1775 string_set(&ServicePtrs[i]->_printername, pszPrintername);
1776 string_set(&ServicePtrs[i]->comment, comment);
1778 /* set the browseable flag from the gloabl default */
1779 ServicePtrs[i]->browseable = sDefault.browseable;
1781 /* Printers cannot be read_only. */
1782 ServicePtrs[i]->read_only = false;
1783 /* No oplocks on printer services. */
1784 ServicePtrs[i]->oplocks = false;
1785 /* Printer services must be printable. */
1786 ServicePtrs[i]->printable = true;
1788 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1794 /***************************************************************************
1795 Check whether the given parameter name is valid.
1796 Parametric options (names containing a colon) are considered valid.
1797 ***************************************************************************/
1799 bool lp_parameter_is_valid(const char *pszParmName)
1801 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1802 (strchr(pszParmName, ':') != NULL));
1805 /***************************************************************************
1806 Check whether the given name is the name of a global parameter.
1807 Returns true for strings belonging to parameters of class
1808 P_GLOBAL, false for all other strings, also for parametric options
1809 and strings not belonging to any option.
1810 ***************************************************************************/
1812 bool lp_parameter_is_global(const char *pszParmName)
1814 int num = lpcfg_map_parameter(pszParmName);
1817 return (parm_table[num].p_class == P_GLOBAL);
1823 /**************************************************************************
1824 Check whether the given name is the canonical name of a parameter.
1825 Returns false if it is not a valid parameter Name.
1826 For parametric options, true is returned.
1827 **************************************************************************/
1829 bool lp_parameter_is_canonical(const char *parm_name)
1831 if (!lp_parameter_is_valid(parm_name)) {
1835 return (lpcfg_map_parameter(parm_name) ==
1836 map_parameter_canonical(parm_name, NULL));
1839 /**************************************************************************
1840 Determine the canonical name for a parameter.
1841 Indicate when it is an inverse (boolean) synonym instead of a
1843 **************************************************************************/
1845 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1850 if (!lp_parameter_is_valid(parm_name)) {
1855 num = map_parameter_canonical(parm_name, inverse);
1857 /* parametric option */
1858 *canon_parm = parm_name;
1860 *canon_parm = parm_table[num].label;
1867 /**************************************************************************
1868 Determine the canonical name for a parameter.
1869 Turn the value given into the inverse boolean expression when
1870 the synonym is an invers boolean synonym.
1872 Return true if parm_name is a valid parameter name and
1873 in case it is an invers boolean synonym, if the val string could
1874 successfully be converted to the reverse bool.
1875 Return false in all other cases.
1876 **************************************************************************/
1878 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1880 const char **canon_parm,
1881 const char **canon_val)
1886 if (!lp_parameter_is_valid(parm_name)) {
1892 num = map_parameter_canonical(parm_name, &inverse);
1894 /* parametric option */
1895 *canon_parm = parm_name;
1898 *canon_parm = parm_table[num].label;
1900 if (!lp_invert_boolean(val, canon_val)) {
1912 /***************************************************************************
1913 Map a parameter's string representation to the index of the canonical
1914 form of the parameter (it might be a synonym).
1915 Returns -1 if the parameter string is not recognised.
1916 ***************************************************************************/
1918 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1920 int parm_num, canon_num;
1921 bool loc_inverse = false;
1923 parm_num = lpcfg_map_parameter(pszParmName);
1924 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
1925 /* invalid, parametric or no canidate for synonyms ... */
1929 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1930 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1931 parm_num = canon_num;
1937 if (inverse != NULL) {
1938 *inverse = loc_inverse;
1943 /***************************************************************************
1944 return true if parameter number parm1 is a synonym of parameter
1945 number parm2 (parm2 being the principal name).
1946 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1948 ***************************************************************************/
1950 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1952 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1953 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1954 (parm_table[parm1].flags & FLAG_HIDE) &&
1955 !(parm_table[parm2].flags & FLAG_HIDE))
1957 if (inverse != NULL) {
1958 if ((parm_table[parm1].type == P_BOOLREV) &&
1959 (parm_table[parm2].type == P_BOOL))
1971 /***************************************************************************
1972 Show one parameter's name, type, [values,] and flags.
1973 (helper functions for show_parameter_list)
1974 ***************************************************************************/
1976 static void show_parameter(int parmIndex)
1978 int enumIndex, flagIndex;
1983 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1984 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1986 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
1987 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
1989 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
1990 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
1991 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
1993 printf("%s=%s", parm_table[parmIndex].label,
1994 type[parm_table[parmIndex].type]);
1995 if (parm_table[parmIndex].type == P_ENUM) {
1998 parm_table[parmIndex].enum_list[enumIndex].name;
2002 enumIndex ? "|" : "",
2003 parm_table[parmIndex].enum_list[enumIndex].name);
2008 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
2009 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2012 flag_names[flagIndex]);
2017 /* output synonyms */
2019 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
2020 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
2021 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
2022 parm_table[parmIndex2].label);
2023 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
2025 printf(" (synonyms: ");
2030 printf("%s%s", parm_table[parmIndex2].label,
2031 inverse ? "[i]" : "");
2041 /***************************************************************************
2042 Show all parameter's name, type, [values,] and flags.
2043 ***************************************************************************/
2045 void show_parameter_list(void)
2047 int classIndex, parmIndex;
2048 const char *section_names[] = { "local", "global", NULL};
2050 for (classIndex=0; section_names[classIndex]; classIndex++) {
2051 printf("[%s]\n", section_names[classIndex]);
2052 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2053 if (parm_table[parmIndex].p_class == classIndex) {
2054 show_parameter(parmIndex);
2060 /***************************************************************************
2061 Check if a given string correctly represents a boolean value.
2062 ***************************************************************************/
2064 bool lp_string_is_valid_boolean(const char *parm_value)
2066 return set_boolean(parm_value, NULL);
2069 /***************************************************************************
2070 Get the standard string representation of a boolean value ("yes" or "no")
2071 ***************************************************************************/
2073 static const char *get_boolean(bool bool_value)
2075 static const char *yes_str = "yes";
2076 static const char *no_str = "no";
2078 return (bool_value ? yes_str : no_str);
2081 /***************************************************************************
2082 Provide the string of the negated boolean value associated to the boolean
2083 given as a string. Returns false if the passed string does not correctly
2084 represent a boolean.
2085 ***************************************************************************/
2087 bool lp_invert_boolean(const char *str, const char **inverse_str)
2091 if (!set_boolean(str, &val)) {
2095 *inverse_str = get_boolean(!val);
2099 /***************************************************************************
2100 Provide the canonical string representation of a boolean value given
2101 as a string. Return true on success, false if the string given does
2102 not correctly represent a boolean.
2103 ***************************************************************************/
2105 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2109 if (!set_boolean(str, &val)) {
2113 *canon_str = get_boolean(val);
2117 /***************************************************************************
2118 Find a service by name. Otherwise works like get_service.
2119 ***************************************************************************/
2121 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2128 if (ServiceHash == NULL) {
2132 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2134 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2137 if (NT_STATUS_IS_OK(status) &&
2138 (data.dptr != NULL) &&
2139 (data.dsize == sizeof(iService)))
2141 iService = *(int *)data.dptr;
2144 TALLOC_FREE(canon_name);
2146 if ((iService != -1) && (LP_SNUM_OK(iService))
2147 && (pserviceDest != NULL)) {
2148 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2154 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2155 struct loadparm_service *lp_service(const char *pszServiceName)
2157 int iService = getservicebyname(pszServiceName, NULL);
2158 if (iService == -1 || !LP_SNUM_OK(iService)) {
2161 return ServicePtrs[iService];
2164 struct loadparm_service *lp_servicebynum(int snum)
2166 if ((snum == -1) || !LP_SNUM_OK(snum)) {
2169 return ServicePtrs[snum];
2172 struct loadparm_service *lp_default_loadparm_service()
2178 /***************************************************************************
2179 Copy a service structure to another.
2180 If pcopymapDest is NULL then copy all fields
2181 ***************************************************************************/
2184 * Add a parametric option to a parmlist_entry,
2185 * replacing old value, if already present.
2187 static void set_param_opt(struct parmlist_entry **opt_list,
2188 const char *opt_name,
2189 const char *opt_value,
2192 struct parmlist_entry *new_opt, *opt;
2198 /* Traverse destination */
2200 /* If we already have same option, override it */
2201 if (strwicmp(opt->key, opt_name) == 0) {
2202 if ((opt->priority & FLAG_CMDLINE) &&
2203 !(priority & FLAG_CMDLINE)) {
2204 /* it's been marked as not to be
2208 string_free(&opt->value);
2209 TALLOC_FREE(opt->list);
2210 opt->value = SMB_STRDUP(opt_value);
2211 opt->priority = priority;
2218 new_opt = SMB_XMALLOC_P(struct parmlist_entry);
2219 new_opt->key = SMB_STRDUP(opt_name);
2220 new_opt->value = SMB_STRDUP(opt_value);
2221 new_opt->list = NULL;
2222 new_opt->priority = priority;
2223 DLIST_ADD(*opt_list, new_opt);
2227 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
2228 struct bitmap *pcopymapDest)
2231 bool bcopyall = (pcopymapDest == NULL);
2232 struct parmlist_entry *data;
2234 for (i = 0; parm_table[i].label; i++)
2235 if (parm_table[i].p_class == P_LOCAL &&
2236 (bcopyall || bitmap_query(pcopymapDest,i))) {
2237 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
2238 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
2240 switch (parm_table[i].type) {
2243 *(bool *)dest_ptr = *(bool *)src_ptr;
2250 *(int *)dest_ptr = *(int *)src_ptr;
2254 *(char *)dest_ptr = *(char *)src_ptr;
2258 string_set((char **)dest_ptr,
2264 char *upper_string = strupper_talloc(talloc_tos(),
2266 string_set((char **)dest_ptr,
2268 TALLOC_FREE(upper_string);
2272 TALLOC_FREE(*((char ***)dest_ptr));
2273 *((char ***)dest_ptr) = str_list_copy(NULL,
2274 *(const char ***)src_ptr);
2282 init_copymap(pserviceDest);
2283 if (pserviceSource->copymap)
2284 bitmap_copy(pserviceDest->copymap,
2285 pserviceSource->copymap);
2288 data = pserviceSource->param_opt;
2290 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
2295 /***************************************************************************
2296 Check a service for consistency. Return false if the service is in any way
2297 incomplete or faulty, else true.
2298 ***************************************************************************/
2300 bool service_ok(int iService)
2305 if (ServicePtrs[iService]->szService[0] == '\0') {
2306 DEBUG(0, ("The following message indicates an internal error:\n"));
2307 DEBUG(0, ("No service name in service entry.\n"));
2311 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2312 /* I can't see why you'd want a non-printable printer service... */
2313 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2314 if (!ServicePtrs[iService]->printable) {
2315 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2316 ServicePtrs[iService]->szService));
2317 ServicePtrs[iService]->printable = true;
2319 /* [printers] service must also be non-browsable. */
2320 if (ServicePtrs[iService]->browseable)
2321 ServicePtrs[iService]->browseable = false;
2324 if (ServicePtrs[iService]->path[0] == '\0' &&
2325 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2326 ServicePtrs[iService]->msdfs_proxy[0] == '\0'
2328 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2329 ServicePtrs[iService]->szService));
2330 ServicePtrs[iService]->bAvailable = false;
2333 /* If a service is flagged unavailable, log the fact at level 1. */
2334 if (!ServicePtrs[iService]->bAvailable)
2335 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2336 ServicePtrs[iService]->szService));
2341 static struct smbconf_ctx *lp_smbconf_ctx(void)
2344 static struct smbconf_ctx *conf_ctx = NULL;
2346 if (conf_ctx == NULL) {
2347 err = smbconf_init(NULL, &conf_ctx, "registry:");
2348 if (!SBC_ERROR_IS_OK(err)) {
2349 DEBUG(1, ("error initializing registry configuration: "
2350 "%s\n", sbcErrorString(err)));
2358 static bool process_smbconf_service(struct smbconf_service *service)
2363 if (service == NULL) {
2367 ret = do_section(service->name, NULL);
2371 for (count = 0; count < service->num_params; count++) {
2372 ret = do_parameter(service->param_names[count],
2373 service->param_values[count],
2379 if (iServiceIndex >= 0) {
2380 return service_ok(iServiceIndex);
2386 * load a service from registry and activate it
2388 bool process_registry_service(const char *service_name)
2391 struct smbconf_service *service = NULL;
2392 TALLOC_CTX *mem_ctx = talloc_stackframe();
2393 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2396 if (conf_ctx == NULL) {
2400 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2402 if (!smbconf_share_exists(conf_ctx, service_name)) {
2404 * Registry does not contain data for this service (yet),
2405 * but make sure lp_load doesn't return false.
2411 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2412 if (!SBC_ERROR_IS_OK(err)) {
2416 ret = process_smbconf_service(service);
2422 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2425 TALLOC_FREE(mem_ctx);
2430 * process_registry_globals
2432 static bool process_registry_globals(void)
2436 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2438 ret = do_parameter("registry shares", "yes", NULL);
2443 return process_registry_service(GLOBAL_NAME);
2446 bool process_registry_shares(void)
2450 struct smbconf_service **service = NULL;
2451 uint32_t num_shares = 0;
2452 TALLOC_CTX *mem_ctx = talloc_stackframe();
2453 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2456 if (conf_ctx == NULL) {
2460 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2461 if (!SBC_ERROR_IS_OK(err)) {
2467 for (count = 0; count < num_shares; count++) {
2468 if (strequal(service[count]->name, GLOBAL_NAME)) {
2471 ret = process_smbconf_service(service[count]);
2478 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2481 TALLOC_FREE(mem_ctx);
2486 * reload those shares from registry that are already
2487 * activated in the services array.
2489 static bool reload_registry_shares(void)
2494 for (i = 0; i < iNumServices; i++) {
2499 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2503 ret = process_registry_service(ServicePtrs[i]->szService);
2514 #define MAX_INCLUDE_DEPTH 100
2516 static uint8_t include_depth;
2518 static struct file_lists {
2519 struct file_lists *next;
2523 } *file_lists = NULL;
2525 /*******************************************************************
2526 Keep a linked list of all config files so we know when one has changed
2527 it's date and needs to be reloaded.
2528 ********************************************************************/
2530 static void add_to_file_list(const char *fname, const char *subfname)
2532 struct file_lists *f = file_lists;
2535 if (f->name && !strcmp(f->name, fname))
2541 f = SMB_MALLOC_P(struct file_lists);
2544 f->next = file_lists;
2545 f->name = SMB_STRDUP(fname);
2550 f->subfname = SMB_STRDUP(subfname);
2557 f->modtime = file_modtime(subfname);
2559 time_t t = file_modtime(subfname);
2567 * Free the file lists
2569 static void free_file_list(void)
2571 struct file_lists *f;
2572 struct file_lists *next;
2577 SAFE_FREE( f->name );
2578 SAFE_FREE( f->subfname );
2587 * Utility function for outsiders to check if we're running on registry.
2589 bool lp_config_backend_is_registry(void)
2591 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2595 * Utility function to check if the config backend is FILE.
2597 bool lp_config_backend_is_file(void)
2599 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2602 /*******************************************************************
2603 Check if a config file has changed date.
2604 ********************************************************************/
2606 bool lp_file_list_changed(void)
2608 struct file_lists *f = file_lists;
2610 DEBUG(6, ("lp_file_list_changed()\n"));
2615 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2616 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2618 if (conf_ctx == NULL) {
2621 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2624 DEBUGADD(6, ("registry config changed\n"));
2629 n2 = talloc_sub_basic(talloc_tos(),
2630 get_current_username(),
2631 current_user_info.domain,
2636 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2637 f->name, n2, ctime(&f->modtime)));
2639 mod_time = file_modtime(n2);
2642 ((f->modtime != mod_time) ||
2643 (f->subfname == NULL) ||
2644 (strcmp(n2, f->subfname) != 0)))
2647 ("file %s modified: %s\n", n2,
2649 f->modtime = mod_time;
2650 SAFE_FREE(f->subfname);
2651 f->subfname = SMB_STRDUP(n2);
2664 * Initialize iconv conversion descriptors.
2666 * This is called the first time it is needed, and also called again
2667 * every time the configuration is reloaded, because the charset or
2668 * codepage might have changed.
2670 static void init_iconv(void)
2672 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2674 true, global_iconv_handle);
2677 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2679 if (strcmp(*ptr, pszParmValue) != 0) {
2680 string_set(ptr, pszParmValue);
2686 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2688 bool is_utf8 = false;
2689 size_t len = strlen(pszParmValue);
2691 if (len == 4 || len == 5) {
2692 /* Don't use StrCaseCmp here as we don't want to
2693 initialize iconv. */
2694 if ((toupper_m(pszParmValue[0]) == 'U') &&
2695 (toupper_m(pszParmValue[1]) == 'T') &&
2696 (toupper_m(pszParmValue[2]) == 'F')) {
2698 if (pszParmValue[3] == '8') {
2702 if (pszParmValue[3] == '-' &&
2703 pszParmValue[4] == '8') {
2710 if (strcmp(*ptr, pszParmValue) != 0) {
2712 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2713 "be UTF8, using (default value) %s instead.\n",
2714 DEFAULT_DOS_CHARSET));
2715 pszParmValue = DEFAULT_DOS_CHARSET;
2717 string_set(ptr, pszParmValue);
2723 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2726 TALLOC_CTX *frame = talloc_stackframe();
2727 char *realm = strupper_talloc(frame, pszParmValue);
2728 char *dnsdomain = strlower_talloc(realm, pszParmValue);
2730 ret &= string_set(&Globals.realm_original, pszParmValue);
2731 ret &= string_set(&Globals.realm, realm);
2732 ret &= string_set(&Globals.dnsdomain, dnsdomain);
2738 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2740 TALLOC_FREE(Globals.netbios_aliases);
2741 Globals.netbios_aliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
2742 return set_netbios_aliases(Globals.netbios_aliases);
2745 /***************************************************************************
2746 Handle the include operation.
2747 ***************************************************************************/
2748 static bool bAllowIncludeRegistry = true;
2750 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2754 if (include_depth >= MAX_INCLUDE_DEPTH) {
2755 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2760 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2761 if (!bAllowIncludeRegistry) {
2764 if (bInGlobalSection) {
2767 ret = process_registry_globals();
2771 DEBUG(1, ("\"include = registry\" only effective "
2772 "in %s section\n", GLOBAL_NAME));
2777 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2778 current_user_info.domain,
2781 add_to_file_list(pszParmValue, fname);
2783 string_set(ptr, fname);
2785 if (file_exist(fname)) {
2788 ret = pm_process(fname, do_section, do_parameter, NULL);
2794 DEBUG(2, ("Can't find include file %s\n", fname));
2799 /***************************************************************************
2800 Handle the interpretation of the copy parameter.
2801 ***************************************************************************/
2803 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2807 struct loadparm_service serviceTemp;
2809 string_set(ptr, pszParmValue);
2811 init_service(&serviceTemp);
2815 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2817 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2818 if (iTemp == iServiceIndex) {
2819 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2821 copy_service(ServicePtrs[iServiceIndex],
2823 ServicePtrs[iServiceIndex]->copymap);
2827 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2831 free_service(&serviceTemp);
2835 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2837 Globals.ldap_debug_level = lp_int(pszParmValue);
2838 init_ldap_debugging();
2843 * idmap related parameters
2846 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2848 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
2853 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2855 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2860 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2862 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2867 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2869 char *config_option = NULL;
2870 const char *range = NULL;
2873 SMB_ASSERT(low != NULL);
2874 SMB_ASSERT(high != NULL);
2876 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2880 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2882 if (config_option == NULL) {
2883 DEBUG(0, ("out of memory\n"));
2887 range = lp_parm_const_string(-1, config_option, "range", NULL);
2888 if (range == NULL) {
2889 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2893 if (sscanf(range, "%u - %u", low, high) != 2) {
2894 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2895 range, domain_name));
2902 talloc_free(config_option);
2907 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2909 return lp_idmap_range("*", low, high);
2912 const char *lp_idmap_backend(const char *domain_name)
2914 char *config_option = NULL;
2915 const char *backend = NULL;
2917 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2921 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2923 if (config_option == NULL) {
2924 DEBUG(0, ("out of memory\n"));
2928 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2929 if (backend == NULL) {
2930 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2935 talloc_free(config_option);
2939 const char *lp_idmap_default_backend(void)
2941 return lp_idmap_backend("*");
2944 /***************************************************************************
2945 Handle the DEBUG level list.
2946 ***************************************************************************/
2948 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
2950 string_set(ptr, pszParmValueIn);
2951 return debug_parse_levels(pszParmValueIn);
2954 /***************************************************************************
2955 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2956 ***************************************************************************/
2958 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2960 const char *suffix_string;
2962 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2963 Globals.ldap_suffix );
2964 if ( !suffix_string ) {
2965 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2969 return suffix_string;
2972 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2974 if (Globals.szLdapMachineSuffix[0])
2975 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
2977 return lp_string(ctx, Globals.ldap_suffix);
2980 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2982 if (Globals.szLdapUserSuffix[0])
2983 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
2985 return lp_string(ctx, Globals.ldap_suffix);
2988 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2990 if (Globals.szLdapGroupSuffix[0])
2991 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
2993 return lp_string(ctx, Globals.ldap_suffix);
2996 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2998 if (Globals.szLdapIdmapSuffix[0])
2999 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
3001 return lp_string(ctx, Globals.ldap_suffix);
3004 /****************************************************************************
3005 set the value for a P_ENUM
3006 ***************************************************************************/
3008 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3013 for (i = 0; parm->enum_list[i].name; i++) {
3014 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3015 *ptr = parm->enum_list[i].value;
3019 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
3020 pszParmValue, parm->label));
3023 /***************************************************************************
3024 ***************************************************************************/
3026 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
3028 static int parm_num = -1;
3029 struct loadparm_service *s;
3031 if ( parm_num == -1 )
3032 parm_num = lpcfg_map_parameter( "printing" );
3034 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3039 s = ServicePtrs[snum];
3041 init_printer_values( s );
3047 /***************************************************************************
3048 Initialise a copymap.
3049 ***************************************************************************/
3051 static void init_copymap(struct loadparm_service *pservice)
3055 TALLOC_FREE(pservice->copymap);
3057 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
3058 if (!pservice->copymap)
3060 ("Couldn't allocate copymap!! (size %d)\n",
3061 (int)NUMPARAMETERS));
3063 for (i = 0; i < NUMPARAMETERS; i++)
3064 bitmap_set(pservice->copymap, i);
3068 return the parameter pointer for a parameter
3070 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
3072 if (service == NULL) {
3073 if (parm->p_class == P_LOCAL)
3074 return (void *)(((char *)&sDefault)+parm->offset);
3075 else if (parm->p_class == P_GLOBAL)
3076 return (void *)(((char *)&Globals)+parm->offset);
3079 return (void *)(((char *)service) + parm->offset);
3083 /***************************************************************************
3084 Return the local pointer to a parameter given the service number and parameter
3085 ***************************************************************************/
3087 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
3089 return lp_parm_ptr(ServicePtrs[snum], parm);
3092 /***************************************************************************
3093 Process a parameter for a particular service number. If snum < 0
3094 then assume we are in the globals.
3095 ***************************************************************************/
3097 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3100 void *parm_ptr = NULL; /* where we are going to store the result */
3101 struct parmlist_entry **opt_list;
3103 parmnum = lpcfg_map_parameter(pszParmName);
3106 if (strchr(pszParmName, ':') == NULL) {
3107 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
3113 * We've got a parametric option
3116 opt_list = (snum < 0)
3117 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
3118 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
3123 /* if it's already been set by the command line, then we don't
3125 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
3129 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3130 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3134 /* we might point at a service, the default service or a global */
3136 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
3138 if (parm_table[parmnum].p_class == P_GLOBAL) {
3140 ("Global parameter %s found in service section!\n",
3144 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
3148 if (!ServicePtrs[snum]->copymap)
3149 init_copymap(ServicePtrs[snum]);
3151 /* this handles the aliases - set the copymap for other entries with
3152 the same data pointer */
3153 for (i = 0; parm_table[i].label; i++) {
3154 if ((parm_table[i].offset == parm_table[parmnum].offset)
3155 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
3156 bitmap_clear(ServicePtrs[snum]->copymap, i);
3161 /* if it is a special case then go ahead */
3162 if (parm_table[parmnum].special) {
3163 return parm_table[parmnum].special(NULL, snum, pszParmValue,
3167 /* now switch on the type of variable it is */
3168 switch (parm_table[parmnum].type)
3171 *(bool *)parm_ptr = lp_bool(pszParmValue);
3175 *(bool *)parm_ptr = !lp_bool(pszParmValue);
3179 *(int *)parm_ptr = lp_int(pszParmValue);
3183 *(char *)parm_ptr = *pszParmValue;
3187 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3189 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3196 if (conv_str_size_error(pszParmValue, &val)) {
3197 if (val <= INT_MAX) {
3198 *(int *)parm_ptr = (int)val;
3203 DEBUG(0,("lp_do_parameter(%s): value is not "
3204 "a valid size specifier!\n", pszParmValue));
3210 TALLOC_FREE(*((char ***)parm_ptr));
3211 *(char ***)parm_ptr = str_list_make_v3(
3212 NULL, pszParmValue, NULL);
3216 string_set((char **)parm_ptr, pszParmValue);
3221 char *upper_string = strupper_talloc(talloc_tos(),
3223 string_set((char **)parm_ptr, upper_string);
3224 TALLOC_FREE(upper_string);
3228 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3237 /***************************************************************************
3238 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
3239 FLAG_CMDLINE won't be overridden by loads from smb.conf.
3240 ***************************************************************************/
3242 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
3245 parmnum = lpcfg_map_parameter(pszParmName);
3247 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
3248 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
3251 parm_table[parmnum].flags |= FLAG_CMDLINE;
3253 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
3254 * be grouped in the table, so we don't have to search the
3257 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
3258 && parm_table[i].p_class == parm_table[parmnum].p_class;
3260 parm_table[i].flags |= FLAG_CMDLINE;
3262 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
3263 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
3264 parm_table[i].flags |= FLAG_CMDLINE;
3268 store_lp_set_cmdline(pszParmName, pszParmValue);
3273 /* it might be parametric */
3274 if (strchr(pszParmName, ':') != NULL) {
3275 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
3277 store_lp_set_cmdline(pszParmName, pszParmValue);
3282 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3286 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
3288 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
3291 /***************************************************************************
3292 Process a parameter.
3293 ***************************************************************************/
3295 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
3298 if (!bInGlobalSection && bGlobalOnly)
3301 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3303 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3304 pszParmName, pszParmValue));
3308 set a option from the commandline in 'a=b' format. Use to support --option
3310 bool lp_set_option(const char *option)
3315 s = talloc_strdup(NULL, option);
3328 /* skip white spaces after the = sign */
3331 } while (*p == ' ');
3333 ret = lp_set_cmdline(s, p);
3338 /***************************************************************************
3339 Initialize any local variables in the sDefault table, after parsing a
3341 ***************************************************************************/
3343 static void init_locals(void)
3346 * We run this check once the [globals] is parsed, to force
3347 * the VFS objects and other per-share settings we need for
3348 * the standard way a AD DC is operated. We may change these
3349 * as our code evolves, which is why we force these settings.
3351 * We can't do this at the end of lp_load_ex(), as by that
3352 * point the services have been loaded and they will already
3353 * have "" as their vfs objects.
3355 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3356 const char **vfs_objects = lp_vfs_objects(-1);
3357 if (!vfs_objects || !vfs_objects[0]) {
3358 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
3359 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3360 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
3361 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3363 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3367 lp_do_parameter(-1, "map hidden", "no");
3368 lp_do_parameter(-1, "map system", "no");
3369 lp_do_parameter(-1, "map readonly", "no");
3370 lp_do_parameter(-1, "map archive", "no");
3371 lp_do_parameter(-1, "store dos attributes", "yes");
3375 /***************************************************************************
3376 Process a new section (service). At this stage all sections are services.
3377 Later we'll have special sections that permit server parameters to be set.
3378 Returns true on success, false on failure.
3379 ***************************************************************************/
3381 static bool do_section(const char *pszSectionName, void *userdata)
3384 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3385 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3388 /* if we were in a global section then do the local inits */
3389 if (bInGlobalSection && !isglobal)
3392 /* if we've just struck a global section, note the fact. */
3393 bInGlobalSection = isglobal;
3395 /* check for multiple global sections */
3396 if (bInGlobalSection) {
3397 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3401 if (!bInGlobalSection && bGlobalOnly)
3404 /* if we have a current service, tidy it up before moving on */
3407 if (iServiceIndex >= 0)
3408 bRetval = service_ok(iServiceIndex);
3410 /* if all is still well, move to the next record in the services array */
3412 /* We put this here to avoid an odd message order if messages are */
3413 /* issued by the post-processing of a previous section. */
3414 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3416 iServiceIndex = add_a_service(&sDefault, pszSectionName);
3417 if (iServiceIndex < 0) {
3418 DEBUG(0, ("Failed to add a new service\n"));
3421 /* Clean all parametric options for service */
3422 /* They will be added during parsing again */
3423 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
3430 /***************************************************************************
3431 Determine if a partcular base parameter is currentl set to the default value.
3432 ***************************************************************************/
3434 static bool is_default(int i)
3436 switch (parm_table[i].type) {
3439 return str_list_equal((const char **)parm_table[i].def.lvalue,
3440 *(const char ***)lp_parm_ptr(NULL,
3444 return strequal(parm_table[i].def.svalue,
3445 *(char **)lp_parm_ptr(NULL,
3449 return parm_table[i].def.bvalue ==
3450 *(bool *)lp_parm_ptr(NULL,
3453 return parm_table[i].def.cvalue ==
3454 *(char *)lp_parm_ptr(NULL,
3460 return parm_table[i].def.ivalue ==
3461 *(int *)lp_parm_ptr(NULL,
3469 /***************************************************************************
3470 Display the contents of the global structure.
3471 ***************************************************************************/
3473 static void dump_globals(FILE *f)
3476 struct parmlist_entry *data;
3478 fprintf(f, "[global]\n");
3480 for (i = 0; parm_table[i].label; i++)
3481 if (parm_table[i].p_class == P_GLOBAL &&
3482 !(parm_table[i].flags & FLAG_META) &&
3483 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
3484 if (defaults_saved && is_default(i))
3486 fprintf(f, "\t%s = ", parm_table[i].label);
3487 lpcfg_print_parameter(&parm_table[i], lp_parm_ptr(NULL,
3492 if (Globals.param_opt != NULL) {
3493 data = Globals.param_opt;
3495 fprintf(f, "\t%s = %s\n", data->key, data->value);
3502 /***************************************************************************
3503 Display the contents of a single services record.
3504 ***************************************************************************/
3506 static void dump_a_service(struct loadparm_service *pService, FILE * f)
3509 struct parmlist_entry *data;
3511 if (pService != &sDefault)
3512 fprintf(f, "[%s]\n", pService->szService);
3514 for (i = 0; parm_table[i].label; i++) {
3516 if (parm_table[i].p_class == P_LOCAL &&
3517 !(parm_table[i].flags & FLAG_META) &&
3518 (*parm_table[i].label != '-') &&
3519 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
3521 if (pService == &sDefault) {
3522 if (defaults_saved && is_default(i))
3525 if (lpcfg_equal_parameter(parm_table[i].type,
3526 lp_parm_ptr(pService, &parm_table[i]),
3527 lp_parm_ptr(NULL, &parm_table[i])))
3531 fprintf(f, "\t%s = ", parm_table[i].label);
3532 lpcfg_print_parameter(&parm_table[i],
3533 lp_parm_ptr(pService, &parm_table[i]),
3539 if (pService->param_opt != NULL) {
3540 data = pService->param_opt;
3542 fprintf(f, "\t%s = %s\n", data->key, data->value);
3548 /***************************************************************************
3549 Display the contents of a parameter of a single services record.
3550 ***************************************************************************/
3552 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
3554 bool result = false;
3555 fstring local_parm_name;
3557 const char *parm_opt_value;
3559 struct loadparm_context *lp_ctx;
3561 /* check for parametrical option */
3562 fstrcpy( local_parm_name, parm_name);
3563 parm_opt = strchr( local_parm_name, ':');
3568 if (strlen(parm_opt)) {
3569 parm_opt_value = lp_parm_const_string( snum,
3570 local_parm_name, parm_opt, NULL);
3571 if (parm_opt_value) {
3572 printf( "%s\n", parm_opt_value);
3579 lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3580 if (lp_ctx == NULL) {
3585 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
3587 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
3589 TALLOC_FREE(lp_ctx);
3593 /***************************************************************************
3594 Return info about the requested parameter (given as a string).
3595 Return NULL when the string is not a valid parameter name.
3596 ***************************************************************************/
3598 struct parm_struct *lp_get_parameter(const char *param_name)
3600 int num = lpcfg_map_parameter(param_name);
3606 return &parm_table[num];
3610 /***************************************************************************
3611 Display the contents of a single copy structure.
3612 ***************************************************************************/
3613 static void dump_copy_map(bool *pcopymap)
3619 printf("\n\tNon-Copied parameters:\n");
3621 for (i = 0; parm_table[i].label; i++)
3622 if (parm_table[i].p_class == P_LOCAL &&
3623 parm_table[i].ptr && !pcopymap[i] &&
3624 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3626 printf("\t\t%s\n", parm_table[i].label);
3631 /***************************************************************************
3632 Return TRUE if the passed service number is within range.
3633 ***************************************************************************/
3635 bool lp_snum_ok(int iService)
3637 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3640 /***************************************************************************
3641 Auto-load some home services.
3642 ***************************************************************************/
3644 static void lp_add_auto_services(char *str)
3654 s = SMB_STRDUP(str);
3658 homes = lp_servicenumber(HOMES_NAME);
3660 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3661 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3664 if (lp_servicenumber(p) >= 0)
3667 home = get_user_home_dir(talloc_tos(), p);
3669 if (home && home[0] && homes >= 0)
3670 lp_add_home(p, homes, p, home);
3677 /***************************************************************************
3678 Auto-load one printer.
3679 ***************************************************************************/
3681 void lp_add_one_printer(const char *name, const char *comment,
3682 const char *location, void *pdata)
3684 int printers = lp_servicenumber(PRINTERS_NAME);
3687 if (lp_servicenumber(name) < 0) {
3688 lp_add_printer(name, printers);
3689 if ((i = lp_servicenumber(name)) >= 0) {
3690 string_set(&ServicePtrs[i]->comment, comment);
3691 ServicePtrs[i]->autoloaded = true;
3696 /***************************************************************************
3697 Have we loaded a services file yet?
3698 ***************************************************************************/
3700 bool lp_loaded(void)
3705 /***************************************************************************
3706 Unload unused services.
3707 ***************************************************************************/
3709 void lp_killunused(struct smbd_server_connection *sconn,
3710 bool (*snumused) (struct smbd_server_connection *, int))
3713 for (i = 0; i < iNumServices; i++) {
3717 /* don't kill autoloaded or usershare services */
3718 if ( ServicePtrs[i]->autoloaded ||
3719 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3723 if (!snumused || !snumused(sconn, i)) {
3724 free_service_byindex(i);
3730 * Kill all except autoloaded and usershare services - convenience wrapper
3732 void lp_kill_all_services(void)
3734 lp_killunused(NULL, NULL);
3737 /***************************************************************************
3739 ***************************************************************************/
3741 void lp_killservice(int iServiceIn)
3743 if (VALID(iServiceIn)) {
3744 free_service_byindex(iServiceIn);
3748 /***************************************************************************
3749 Save the curent values of all global and sDefault parameters into the
3750 defaults union. This allows testparm to show only the
3751 changed (ie. non-default) parameters.
3752 ***************************************************************************/
3754 static void lp_save_defaults(void)
3757 for (i = 0; parm_table[i].label; i++) {
3758 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3759 && parm_table[i].p_class == parm_table[i - 1].p_class)
3761 switch (parm_table[i].type) {
3764 parm_table[i].def.lvalue = str_list_copy(
3765 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3769 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
3773 parm_table[i].def.bvalue =
3774 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3777 parm_table[i].def.cvalue =
3778 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3784 parm_table[i].def.ivalue =
3785 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3791 defaults_saved = true;
3794 /***********************************************************
3795 If we should send plaintext/LANMAN passwords in the clinet
3796 ************************************************************/
3798 static void set_allowed_client_auth(void)
3800 if (Globals.client_ntlmv2_auth) {
3801 Globals.client_lanman_auth = false;
3803 if (!Globals.client_lanman_auth) {
3804 Globals.client_plaintext_auth = false;
3808 /***************************************************************************
3810 The following code allows smbd to read a user defined share file.
3811 Yes, this is my intent. Yes, I'm comfortable with that...
3813 THE FOLLOWING IS SECURITY CRITICAL CODE.
3815 It washes your clothes, it cleans your house, it guards you while you sleep...
3816 Do not f%^k with it....
3817 ***************************************************************************/
3819 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3821 /***************************************************************************
3822 Check allowed stat state of a usershare file.
3823 Ensure we print out who is dicking with us so the admin can
3824 get their sorry ass fired.
3825 ***************************************************************************/
3827 static bool check_usershare_stat(const char *fname,
3828 const SMB_STRUCT_STAT *psbuf)
3830 if (!S_ISREG(psbuf->st_ex_mode)) {
3831 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3832 "not a regular file\n",
3833 fname, (unsigned int)psbuf->st_ex_uid ));
3837 /* Ensure this doesn't have the other write bit set. */
3838 if (psbuf->st_ex_mode & S_IWOTH) {
3839 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3840 "public write. Refusing to allow as a usershare file.\n",
3841 fname, (unsigned int)psbuf->st_ex_uid ));
3845 /* Should be 10k or less. */
3846 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3847 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3848 "too large (%u) to be a user share file.\n",
3849 fname, (unsigned int)psbuf->st_ex_uid,
3850 (unsigned int)psbuf->st_ex_size ));
3857 /***************************************************************************
3858 Parse the contents of a usershare file.
3859 ***************************************************************************/
3861 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3862 SMB_STRUCT_STAT *psbuf,
3863 const char *servicename,
3867 char **pp_sharepath,
3869 char **pp_cp_servicename,
3870 struct security_descriptor **ppsd,
3873 const char **prefixallowlist = lp_usershare_prefix_allow_list();
3874 const char **prefixdenylist = lp_usershare_prefix_deny_list();
3877 SMB_STRUCT_STAT sbuf;
3878 char *sharepath = NULL;
3879 char *comment = NULL;
3881 *pp_sharepath = NULL;
3884 *pallow_guest = false;
3887 return USERSHARE_MALFORMED_FILE;
3890 if (strcmp(lines[0], "#VERSION 1") == 0) {
3892 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3895 return USERSHARE_MALFORMED_FILE;
3898 return USERSHARE_BAD_VERSION;
3901 if (strncmp(lines[1], "path=", 5) != 0) {
3902 return USERSHARE_MALFORMED_PATH;
3905 sharepath = talloc_strdup(ctx, &lines[1][5]);
3907 return USERSHARE_POSIX_ERR;
3909 trim_string(sharepath, " ", " ");
3911 if (strncmp(lines[2], "comment=", 8) != 0) {
3912 return USERSHARE_MALFORMED_COMMENT_DEF;
3915 comment = talloc_strdup(ctx, &lines[2][8]);
3917 return USERSHARE_POSIX_ERR;
3919 trim_string(comment, " ", " ");
3920 trim_char(comment, '"', '"');
3922 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3923 return USERSHARE_MALFORMED_ACL_DEF;
3926 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3927 return USERSHARE_ACL_ERR;
3931 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3932 return USERSHARE_MALFORMED_ACL_DEF;
3934 if (lines[4][9] == 'y') {
3935 *pallow_guest = true;
3938 /* Backwards compatible extension to file version #2. */
3940 if (strncmp(lines[5], "sharename=", 10) != 0) {
3941 return USERSHARE_MALFORMED_SHARENAME_DEF;
3943 if (!strequal(&lines[5][10], servicename)) {
3944 return USERSHARE_BAD_SHARENAME;
3946 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3947 if (!*pp_cp_servicename) {
3948 return USERSHARE_POSIX_ERR;
3953 if (*pp_cp_servicename == NULL) {
3954 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3955 if (!*pp_cp_servicename) {
3956 return USERSHARE_POSIX_ERR;
3960 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3961 /* Path didn't change, no checks needed. */
3962 *pp_sharepath = sharepath;
3963 *pp_comment = comment;
3964 return USERSHARE_OK;
3967 /* The path *must* be absolute. */
3968 if (sharepath[0] != '/') {
3969 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3970 servicename, sharepath));
3971 return USERSHARE_PATH_NOT_ABSOLUTE;
3974 /* If there is a usershare prefix deny list ensure one of these paths
3975 doesn't match the start of the user given path. */
3976 if (prefixdenylist) {
3978 for ( i=0; prefixdenylist[i]; i++ ) {
3979 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3980 servicename, i, prefixdenylist[i], sharepath ));
3981 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3982 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3983 "usershare prefix deny list entries.\n",
3984 servicename, sharepath));
3985 return USERSHARE_PATH_IS_DENIED;
3990 /* If there is a usershare prefix allow list ensure one of these paths
3991 does match the start of the user given path. */
3993 if (prefixallowlist) {
3995 for ( i=0; prefixallowlist[i]; i++ ) {
3996 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3997 servicename, i, prefixallowlist[i], sharepath ));
3998 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4002 if (prefixallowlist[i] == NULL) {
4003 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4004 "usershare prefix allow list entries.\n",
4005 servicename, sharepath));
4006 return USERSHARE_PATH_NOT_ALLOWED;
4010 /* Ensure this is pointing to a directory. */
4011 dp = opendir(sharepath);
4014 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4015 servicename, sharepath));
4016 return USERSHARE_PATH_NOT_DIRECTORY;
4019 /* Ensure the owner of the usershare file has permission to share
4022 if (sys_stat(sharepath, &sbuf, false) == -1) {
4023 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4024 servicename, sharepath, strerror(errno) ));
4026 return USERSHARE_POSIX_ERR;
4031 if (!S_ISDIR(sbuf.st_ex_mode)) {
4032 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4033 servicename, sharepath ));
4034 return USERSHARE_PATH_NOT_DIRECTORY;
4037 /* Check if sharing is restricted to owner-only. */
4038 /* psbuf is the stat of the usershare definition file,
4039 sbuf is the stat of the target directory to be shared. */
4041 if (lp_usershare_owner_only()) {
4042 /* root can share anything. */
4043 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
4044 return USERSHARE_PATH_NOT_ALLOWED;
4048 *pp_sharepath = sharepath;
4049 *pp_comment = comment;
4050 return USERSHARE_OK;
4053 /***************************************************************************
4054 Deal with a usershare file.
4057 -1 - Bad name, invalid contents.
4058 - service name already existed and not a usershare, problem
4059 with permissions to share directory etc.
4060 ***************************************************************************/
4062 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4064 SMB_STRUCT_STAT sbuf;
4065 SMB_STRUCT_STAT lsbuf;
4067 char *sharepath = NULL;
4068 char *comment = NULL;
4069 char *cp_service_name = NULL;
4070 char **lines = NULL;
4074 TALLOC_CTX *ctx = talloc_stackframe();
4075 struct security_descriptor *psd = NULL;
4076 bool guest_ok = false;
4077 char *canon_name = NULL;
4078 bool added_service = false;
4081 /* Ensure share name doesn't contain invalid characters. */
4082 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4083 DEBUG(0,("process_usershare_file: share name %s contains "
4084 "invalid characters (any of %s)\n",
4085 file_name, INVALID_SHARENAME_CHARS ));
4089 canon_name = canonicalize_servicename(ctx, file_name);
4094 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
4099 /* Minimize the race condition by doing an lstat before we
4100 open and fstat. Ensure this isn't a symlink link. */
4102 if (sys_lstat(fname, &lsbuf, false) != 0) {
4103 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4104 fname, strerror(errno) ));
4108 /* This must be a regular file, not a symlink, directory or
4109 other strange filetype. */
4110 if (!check_usershare_stat(fname, &lsbuf)) {
4118 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
4123 if (NT_STATUS_IS_OK(status) &&
4124 (data.dptr != NULL) &&
4125 (data.dsize == sizeof(iService))) {
4126 memcpy(&iService, data.dptr, sizeof(iService));
4130 if (iService != -1 &&
4131 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4132 &lsbuf.st_ex_mtime) == 0) {
4133 /* Nothing changed - Mark valid and return. */
4134 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4136 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4141 /* Try and open the file read only - no symlinks allowed. */
4143 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
4145 fd = open(fname, O_RDONLY, 0);
4149 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4150 fname, strerror(errno) ));
4154 /* Now fstat to be *SURE* it's a regular file. */
4155 if (sys_fstat(fd, &sbuf, false) != 0) {
4157 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4158 fname, strerror(errno) ));
4162 /* Is it the same dev/inode as was lstated ? */
4163 if (!check_same_stat(&lsbuf, &sbuf)) {
4165 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4166 "Symlink spoofing going on ?\n", fname ));
4170 /* This must be a regular file, not a symlink, directory or
4171 other strange filetype. */
4172 if (!check_usershare_stat(fname, &sbuf)) {
4177 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
4180 if (lines == NULL) {
4181 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4182 fname, (unsigned int)sbuf.st_ex_uid ));
4186 if (parse_usershare_file(ctx, &sbuf, file_name,
4187 iService, lines, numlines, &sharepath,
4188 &comment, &cp_service_name,
4189 &psd, &guest_ok) != USERSHARE_OK) {
4193 /* Everything ok - add the service possibly using a template. */
4195 const struct loadparm_service *sp = &sDefault;
4196 if (snum_template != -1) {
4197 sp = ServicePtrs[snum_template];
4200 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
4201 DEBUG(0, ("process_usershare_file: Failed to add "
4202 "new service %s\n", cp_service_name));
4206 added_service = true;
4208 /* Read only is controlled by usershare ACL below. */
4209 ServicePtrs[iService]->read_only = false;
4212 /* Write the ACL of the new/modified share. */
4213 if (!set_share_security(canon_name, psd)) {
4214 DEBUG(0, ("process_usershare_file: Failed to set share "
4215 "security for user share %s\n",
4220 /* If from a template it may be marked invalid. */
4221 ServicePtrs[iService]->valid = true;
4223 /* Set the service as a valid usershare. */
4224 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4226 /* Set guest access. */
4227 if (lp_usershare_allow_guests()) {
4228 ServicePtrs[iService]->guest_ok = guest_ok;
4231 /* And note when it was loaded. */
4232 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
4233 string_set(&ServicePtrs[iService]->path, sharepath);
4234 string_set(&ServicePtrs[iService]->comment, comment);
4240 if (ret == -1 && iService != -1 && added_service) {
4241 lp_remove_service(iService);
4249 /***************************************************************************
4250 Checks if a usershare entry has been modified since last load.
4251 ***************************************************************************/
4253 static bool usershare_exists(int iService, struct timespec *last_mod)
4255 SMB_STRUCT_STAT lsbuf;
4256 const char *usersharepath = Globals.usershare_path;
4259 if (asprintf(&fname, "%s/%s",
4261 ServicePtrs[iService]->szService) < 0) {
4265 if (sys_lstat(fname, &lsbuf, false) != 0) {
4270 if (!S_ISREG(lsbuf.st_ex_mode)) {
4276 *last_mod = lsbuf.st_ex_mtime;
4280 /***************************************************************************
4281 Load a usershare service by name. Returns a valid servicenumber or -1.
4282 ***************************************************************************/
4284 int load_usershare_service(const char *servicename)
4286 SMB_STRUCT_STAT sbuf;
4287 const char *usersharepath = Globals.usershare_path;
4288 int max_user_shares = Globals.usershare_max_shares;
4289 int snum_template = -1;
4291 if (*usersharepath == 0 || max_user_shares == 0) {
4295 if (sys_stat(usersharepath, &sbuf, false) != 0) {
4296 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4297 usersharepath, strerror(errno) ));
4301 if (!S_ISDIR(sbuf.st_ex_mode)) {
4302 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4308 * This directory must be owned by root, and have the 't' bit set.
4309 * It also must not be writable by "other".
4313 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4315 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4317 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4318 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4323 /* Ensure the template share exists if it's set. */
4324 if (Globals.usershare_template_share[0]) {
4325 /* We can't use lp_servicenumber here as we are recommending that
4326 template shares have -valid=false set. */
4327 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4328 if (ServicePtrs[snum_template]->szService &&
4329 strequal(ServicePtrs[snum_template]->szService,
4330 Globals.usershare_template_share)) {
4335 if (snum_template == -1) {
4336 DEBUG(0,("load_usershare_service: usershare template share %s "
4337 "does not exist.\n",
4338 Globals.usershare_template_share ));
4343 return process_usershare_file(usersharepath, servicename, snum_template);
4346 /***************************************************************************
4347 Load all user defined shares from the user share directory.
4348 We only do this if we're enumerating the share list.
4349 This is the function that can delete usershares that have
4351 ***************************************************************************/
4353 int load_usershare_shares(struct smbd_server_connection *sconn,
4354 bool (*snumused) (struct smbd_server_connection *, int))
4357 SMB_STRUCT_STAT sbuf;
4359 int num_usershares = 0;
4360 int max_user_shares = Globals.usershare_max_shares;
4361 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4362 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4363 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4365 int snum_template = -1;
4366 const char *usersharepath = Globals.usershare_path;
4367 int ret = lp_numservices();
4368 TALLOC_CTX *tmp_ctx;
4370 if (max_user_shares == 0 || *usersharepath == '\0') {
4371 return lp_numservices();
4374 if (sys_stat(usersharepath, &sbuf, false) != 0) {
4375 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4376 usersharepath, strerror(errno) ));
4381 * This directory must be owned by root, and have the 't' bit set.
4382 * It also must not be writable by "other".
4386 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4388 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4390 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4391 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4396 /* Ensure the template share exists if it's set. */
4397 if (Globals.usershare_template_share[0]) {
4398 /* We can't use lp_servicenumber here as we are recommending that
4399 template shares have -valid=false set. */
4400 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4401 if (ServicePtrs[snum_template]->szService &&
4402 strequal(ServicePtrs[snum_template]->szService,
4403 Globals.usershare_template_share)) {
4408 if (snum_template == -1) {
4409 DEBUG(0,("load_usershare_shares: usershare template share %s "
4410 "does not exist.\n",
4411 Globals.usershare_template_share ));
4416 /* Mark all existing usershares as pending delete. */
4417 for (iService = iNumServices - 1; iService >= 0; iService--) {
4418 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4419 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4423 dp = opendir(usersharepath);
4425 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4426 usersharepath, strerror(errno) ));
4430 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4432 num_dir_entries++ ) {
4434 const char *n = de->d_name;
4436 /* Ignore . and .. */
4438 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4444 /* Temporary file used when creating a share. */
4445 num_tmp_dir_entries++;
4448 /* Allow 20% tmp entries. */
4449 if (num_tmp_dir_entries > allowed_tmp_entries) {
4450 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4451 "in directory %s\n",
4452 num_tmp_dir_entries, usersharepath));
4456 r = process_usershare_file(usersharepath, n, snum_template);
4458 /* Update the services count. */
4460 if (num_usershares >= max_user_shares) {
4461 DEBUG(0,("load_usershare_shares: max user shares reached "
4462 "on file %s in directory %s\n",
4463 n, usersharepath ));
4466 } else if (r == -1) {
4467 num_bad_dir_entries++;
4470 /* Allow 20% bad entries. */
4471 if (num_bad_dir_entries > allowed_bad_entries) {
4472 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4473 "in directory %s\n",
4474 num_bad_dir_entries, usersharepath));
4478 /* Allow 20% bad entries. */
4479 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4480 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4481 "in directory %s\n",
4482 num_dir_entries, usersharepath));
4489 /* Sweep through and delete any non-refreshed usershares that are
4490 not currently in use. */
4491 tmp_ctx = talloc_stackframe();
4492 for (iService = iNumServices - 1; iService >= 0; iService--) {
4493 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4496 if (snumused && snumused(sconn, iService)) {
4500 servname = lp_servicename(tmp_ctx, iService);
4502 /* Remove from the share ACL db. */
4503 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4505 delete_share_security(servname);
4506 free_service_byindex(iService);
4509 talloc_free(tmp_ctx);
4511 return lp_numservices();
4514 /********************************************************
4515 Destroy global resources allocated in this file
4516 ********************************************************/
4518 void gfree_loadparm(void)
4524 /* Free resources allocated to services */
4526 for ( i = 0; i < iNumServices; i++ ) {
4528 free_service_byindex(i);
4532 SAFE_FREE( ServicePtrs );
4535 /* Now release all resources allocated to global
4536 parameters and the default service */
4538 free_global_parameters();
4542 /***************************************************************************
4543 Allow client apps to specify that they are a client
4544 ***************************************************************************/
4545 static void lp_set_in_client(bool b)
4551 /***************************************************************************
4552 Determine if we're running in a client app
4553 ***************************************************************************/
4554 static bool lp_is_in_client(void)
4559 /***************************************************************************
4560 Load the services array from the services file. Return true on success,
4562 ***************************************************************************/
4564 static bool lp_load_ex(const char *pszFname,
4568 bool initialize_globals,
4569 bool allow_include_registry,
4570 bool load_all_shares)
4577 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4579 bInGlobalSection = true;
4580 bGlobalOnly = global_only;
4581 bAllowIncludeRegistry = allow_include_registry;
4583 init_globals(initialize_globals);
4587 if (save_defaults) {
4592 if (!initialize_globals) {
4593 free_param_opts(&Globals.param_opt);
4594 apply_lp_set_cmdline();
4597 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
4599 /* We get sections first, so have to start 'behind' to make up */
4602 if (lp_config_backend_is_file()) {
4603 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4604 current_user_info.domain,
4607 smb_panic("lp_load_ex: out of memory");
4610 add_to_file_list(pszFname, n2);
4612 bRetval = pm_process(n2, do_section, do_parameter, NULL);
4615 /* finish up the last section */
4616 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4618 if (iServiceIndex >= 0) {
4619 bRetval = service_ok(iServiceIndex);
4623 if (lp_config_backend_is_registry()) {
4624 /* config backend changed to registry in config file */
4626 * We need to use this extra global variable here to
4627 * survive restart: init_globals uses this as a default
4628 * for config_backend. Otherwise, init_globals would
4629 * send us into an endless loop here.
4631 config_backend = CONFIG_BACKEND_REGISTRY;
4633 DEBUG(1, ("lp_load_ex: changing to config backend "
4636 lp_kill_all_services();
4637 return lp_load_ex(pszFname, global_only, save_defaults,
4638 add_ipc, initialize_globals,
4639 allow_include_registry,
4642 } else if (lp_config_backend_is_registry()) {
4643 bRetval = process_registry_globals();
4645 DEBUG(0, ("Illegal config backend given: %d\n",
4646 lp_config_backend()));
4650 if (bRetval && lp_registry_shares()) {
4651 if (load_all_shares) {
4652 bRetval = process_registry_shares();
4654 bRetval = reload_registry_shares();
4659 char *serv = lp_auto_services(talloc_tos());
4660 lp_add_auto_services(serv);
4665 /* When 'restrict anonymous = 2' guest connections to ipc$
4667 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4668 if ( lp_enable_asu_support() ) {
4669 lp_add_ipc("ADMIN$", false);
4673 set_allowed_client_auth();
4675 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4676 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4677 lp_password_server()));
4682 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4683 /* if we_are_a_wins_server is true and we are in the client */
4684 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4685 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4690 fault_configure(smb_panic_s3);
4693 * We run this check once the whole smb.conf is parsed, to
4694 * force some settings for the standard way a AD DC is
4695 * operated. We may changed these as our code evolves, which
4696 * is why we force these settings.
4698 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4699 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4701 lp_do_parameter(-1, "rpc_server:default", "external");
4702 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4703 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4704 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4705 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4706 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4707 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4708 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4709 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4712 bAllowIncludeRegistry = true;
4717 bool lp_load(const char *pszFname,
4721 bool initialize_globals)
4723 return lp_load_ex(pszFname,
4728 true, /* allow_include_registry */
4729 false); /* load_all_shares*/
4732 bool lp_load_initial_only(const char *pszFname)
4734 return lp_load_ex(pszFname,
4735 true, /* global only */
4736 false, /* save_defaults */
4737 false, /* add_ipc */
4738 true, /* initialize_globals */
4739 false, /* allow_include_registry */
4740 false); /* load_all_shares*/
4744 * most common lp_load wrapper, loading only the globals
4746 bool lp_load_global(const char *file_name)
4748 return lp_load_ex(file_name,
4749 true, /* global_only */
4750 false, /* save_defaults */
4751 false, /* add_ipc */
4752 true, /* initialize_globals */
4753 true, /* allow_include_registry */
4754 false); /* load_all_shares*/
4758 * lp_load wrapper, especially for clients
4760 bool lp_load_client(const char *file_name)
4762 lp_set_in_client(true);
4764 return lp_load_global(file_name);
4768 * lp_load wrapper, loading only globals, but intended
4769 * for subsequent calls, not reinitializing the globals
4772 bool lp_load_global_no_reinit(const char *file_name)
4774 return lp_load_ex(file_name,
4775 true, /* global_only */
4776 false, /* save_defaults */
4777 false, /* add_ipc */
4778 false, /* initialize_globals */
4779 true, /* allow_include_registry */
4780 false); /* load_all_shares*/
4784 * lp_load wrapper, especially for clients, no reinitialization
4786 bool lp_load_client_no_reinit(const char *file_name)
4788 lp_set_in_client(true);
4790 return lp_load_global_no_reinit(file_name);
4793 bool lp_load_with_registry_shares(const char *pszFname,
4797 bool initialize_globals)
4799 return lp_load_ex(pszFname,
4804 true, /* allow_include_registry */
4805 true); /* load_all_shares*/
4808 /***************************************************************************
4809 Return the max number of services.
4810 ***************************************************************************/
4812 int lp_numservices(void)
4814 return (iNumServices);
4817 /***************************************************************************
4818 Display the contents of the services array in human-readable form.
4819 ***************************************************************************/
4821 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4826 defaults_saved = false;
4830 dump_a_service(&sDefault, f);
4832 for (iService = 0; iService < maxtoprint; iService++) {
4834 lp_dump_one(f, show_defaults, iService);
4838 /***************************************************************************
4839 Display the contents of one service in human-readable form.
4840 ***************************************************************************/
4842 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4845 if (ServicePtrs[snum]->szService[0] == '\0')
4847 dump_a_service(ServicePtrs[snum], f);
4851 /***************************************************************************
4852 Return the number of the service with the given name, or -1 if it doesn't
4853 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4854 getservicebyname()! This works ONLY if all services have been loaded, and
4855 does not copy the found service.
4856 ***************************************************************************/
4858 int lp_servicenumber(const char *pszServiceName)
4861 fstring serviceName;
4863 if (!pszServiceName) {
4864 return GLOBAL_SECTION_SNUM;
4867 for (iService = iNumServices - 1; iService >= 0; iService--) {
4868 if (VALID(iService) && ServicePtrs[iService]->szService) {
4870 * The substitution here is used to support %U is
4873 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4874 standard_sub_basic(get_current_username(),
4875 current_user_info.domain,
4876 serviceName,sizeof(serviceName));
4877 if (strequal(serviceName, pszServiceName)) {
4883 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4884 struct timespec last_mod;
4886 if (!usershare_exists(iService, &last_mod)) {
4887 /* Remove the share security tdb entry for it. */
4888 delete_share_security(lp_servicename(talloc_tos(), iService));
4889 /* Remove it from the array. */
4890 free_service_byindex(iService);
4891 /* Doesn't exist anymore. */
4892 return GLOBAL_SECTION_SNUM;
4895 /* Has it been modified ? If so delete and reload. */
4896 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4898 /* Remove it from the array. */
4899 free_service_byindex(iService);
4900 /* and now reload it. */
4901 iService = load_usershare_service(pszServiceName);
4906 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4907 return GLOBAL_SECTION_SNUM;
4913 /*******************************************************************
4914 A useful volume label function.
4915 ********************************************************************/
4917 const char *volume_label(TALLOC_CTX *ctx, int snum)
4920 const char *label = lp_volume(ctx, snum);
4922 label = lp_servicename(ctx, snum);
4925 /* This returns a 33 byte guarenteed null terminated string. */
4926 ret = talloc_strndup(ctx, label, 32);
4933 /*******************************************************************
4934 Get the default server type we will announce as via nmbd.
4935 ********************************************************************/
4937 int lp_default_server_announce(void)
4939 int default_server_announce = 0;
4940 default_server_announce |= SV_TYPE_WORKSTATION;
4941 default_server_announce |= SV_TYPE_SERVER;
4942 default_server_announce |= SV_TYPE_SERVER_UNIX;
4944 /* note that the flag should be set only if we have a
4945 printer service but nmbd doesn't actually load the
4946 services so we can't tell --jerry */
4948 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4950 default_server_announce |= SV_TYPE_SERVER_NT;
4951 default_server_announce |= SV_TYPE_NT;
4953 switch (lp_server_role()) {
4954 case ROLE_DOMAIN_MEMBER:
4955 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4957 case ROLE_DOMAIN_PDC:
4958 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4960 case ROLE_DOMAIN_BDC:
4961 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4963 case ROLE_STANDALONE:
4967 if (lp_time_server())
4968 default_server_announce |= SV_TYPE_TIME_SOURCE;
4970 if (lp_host_msdfs())
4971 default_server_announce |= SV_TYPE_DFS_SERVER;
4973 return default_server_announce;
4976 /***********************************************************
4977 If we are PDC then prefer us as DMB
4978 ************************************************************/
4980 bool lp_domain_master(void)
4982 if (Globals._domain_master == Auto)
4983 return (lp_server_role() == ROLE_DOMAIN_PDC);
4985 return (bool)Globals._domain_master;
4988 /***********************************************************
4989 If we are PDC then prefer us as DMB
4990 ************************************************************/
4992 static bool lp_domain_master_true_or_auto(void)
4994 if (Globals._domain_master) /* auto or yes */
5000 /***********************************************************
5001 If we are DMB then prefer us as LMB
5002 ************************************************************/
5004 bool lp_preferred_master(void)
5006 if (Globals.iPreferredMaster == Auto)
5007 return (lp_local_master() && lp_domain_master());
5009 return (bool)Globals.iPreferredMaster;
5012 /*******************************************************************
5014 ********************************************************************/
5016 void lp_remove_service(int snum)
5018 ServicePtrs[snum]->valid = false;
5021 /*******************************************************************
5023 ********************************************************************/
5025 void lp_copy_service(int snum, const char *new_name)
5027 do_section(new_name, NULL);
5029 snum = lp_servicenumber(new_name);
5031 char *name = lp_servicename(talloc_tos(), snum);
5032 lp_do_parameter(snum, "copy", name);
5037 const char *lp_printername(TALLOC_CTX *ctx, int snum)
5039 const char *ret = lp__printername(ctx, snum);
5040 if (ret == NULL || *ret == '\0') {
5041 ret = lp_const_servicename(snum);
5048 /***********************************************************
5049 Allow daemons such as winbindd to fix their logfile name.
5050 ************************************************************/
5052 void lp_set_logfile(const char *name)
5054 string_set(&Globals.logfile, name);
5055 debug_set_logfile(name);
5058 /*******************************************************************
5059 Return the max print jobs per queue.
5060 ********************************************************************/
5062 int lp_maxprintjobs(int snum)
5064 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5065 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5066 maxjobs = PRINT_MAX_JOBID - 1;
5071 const char *lp_printcapname(void)
5073 if ((Globals.szPrintcapname != NULL) &&
5074 (Globals.szPrintcapname[0] != '\0'))
5075 return Globals.szPrintcapname;
5077 if (sDefault.printing == PRINT_CUPS) {
5081 if (sDefault.printing == PRINT_BSD)
5082 return "/etc/printcap";
5084 return PRINTCAP_NAME;
5087 static uint32 spoolss_state;
5089 bool lp_disable_spoolss( void )
5091 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5092 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5094 return spoolss_state == SVCCTL_STOPPED ? true : false;
5097 void lp_set_spoolss_state( uint32 state )
5099 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5101 spoolss_state = state;
5104 uint32 lp_get_spoolss_state( void )
5106 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5109 /*******************************************************************
5110 Ensure we don't use sendfile if server smb signing is active.
5111 ********************************************************************/
5113 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
5115 bool sign_active = false;
5117 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5118 if (get_Protocol() < PROTOCOL_NT1) {
5121 if (signing_state) {
5122 sign_active = smb_signing_is_active(signing_state);
5124 return (lp__use_sendfile(snum) &&
5125 (get_remote_arch() != RA_WIN95) &&
5129 /*******************************************************************
5130 Turn off sendfile if we find the underlying OS doesn't support it.
5131 ********************************************************************/
5133 void set_use_sendfile(int snum, bool val)
5135 if (LP_SNUM_OK(snum))
5136 ServicePtrs[snum]->_use_sendfile = val;
5138 sDefault._use_sendfile = val;
5141 /*******************************************************************
5142 Turn off storing DOS attributes if this share doesn't support it.
5143 ********************************************************************/
5145 void set_store_dos_attributes(int snum, bool val)
5147 if (!LP_SNUM_OK(snum))
5149 ServicePtrs[(snum)]->store_dos_attributes = val;
5152 void lp_set_mangling_method(const char *new_method)
5154 string_set(&Globals.mangling_method, new_method);
5157 /*******************************************************************
5158 Global state for POSIX pathname processing.
5159 ********************************************************************/
5161 static bool posix_pathnames;
5163 bool lp_posix_pathnames(void)
5165 return posix_pathnames;
5168 /*******************************************************************
5169 Change everything needed to ensure POSIX pathname processing (currently
5171 ********************************************************************/
5173 void lp_set_posix_pathnames(void)
5175 posix_pathnames = true;
5178 /*******************************************************************
5179 Global state for POSIX lock processing - CIFS unix extensions.
5180 ********************************************************************/
5182 bool posix_default_lock_was_set;
5183 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5185 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5187 if (posix_default_lock_was_set) {
5188 return posix_cifsx_locktype;
5190 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5194 /*******************************************************************
5195 ********************************************************************/
5197 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5199 posix_default_lock_was_set = true;
5200 posix_cifsx_locktype = val;
5203 int lp_min_receive_file_size(void)
5205 if (Globals.iminreceivefile < 0) {
5208 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
5211 /*******************************************************************
5212 Safe wide links checks.
5213 This helper function always verify the validity of wide links,
5214 even after a configuration file reload.
5215 ********************************************************************/
5217 static bool lp_widelinks_internal(int snum)
5219 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
5220 sDefault.bWidelinks);
5223 void widelinks_warning(int snum)
5225 if (lp_allow_insecure_wide_links()) {
5229 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
5230 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
5231 "These parameters are incompatible. "
5232 "Wide links will be disabled for this share.\n",
5233 lp_servicename(talloc_tos(), snum) ));
5237 bool lp_widelinks(int snum)
5239 /* wide links is always incompatible with unix extensions */
5240 if (lp_unix_extensions()) {
5242 * Unless we have "allow insecure widelinks"
5245 if (!lp_allow_insecure_wide_links()) {
5250 return lp_widelinks_internal(snum);
5253 int lp_server_role(void)
5255 return lp_find_server_role(lp__server_role(),
5257 lp__domain_logons(),
5258 lp_domain_master_true_or_auto());
5261 int lp_security(void)
5263 return lp_find_security(lp__server_role(),