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 #define LOADPARM_EXTRA_GLOBALS \
112 struct parmlist_entry *param_opt; \
113 char *realm_original; \
114 int iminreceivefile; \
115 char *szPrintcapname; \
117 int iPreferredMaster; \
118 char *szLdapMachineSuffix; \
119 char *szLdapUserSuffix; \
120 char *szLdapIdmapSuffix; \
121 char *szLdapGroupSuffix; \
126 char *szIdmapBackend; \
127 int winbindMaxDomainConnections; \
128 int ismb2_max_credits; \
130 char *tls_certfile; \
135 #include "param/param_global.h"
137 static struct loadparm_global Globals;
139 /* This is a default service used to prime a services structure */
140 static struct loadparm_service sDefault =
145 .usershare_last_mod = {0, 0},
149 .invalid_users = NULL,
156 .root_preexec = NULL,
157 .root_postexec = NULL,
158 .cups_options = NULL,
159 .print_command = NULL,
161 .lprm_command = NULL,
162 .lppause_command = NULL,
163 .lpresume_command = NULL,
164 .queuepause_command = NULL,
165 .queueresume_command = NULL,
166 ._printername = NULL,
167 .printjob_username = NULL,
168 .dont_descend = NULL,
171 .magic_script = NULL,
172 .magic_output = NULL,
175 .veto_oplock_files = NULL,
185 .aio_write_behind = NULL,
186 .dfree_command = NULL,
187 .min_print_space = 0,
188 .iMaxPrintJobs = 1000,
189 .max_reported_print_jobs = 0,
190 .write_cache_size = 0,
192 .force_create_mode = 0,
193 .directory_mask = 0755,
194 .force_directory_mode = 0,
195 .max_connections = 0,
196 .default_case = CASE_LOWER,
197 .printing = DEFAULT_PRINTING,
198 .oplock_contention_limit = 2,
201 .dfree_cache_time = 0,
202 .preexec_close = false,
203 .root_preexec_close = false,
204 .case_sensitive = Auto,
205 .preserve_case = true,
206 .short_preserve_case = true,
207 .hide_dot_files = true,
208 .hide_special_files = false,
209 .hide_unreadable = false,
210 .hide_unwriteable_files = false,
212 .access_based_share_enum = false,
216 .administrative_share = false,
219 .print_notify_backchannel = false,
223 .store_dos_attributes = false,
224 .dmapi_support = false,
226 .strict_locking = Auto,
227 .posix_locking = true,
229 .kernel_oplocks = false,
230 .level2_oplocks = true,
232 .mangled_names = true,
234 .follow_symlinks = true,
235 .sync_always = false,
236 .strict_allocate = false,
237 .strict_sync = false,
238 .mangling_char = '~',
240 .delete_readonly = false,
241 .fake_oplocks = false,
242 .delete_veto_files = false,
243 .dos_filemode = false,
244 .dos_filetimes = true,
245 .dos_filetime_resolution = false,
246 .fake_directory_create_times = false,
247 .blocking_locks = true,
248 .inherit_permissions = false,
249 .inherit_acls = false,
250 .inherit_owner = false,
252 .use_client_driver = false,
253 .default_devmode = true,
254 .force_printername = false,
255 .nt_acl_support = true,
256 .force_unknown_acl_user = false,
257 ._use_sendfile = false,
258 .profile_acls = false,
259 .map_acl_inherit = false,
262 .acl_check_permissions = true,
263 .acl_map_full_control = true,
264 .acl_group_control = false,
265 .acl_allow_execute_always = false,
266 .change_notify = true,
267 .kernel_change_notify = true,
268 .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
271 .map_readonly = MAP_READONLY_YES,
272 .directory_name_cache_size = 100,
273 .smb_encrypt = SMB_SIGNING_DEFAULT,
274 .kernel_share_modes = true,
275 .durable_handles = true,
280 /* local variables */
281 static struct loadparm_service **ServicePtrs = NULL;
282 static int iNumServices = 0;
283 static int iServiceIndex = 0;
284 static struct db_context *ServiceHash;
285 static bool bInGlobalSection = true;
286 static bool bGlobalOnly = false;
288 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
290 /* prototypes for the special type handlers */
291 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
292 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
293 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
294 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
295 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
296 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
297 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
298 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
299 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
300 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
301 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
302 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
304 /* these are parameter handlers which are not needed in the
308 #define handle_logfile NULL
310 static void set_allowed_client_auth(void);
312 static void add_to_file_list(const char *fname, const char *subfname);
313 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
314 static void free_param_opts(struct parmlist_entry **popts);
316 #include "lib/param/param_table.c"
318 /* this is used to prevent lots of mallocs of size 1 */
319 static const char null_string[] = "";
322 Set a string value, allocing the space for the string
325 static bool string_init(char **dest,const char *src)
335 *dest = discard_const_p(char, null_string);
337 (*dest) = SMB_STRDUP(src);
338 if ((*dest) == NULL) {
339 DEBUG(0,("Out of memory in string_init\n"));
350 static void string_free(char **s)
354 if (*s == null_string)
360 Set a string value, deallocating any existing space, and allocing the space
364 static bool string_set(char **dest,const char *src)
367 return(string_init(dest,src));
370 /***************************************************************************
371 Initialise the sDefault parameter structure for the printer values.
372 ***************************************************************************/
374 static void init_printer_values(struct loadparm_service *pService)
376 /* choose defaults depending on the type of printing */
377 switch (pService->printing) {
382 string_set(&pService->lpq_command, "lpq -P'%p'");
383 string_set(&pService->lprm_command, "lprm -P'%p' %j");
384 string_set(&pService->print_command, "lpr -r -P'%p' %s");
389 string_set(&pService->lpq_command, "lpq -P'%p'");
390 string_set(&pService->lprm_command, "lprm -P'%p' %j");
391 string_set(&pService->print_command, "lpr -r -P'%p' %s");
392 string_set(&pService->queuepause_command, "lpc stop '%p'");
393 string_set(&pService->queueresume_command, "lpc start '%p'");
394 string_set(&pService->lppause_command, "lpc hold '%p' %j");
395 string_set(&pService->lpresume_command, "lpc release '%p' %j");
400 /* set the lpq command to contain the destination printer
401 name only. This is used by cups_queue_get() */
402 string_set(&pService->lpq_command, "%p");
403 string_set(&pService->lprm_command, "");
404 string_set(&pService->print_command, "");
405 string_set(&pService->lppause_command, "");
406 string_set(&pService->lpresume_command, "");
407 string_set(&pService->queuepause_command, "");
408 string_set(&pService->queueresume_command, "");
413 string_set(&pService->lpq_command, "lpstat -o%p");
414 string_set(&pService->lprm_command, "cancel %p-%j");
415 string_set(&pService->print_command, "lp -c -d%p %s; rm %s");
416 string_set(&pService->queuepause_command, "disable %p");
417 string_set(&pService->queueresume_command, "enable %p");
419 string_set(&pService->lppause_command, "lp -i %p-%j -H hold");
420 string_set(&pService->lpresume_command, "lp -i %p-%j -H resume");
425 string_set(&pService->lpq_command, "lpq -P%p");
426 string_set(&pService->lprm_command, "lprm -P%p %j");
427 string_set(&pService->print_command, "lp -r -P%p %s");
430 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
435 TALLOC_CTX *tmp_ctx = talloc_stackframe();
438 tdbfile = talloc_asprintf(
439 tmp_ctx, "tdbfile=%s",
440 lp_parm_const_string(-1, "vlp", "tdbfile",
442 if (tdbfile == NULL) {
443 tdbfile="tdbfile=/tmp/vlp.tdb";
446 tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
448 string_set(&pService->print_command,
449 tmp ? tmp : "vlp print %p %s");
451 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
453 string_set(&pService->lpq_command,
454 tmp ? tmp : "vlp lpq %p");
456 tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
458 string_set(&pService->lprm_command,
459 tmp ? tmp : "vlp lprm %p %j");
461 tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
463 string_set(&pService->lppause_command,
464 tmp ? tmp : "vlp lppause %p %j");
466 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
468 string_set(&pService->lpresume_command,
469 tmp ? tmp : "vlp lpresume %p %j");
471 tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
473 string_set(&pService->queuepause_command,
474 tmp ? tmp : "vlp queuepause %p");
476 tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
478 string_set(&pService->queueresume_command,
479 tmp ? tmp : "vlp queueresume %p");
480 TALLOC_FREE(tmp_ctx);
484 #endif /* DEVELOPER */
489 * Function to return the default value for the maximum number of open
490 * file descriptors permitted. This function tries to consult the
491 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
492 * the smaller of those.
494 static int max_open_files(void)
496 int sysctl_max = MAX_OPEN_FILES;
497 int rlimit_max = MAX_OPEN_FILES;
499 #ifdef HAVE_SYSCTLBYNAME
501 size_t size = sizeof(sysctl_max);
502 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
507 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
513 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
514 rlimit_max = rl.rlim_cur;
516 #if defined(RLIM_INFINITY)
517 if(rl.rlim_cur == RLIM_INFINITY)
518 rlimit_max = MAX_OPEN_FILES;
523 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
524 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
525 "minimum Windows limit (%d)\n",
527 MIN_OPEN_FILES_WINDOWS));
528 sysctl_max = MIN_OPEN_FILES_WINDOWS;
531 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
532 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
533 "minimum Windows limit (%d)\n",
535 MIN_OPEN_FILES_WINDOWS));
536 rlimit_max = MIN_OPEN_FILES_WINDOWS;
539 return MIN(sysctl_max, rlimit_max);
543 * Common part of freeing allocated data for one parameter.
545 static void free_one_parameter_common(void *parm_ptr,
546 struct parm_struct parm)
548 if ((parm.type == P_STRING) ||
549 (parm.type == P_USTRING))
551 string_free((char**)parm_ptr);
552 } else if (parm.type == P_LIST) {
553 TALLOC_FREE(*((char***)parm_ptr));
558 * Free the allocated data for one parameter for a share
559 * given as a service struct.
561 static void free_one_parameter(struct loadparm_service *service,
562 struct parm_struct parm)
566 if (parm.p_class != P_LOCAL) {
570 parm_ptr = lp_parm_ptr(service, &parm);
572 free_one_parameter_common(parm_ptr, parm);
576 * Free the allocated parameter data of a share given
577 * as a service struct.
579 static void free_parameters(struct loadparm_service *service)
583 for (i=0; parm_table[i].label; i++) {
584 free_one_parameter(service, parm_table[i]);
589 * Free the allocated data for one parameter for a given share
590 * specified by an snum.
592 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
597 parm_ptr = lp_parm_ptr(NULL, &parm);
598 } else if (parm.p_class != P_LOCAL) {
601 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
604 free_one_parameter_common(parm_ptr, parm);
608 * Free the allocated parameter data for a share specified
611 static void free_parameters_by_snum(int snum)
615 for (i=0; parm_table[i].label; i++) {
616 free_one_parameter_by_snum(snum, parm_table[i]);
621 * Free the allocated global parameters.
623 static void free_global_parameters(void)
625 free_param_opts(&Globals.param_opt);
626 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
627 TALLOC_FREE(Globals.ctx);
630 struct lp_stored_option {
631 struct lp_stored_option *prev, *next;
636 static struct lp_stored_option *stored_options;
639 save options set by lp_set_cmdline() into a list. This list is
640 re-applied when we do a globals reset, so that cmdline set options
641 are sticky across reloads of smb.conf
643 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
645 struct lp_stored_option *entry, *entry_next;
646 for (entry = stored_options; entry != NULL; entry = entry_next) {
647 entry_next = entry->next;
648 if (strcmp(pszParmName, entry->label) == 0) {
649 DLIST_REMOVE(stored_options, entry);
655 entry = talloc(NULL, struct lp_stored_option);
660 entry->label = talloc_strdup(entry, pszParmName);
666 entry->value = talloc_strdup(entry, pszParmValue);
672 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
677 static bool apply_lp_set_cmdline(void)
679 struct lp_stored_option *entry = NULL;
680 for (entry = stored_options; entry != NULL; entry = entry->next) {
681 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
682 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
683 entry->label, entry->value));
690 /***************************************************************************
691 Initialise the global parameter structure.
692 ***************************************************************************/
694 static void init_globals(bool reinit_globals)
696 static bool done_init = false;
700 /* If requested to initialize only once and we've already done it... */
701 if (!reinit_globals && done_init) {
702 /* ... then we have nothing more to do */
707 /* The logfile can be set before this is invoked. Free it if so. */
708 if (Globals.logfile != NULL) {
709 string_free(&Globals.logfile);
710 Globals.logfile = NULL;
714 free_global_parameters();
717 /* This memset and the free_global_parameters() above will
718 * wipe out smb.conf options set with lp_set_cmdline(). The
719 * apply_lp_set_cmdline() call puts these values back in the
720 * table once the defaults are set */
721 ZERO_STRUCT(Globals);
723 Globals.ctx = talloc_new(NULL);
725 for (i = 0; parm_table[i].label; i++) {
726 if ((parm_table[i].type == P_STRING ||
727 parm_table[i].type == P_USTRING))
729 string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
734 string_set(&sDefault.fstype, FSTYPE_STRING);
735 string_set(&sDefault.printjob_username, "%U");
737 init_printer_values(&sDefault);
739 sDefault.ntvfs_handler = (const char **)str_list_make_v3(NULL, "unixuid default", NULL);
741 DEBUG(3, ("Initialising global parameters\n"));
743 /* Must manually force to upper case here, as this does not go via the handler */
744 string_set(&Globals.netbios_name, myhostname_upper());
746 string_set(&Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
747 string_set(&Globals.private_dir, get_dyn_PRIVATE_DIR());
749 /* use the new 'hash2' method by default, with a prefix of 1 */
750 string_set(&Globals.mangling_method, "hash2");
751 Globals.mangle_prefix = 1;
753 string_set(&Globals.guest_account, GUEST_ACCOUNT);
755 /* using UTF8 by default allows us to support all chars */
756 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
758 /* Use codepage 850 as a default for the dos character set */
759 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
762 * Allow the default PASSWD_CHAT to be overridden in local.h.
764 string_set(&Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
766 string_set(&Globals.workgroup, DEFAULT_WORKGROUP);
768 string_set(&Globals.passwd_program, "");
769 string_set(&Globals.lock_directory, get_dyn_LOCKDIR());
770 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
771 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
772 string_set(&Globals.pid_directory, get_dyn_PIDDIR());
773 string_set(&Globals.nbt_client_socket_address, "0.0.0.0");
775 * By default support explicit binding to broadcast
778 Globals.nmbd_bind_explicit_broadcast = true;
780 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
781 smb_panic("init_globals: ENOMEM");
783 string_set(&Globals.server_string, s);
786 string_set(&Globals.panic_action, "/bin/sleep 999999999");
789 string_set(&Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
791 string_set(&Globals.logon_drive, "");
792 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
793 string_set(&Globals.logon_home, "\\\\%N\\%U");
794 string_set(&Globals.logon_path, "\\\\%N\\%U\\profile");
796 Globals.name_resolve_order = (const char **)str_list_make_v3(NULL, "lmhosts wins host bcast", NULL);
797 string_set(&Globals.password_server, "*");
799 Globals.algorithmic_rid_base = BASE_RID;
801 Globals.load_printers = true;
802 Globals.printcap_cache_time = 750; /* 12.5 minutes */
804 Globals.config_backend = config_backend;
805 Globals._server_role = ROLE_AUTO;
807 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
808 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
809 Globals.max_xmit = 0x4104;
810 Globals.max_mux = 50; /* This is *needed* for profile support. */
811 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
812 Globals._disable_spoolss = false;
813 Globals.max_smbd_processes = 0;/* no limit specified */
814 Globals.username_level = 0;
815 Globals.deadtime = 0;
816 Globals.getwd_cache = true;
817 Globals.large_readwrite = true;
818 Globals.max_log_size = 5000;
819 Globals.max_open_files = max_open_files();
820 Globals.server_max_protocol = PROTOCOL_SMB3_00;
821 Globals.server_min_protocol = PROTOCOL_LANMAN1;
822 Globals.client_max_protocol = PROTOCOL_NT1;
823 Globals.client_min_protocol = PROTOCOL_CORE;
824 Globals._security = SEC_AUTO;
825 Globals.encrypt_passwords = true;
826 Globals.client_schannel = Auto;
827 Globals.winbind_sealed_pipes = true;
828 Globals.require_strong_key = true;
829 Globals.server_schannel = Auto;
830 Globals.bReadRaw = true;
831 Globals.bWriteRaw = true;
832 Globals.null_passwords = false;
833 Globals.obey_pam_restrictions = false;
835 Globals.syslog_only = false;
836 Globals.timestamp_logs = true;
837 string_set(&Globals.log_level, "0");
838 Globals.debug_prefix_timestamp = false;
839 Globals.debug_hires_timestamp = true;
840 Globals.debug_pid = false;
841 Globals.debug_uid = false;
842 Globals.debug_class = false;
843 Globals.enable_core_files = true;
844 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
845 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
846 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
847 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
848 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
849 Globals.lm_interval = 60;
850 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
851 Globals.nis_homedir = false;
852 #ifdef WITH_NISPLUS_HOME
853 string_set(&Globals.homedir_map, "auto_home.org_dir");
855 string_set(&Globals.homedir_map, "auto.home");
858 Globals.time_server = false;
859 Globals.bind_interfaces_only = false;
860 Globals.unix_password_sync = false;
861 Globals.pam_password_change = false;
862 Globals.passwd_chat_debug = false;
863 Globals.passwd_chat_timeout = 2; /* 2 second default. */
864 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
865 Globals.nt_status_support = true; /* Use NT status by default. */
866 Globals.stat_cache = true; /* use stat cache by default */
867 Globals.max_stat_cache_size = 256; /* 256k by default */
868 Globals.restrict_anonymous = 0;
869 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
870 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
871 Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
872 Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
873 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 */
874 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
876 Globals.map_to_guest = 0; /* By Default, "Never" */
877 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
878 Globals.enhanced_browsing = true;
879 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
880 #ifdef MMAP_BLACKLIST
881 Globals.use_mmap = false;
883 Globals.use_mmap = true;
885 Globals.unicode = true;
886 Globals.unix_extensions = true;
887 Globals.reset_on_zero_vc = false;
888 Globals.log_writeable_files_on_exit = false;
889 Globals.create_krb5_conf = true;
890 Globals.winbindMaxDomainConnections = 1;
892 /* hostname lookups can be very expensive and are broken on
893 a large number of sites (tridge) */
894 Globals.hostname_lookups = false;
896 string_set(&Globals.passdb_backend, "tdbsam");
897 string_set(&Globals.ldap_suffix, "");
898 string_set(&Globals.szLdapMachineSuffix, "");
899 string_set(&Globals.szLdapUserSuffix, "");
900 string_set(&Globals.szLdapGroupSuffix, "");
901 string_set(&Globals.szLdapIdmapSuffix, "");
903 string_set(&Globals.ldap_admin_dn, "");
904 Globals.ldap_ssl = LDAP_SSL_START_TLS;
905 Globals.ldap_ssl_ads = false;
906 Globals.ldap_deref = -1;
907 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
908 Globals.ldap_delete_dn = false;
909 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
910 Globals.ldap_follow_referral = Auto;
911 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
912 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
913 Globals.ldap_page_size = LDAP_PAGE_SIZE;
915 Globals.ldap_debug_level = 0;
916 Globals.ldap_debug_threshold = 10;
918 /* This is what we tell the afs client. in reality we set the token
919 * to never expire, though, when this runs out the afs client will
920 * forget the token. Set to 0 to get NEVERDATE.*/
921 Globals.afs_token_lifetime = 604800;
922 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
924 /* these parameters are set to defaults that are more appropriate
925 for the increasing samba install base:
927 as a member of the workgroup, that will possibly become a
928 _local_ master browser (lm = true). this is opposed to a forced
929 local master browser startup (pm = true).
931 doesn't provide WINS server service by default (wsupp = false),
932 and doesn't provide domain master browser services by default, either.
936 Globals.show_add_printer_wizard = true;
937 Globals.os_level = 20;
938 Globals.local_master = true;
939 Globals._domain_master = Auto; /* depending on _domain_logons */
940 Globals._domain_logons = false;
941 Globals.browse_list = true;
942 Globals.we_are_a_wins_server = false;
943 Globals.wins_proxy = false;
945 TALLOC_FREE(Globals.init_logon_delayed_hosts);
946 Globals.init_logon_delay = 100; /* 100 ms default delay */
948 Globals.wins_dns_proxy = true;
950 Globals.allow_trusted_domains = true;
951 string_set(&Globals.szIdmapBackend, "tdb");
953 string_set(&Globals.template_shell, "/bin/false");
954 string_set(&Globals.template_homedir, "/home/%D/%U");
955 string_set(&Globals.winbind_separator, "\\");
956 string_set(&Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
958 string_set(&Globals.cups_server, "");
959 string_set(&Globals.iprint_server, "");
961 #ifdef CLUSTER_SUPPORT
962 string_set(&Globals.ctdbd_socket, CTDB_PATH);
964 string_set(&Globals.ctdbd_socket, "");
967 Globals.cluster_addresses = NULL;
968 Globals.clustering = false;
969 Globals.ctdb_timeout = 0;
970 Globals.ctdb_locktime_warn_threshold = 0;
972 Globals.winbind_cache_time = 300; /* 5 minutes */
973 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
974 Globals.winbind_max_clients = 200;
975 Globals.winbind_enum_users = false;
976 Globals.winbind_enum_groups = false;
977 Globals.winbind_use_default_domain = false;
978 Globals.winbind_trusted_domains_only = false;
979 Globals.winbind_nested_groups = true;
980 Globals.winbind_expand_groups = 1;
981 Globals.winbind_nss_info = (const char **)str_list_make_v3(NULL, "template", NULL);
982 Globals.winbind_refresh_tickets = false;
983 Globals.winbind_offline_logon = false;
985 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
986 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
988 Globals.passdb_expand_explicit = false;
990 Globals.name_cache_timeout = 660; /* In seconds */
992 Globals.use_spnego = true;
993 Globals.client_use_spnego = true;
995 Globals.client_signing = SMB_SIGNING_DEFAULT;
996 Globals.server_signing = SMB_SIGNING_DEFAULT;
998 Globals.defer_sharing_violations = true;
999 Globals.smb_ports = (const char **)str_list_make_v3(NULL, SMB_PORTS, NULL);
1001 Globals.enable_privileges = true;
1002 Globals.host_msdfs = true;
1003 Globals.enable_asu_support = false;
1005 /* User defined shares. */
1006 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
1007 smb_panic("init_globals: ENOMEM");
1009 string_set(&Globals.usershare_path, s);
1011 string_set(&Globals.usershare_template_share, "");
1012 Globals.usershare_max_shares = 0;
1013 /* By default disallow sharing of directories not owned by the sharer. */
1014 Globals.usershare_owner_only = true;
1015 /* By default disallow guest access to usershares. */
1016 Globals.usershare_allow_guests = false;
1018 Globals.keepalive = DEFAULT_KEEPALIVE;
1020 /* By default no shares out of the registry */
1021 Globals.registry_shares = false;
1023 Globals.iminreceivefile = 0;
1025 Globals.map_untrusted_to_domain = false;
1026 Globals.multicast_dns_register = true;
1028 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
1029 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
1030 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
1031 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1033 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
1035 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);
1037 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);
1039 Globals.tls_enabled = true;
1041 string_set(&Globals.tls_keyfile, "tls/key.pem");
1042 string_set(&Globals.tls_certfile, "tls/cert.pem");
1043 string_set(&Globals.tls_cafile, "tls/ca.pem");
1045 string_set(&Globals.share_backend, "classic");
1047 Globals.iPreferredMaster = Auto;
1049 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
1051 string_set(&Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
1053 string_set(&Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
1055 if (asprintf(&s, "%s/samba_kcc", get_dyn_SCRIPTSBINDIR()) < 0) {
1056 smb_panic("init_globals: ENOMEM");
1058 Globals.samba_kcc_command = (const char **)str_list_make_v3(NULL, s, NULL);
1061 if (asprintf(&s, "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1062 smb_panic("init_globals: ENOMEM");
1064 Globals.dns_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1067 if (asprintf(&s, "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1068 smb_panic("init_globals: ENOMEM");
1070 Globals.spn_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1073 Globals.nsupdate_command = (const char **)str_list_make_v3(NULL, "/usr/bin/nsupdate -g", NULL);
1075 Globals.rndc_command = (const char **)str_list_make_v3(NULL, "/usr/sbin/rndc", NULL);
1077 Globals.cldap_port = 389;
1079 Globals.dgram_port = 138;
1081 Globals.nbt_port = 137;
1083 Globals.krb5_port = 88;
1085 Globals.kpasswd_port = 464;
1087 Globals.web_port = 901;
1089 /* Now put back the settings that were set with lp_set_cmdline() */
1090 apply_lp_set_cmdline();
1093 /*******************************************************************
1094 Convenience routine to grab string parameters into talloced memory
1095 and run standard_sub_basic on them. The buffers can be written to by
1096 callers without affecting the source string.
1097 ********************************************************************/
1099 static char *lp_string(TALLOC_CTX *ctx, const char *s)
1103 /* The follow debug is useful for tracking down memory problems
1104 especially if you have an inner loop that is calling a lp_*()
1105 function that returns a string. Perhaps this debug should be
1106 present all the time? */
1109 DEBUG(10, ("lp_string(%s)\n", s));
1115 ret = talloc_sub_basic(ctx,
1116 get_current_username(),
1117 current_user_info.domain,
1119 if (trim_char(ret, '\"', '\"')) {
1120 if (strchr(ret,'\"') != NULL) {
1122 ret = talloc_sub_basic(ctx,
1123 get_current_username(),
1124 current_user_info.domain,
1132 In this section all the functions that are used to access the
1133 parameters from the rest of the program are defined
1136 #define FN_GLOBAL_STRING(fn_name,ptr) \
1137 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1138 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1139 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1140 #define FN_GLOBAL_LIST(fn_name,ptr) \
1141 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1142 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1143 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1144 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1145 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1146 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1147 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1149 #define FN_LOCAL_STRING(fn_name,val) \
1150 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));}
1151 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1152 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1153 #define FN_LOCAL_LIST(fn_name,val) \
1154 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1155 #define FN_LOCAL_BOOL(fn_name,val) \
1156 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1157 #define FN_LOCAL_INTEGER(fn_name,val) \
1158 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1160 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1161 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1162 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1163 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1164 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1165 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1168 static FN_GLOBAL_BOOL(_readraw, bReadRaw)
1169 static FN_GLOBAL_BOOL(_writeraw, bWriteRaw)
1171 /* If lp_statedir() and lp_cachedir() are explicitely set during the
1172 * build process or in smb.conf, we use that value. Otherwise they
1173 * default to the value of lp_lock_directory(). */
1174 const char *lp_statedir(void) {
1175 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
1176 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
1177 return(*(char **)(&Globals.szStateDir) ?
1178 *(char **)(&Globals.szStateDir) : "");
1180 return(*(char **)(&Globals.lock_directory) ?
1181 *(char **)(&Globals.lock_directory) : "");
1183 const char *lp_cachedir(void) {
1184 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
1185 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
1186 return(*(char **)(&Globals.szCacheDir) ?
1187 *(char **)(&Globals.szCacheDir) : "");
1189 return(*(char **)(&Globals.lock_directory) ?
1190 *(char **)(&Globals.lock_directory) : "");
1192 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
1193 winbindMaxDomainConnections)
1195 int lp_winbind_max_domain_connections(void)
1197 if (lp_winbind_offline_logon() &&
1198 lp_winbind_max_domain_connections_int() > 1) {
1199 DEBUG(1, ("offline logons active, restricting max domain "
1200 "connections to 1\n"));
1203 return MAX(1, lp_winbind_max_domain_connections_int());
1206 int lp_smb2_max_credits(void)
1208 if (Globals.ismb2_max_credits == 0) {
1209 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1211 return Globals.ismb2_max_credits;
1213 int lp_cups_encrypt(void)
1216 #ifdef HAVE_HTTPCONNECTENCRYPT
1217 switch (Globals.CupsEncrypt) {
1219 result = HTTP_ENCRYPT_REQUIRED;
1222 result = HTTP_ENCRYPT_ALWAYS;
1225 result = HTTP_ENCRYPT_NEVER;
1232 /* These functions remain in source3/param for now */
1234 FN_GLOBAL_STRING(configfile, szConfigFile)
1236 #include "lib/param/param_functions.c"
1238 FN_LOCAL_STRING(servicename, szService)
1239 FN_LOCAL_CONST_STRING(const_servicename, szService)
1241 /* local prototypes */
1243 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1244 static const char *get_boolean(bool bool_value);
1245 static int getservicebyname(const char *pszServiceName,
1246 struct loadparm_service *pserviceDest);
1247 static void copy_service(struct loadparm_service *pserviceDest,
1248 struct loadparm_service *pserviceSource,
1249 struct bitmap *pcopymapDest);
1250 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1252 static bool do_section(const char *pszSectionName, void *userdata);
1253 static void init_copymap(struct loadparm_service *pservice);
1254 static bool hash_a_service(const char *name, int number);
1255 static void free_service_byindex(int iService);
1256 static void show_parameter(int parmIndex);
1257 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1260 * This is a helper function for parametrical options support. It returns a
1261 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1262 * parametrical functions are quite simple
1264 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
1267 bool global_section = false;
1269 struct parmlist_entry *data;
1271 if (service == NULL) {
1272 data = Globals.param_opt;
1273 global_section = true;
1275 data = service->param_opt;
1278 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
1279 DEBUG(0,("asprintf failed!\n"));
1284 if (strwicmp(data->key, param_key) == 0) {
1285 string_free(¶m_key);
1291 if (!global_section) {
1292 /* Try to fetch the same option but from globals */
1293 /* but only if we are not already working with Globals */
1294 data = Globals.param_opt;
1296 if (strwicmp(data->key, param_key) == 0) {
1297 string_free(¶m_key);
1304 string_free(¶m_key);
1310 * This is a helper function for parametrical options support. It returns a
1311 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1312 * parametrical functions are quite simple
1314 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1317 if (snum >= iNumServices) return NULL;
1320 return get_parametrics_by_service(NULL, type, option);
1322 return get_parametrics_by_service(ServicePtrs[snum], type, option);
1327 #define MISSING_PARAMETER(name) \
1328 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1330 /*******************************************************************
1331 convenience routine to return int parameters.
1332 ********************************************************************/
1333 static int lp_int(const char *s)
1337 MISSING_PARAMETER(lp_int);
1341 return (int)strtol(s, NULL, 0);
1344 /*******************************************************************
1345 convenience routine to return unsigned long parameters.
1346 ********************************************************************/
1347 static unsigned long lp_ulong(const char *s)
1351 MISSING_PARAMETER(lp_ulong);
1355 return strtoul(s, NULL, 0);
1358 /*******************************************************************
1359 convenience routine to return boolean parameters.
1360 ********************************************************************/
1361 static bool lp_bool(const char *s)
1366 MISSING_PARAMETER(lp_bool);
1370 if (!set_boolean(s, &ret)) {
1371 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1378 /*******************************************************************
1379 convenience routine to return enum parameters.
1380 ********************************************************************/
1381 static int lp_enum(const char *s,const struct enum_list *_enum)
1385 if (!s || !*s || !_enum) {
1386 MISSING_PARAMETER(lp_enum);
1390 for (i=0; _enum[i].name; i++) {
1391 if (strequal(_enum[i].name,s))
1392 return _enum[i].value;
1395 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1399 #undef MISSING_PARAMETER
1401 /* Return parametric option from a given service. Type is a part of option before ':' */
1402 /* Parametric option has following syntax: 'Type: option = value' */
1403 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1405 struct parmlist_entry *data = get_parametrics(snum, type, option);
1407 if (data == NULL||data->value==NULL) {
1409 return lp_string(ctx, def);
1415 return lp_string(ctx, data->value);
1418 /* Return parametric option from a given service. Type is a part of option before ':' */
1419 /* Parametric option has following syntax: 'Type: option = value' */
1420 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1422 struct parmlist_entry *data = get_parametrics(snum, type, option);
1424 if (data == NULL||data->value==NULL)
1430 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
1432 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
1434 if (data == NULL||data->value==NULL)
1441 /* Return parametric option from a given service. Type is a part of option before ':' */
1442 /* Parametric option has following syntax: 'Type: option = value' */
1444 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1446 struct parmlist_entry *data = get_parametrics(snum, type, option);
1448 if (data == NULL||data->value==NULL)
1449 return (const char **)def;
1451 if (data->list==NULL) {
1452 data->list = str_list_make_v3(NULL, data->value, NULL);
1455 return (const char **)data->list;
1458 /* Return parametric option from a given service. Type is a part of option before ':' */
1459 /* Parametric option has following syntax: 'Type: option = value' */
1461 int lp_parm_int(int snum, const char *type, const char *option, int def)
1463 struct parmlist_entry *data = get_parametrics(snum, type, option);
1465 if (data && data->value && *data->value)
1466 return lp_int(data->value);
1471 /* Return parametric option from a given service. Type is a part of option before ':' */
1472 /* Parametric option has following syntax: 'Type: option = value' */
1474 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1476 struct parmlist_entry *data = get_parametrics(snum, type, option);
1478 if (data && data->value && *data->value)
1479 return lp_ulong(data->value);
1484 /* Return parametric option from a given service. Type is a part of option before ':' */
1485 /* Parametric option has following syntax: 'Type: option = value' */
1487 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1489 struct parmlist_entry *data = get_parametrics(snum, type, option);
1491 if (data && data->value && *data->value)
1492 return lp_bool(data->value);
1497 /* Return parametric option from a given service. Type is a part of option before ':' */
1498 /* Parametric option has following syntax: 'Type: option = value' */
1500 int lp_parm_enum(int snum, const char *type, const char *option,
1501 const struct enum_list *_enum, int def)
1503 struct parmlist_entry *data = get_parametrics(snum, type, option);
1505 if (data && data->value && *data->value && _enum)
1506 return lp_enum(data->value, _enum);
1512 /***************************************************************************
1513 Initialise a service to the defaults.
1514 ***************************************************************************/
1516 static void init_service(struct loadparm_service *pservice)
1518 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
1519 copy_service(pservice, &sDefault, NULL);
1524 * free a param_opts structure.
1525 * param_opts handling should be moved to talloc;
1526 * then this whole functions reduces to a TALLOC_FREE().
1529 static void free_param_opts(struct parmlist_entry **popts)
1531 struct parmlist_entry *opt, *next_opt;
1533 if (*popts != NULL) {
1534 DEBUG(5, ("Freeing parametrics:\n"));
1537 while (opt != NULL) {
1538 string_free(&opt->key);
1539 string_free(&opt->value);
1540 TALLOC_FREE(opt->list);
1541 next_opt = opt->next;
1548 /***************************************************************************
1549 Free the dynamically allocated parts of a service struct.
1550 ***************************************************************************/
1552 static void free_service(struct loadparm_service *pservice)
1557 if (pservice->szService)
1558 DEBUG(5, ("free_service: Freeing service %s\n",
1559 pservice->szService));
1561 free_parameters(pservice);
1563 string_free(&pservice->szService);
1564 TALLOC_FREE(pservice->copymap);
1566 free_param_opts(&pservice->param_opt);
1568 ZERO_STRUCTP(pservice);
1572 /***************************************************************************
1573 remove a service indexed in the ServicePtrs array from the ServiceHash
1574 and free the dynamically allocated parts
1575 ***************************************************************************/
1577 static void free_service_byindex(int idx)
1579 if ( !LP_SNUM_OK(idx) )
1582 ServicePtrs[idx]->valid = false;
1584 /* we have to cleanup the hash record */
1586 if (ServicePtrs[idx]->szService) {
1587 char *canon_name = canonicalize_servicename(
1589 ServicePtrs[idx]->szService );
1591 dbwrap_delete_bystring(ServiceHash, canon_name );
1592 TALLOC_FREE(canon_name);
1595 free_service(ServicePtrs[idx]);
1596 talloc_free_children(ServicePtrs[idx]);
1599 /***************************************************************************
1600 Add a new service to the services array initialising it with the given
1602 ***************************************************************************/
1604 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1607 struct loadparm_service tservice;
1608 int num_to_alloc = iNumServices + 1;
1609 struct loadparm_service **tsp = NULL;
1611 tservice = *pservice;
1613 /* it might already exist */
1615 i = getservicebyname(name, NULL);
1621 /* if not, then create one */
1623 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
1625 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1629 ServicePtrs[iNumServices] = talloc(NULL, struct loadparm_service);
1630 if (!ServicePtrs[iNumServices]) {
1631 DEBUG(0,("add_a_service: out of memory!\n"));
1636 ServicePtrs[i]->valid = true;
1638 init_service(ServicePtrs[i]);
1639 copy_service(ServicePtrs[i], &tservice, NULL);
1641 string_set(&ServicePtrs[i]->szService, name);
1643 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1644 i, ServicePtrs[i]->szService));
1646 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1653 /***************************************************************************
1654 Convert a string to uppercase and remove whitespaces.
1655 ***************************************************************************/
1657 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1662 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1666 result = talloc_strdup(ctx, src);
1667 SMB_ASSERT(result != NULL);
1669 if (!strlower_m(result)) {
1670 TALLOC_FREE(result);
1676 /***************************************************************************
1677 Add a name/index pair for the services array to the hash table.
1678 ***************************************************************************/
1680 static bool hash_a_service(const char *name, int idx)
1684 if ( !ServiceHash ) {
1685 DEBUG(10,("hash_a_service: creating servicehash\n"));
1686 ServiceHash = db_open_rbt(NULL);
1687 if ( !ServiceHash ) {
1688 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1693 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1696 canon_name = canonicalize_servicename(talloc_tos(), name );
1698 dbwrap_store_bystring(ServiceHash, canon_name,
1699 make_tdb_data((uint8 *)&idx, sizeof(idx)),
1702 TALLOC_FREE(canon_name);
1707 /***************************************************************************
1708 Add a new home service, with the specified home directory, defaults coming
1710 ***************************************************************************/
1712 bool lp_add_home(const char *pszHomename, int iDefaultService,
1713 const char *user, const char *pszHomedir)
1717 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1718 pszHomedir[0] == '\0') {
1722 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1727 if (!(*(ServicePtrs[iDefaultService]->path))
1728 || strequal(ServicePtrs[iDefaultService]->path,
1729 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1730 string_set(&ServicePtrs[i]->path, pszHomedir);
1733 if (!(*(ServicePtrs[i]->comment))) {
1734 char *comment = NULL;
1735 if (asprintf(&comment, "Home directory of %s", user) < 0) {
1738 string_set(&ServicePtrs[i]->comment, comment);
1742 /* set the browseable flag from the global default */
1744 ServicePtrs[i]->browseable = sDefault.browseable;
1745 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1747 ServicePtrs[i]->autoloaded = true;
1749 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1750 user, ServicePtrs[i]->path ));
1755 /***************************************************************************
1756 Add a new service, based on an old one.
1757 ***************************************************************************/
1759 int lp_add_service(const char *pszService, int iDefaultService)
1761 if (iDefaultService < 0) {
1762 return add_a_service(&sDefault, pszService);
1765 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1768 /***************************************************************************
1769 Add the IPC service.
1770 ***************************************************************************/
1772 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1774 char *comment = NULL;
1775 int i = add_a_service(&sDefault, ipc_name);
1780 if (asprintf(&comment, "IPC Service (%s)",
1781 Globals.server_string) < 0) {
1785 string_set(&ServicePtrs[i]->path, tmpdir());
1786 string_set(&ServicePtrs[i]->username, "");
1787 string_set(&ServicePtrs[i]->comment, comment);
1788 string_set(&ServicePtrs[i]->fstype, "IPC");
1789 ServicePtrs[i]->max_connections = 0;
1790 ServicePtrs[i]->bAvailable = true;
1791 ServicePtrs[i]->read_only = true;
1792 ServicePtrs[i]->guest_only = false;
1793 ServicePtrs[i]->administrative_share = true;
1794 ServicePtrs[i]->guest_ok = guest_ok;
1795 ServicePtrs[i]->printable = false;
1796 ServicePtrs[i]->browseable = sDefault.browseable;
1798 DEBUG(3, ("adding IPC service\n"));
1804 /***************************************************************************
1805 Add a new printer service, with defaults coming from service iFrom.
1806 ***************************************************************************/
1808 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1810 const char *comment = "From Printcap";
1811 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1816 /* note that we do NOT default the availability flag to true - */
1817 /* we take it from the default service passed. This allows all */
1818 /* dynamic printers to be disabled by disabling the [printers] */
1819 /* entry (if/when the 'available' keyword is implemented!). */
1821 /* the printer name is set to the service name. */
1822 string_set(&ServicePtrs[i]->_printername, pszPrintername);
1823 string_set(&ServicePtrs[i]->comment, comment);
1825 /* set the browseable flag from the gloabl default */
1826 ServicePtrs[i]->browseable = sDefault.browseable;
1828 /* Printers cannot be read_only. */
1829 ServicePtrs[i]->read_only = false;
1830 /* No oplocks on printer services. */
1831 ServicePtrs[i]->oplocks = false;
1832 /* Printer services must be printable. */
1833 ServicePtrs[i]->printable = true;
1835 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1841 /***************************************************************************
1842 Check whether the given parameter name is valid.
1843 Parametric options (names containing a colon) are considered valid.
1844 ***************************************************************************/
1846 bool lp_parameter_is_valid(const char *pszParmName)
1848 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1849 (strchr(pszParmName, ':') != NULL));
1852 /***************************************************************************
1853 Check whether the given name is the name of a global parameter.
1854 Returns true for strings belonging to parameters of class
1855 P_GLOBAL, false for all other strings, also for parametric options
1856 and strings not belonging to any option.
1857 ***************************************************************************/
1859 bool lp_parameter_is_global(const char *pszParmName)
1861 int num = lpcfg_map_parameter(pszParmName);
1864 return (parm_table[num].p_class == P_GLOBAL);
1870 /**************************************************************************
1871 Check whether the given name is the canonical name of a parameter.
1872 Returns false if it is not a valid parameter Name.
1873 For parametric options, true is returned.
1874 **************************************************************************/
1876 bool lp_parameter_is_canonical(const char *parm_name)
1878 if (!lp_parameter_is_valid(parm_name)) {
1882 return (lpcfg_map_parameter(parm_name) ==
1883 map_parameter_canonical(parm_name, NULL));
1886 /**************************************************************************
1887 Determine the canonical name for a parameter.
1888 Indicate when it is an inverse (boolean) synonym instead of a
1890 **************************************************************************/
1892 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1897 if (!lp_parameter_is_valid(parm_name)) {
1902 num = map_parameter_canonical(parm_name, inverse);
1904 /* parametric option */
1905 *canon_parm = parm_name;
1907 *canon_parm = parm_table[num].label;
1914 /**************************************************************************
1915 Determine the canonical name for a parameter.
1916 Turn the value given into the inverse boolean expression when
1917 the synonym is an invers boolean synonym.
1919 Return true if parm_name is a valid parameter name and
1920 in case it is an invers boolean synonym, if the val string could
1921 successfully be converted to the reverse bool.
1922 Return false in all other cases.
1923 **************************************************************************/
1925 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1927 const char **canon_parm,
1928 const char **canon_val)
1933 if (!lp_parameter_is_valid(parm_name)) {
1939 num = map_parameter_canonical(parm_name, &inverse);
1941 /* parametric option */
1942 *canon_parm = parm_name;
1945 *canon_parm = parm_table[num].label;
1947 if (!lp_invert_boolean(val, canon_val)) {
1959 /***************************************************************************
1960 Map a parameter's string representation to the index of the canonical
1961 form of the parameter (it might be a synonym).
1962 Returns -1 if the parameter string is not recognised.
1963 ***************************************************************************/
1965 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1967 int parm_num, canon_num;
1968 bool loc_inverse = false;
1970 parm_num = lpcfg_map_parameter(pszParmName);
1971 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
1972 /* invalid, parametric or no canidate for synonyms ... */
1976 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1977 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1978 parm_num = canon_num;
1984 if (inverse != NULL) {
1985 *inverse = loc_inverse;
1990 /***************************************************************************
1991 return true if parameter number parm1 is a synonym of parameter
1992 number parm2 (parm2 being the principal name).
1993 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1995 ***************************************************************************/
1997 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1999 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
2000 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
2001 (parm_table[parm1].flags & FLAG_HIDE) &&
2002 !(parm_table[parm2].flags & FLAG_HIDE))
2004 if (inverse != NULL) {
2005 if ((parm_table[parm1].type == P_BOOLREV) &&
2006 (parm_table[parm2].type == P_BOOL))
2018 /***************************************************************************
2019 Show one parameter's name, type, [values,] and flags.
2020 (helper functions for show_parameter_list)
2021 ***************************************************************************/
2023 static void show_parameter(int parmIndex)
2025 int enumIndex, flagIndex;
2030 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2031 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
2033 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2034 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2036 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2037 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2038 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
2040 printf("%s=%s", parm_table[parmIndex].label,
2041 type[parm_table[parmIndex].type]);
2042 if (parm_table[parmIndex].type == P_ENUM) {
2045 parm_table[parmIndex].enum_list[enumIndex].name;
2049 enumIndex ? "|" : "",
2050 parm_table[parmIndex].enum_list[enumIndex].name);
2055 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
2056 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2059 flag_names[flagIndex]);
2064 /* output synonyms */
2066 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
2067 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
2068 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
2069 parm_table[parmIndex2].label);
2070 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
2072 printf(" (synonyms: ");
2077 printf("%s%s", parm_table[parmIndex2].label,
2078 inverse ? "[i]" : "");
2088 /***************************************************************************
2089 Show all parameter's name, type, [values,] and flags.
2090 ***************************************************************************/
2092 void show_parameter_list(void)
2094 int classIndex, parmIndex;
2095 const char *section_names[] = { "local", "global", NULL};
2097 for (classIndex=0; section_names[classIndex]; classIndex++) {
2098 printf("[%s]\n", section_names[classIndex]);
2099 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2100 if (parm_table[parmIndex].p_class == classIndex) {
2101 show_parameter(parmIndex);
2107 /***************************************************************************
2108 Check if a given string correctly represents a boolean value.
2109 ***************************************************************************/
2111 bool lp_string_is_valid_boolean(const char *parm_value)
2113 return set_boolean(parm_value, NULL);
2116 /***************************************************************************
2117 Get the standard string representation of a boolean value ("yes" or "no")
2118 ***************************************************************************/
2120 static const char *get_boolean(bool bool_value)
2122 static const char *yes_str = "yes";
2123 static const char *no_str = "no";
2125 return (bool_value ? yes_str : no_str);
2128 /***************************************************************************
2129 Provide the string of the negated boolean value associated to the boolean
2130 given as a string. Returns false if the passed string does not correctly
2131 represent a boolean.
2132 ***************************************************************************/
2134 bool lp_invert_boolean(const char *str, const char **inverse_str)
2138 if (!set_boolean(str, &val)) {
2142 *inverse_str = get_boolean(!val);
2146 /***************************************************************************
2147 Provide the canonical string representation of a boolean value given
2148 as a string. Return true on success, false if the string given does
2149 not correctly represent a boolean.
2150 ***************************************************************************/
2152 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2156 if (!set_boolean(str, &val)) {
2160 *canon_str = get_boolean(val);
2164 /***************************************************************************
2165 Find a service by name. Otherwise works like get_service.
2166 ***************************************************************************/
2168 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2175 if (ServiceHash == NULL) {
2179 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2181 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2184 if (NT_STATUS_IS_OK(status) &&
2185 (data.dptr != NULL) &&
2186 (data.dsize == sizeof(iService)))
2188 iService = *(int *)data.dptr;
2191 TALLOC_FREE(canon_name);
2193 if ((iService != -1) && (LP_SNUM_OK(iService))
2194 && (pserviceDest != NULL)) {
2195 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2201 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2202 struct loadparm_service *lp_service(const char *pszServiceName)
2204 int iService = getservicebyname(pszServiceName, NULL);
2205 if (iService == -1 || !LP_SNUM_OK(iService)) {
2208 return ServicePtrs[iService];
2211 struct loadparm_service *lp_servicebynum(int snum)
2213 if ((snum == -1) || !LP_SNUM_OK(snum)) {
2216 return ServicePtrs[snum];
2219 struct loadparm_service *lp_default_loadparm_service()
2225 /***************************************************************************
2226 Copy a service structure to another.
2227 If pcopymapDest is NULL then copy all fields
2228 ***************************************************************************/
2231 * Add a parametric option to a parmlist_entry,
2232 * replacing old value, if already present.
2234 static void set_param_opt(struct parmlist_entry **opt_list,
2235 const char *opt_name,
2236 const char *opt_value,
2239 struct parmlist_entry *new_opt, *opt;
2245 /* Traverse destination */
2247 /* If we already have same option, override it */
2248 if (strwicmp(opt->key, opt_name) == 0) {
2249 if ((opt->priority & FLAG_CMDLINE) &&
2250 !(priority & FLAG_CMDLINE)) {
2251 /* it's been marked as not to be
2255 string_free(&opt->value);
2256 TALLOC_FREE(opt->list);
2257 opt->value = SMB_STRDUP(opt_value);
2258 opt->priority = priority;
2265 new_opt = SMB_XMALLOC_P(struct parmlist_entry);
2266 new_opt->key = SMB_STRDUP(opt_name);
2267 new_opt->value = SMB_STRDUP(opt_value);
2268 new_opt->list = NULL;
2269 new_opt->priority = priority;
2270 DLIST_ADD(*opt_list, new_opt);
2274 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
2275 struct bitmap *pcopymapDest)
2278 bool bcopyall = (pcopymapDest == NULL);
2279 struct parmlist_entry *data;
2281 for (i = 0; parm_table[i].label; i++)
2282 if (parm_table[i].p_class == P_LOCAL &&
2283 (bcopyall || bitmap_query(pcopymapDest,i))) {
2284 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
2285 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
2287 switch (parm_table[i].type) {
2290 *(bool *)dest_ptr = *(bool *)src_ptr;
2297 *(int *)dest_ptr = *(int *)src_ptr;
2301 *(char *)dest_ptr = *(char *)src_ptr;
2305 string_set((char **)dest_ptr,
2311 char *upper_string = strupper_talloc(talloc_tos(),
2313 string_set((char **)dest_ptr,
2315 TALLOC_FREE(upper_string);
2319 TALLOC_FREE(*((char ***)dest_ptr));
2320 *((char ***)dest_ptr) = str_list_copy(NULL,
2321 *(const char ***)src_ptr);
2329 init_copymap(pserviceDest);
2330 if (pserviceSource->copymap)
2331 bitmap_copy(pserviceDest->copymap,
2332 pserviceSource->copymap);
2335 data = pserviceSource->param_opt;
2337 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
2342 /***************************************************************************
2343 Check a service for consistency. Return false if the service is in any way
2344 incomplete or faulty, else true.
2345 ***************************************************************************/
2347 bool service_ok(int iService)
2352 if (ServicePtrs[iService]->szService[0] == '\0') {
2353 DEBUG(0, ("The following message indicates an internal error:\n"));
2354 DEBUG(0, ("No service name in service entry.\n"));
2358 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2359 /* I can't see why you'd want a non-printable printer service... */
2360 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2361 if (!ServicePtrs[iService]->printable) {
2362 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2363 ServicePtrs[iService]->szService));
2364 ServicePtrs[iService]->printable = true;
2366 /* [printers] service must also be non-browsable. */
2367 if (ServicePtrs[iService]->browseable)
2368 ServicePtrs[iService]->browseable = false;
2371 if (ServicePtrs[iService]->path[0] == '\0' &&
2372 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2373 ServicePtrs[iService]->msdfs_proxy[0] == '\0'
2375 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2376 ServicePtrs[iService]->szService));
2377 ServicePtrs[iService]->bAvailable = false;
2380 /* If a service is flagged unavailable, log the fact at level 1. */
2381 if (!ServicePtrs[iService]->bAvailable)
2382 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2383 ServicePtrs[iService]->szService));
2388 static struct smbconf_ctx *lp_smbconf_ctx(void)
2391 static struct smbconf_ctx *conf_ctx = NULL;
2393 if (conf_ctx == NULL) {
2394 err = smbconf_init(NULL, &conf_ctx, "registry:");
2395 if (!SBC_ERROR_IS_OK(err)) {
2396 DEBUG(1, ("error initializing registry configuration: "
2397 "%s\n", sbcErrorString(err)));
2405 static bool process_smbconf_service(struct smbconf_service *service)
2410 if (service == NULL) {
2414 ret = do_section(service->name, NULL);
2418 for (count = 0; count < service->num_params; count++) {
2419 ret = do_parameter(service->param_names[count],
2420 service->param_values[count],
2426 if (iServiceIndex >= 0) {
2427 return service_ok(iServiceIndex);
2433 * load a service from registry and activate it
2435 bool process_registry_service(const char *service_name)
2438 struct smbconf_service *service = NULL;
2439 TALLOC_CTX *mem_ctx = talloc_stackframe();
2440 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2443 if (conf_ctx == NULL) {
2447 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2449 if (!smbconf_share_exists(conf_ctx, service_name)) {
2451 * Registry does not contain data for this service (yet),
2452 * but make sure lp_load doesn't return false.
2458 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2459 if (!SBC_ERROR_IS_OK(err)) {
2463 ret = process_smbconf_service(service);
2469 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2472 TALLOC_FREE(mem_ctx);
2477 * process_registry_globals
2479 static bool process_registry_globals(void)
2483 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2485 ret = do_parameter("registry shares", "yes", NULL);
2490 return process_registry_service(GLOBAL_NAME);
2493 bool process_registry_shares(void)
2497 struct smbconf_service **service = NULL;
2498 uint32_t num_shares = 0;
2499 TALLOC_CTX *mem_ctx = talloc_stackframe();
2500 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2503 if (conf_ctx == NULL) {
2507 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2508 if (!SBC_ERROR_IS_OK(err)) {
2514 for (count = 0; count < num_shares; count++) {
2515 if (strequal(service[count]->name, GLOBAL_NAME)) {
2518 ret = process_smbconf_service(service[count]);
2525 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2528 TALLOC_FREE(mem_ctx);
2533 * reload those shares from registry that are already
2534 * activated in the services array.
2536 static bool reload_registry_shares(void)
2541 for (i = 0; i < iNumServices; i++) {
2546 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2550 ret = process_registry_service(ServicePtrs[i]->szService);
2561 #define MAX_INCLUDE_DEPTH 100
2563 static uint8_t include_depth;
2565 static struct file_lists {
2566 struct file_lists *next;
2570 } *file_lists = NULL;
2572 /*******************************************************************
2573 Keep a linked list of all config files so we know when one has changed
2574 it's date and needs to be reloaded.
2575 ********************************************************************/
2577 static void add_to_file_list(const char *fname, const char *subfname)
2579 struct file_lists *f = file_lists;
2582 if (f->name && !strcmp(f->name, fname))
2588 f = SMB_MALLOC_P(struct file_lists);
2591 f->next = file_lists;
2592 f->name = SMB_STRDUP(fname);
2597 f->subfname = SMB_STRDUP(subfname);
2604 f->modtime = file_modtime(subfname);
2606 time_t t = file_modtime(subfname);
2614 * Free the file lists
2616 static void free_file_list(void)
2618 struct file_lists *f;
2619 struct file_lists *next;
2624 SAFE_FREE( f->name );
2625 SAFE_FREE( f->subfname );
2634 * Utility function for outsiders to check if we're running on registry.
2636 bool lp_config_backend_is_registry(void)
2638 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2642 * Utility function to check if the config backend is FILE.
2644 bool lp_config_backend_is_file(void)
2646 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2649 /*******************************************************************
2650 Check if a config file has changed date.
2651 ********************************************************************/
2653 bool lp_file_list_changed(void)
2655 struct file_lists *f = file_lists;
2657 DEBUG(6, ("lp_file_list_changed()\n"));
2662 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2663 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2665 if (conf_ctx == NULL) {
2668 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2671 DEBUGADD(6, ("registry config changed\n"));
2676 n2 = talloc_sub_basic(talloc_tos(),
2677 get_current_username(),
2678 current_user_info.domain,
2683 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2684 f->name, n2, ctime(&f->modtime)));
2686 mod_time = file_modtime(n2);
2689 ((f->modtime != mod_time) ||
2690 (f->subfname == NULL) ||
2691 (strcmp(n2, f->subfname) != 0)))
2694 ("file %s modified: %s\n", n2,
2696 f->modtime = mod_time;
2697 SAFE_FREE(f->subfname);
2698 f->subfname = SMB_STRDUP(n2);
2711 * Initialize iconv conversion descriptors.
2713 * This is called the first time it is needed, and also called again
2714 * every time the configuration is reloaded, because the charset or
2715 * codepage might have changed.
2717 static void init_iconv(void)
2719 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2721 true, global_iconv_handle);
2724 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2726 if (strcmp(*ptr, pszParmValue) != 0) {
2727 string_set(ptr, pszParmValue);
2733 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2735 bool is_utf8 = false;
2736 size_t len = strlen(pszParmValue);
2738 if (len == 4 || len == 5) {
2739 /* Don't use StrCaseCmp here as we don't want to
2740 initialize iconv. */
2741 if ((toupper_m(pszParmValue[0]) == 'U') &&
2742 (toupper_m(pszParmValue[1]) == 'T') &&
2743 (toupper_m(pszParmValue[2]) == 'F')) {
2745 if (pszParmValue[3] == '8') {
2749 if (pszParmValue[3] == '-' &&
2750 pszParmValue[4] == '8') {
2757 if (strcmp(*ptr, pszParmValue) != 0) {
2759 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2760 "be UTF8, using (default value) %s instead.\n",
2761 DEFAULT_DOS_CHARSET));
2762 pszParmValue = DEFAULT_DOS_CHARSET;
2764 string_set(ptr, pszParmValue);
2770 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2773 TALLOC_CTX *frame = talloc_stackframe();
2774 char *realm = strupper_talloc(frame, pszParmValue);
2775 char *dnsdomain = strlower_talloc(realm, pszParmValue);
2777 ret &= string_set(&Globals.realm_original, pszParmValue);
2778 ret &= string_set(&Globals.realm, realm);
2779 ret &= string_set(&Globals.dnsdomain, dnsdomain);
2785 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2787 TALLOC_FREE(Globals.netbios_aliases);
2788 Globals.netbios_aliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
2789 return set_netbios_aliases(Globals.netbios_aliases);
2792 /***************************************************************************
2793 Handle the include operation.
2794 ***************************************************************************/
2795 static bool bAllowIncludeRegistry = true;
2797 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2801 if (include_depth >= MAX_INCLUDE_DEPTH) {
2802 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2807 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2808 if (!bAllowIncludeRegistry) {
2811 if (bInGlobalSection) {
2814 ret = process_registry_globals();
2818 DEBUG(1, ("\"include = registry\" only effective "
2819 "in %s section\n", GLOBAL_NAME));
2824 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2825 current_user_info.domain,
2828 add_to_file_list(pszParmValue, fname);
2830 string_set(ptr, fname);
2832 if (file_exist(fname)) {
2835 ret = pm_process(fname, do_section, do_parameter, NULL);
2841 DEBUG(2, ("Can't find include file %s\n", fname));
2846 /***************************************************************************
2847 Handle the interpretation of the copy parameter.
2848 ***************************************************************************/
2850 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2854 struct loadparm_service serviceTemp;
2856 string_set(ptr, pszParmValue);
2858 init_service(&serviceTemp);
2862 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2864 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2865 if (iTemp == iServiceIndex) {
2866 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2868 copy_service(ServicePtrs[iServiceIndex],
2870 ServicePtrs[iServiceIndex]->copymap);
2874 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2878 free_service(&serviceTemp);
2882 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2884 Globals.ldap_debug_level = lp_int(pszParmValue);
2885 init_ldap_debugging();
2890 * idmap related parameters
2893 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2895 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
2900 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2902 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2907 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2909 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2914 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2916 char *config_option = NULL;
2917 const char *range = NULL;
2920 SMB_ASSERT(low != NULL);
2921 SMB_ASSERT(high != NULL);
2923 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2927 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2929 if (config_option == NULL) {
2930 DEBUG(0, ("out of memory\n"));
2934 range = lp_parm_const_string(-1, config_option, "range", NULL);
2935 if (range == NULL) {
2936 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2940 if (sscanf(range, "%u - %u", low, high) != 2) {
2941 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2942 range, domain_name));
2949 talloc_free(config_option);
2954 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2956 return lp_idmap_range("*", low, high);
2959 const char *lp_idmap_backend(const char *domain_name)
2961 char *config_option = NULL;
2962 const char *backend = NULL;
2964 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2968 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2970 if (config_option == NULL) {
2971 DEBUG(0, ("out of memory\n"));
2975 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2976 if (backend == NULL) {
2977 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2982 talloc_free(config_option);
2986 const char *lp_idmap_default_backend(void)
2988 return lp_idmap_backend("*");
2991 /***************************************************************************
2992 Handle the DEBUG level list.
2993 ***************************************************************************/
2995 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
2997 string_set(ptr, pszParmValueIn);
2998 return debug_parse_levels(pszParmValueIn);
3001 /***************************************************************************
3002 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3003 ***************************************************************************/
3005 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
3007 const char *suffix_string;
3009 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
3010 Globals.ldap_suffix );
3011 if ( !suffix_string ) {
3012 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3016 return suffix_string;
3019 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
3021 if (Globals.szLdapMachineSuffix[0])
3022 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
3024 return lp_string(ctx, Globals.ldap_suffix);
3027 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
3029 if (Globals.szLdapUserSuffix[0])
3030 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
3032 return lp_string(ctx, Globals.ldap_suffix);
3035 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
3037 if (Globals.szLdapGroupSuffix[0])
3038 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
3040 return lp_string(ctx, Globals.ldap_suffix);
3043 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
3045 if (Globals.szLdapIdmapSuffix[0])
3046 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
3048 return lp_string(ctx, Globals.ldap_suffix);
3051 /****************************************************************************
3052 set the value for a P_ENUM
3053 ***************************************************************************/
3055 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3060 for (i = 0; parm->enum_list[i].name; i++) {
3061 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3062 *ptr = parm->enum_list[i].value;
3066 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
3067 pszParmValue, parm->label));
3070 /***************************************************************************
3071 ***************************************************************************/
3073 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
3075 static int parm_num = -1;
3076 struct loadparm_service *s;
3078 if ( parm_num == -1 )
3079 parm_num = lpcfg_map_parameter( "printing" );
3081 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3086 s = ServicePtrs[snum];
3088 init_printer_values( s );
3094 /***************************************************************************
3095 Initialise a copymap.
3096 ***************************************************************************/
3098 static void init_copymap(struct loadparm_service *pservice)
3102 TALLOC_FREE(pservice->copymap);
3104 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
3105 if (!pservice->copymap)
3107 ("Couldn't allocate copymap!! (size %d)\n",
3108 (int)NUMPARAMETERS));
3110 for (i = 0; i < NUMPARAMETERS; i++)
3111 bitmap_set(pservice->copymap, i);
3115 return the parameter pointer for a parameter
3117 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
3119 if (service == NULL) {
3120 if (parm->p_class == P_LOCAL)
3121 return (void *)(((char *)&sDefault)+parm->offset);
3122 else if (parm->p_class == P_GLOBAL)
3123 return (void *)(((char *)&Globals)+parm->offset);
3126 return (void *)(((char *)service) + parm->offset);
3130 /***************************************************************************
3131 Return the local pointer to a parameter given the service number and parameter
3132 ***************************************************************************/
3134 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
3136 return lp_parm_ptr(ServicePtrs[snum], parm);
3139 /***************************************************************************
3140 Process a parameter for a particular service number. If snum < 0
3141 then assume we are in the globals.
3142 ***************************************************************************/
3144 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3147 void *parm_ptr = NULL; /* where we are going to store the result */
3148 struct parmlist_entry **opt_list;
3150 parmnum = lpcfg_map_parameter(pszParmName);
3153 if (strchr(pszParmName, ':') == NULL) {
3154 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
3160 * We've got a parametric option
3163 opt_list = (snum < 0)
3164 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
3165 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
3170 /* if it's already been set by the command line, then we don't
3172 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
3176 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3177 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3181 /* we might point at a service, the default service or a global */
3183 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
3185 if (parm_table[parmnum].p_class == P_GLOBAL) {
3187 ("Global parameter %s found in service section!\n",
3191 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
3195 if (!ServicePtrs[snum]->copymap)
3196 init_copymap(ServicePtrs[snum]);
3198 /* this handles the aliases - set the copymap for other entries with
3199 the same data pointer */
3200 for (i = 0; parm_table[i].label; i++) {
3201 if ((parm_table[i].offset == parm_table[parmnum].offset)
3202 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
3203 bitmap_clear(ServicePtrs[snum]->copymap, i);
3208 /* if it is a special case then go ahead */
3209 if (parm_table[parmnum].special) {
3210 return parm_table[parmnum].special(NULL, snum, pszParmValue,
3214 /* now switch on the type of variable it is */
3215 switch (parm_table[parmnum].type)
3218 *(bool *)parm_ptr = lp_bool(pszParmValue);
3222 *(bool *)parm_ptr = !lp_bool(pszParmValue);
3226 *(int *)parm_ptr = lp_int(pszParmValue);
3230 *(char *)parm_ptr = *pszParmValue;
3234 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3236 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3243 if (conv_str_size_error(pszParmValue, &val)) {
3244 if (val <= INT_MAX) {
3245 *(int *)parm_ptr = (int)val;
3250 DEBUG(0,("lp_do_parameter(%s): value is not "
3251 "a valid size specifier!\n", pszParmValue));
3257 TALLOC_FREE(*((char ***)parm_ptr));
3258 *(char ***)parm_ptr = str_list_make_v3(
3259 NULL, pszParmValue, NULL);
3263 string_set((char **)parm_ptr, pszParmValue);
3268 char *upper_string = strupper_talloc(talloc_tos(),
3270 string_set((char **)parm_ptr, upper_string);
3271 TALLOC_FREE(upper_string);
3275 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3284 /***************************************************************************
3285 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
3286 FLAG_CMDLINE won't be overridden by loads from smb.conf.
3287 ***************************************************************************/
3289 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
3292 parmnum = lpcfg_map_parameter(pszParmName);
3294 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
3295 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
3298 parm_table[parmnum].flags |= FLAG_CMDLINE;
3300 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
3301 * be grouped in the table, so we don't have to search the
3304 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
3305 && parm_table[i].p_class == parm_table[parmnum].p_class;
3307 parm_table[i].flags |= FLAG_CMDLINE;
3309 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
3310 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
3311 parm_table[i].flags |= FLAG_CMDLINE;
3315 store_lp_set_cmdline(pszParmName, pszParmValue);
3320 /* it might be parametric */
3321 if (strchr(pszParmName, ':') != NULL) {
3322 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
3324 store_lp_set_cmdline(pszParmName, pszParmValue);
3329 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3333 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
3335 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
3338 /***************************************************************************
3339 Process a parameter.
3340 ***************************************************************************/
3342 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
3345 if (!bInGlobalSection && bGlobalOnly)
3348 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3350 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3351 pszParmName, pszParmValue));
3355 set a option from the commandline in 'a=b' format. Use to support --option
3357 bool lp_set_option(const char *option)
3362 s = talloc_strdup(NULL, option);
3375 /* skip white spaces after the = sign */
3378 } while (*p == ' ');
3380 ret = lp_set_cmdline(s, p);
3385 /***************************************************************************
3386 Initialize any local variables in the sDefault table, after parsing a
3388 ***************************************************************************/
3390 static void init_locals(void)
3393 * We run this check once the [globals] is parsed, to force
3394 * the VFS objects and other per-share settings we need for
3395 * the standard way a AD DC is operated. We may change these
3396 * as our code evolves, which is why we force these settings.
3398 * We can't do this at the end of lp_load_ex(), as by that
3399 * point the services have been loaded and they will already
3400 * have "" as their vfs objects.
3402 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3403 const char **vfs_objects = lp_vfs_objects(-1);
3404 if (!vfs_objects || !vfs_objects[0]) {
3405 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
3406 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3407 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
3408 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3410 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3414 lp_do_parameter(-1, "map hidden", "no");
3415 lp_do_parameter(-1, "map system", "no");
3416 lp_do_parameter(-1, "map readonly", "no");
3417 lp_do_parameter(-1, "map archive", "no");
3418 lp_do_parameter(-1, "store dos attributes", "yes");
3422 /***************************************************************************
3423 Process a new section (service). At this stage all sections are services.
3424 Later we'll have special sections that permit server parameters to be set.
3425 Returns true on success, false on failure.
3426 ***************************************************************************/
3428 static bool do_section(const char *pszSectionName, void *userdata)
3431 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3432 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3435 /* if we were in a global section then do the local inits */
3436 if (bInGlobalSection && !isglobal)
3439 /* if we've just struck a global section, note the fact. */
3440 bInGlobalSection = isglobal;
3442 /* check for multiple global sections */
3443 if (bInGlobalSection) {
3444 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3448 if (!bInGlobalSection && bGlobalOnly)
3451 /* if we have a current service, tidy it up before moving on */
3454 if (iServiceIndex >= 0)
3455 bRetval = service_ok(iServiceIndex);
3457 /* if all is still well, move to the next record in the services array */
3459 /* We put this here to avoid an odd message order if messages are */
3460 /* issued by the post-processing of a previous section. */
3461 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3463 iServiceIndex = add_a_service(&sDefault, pszSectionName);
3464 if (iServiceIndex < 0) {
3465 DEBUG(0, ("Failed to add a new service\n"));
3468 /* Clean all parametric options for service */
3469 /* They will be added during parsing again */
3470 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
3477 /***************************************************************************
3478 Determine if a partcular base parameter is currentl set to the default value.
3479 ***************************************************************************/
3481 static bool is_default(int i)
3483 switch (parm_table[i].type) {
3486 return str_list_equal((const char **)parm_table[i].def.lvalue,
3487 *(const char ***)lp_parm_ptr(NULL,
3491 return strequal(parm_table[i].def.svalue,
3492 *(char **)lp_parm_ptr(NULL,
3496 return parm_table[i].def.bvalue ==
3497 *(bool *)lp_parm_ptr(NULL,
3500 return parm_table[i].def.cvalue ==
3501 *(char *)lp_parm_ptr(NULL,
3507 return parm_table[i].def.ivalue ==
3508 *(int *)lp_parm_ptr(NULL,
3516 /***************************************************************************
3517 Display the contents of the global structure.
3518 ***************************************************************************/
3520 static void dump_globals(FILE *f)
3523 struct parmlist_entry *data;
3525 fprintf(f, "[global]\n");
3527 for (i = 0; parm_table[i].label; i++)
3528 if (parm_table[i].p_class == P_GLOBAL &&
3529 !(parm_table[i].flags & FLAG_META) &&
3530 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
3531 if (defaults_saved && is_default(i))
3533 fprintf(f, "\t%s = ", parm_table[i].label);
3534 lpcfg_print_parameter(&parm_table[i], lp_parm_ptr(NULL,
3539 if (Globals.param_opt != NULL) {
3540 data = Globals.param_opt;
3542 fprintf(f, "\t%s = %s\n", data->key, data->value);
3549 /***************************************************************************
3550 Display the contents of a single services record.
3551 ***************************************************************************/
3553 static void dump_a_service(struct loadparm_service *pService, FILE * f)
3556 struct parmlist_entry *data;
3558 if (pService != &sDefault)
3559 fprintf(f, "[%s]\n", pService->szService);
3561 for (i = 0; parm_table[i].label; i++) {
3563 if (parm_table[i].p_class == P_LOCAL &&
3564 !(parm_table[i].flags & FLAG_META) &&
3565 (*parm_table[i].label != '-') &&
3566 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
3568 if (pService == &sDefault) {
3569 if (defaults_saved && is_default(i))
3572 if (lpcfg_equal_parameter(parm_table[i].type,
3573 lp_parm_ptr(pService, &parm_table[i]),
3574 lp_parm_ptr(NULL, &parm_table[i])))
3578 fprintf(f, "\t%s = ", parm_table[i].label);
3579 lpcfg_print_parameter(&parm_table[i],
3580 lp_parm_ptr(pService, &parm_table[i]),
3586 if (pService->param_opt != NULL) {
3587 data = pService->param_opt;
3589 fprintf(f, "\t%s = %s\n", data->key, data->value);
3595 /***************************************************************************
3596 Display the contents of a parameter of a single services record.
3597 ***************************************************************************/
3599 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
3601 bool result = false;
3602 fstring local_parm_name;
3604 const char *parm_opt_value;
3606 struct loadparm_context *lp_ctx;
3608 /* check for parametrical option */
3609 fstrcpy( local_parm_name, parm_name);
3610 parm_opt = strchr( local_parm_name, ':');
3615 if (strlen(parm_opt)) {
3616 parm_opt_value = lp_parm_const_string( snum,
3617 local_parm_name, parm_opt, NULL);
3618 if (parm_opt_value) {
3619 printf( "%s\n", parm_opt_value);
3626 lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3627 if (lp_ctx == NULL) {
3632 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
3634 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
3636 TALLOC_FREE(lp_ctx);
3640 /***************************************************************************
3641 Return info about the requested parameter (given as a string).
3642 Return NULL when the string is not a valid parameter name.
3643 ***************************************************************************/
3645 struct parm_struct *lp_get_parameter(const char *param_name)
3647 int num = lpcfg_map_parameter(param_name);
3653 return &parm_table[num];
3657 /***************************************************************************
3658 Display the contents of a single copy structure.
3659 ***************************************************************************/
3660 static void dump_copy_map(bool *pcopymap)
3666 printf("\n\tNon-Copied parameters:\n");
3668 for (i = 0; parm_table[i].label; i++)
3669 if (parm_table[i].p_class == P_LOCAL &&
3670 parm_table[i].ptr && !pcopymap[i] &&
3671 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3673 printf("\t\t%s\n", parm_table[i].label);
3678 /***************************************************************************
3679 Return TRUE if the passed service number is within range.
3680 ***************************************************************************/
3682 bool lp_snum_ok(int iService)
3684 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3687 /***************************************************************************
3688 Auto-load some home services.
3689 ***************************************************************************/
3691 static void lp_add_auto_services(char *str)
3701 s = SMB_STRDUP(str);
3705 homes = lp_servicenumber(HOMES_NAME);
3707 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3708 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3711 if (lp_servicenumber(p) >= 0)
3714 home = get_user_home_dir(talloc_tos(), p);
3716 if (home && home[0] && homes >= 0)
3717 lp_add_home(p, homes, p, home);
3724 /***************************************************************************
3725 Auto-load one printer.
3726 ***************************************************************************/
3728 void lp_add_one_printer(const char *name, const char *comment,
3729 const char *location, void *pdata)
3731 int printers = lp_servicenumber(PRINTERS_NAME);
3734 if (lp_servicenumber(name) < 0) {
3735 lp_add_printer(name, printers);
3736 if ((i = lp_servicenumber(name)) >= 0) {
3737 string_set(&ServicePtrs[i]->comment, comment);
3738 ServicePtrs[i]->autoloaded = true;
3743 /***************************************************************************
3744 Have we loaded a services file yet?
3745 ***************************************************************************/
3747 bool lp_loaded(void)
3752 /***************************************************************************
3753 Unload unused services.
3754 ***************************************************************************/
3756 void lp_killunused(struct smbd_server_connection *sconn,
3757 bool (*snumused) (struct smbd_server_connection *, int))
3760 for (i = 0; i < iNumServices; i++) {
3764 /* don't kill autoloaded or usershare services */
3765 if ( ServicePtrs[i]->autoloaded ||
3766 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3770 if (!snumused || !snumused(sconn, i)) {
3771 free_service_byindex(i);
3777 * Kill all except autoloaded and usershare services - convenience wrapper
3779 void lp_kill_all_services(void)
3781 lp_killunused(NULL, NULL);
3784 /***************************************************************************
3786 ***************************************************************************/
3788 void lp_killservice(int iServiceIn)
3790 if (VALID(iServiceIn)) {
3791 free_service_byindex(iServiceIn);
3795 /***************************************************************************
3796 Save the curent values of all global and sDefault parameters into the
3797 defaults union. This allows testparm to show only the
3798 changed (ie. non-default) parameters.
3799 ***************************************************************************/
3801 static void lp_save_defaults(void)
3804 for (i = 0; parm_table[i].label; i++) {
3805 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3806 && parm_table[i].p_class == parm_table[i - 1].p_class)
3808 switch (parm_table[i].type) {
3811 parm_table[i].def.lvalue = str_list_copy(
3812 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3816 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
3820 parm_table[i].def.bvalue =
3821 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3824 parm_table[i].def.cvalue =
3825 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3831 parm_table[i].def.ivalue =
3832 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3838 defaults_saved = true;
3841 /***********************************************************
3842 If we should send plaintext/LANMAN passwords in the clinet
3843 ************************************************************/
3845 static void set_allowed_client_auth(void)
3847 if (Globals.client_ntlmv2_auth) {
3848 Globals.client_lanman_auth = false;
3850 if (!Globals.client_lanman_auth) {
3851 Globals.client_plaintext_auth = false;
3855 /***************************************************************************
3857 The following code allows smbd to read a user defined share file.
3858 Yes, this is my intent. Yes, I'm comfortable with that...
3860 THE FOLLOWING IS SECURITY CRITICAL CODE.
3862 It washes your clothes, it cleans your house, it guards you while you sleep...
3863 Do not f%^k with it....
3864 ***************************************************************************/
3866 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3868 /***************************************************************************
3869 Check allowed stat state of a usershare file.
3870 Ensure we print out who is dicking with us so the admin can
3871 get their sorry ass fired.
3872 ***************************************************************************/
3874 static bool check_usershare_stat(const char *fname,
3875 const SMB_STRUCT_STAT *psbuf)
3877 if (!S_ISREG(psbuf->st_ex_mode)) {
3878 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3879 "not a regular file\n",
3880 fname, (unsigned int)psbuf->st_ex_uid ));
3884 /* Ensure this doesn't have the other write bit set. */
3885 if (psbuf->st_ex_mode & S_IWOTH) {
3886 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3887 "public write. Refusing to allow as a usershare file.\n",
3888 fname, (unsigned int)psbuf->st_ex_uid ));
3892 /* Should be 10k or less. */
3893 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3894 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3895 "too large (%u) to be a user share file.\n",
3896 fname, (unsigned int)psbuf->st_ex_uid,
3897 (unsigned int)psbuf->st_ex_size ));
3904 /***************************************************************************
3905 Parse the contents of a usershare file.
3906 ***************************************************************************/
3908 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3909 SMB_STRUCT_STAT *psbuf,
3910 const char *servicename,
3914 char **pp_sharepath,
3916 char **pp_cp_servicename,
3917 struct security_descriptor **ppsd,
3920 const char **prefixallowlist = lp_usershare_prefix_allow_list();
3921 const char **prefixdenylist = lp_usershare_prefix_deny_list();
3924 SMB_STRUCT_STAT sbuf;
3925 char *sharepath = NULL;
3926 char *comment = NULL;
3928 *pp_sharepath = NULL;
3931 *pallow_guest = false;
3934 return USERSHARE_MALFORMED_FILE;
3937 if (strcmp(lines[0], "#VERSION 1") == 0) {
3939 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3942 return USERSHARE_MALFORMED_FILE;
3945 return USERSHARE_BAD_VERSION;
3948 if (strncmp(lines[1], "path=", 5) != 0) {
3949 return USERSHARE_MALFORMED_PATH;
3952 sharepath = talloc_strdup(ctx, &lines[1][5]);
3954 return USERSHARE_POSIX_ERR;
3956 trim_string(sharepath, " ", " ");
3958 if (strncmp(lines[2], "comment=", 8) != 0) {
3959 return USERSHARE_MALFORMED_COMMENT_DEF;
3962 comment = talloc_strdup(ctx, &lines[2][8]);
3964 return USERSHARE_POSIX_ERR;
3966 trim_string(comment, " ", " ");
3967 trim_char(comment, '"', '"');
3969 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3970 return USERSHARE_MALFORMED_ACL_DEF;
3973 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3974 return USERSHARE_ACL_ERR;
3978 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3979 return USERSHARE_MALFORMED_ACL_DEF;
3981 if (lines[4][9] == 'y') {
3982 *pallow_guest = true;
3985 /* Backwards compatible extension to file version #2. */
3987 if (strncmp(lines[5], "sharename=", 10) != 0) {
3988 return USERSHARE_MALFORMED_SHARENAME_DEF;
3990 if (!strequal(&lines[5][10], servicename)) {
3991 return USERSHARE_BAD_SHARENAME;
3993 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3994 if (!*pp_cp_servicename) {
3995 return USERSHARE_POSIX_ERR;
4000 if (*pp_cp_servicename == NULL) {
4001 *pp_cp_servicename = talloc_strdup(ctx, servicename);
4002 if (!*pp_cp_servicename) {
4003 return USERSHARE_POSIX_ERR;
4007 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
4008 /* Path didn't change, no checks needed. */
4009 *pp_sharepath = sharepath;
4010 *pp_comment = comment;
4011 return USERSHARE_OK;
4014 /* The path *must* be absolute. */
4015 if (sharepath[0] != '/') {
4016 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4017 servicename, sharepath));
4018 return USERSHARE_PATH_NOT_ABSOLUTE;
4021 /* If there is a usershare prefix deny list ensure one of these paths
4022 doesn't match the start of the user given path. */
4023 if (prefixdenylist) {
4025 for ( i=0; prefixdenylist[i]; i++ ) {
4026 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4027 servicename, i, prefixdenylist[i], sharepath ));
4028 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4029 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4030 "usershare prefix deny list entries.\n",
4031 servicename, sharepath));
4032 return USERSHARE_PATH_IS_DENIED;
4037 /* If there is a usershare prefix allow list ensure one of these paths
4038 does match the start of the user given path. */
4040 if (prefixallowlist) {
4042 for ( i=0; prefixallowlist[i]; i++ ) {
4043 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4044 servicename, i, prefixallowlist[i], sharepath ));
4045 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4049 if (prefixallowlist[i] == NULL) {
4050 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4051 "usershare prefix allow list entries.\n",
4052 servicename, sharepath));
4053 return USERSHARE_PATH_NOT_ALLOWED;
4057 /* Ensure this is pointing to a directory. */
4058 dp = opendir(sharepath);
4061 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4062 servicename, sharepath));
4063 return USERSHARE_PATH_NOT_DIRECTORY;
4066 /* Ensure the owner of the usershare file has permission to share
4069 if (sys_stat(sharepath, &sbuf, false) == -1) {
4070 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4071 servicename, sharepath, strerror(errno) ));
4073 return USERSHARE_POSIX_ERR;
4078 if (!S_ISDIR(sbuf.st_ex_mode)) {
4079 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4080 servicename, sharepath ));
4081 return USERSHARE_PATH_NOT_DIRECTORY;
4084 /* Check if sharing is restricted to owner-only. */
4085 /* psbuf is the stat of the usershare definition file,
4086 sbuf is the stat of the target directory to be shared. */
4088 if (lp_usershare_owner_only()) {
4089 /* root can share anything. */
4090 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
4091 return USERSHARE_PATH_NOT_ALLOWED;
4095 *pp_sharepath = sharepath;
4096 *pp_comment = comment;
4097 return USERSHARE_OK;
4100 /***************************************************************************
4101 Deal with a usershare file.
4104 -1 - Bad name, invalid contents.
4105 - service name already existed and not a usershare, problem
4106 with permissions to share directory etc.
4107 ***************************************************************************/
4109 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4111 SMB_STRUCT_STAT sbuf;
4112 SMB_STRUCT_STAT lsbuf;
4114 char *sharepath = NULL;
4115 char *comment = NULL;
4116 char *cp_service_name = NULL;
4117 char **lines = NULL;
4121 TALLOC_CTX *ctx = talloc_stackframe();
4122 struct security_descriptor *psd = NULL;
4123 bool guest_ok = false;
4124 char *canon_name = NULL;
4125 bool added_service = false;
4128 /* Ensure share name doesn't contain invalid characters. */
4129 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4130 DEBUG(0,("process_usershare_file: share name %s contains "
4131 "invalid characters (any of %s)\n",
4132 file_name, INVALID_SHARENAME_CHARS ));
4136 canon_name = canonicalize_servicename(ctx, file_name);
4141 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
4146 /* Minimize the race condition by doing an lstat before we
4147 open and fstat. Ensure this isn't a symlink link. */
4149 if (sys_lstat(fname, &lsbuf, false) != 0) {
4150 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4151 fname, strerror(errno) ));
4155 /* This must be a regular file, not a symlink, directory or
4156 other strange filetype. */
4157 if (!check_usershare_stat(fname, &lsbuf)) {
4165 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
4170 if (NT_STATUS_IS_OK(status) &&
4171 (data.dptr != NULL) &&
4172 (data.dsize == sizeof(iService))) {
4173 memcpy(&iService, data.dptr, sizeof(iService));
4177 if (iService != -1 &&
4178 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4179 &lsbuf.st_ex_mtime) == 0) {
4180 /* Nothing changed - Mark valid and return. */
4181 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4183 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4188 /* Try and open the file read only - no symlinks allowed. */
4190 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
4192 fd = open(fname, O_RDONLY, 0);
4196 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4197 fname, strerror(errno) ));
4201 /* Now fstat to be *SURE* it's a regular file. */
4202 if (sys_fstat(fd, &sbuf, false) != 0) {
4204 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4205 fname, strerror(errno) ));
4209 /* Is it the same dev/inode as was lstated ? */
4210 if (!check_same_stat(&lsbuf, &sbuf)) {
4212 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4213 "Symlink spoofing going on ?\n", fname ));
4217 /* This must be a regular file, not a symlink, directory or
4218 other strange filetype. */
4219 if (!check_usershare_stat(fname, &sbuf)) {
4224 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
4227 if (lines == NULL) {
4228 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4229 fname, (unsigned int)sbuf.st_ex_uid ));
4233 if (parse_usershare_file(ctx, &sbuf, file_name,
4234 iService, lines, numlines, &sharepath,
4235 &comment, &cp_service_name,
4236 &psd, &guest_ok) != USERSHARE_OK) {
4240 /* Everything ok - add the service possibly using a template. */
4242 const struct loadparm_service *sp = &sDefault;
4243 if (snum_template != -1) {
4244 sp = ServicePtrs[snum_template];
4247 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
4248 DEBUG(0, ("process_usershare_file: Failed to add "
4249 "new service %s\n", cp_service_name));
4253 added_service = true;
4255 /* Read only is controlled by usershare ACL below. */
4256 ServicePtrs[iService]->read_only = false;
4259 /* Write the ACL of the new/modified share. */
4260 if (!set_share_security(canon_name, psd)) {
4261 DEBUG(0, ("process_usershare_file: Failed to set share "
4262 "security for user share %s\n",
4267 /* If from a template it may be marked invalid. */
4268 ServicePtrs[iService]->valid = true;
4270 /* Set the service as a valid usershare. */
4271 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4273 /* Set guest access. */
4274 if (lp_usershare_allow_guests()) {
4275 ServicePtrs[iService]->guest_ok = guest_ok;
4278 /* And note when it was loaded. */
4279 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
4280 string_set(&ServicePtrs[iService]->path, sharepath);
4281 string_set(&ServicePtrs[iService]->comment, comment);
4287 if (ret == -1 && iService != -1 && added_service) {
4288 lp_remove_service(iService);
4296 /***************************************************************************
4297 Checks if a usershare entry has been modified since last load.
4298 ***************************************************************************/
4300 static bool usershare_exists(int iService, struct timespec *last_mod)
4302 SMB_STRUCT_STAT lsbuf;
4303 const char *usersharepath = Globals.usershare_path;
4306 if (asprintf(&fname, "%s/%s",
4308 ServicePtrs[iService]->szService) < 0) {
4312 if (sys_lstat(fname, &lsbuf, false) != 0) {
4317 if (!S_ISREG(lsbuf.st_ex_mode)) {
4323 *last_mod = lsbuf.st_ex_mtime;
4327 /***************************************************************************
4328 Load a usershare service by name. Returns a valid servicenumber or -1.
4329 ***************************************************************************/
4331 int load_usershare_service(const char *servicename)
4333 SMB_STRUCT_STAT sbuf;
4334 const char *usersharepath = Globals.usershare_path;
4335 int max_user_shares = Globals.usershare_max_shares;
4336 int snum_template = -1;
4338 if (*usersharepath == 0 || max_user_shares == 0) {
4342 if (sys_stat(usersharepath, &sbuf, false) != 0) {
4343 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4344 usersharepath, strerror(errno) ));
4348 if (!S_ISDIR(sbuf.st_ex_mode)) {
4349 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4355 * This directory must be owned by root, and have the 't' bit set.
4356 * It also must not be writable by "other".
4360 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4362 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4364 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4365 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4370 /* Ensure the template share exists if it's set. */
4371 if (Globals.usershare_template_share[0]) {
4372 /* We can't use lp_servicenumber here as we are recommending that
4373 template shares have -valid=false set. */
4374 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4375 if (ServicePtrs[snum_template]->szService &&
4376 strequal(ServicePtrs[snum_template]->szService,
4377 Globals.usershare_template_share)) {
4382 if (snum_template == -1) {
4383 DEBUG(0,("load_usershare_service: usershare template share %s "
4384 "does not exist.\n",
4385 Globals.usershare_template_share ));
4390 return process_usershare_file(usersharepath, servicename, snum_template);
4393 /***************************************************************************
4394 Load all user defined shares from the user share directory.
4395 We only do this if we're enumerating the share list.
4396 This is the function that can delete usershares that have
4398 ***************************************************************************/
4400 int load_usershare_shares(struct smbd_server_connection *sconn,
4401 bool (*snumused) (struct smbd_server_connection *, int))
4404 SMB_STRUCT_STAT sbuf;
4406 int num_usershares = 0;
4407 int max_user_shares = Globals.usershare_max_shares;
4408 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4409 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4410 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4412 int snum_template = -1;
4413 const char *usersharepath = Globals.usershare_path;
4414 int ret = lp_numservices();
4415 TALLOC_CTX *tmp_ctx;
4417 if (max_user_shares == 0 || *usersharepath == '\0') {
4418 return lp_numservices();
4421 if (sys_stat(usersharepath, &sbuf, false) != 0) {
4422 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4423 usersharepath, strerror(errno) ));
4428 * This directory must be owned by root, and have the 't' bit set.
4429 * It also must not be writable by "other".
4433 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4435 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4437 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4438 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4443 /* Ensure the template share exists if it's set. */
4444 if (Globals.usershare_template_share[0]) {
4445 /* We can't use lp_servicenumber here as we are recommending that
4446 template shares have -valid=false set. */
4447 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4448 if (ServicePtrs[snum_template]->szService &&
4449 strequal(ServicePtrs[snum_template]->szService,
4450 Globals.usershare_template_share)) {
4455 if (snum_template == -1) {
4456 DEBUG(0,("load_usershare_shares: usershare template share %s "
4457 "does not exist.\n",
4458 Globals.usershare_template_share ));
4463 /* Mark all existing usershares as pending delete. */
4464 for (iService = iNumServices - 1; iService >= 0; iService--) {
4465 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4466 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4470 dp = opendir(usersharepath);
4472 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4473 usersharepath, strerror(errno) ));
4477 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4479 num_dir_entries++ ) {
4481 const char *n = de->d_name;
4483 /* Ignore . and .. */
4485 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4491 /* Temporary file used when creating a share. */
4492 num_tmp_dir_entries++;
4495 /* Allow 20% tmp entries. */
4496 if (num_tmp_dir_entries > allowed_tmp_entries) {
4497 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4498 "in directory %s\n",
4499 num_tmp_dir_entries, usersharepath));
4503 r = process_usershare_file(usersharepath, n, snum_template);
4505 /* Update the services count. */
4507 if (num_usershares >= max_user_shares) {
4508 DEBUG(0,("load_usershare_shares: max user shares reached "
4509 "on file %s in directory %s\n",
4510 n, usersharepath ));
4513 } else if (r == -1) {
4514 num_bad_dir_entries++;
4517 /* Allow 20% bad entries. */
4518 if (num_bad_dir_entries > allowed_bad_entries) {
4519 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4520 "in directory %s\n",
4521 num_bad_dir_entries, usersharepath));
4525 /* Allow 20% bad entries. */
4526 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4527 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4528 "in directory %s\n",
4529 num_dir_entries, usersharepath));
4536 /* Sweep through and delete any non-refreshed usershares that are
4537 not currently in use. */
4538 tmp_ctx = talloc_stackframe();
4539 for (iService = iNumServices - 1; iService >= 0; iService--) {
4540 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4543 if (snumused && snumused(sconn, iService)) {
4547 servname = lp_servicename(tmp_ctx, iService);
4549 /* Remove from the share ACL db. */
4550 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4552 delete_share_security(servname);
4553 free_service_byindex(iService);
4556 talloc_free(tmp_ctx);
4558 return lp_numservices();
4561 /********************************************************
4562 Destroy global resources allocated in this file
4563 ********************************************************/
4565 void gfree_loadparm(void)
4571 /* Free resources allocated to services */
4573 for ( i = 0; i < iNumServices; i++ ) {
4575 free_service_byindex(i);
4579 SAFE_FREE( ServicePtrs );
4582 /* Now release all resources allocated to global
4583 parameters and the default service */
4585 free_global_parameters();
4589 /***************************************************************************
4590 Allow client apps to specify that they are a client
4591 ***************************************************************************/
4592 static void lp_set_in_client(bool b)
4598 /***************************************************************************
4599 Determine if we're running in a client app
4600 ***************************************************************************/
4601 static bool lp_is_in_client(void)
4606 /***************************************************************************
4607 Load the services array from the services file. Return true on success,
4609 ***************************************************************************/
4611 static bool lp_load_ex(const char *pszFname,
4615 bool initialize_globals,
4616 bool allow_include_registry,
4617 bool load_all_shares)
4624 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4626 bInGlobalSection = true;
4627 bGlobalOnly = global_only;
4628 bAllowIncludeRegistry = allow_include_registry;
4630 init_globals(initialize_globals);
4634 if (save_defaults) {
4639 if (!initialize_globals) {
4640 free_param_opts(&Globals.param_opt);
4641 apply_lp_set_cmdline();
4644 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
4646 /* We get sections first, so have to start 'behind' to make up */
4649 if (lp_config_backend_is_file()) {
4650 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4651 current_user_info.domain,
4654 smb_panic("lp_load_ex: out of memory");
4657 add_to_file_list(pszFname, n2);
4659 bRetval = pm_process(n2, do_section, do_parameter, NULL);
4662 /* finish up the last section */
4663 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4665 if (iServiceIndex >= 0) {
4666 bRetval = service_ok(iServiceIndex);
4670 if (lp_config_backend_is_registry()) {
4671 /* config backend changed to registry in config file */
4673 * We need to use this extra global variable here to
4674 * survive restart: init_globals uses this as a default
4675 * for config_backend. Otherwise, init_globals would
4676 * send us into an endless loop here.
4678 config_backend = CONFIG_BACKEND_REGISTRY;
4680 DEBUG(1, ("lp_load_ex: changing to config backend "
4683 lp_kill_all_services();
4684 return lp_load_ex(pszFname, global_only, save_defaults,
4685 add_ipc, initialize_globals,
4686 allow_include_registry,
4689 } else if (lp_config_backend_is_registry()) {
4690 bRetval = process_registry_globals();
4692 DEBUG(0, ("Illegal config backend given: %d\n",
4693 lp_config_backend()));
4697 if (bRetval && lp_registry_shares()) {
4698 if (load_all_shares) {
4699 bRetval = process_registry_shares();
4701 bRetval = reload_registry_shares();
4706 char *serv = lp_auto_services(talloc_tos());
4707 lp_add_auto_services(serv);
4712 /* When 'restrict anonymous = 2' guest connections to ipc$
4714 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4715 if ( lp_enable_asu_support() ) {
4716 lp_add_ipc("ADMIN$", false);
4720 set_allowed_client_auth();
4722 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4723 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4724 lp_password_server()));
4729 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4730 /* if we_are_a_wins_server is true and we are in the client */
4731 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4732 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4737 fault_configure(smb_panic_s3);
4740 * We run this check once the whole smb.conf is parsed, to
4741 * force some settings for the standard way a AD DC is
4742 * operated. We may changed these as our code evolves, which
4743 * is why we force these settings.
4745 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4746 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4748 lp_do_parameter(-1, "rpc_server:default", "external");
4749 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4750 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4751 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4752 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4753 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4754 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4755 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4756 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4759 bAllowIncludeRegistry = true;
4764 bool lp_load(const char *pszFname,
4768 bool initialize_globals)
4770 return lp_load_ex(pszFname,
4775 true, /* allow_include_registry */
4776 false); /* load_all_shares*/
4779 bool lp_load_initial_only(const char *pszFname)
4781 return lp_load_ex(pszFname,
4782 true, /* global only */
4783 false, /* save_defaults */
4784 false, /* add_ipc */
4785 true, /* initialize_globals */
4786 false, /* allow_include_registry */
4787 false); /* load_all_shares*/
4791 * most common lp_load wrapper, loading only the globals
4793 bool lp_load_global(const char *file_name)
4795 return lp_load_ex(file_name,
4796 true, /* global_only */
4797 false, /* save_defaults */
4798 false, /* add_ipc */
4799 true, /* initialize_globals */
4800 true, /* allow_include_registry */
4801 false); /* load_all_shares*/
4805 * lp_load wrapper, especially for clients
4807 bool lp_load_client(const char *file_name)
4809 lp_set_in_client(true);
4811 return lp_load_global(file_name);
4815 * lp_load wrapper, loading only globals, but intended
4816 * for subsequent calls, not reinitializing the globals
4819 bool lp_load_global_no_reinit(const char *file_name)
4821 return lp_load_ex(file_name,
4822 true, /* global_only */
4823 false, /* save_defaults */
4824 false, /* add_ipc */
4825 false, /* initialize_globals */
4826 true, /* allow_include_registry */
4827 false); /* load_all_shares*/
4831 * lp_load wrapper, especially for clients, no reinitialization
4833 bool lp_load_client_no_reinit(const char *file_name)
4835 lp_set_in_client(true);
4837 return lp_load_global_no_reinit(file_name);
4840 bool lp_load_with_registry_shares(const char *pszFname,
4844 bool initialize_globals)
4846 return lp_load_ex(pszFname,
4851 true, /* allow_include_registry */
4852 true); /* load_all_shares*/
4855 /***************************************************************************
4856 Return the max number of services.
4857 ***************************************************************************/
4859 int lp_numservices(void)
4861 return (iNumServices);
4864 /***************************************************************************
4865 Display the contents of the services array in human-readable form.
4866 ***************************************************************************/
4868 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4873 defaults_saved = false;
4877 dump_a_service(&sDefault, f);
4879 for (iService = 0; iService < maxtoprint; iService++) {
4881 lp_dump_one(f, show_defaults, iService);
4885 /***************************************************************************
4886 Display the contents of one service in human-readable form.
4887 ***************************************************************************/
4889 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4892 if (ServicePtrs[snum]->szService[0] == '\0')
4894 dump_a_service(ServicePtrs[snum], f);
4898 /***************************************************************************
4899 Return the number of the service with the given name, or -1 if it doesn't
4900 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4901 getservicebyname()! This works ONLY if all services have been loaded, and
4902 does not copy the found service.
4903 ***************************************************************************/
4905 int lp_servicenumber(const char *pszServiceName)
4908 fstring serviceName;
4910 if (!pszServiceName) {
4911 return GLOBAL_SECTION_SNUM;
4914 for (iService = iNumServices - 1; iService >= 0; iService--) {
4915 if (VALID(iService) && ServicePtrs[iService]->szService) {
4917 * The substitution here is used to support %U is
4920 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4921 standard_sub_basic(get_current_username(),
4922 current_user_info.domain,
4923 serviceName,sizeof(serviceName));
4924 if (strequal(serviceName, pszServiceName)) {
4930 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4931 struct timespec last_mod;
4933 if (!usershare_exists(iService, &last_mod)) {
4934 /* Remove the share security tdb entry for it. */
4935 delete_share_security(lp_servicename(talloc_tos(), iService));
4936 /* Remove it from the array. */
4937 free_service_byindex(iService);
4938 /* Doesn't exist anymore. */
4939 return GLOBAL_SECTION_SNUM;
4942 /* Has it been modified ? If so delete and reload. */
4943 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4945 /* Remove it from the array. */
4946 free_service_byindex(iService);
4947 /* and now reload it. */
4948 iService = load_usershare_service(pszServiceName);
4953 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4954 return GLOBAL_SECTION_SNUM;
4960 /*******************************************************************
4961 A useful volume label function.
4962 ********************************************************************/
4964 const char *volume_label(TALLOC_CTX *ctx, int snum)
4967 const char *label = lp_volume(ctx, snum);
4969 label = lp_servicename(ctx, snum);
4972 /* This returns a 33 byte guarenteed null terminated string. */
4973 ret = talloc_strndup(ctx, label, 32);
4980 /*******************************************************************
4981 Get the default server type we will announce as via nmbd.
4982 ********************************************************************/
4984 int lp_default_server_announce(void)
4986 int default_server_announce = 0;
4987 default_server_announce |= SV_TYPE_WORKSTATION;
4988 default_server_announce |= SV_TYPE_SERVER;
4989 default_server_announce |= SV_TYPE_SERVER_UNIX;
4991 /* note that the flag should be set only if we have a
4992 printer service but nmbd doesn't actually load the
4993 services so we can't tell --jerry */
4995 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4997 default_server_announce |= SV_TYPE_SERVER_NT;
4998 default_server_announce |= SV_TYPE_NT;
5000 switch (lp_server_role()) {
5001 case ROLE_DOMAIN_MEMBER:
5002 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5004 case ROLE_DOMAIN_PDC:
5005 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5007 case ROLE_DOMAIN_BDC:
5008 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5010 case ROLE_STANDALONE:
5014 if (lp_time_server())
5015 default_server_announce |= SV_TYPE_TIME_SOURCE;
5017 if (lp_host_msdfs())
5018 default_server_announce |= SV_TYPE_DFS_SERVER;
5020 return default_server_announce;
5023 /***********************************************************
5024 If we are PDC then prefer us as DMB
5025 ************************************************************/
5027 bool lp_domain_master(void)
5029 if (Globals._domain_master == Auto)
5030 return (lp_server_role() == ROLE_DOMAIN_PDC);
5032 return (bool)Globals._domain_master;
5035 /***********************************************************
5036 If we are PDC then prefer us as DMB
5037 ************************************************************/
5039 static bool lp_domain_master_true_or_auto(void)
5041 if (Globals._domain_master) /* auto or yes */
5047 /***********************************************************
5048 If we are DMB then prefer us as LMB
5049 ************************************************************/
5051 bool lp_preferred_master(void)
5053 if (Globals.iPreferredMaster == Auto)
5054 return (lp_local_master() && lp_domain_master());
5056 return (bool)Globals.iPreferredMaster;
5059 /*******************************************************************
5061 ********************************************************************/
5063 void lp_remove_service(int snum)
5065 ServicePtrs[snum]->valid = false;
5068 /*******************************************************************
5070 ********************************************************************/
5072 void lp_copy_service(int snum, const char *new_name)
5074 do_section(new_name, NULL);
5076 snum = lp_servicenumber(new_name);
5078 char *name = lp_servicename(talloc_tos(), snum);
5079 lp_do_parameter(snum, "copy", name);
5084 const char *lp_printername(TALLOC_CTX *ctx, int snum)
5086 const char *ret = lp__printername(ctx, snum);
5087 if (ret == NULL || *ret == '\0') {
5088 ret = lp_const_servicename(snum);
5095 /***********************************************************
5096 Allow daemons such as winbindd to fix their logfile name.
5097 ************************************************************/
5099 void lp_set_logfile(const char *name)
5101 string_set(&Globals.logfile, name);
5102 debug_set_logfile(name);
5105 /*******************************************************************
5106 Return the max print jobs per queue.
5107 ********************************************************************/
5109 int lp_maxprintjobs(int snum)
5111 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5112 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5113 maxjobs = PRINT_MAX_JOBID - 1;
5118 const char *lp_printcapname(void)
5120 if ((Globals.szPrintcapname != NULL) &&
5121 (Globals.szPrintcapname[0] != '\0'))
5122 return Globals.szPrintcapname;
5124 if (sDefault.printing == PRINT_CUPS) {
5128 if (sDefault.printing == PRINT_BSD)
5129 return "/etc/printcap";
5131 return PRINTCAP_NAME;
5134 static uint32 spoolss_state;
5136 bool lp_disable_spoolss( void )
5138 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5139 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5141 return spoolss_state == SVCCTL_STOPPED ? true : false;
5144 void lp_set_spoolss_state( uint32 state )
5146 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5148 spoolss_state = state;
5151 uint32 lp_get_spoolss_state( void )
5153 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5156 /*******************************************************************
5157 Ensure we don't use sendfile if server smb signing is active.
5158 ********************************************************************/
5160 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
5162 bool sign_active = false;
5164 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5165 if (get_Protocol() < PROTOCOL_NT1) {
5168 if (signing_state) {
5169 sign_active = smb_signing_is_active(signing_state);
5171 return (lp__use_sendfile(snum) &&
5172 (get_remote_arch() != RA_WIN95) &&
5176 /*******************************************************************
5177 Turn off sendfile if we find the underlying OS doesn't support it.
5178 ********************************************************************/
5180 void set_use_sendfile(int snum, bool val)
5182 if (LP_SNUM_OK(snum))
5183 ServicePtrs[snum]->_use_sendfile = val;
5185 sDefault._use_sendfile = val;
5188 /*******************************************************************
5189 Turn off storing DOS attributes if this share doesn't support it.
5190 ********************************************************************/
5192 void set_store_dos_attributes(int snum, bool val)
5194 if (!LP_SNUM_OK(snum))
5196 ServicePtrs[(snum)]->store_dos_attributes = val;
5199 void lp_set_mangling_method(const char *new_method)
5201 string_set(&Globals.mangling_method, new_method);
5204 /*******************************************************************
5205 Global state for POSIX pathname processing.
5206 ********************************************************************/
5208 static bool posix_pathnames;
5210 bool lp_posix_pathnames(void)
5212 return posix_pathnames;
5215 /*******************************************************************
5216 Change everything needed to ensure POSIX pathname processing (currently
5218 ********************************************************************/
5220 void lp_set_posix_pathnames(void)
5222 posix_pathnames = true;
5225 /*******************************************************************
5226 Global state for POSIX lock processing - CIFS unix extensions.
5227 ********************************************************************/
5229 bool posix_default_lock_was_set;
5230 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5232 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5234 if (posix_default_lock_was_set) {
5235 return posix_cifsx_locktype;
5237 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5241 /*******************************************************************
5242 ********************************************************************/
5244 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5246 posix_default_lock_was_set = true;
5247 posix_cifsx_locktype = val;
5250 int lp_min_receive_file_size(void)
5252 if (Globals.iminreceivefile < 0) {
5255 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
5258 /*******************************************************************
5259 Safe wide links checks.
5260 This helper function always verify the validity of wide links,
5261 even after a configuration file reload.
5262 ********************************************************************/
5264 static bool lp_widelinks_internal(int snum)
5266 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
5267 sDefault.bWidelinks);
5270 void widelinks_warning(int snum)
5272 if (lp_allow_insecure_wide_links()) {
5276 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
5277 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
5278 "These parameters are incompatible. "
5279 "Wide links will be disabled for this share.\n",
5280 lp_servicename(talloc_tos(), snum) ));
5284 bool lp_widelinks(int snum)
5286 /* wide links is always incompatible with unix extensions */
5287 if (lp_unix_extensions()) {
5289 * Unless we have "allow insecure widelinks"
5292 if (!lp_allow_insecure_wide_links()) {
5297 return lp_widelinks_internal(snum);
5300 bool lp_writeraw(void)
5302 if (lp_async_smb_echo_handler()) {
5305 return lp__writeraw();
5308 bool lp_readraw(void)
5310 if (lp_async_smb_echo_handler()) {
5313 return lp__readraw();
5316 int lp_server_role(void)
5318 return lp_find_server_role(lp__server_role(),
5320 lp__domain_logons(),
5321 lp_domain_master_true_or_auto());
5324 int lp_security(void)
5326 return lp_find_security(lp__server_role(),