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"
61 #include "lib/smbconf/smbconf.h"
62 #include "lib/smbconf/smbconf_init.h"
65 #include "../librpc/gen_ndr/svcctl.h"
67 #include "../libcli/smb/smb_signing.h"
68 #include "dbwrap/dbwrap.h"
69 #include "dbwrap/dbwrap_rbt.h"
70 #include "../lib/util/bitmap.h"
72 #ifdef HAVE_SYS_SYSCTL_H
73 #include <sys/sysctl.h>
76 #ifdef HAVE_HTTPCONNECTENCRYPT
77 #include <cups/http.h>
80 #ifdef CLUSTER_SUPPORT
81 #include "ctdb_private.h"
86 extern userdom_struct current_user_info;
88 /* the special value for the include parameter
89 * to be interpreted not as a file name but to
90 * trigger loading of the global smb.conf options
92 #ifndef INCLUDE_REGISTRY_NAME
93 #define INCLUDE_REGISTRY_NAME "registry"
96 static bool in_client = false; /* Not in the client by default */
97 static struct smbconf_csn conf_last_csn;
99 static int config_backend = CONFIG_BACKEND_FILE;
101 /* some helpful bits */
102 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
103 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
105 #define USERSHARE_VALID 1
106 #define USERSHARE_PENDING_DELETE 2
108 static bool defaults_saved = false;
110 #define LOADPARM_EXTRA_GLOBALS \
111 struct parmlist_entry *param_opt; \
114 int iminreceivefile; \
115 char *szPrintcapname; \
117 int iPreferredMaster; \
118 char *szLdapMachineSuffix; \
119 char *szLdapUserSuffix; \
120 char *szLdapIdmapSuffix; \
121 char *szLdapGroupSuffix; \
124 char *szUsershareTemplateShare; \
127 char *szIdmapBackend; \
128 int winbindMaxDomainConnections; \
129 int ismb2_max_credits; \
131 char *tls_certfile; \
135 int bPreferredMaster;
137 #include "param/param_global.h"
139 static struct loadparm_global Globals;
141 /* This is a default service used to prime a services structure */
142 static struct loadparm_service sDefault =
147 .usershare_last_mod = {0, 0},
151 .szInvalidUsers = NULL,
152 .szValidUsers = NULL,
153 .szAdminUsers = NULL,
158 .szRootPreExec = NULL,
159 .szRootPostExec = NULL,
160 .szCupsOptions = NULL,
161 .szPrintcommand = NULL,
162 .szLpqcommand = NULL,
163 .szLprmcommand = NULL,
164 .szLppausecommand = NULL,
165 .szLpresumecommand = NULL,
166 .szQueuepausecommand = NULL,
167 .szQueueresumecommand = NULL,
168 .szPrintername = NULL,
169 .szPrintjobUsername = NULL,
170 .szDontdescend = NULL,
171 .szHostsallow = NULL,
173 .szMagicScript = NULL,
174 .szMagicOutput = NULL,
177 .szVetoOplockFiles = NULL,
185 .szVfsObjects = NULL,
186 .szMSDfsProxy = NULL,
187 .szAioWriteBehind = NULL,
190 .iMaxPrintJobs = 1000,
191 .iMaxReportedPrintJobs = 0,
192 .iWriteCacheSize = 0,
193 .iCreate_mask = 0744,
194 .iCreate_force_mode = 0,
196 .iDir_force_mode = 0,
197 .iMaxConnections = 0,
198 .iDefaultCase = CASE_LOWER,
199 .iPrinting = DEFAULT_PRINTING,
200 .iOplockContentionLimit = 2,
203 .iDfreeCacheTime = 0,
204 .bPreexecClose = false,
205 .bRootpreexecClose = false,
206 .iCaseSensitive = Auto,
207 .bCasePreserve = true,
208 .bShortCasePreserve = true,
209 .bHideDotFiles = true,
210 .bHideSpecialFiles = false,
211 .bHideUnReadable = false,
212 .bHideUnWriteableFiles = false,
214 .bAccessBasedShareEnum = false,
217 .bGuest_only = false,
218 .bAdministrative_share = false,
221 .bPrintNotifyBackchannel = false,
222 .bMap_system = false,
223 .bMap_hidden = false,
224 .bMap_archive = true,
225 .bStoreDosAttributes = false,
226 .bDmapiSupport = false,
228 .iStrictLocking = Auto,
229 .bPosixLocking = true,
231 .bKernelOplocks = false,
232 .bLevel2OpLocks = true,
234 .bMangledNames = true,
237 .bSyncAlways = false,
238 .bStrictAllocate = false,
239 .bStrictSync = false,
242 .bDeleteReadonly = false,
243 .bFakeOplocks = false,
244 .bDeleteVetoFiles = false,
245 .bDosFilemode = false,
246 .bDosFiletimes = true,
247 .bDosFiletimeResolution = false,
248 .bFakeDirCreateTimes = false,
249 .bBlockingLocks = true,
250 .bInheritPerms = false,
251 .bInheritACLS = false,
252 .bInheritOwner = false,
254 .bUseClientDriver = false,
255 .bDefaultDevmode = true,
256 .bForcePrintername = false,
257 .bNTAclSupport = true,
258 .bForceUnknownAclUser = false,
259 .bUseSendfile = false,
260 .bProfileAcls = false,
261 .bMap_acl_inherit = false,
264 .bAclCheckPermissions = true,
265 .bAclMapFullControl = true,
266 .bAclGroupControl = false,
267 .bAclAllowExecuteAlways = false,
268 .bChangeNotify = true,
269 .bKernelChangeNotify = true,
270 .iallocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
273 .iMap_readonly = MAP_READONLY_YES,
274 #ifdef BROKEN_DIRECTORY_HANDLING
275 .iDirectoryNameCacheSize = 0,
277 .iDirectoryNameCacheSize = 100,
279 .ismb_encrypt = SMB_SIGNING_DEFAULT,
280 .bKernelShareModes = true,
281 .bDurableHandles = true,
286 /* local variables */
287 static struct loadparm_service **ServicePtrs = NULL;
288 static int iNumServices = 0;
289 static int iServiceIndex = 0;
290 static struct db_context *ServiceHash;
291 static bool bInGlobalSection = true;
292 static bool bGlobalOnly = false;
294 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
296 /* prototypes for the special type handlers */
297 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
298 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
299 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
300 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
301 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
302 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
303 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
304 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
305 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
306 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
307 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
308 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
310 /* these are parameter handlers which are not needed in the
314 #define handle_logfile NULL
316 static void set_allowed_client_auth(void);
318 static void add_to_file_list(const char *fname, const char *subfname);
319 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
320 static void free_param_opts(struct parmlist_entry **popts);
322 #include "lib/param/param_table.c"
324 /* this is used to prevent lots of mallocs of size 1 */
325 static const char null_string[] = "";
328 Set a string value, allocing the space for the string
331 static bool string_init(char **dest,const char *src)
341 *dest = discard_const_p(char, null_string);
343 (*dest) = SMB_STRDUP(src);
344 if ((*dest) == NULL) {
345 DEBUG(0,("Out of memory in string_init\n"));
356 static void string_free(char **s)
360 if (*s == null_string)
366 Set a string value, deallocating any existing space, and allocing the space
370 static bool string_set(char **dest,const char *src)
373 return(string_init(dest,src));
376 /***************************************************************************
377 Initialise the sDefault parameter structure for the printer values.
378 ***************************************************************************/
380 static void init_printer_values(struct loadparm_service *pService)
382 /* choose defaults depending on the type of printing */
383 switch (pService->iPrinting) {
388 string_set(&pService->szLpqcommand, "lpq -P'%p'");
389 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
390 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
395 string_set(&pService->szLpqcommand, "lpq -P'%p'");
396 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
397 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
398 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
399 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
400 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
401 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
406 /* set the lpq command to contain the destination printer
407 name only. This is used by cups_queue_get() */
408 string_set(&pService->szLpqcommand, "%p");
409 string_set(&pService->szLprmcommand, "");
410 string_set(&pService->szPrintcommand, "");
411 string_set(&pService->szLppausecommand, "");
412 string_set(&pService->szLpresumecommand, "");
413 string_set(&pService->szQueuepausecommand, "");
414 string_set(&pService->szQueueresumecommand, "");
419 string_set(&pService->szLpqcommand, "lpstat -o%p");
420 string_set(&pService->szLprmcommand, "cancel %p-%j");
421 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
422 string_set(&pService->szQueuepausecommand, "disable %p");
423 string_set(&pService->szQueueresumecommand, "enable %p");
425 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
426 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
431 string_set(&pService->szLpqcommand, "lpq -P%p");
432 string_set(&pService->szLprmcommand, "lprm -P%p %j");
433 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
436 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
441 TALLOC_CTX *tmp_ctx = talloc_stackframe();
444 tdbfile = talloc_asprintf(
445 tmp_ctx, "tdbfile=%s",
446 lp_parm_const_string(-1, "vlp", "tdbfile",
448 if (tdbfile == NULL) {
449 tdbfile="tdbfile=/tmp/vlp.tdb";
452 tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
454 string_set(&pService->szPrintcommand,
455 tmp ? tmp : "vlp print %p %s");
457 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
459 string_set(&pService->szLpqcommand,
460 tmp ? tmp : "vlp lpq %p");
462 tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
464 string_set(&pService->szLprmcommand,
465 tmp ? tmp : "vlp lprm %p %j");
467 tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
469 string_set(&pService->szLppausecommand,
470 tmp ? tmp : "vlp lppause %p %j");
472 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
474 string_set(&pService->szLpresumecommand,
475 tmp ? tmp : "vlp lpresume %p %j");
477 tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
479 string_set(&pService->szQueuepausecommand,
480 tmp ? tmp : "vlp queuepause %p");
482 tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
484 string_set(&pService->szQueueresumecommand,
485 tmp ? tmp : "vlp queueresume %p");
486 TALLOC_FREE(tmp_ctx);
490 #endif /* DEVELOPER */
495 * Function to return the default value for the maximum number of open
496 * file descriptors permitted. This function tries to consult the
497 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
498 * the smaller of those.
500 static int max_open_files(void)
502 int sysctl_max = MAX_OPEN_FILES;
503 int rlimit_max = MAX_OPEN_FILES;
505 #ifdef HAVE_SYSCTLBYNAME
507 size_t size = sizeof(sysctl_max);
508 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
513 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
519 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
520 rlimit_max = rl.rlim_cur;
522 #if defined(RLIM_INFINITY)
523 if(rl.rlim_cur == RLIM_INFINITY)
524 rlimit_max = MAX_OPEN_FILES;
529 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
530 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
531 "minimum Windows limit (%d)\n",
533 MIN_OPEN_FILES_WINDOWS));
534 sysctl_max = MIN_OPEN_FILES_WINDOWS;
537 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
538 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
539 "minimum Windows limit (%d)\n",
541 MIN_OPEN_FILES_WINDOWS));
542 rlimit_max = MIN_OPEN_FILES_WINDOWS;
545 return MIN(sysctl_max, rlimit_max);
549 * Common part of freeing allocated data for one parameter.
551 static void free_one_parameter_common(void *parm_ptr,
552 struct parm_struct parm)
554 if ((parm.type == P_STRING) ||
555 (parm.type == P_USTRING))
557 string_free((char**)parm_ptr);
558 } else if (parm.type == P_LIST) {
559 TALLOC_FREE(*((char***)parm_ptr));
564 * Free the allocated data for one parameter for a share
565 * given as a service struct.
567 static void free_one_parameter(struct loadparm_service *service,
568 struct parm_struct parm)
572 if (parm.p_class != P_LOCAL) {
576 parm_ptr = lp_parm_ptr(service, &parm);
578 free_one_parameter_common(parm_ptr, parm);
582 * Free the allocated parameter data of a share given
583 * as a service struct.
585 static void free_parameters(struct loadparm_service *service)
589 for (i=0; parm_table[i].label; i++) {
590 free_one_parameter(service, parm_table[i]);
595 * Free the allocated data for one parameter for a given share
596 * specified by an snum.
598 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
603 parm_ptr = lp_parm_ptr(NULL, &parm);
604 } else if (parm.p_class != P_LOCAL) {
607 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
610 free_one_parameter_common(parm_ptr, parm);
614 * Free the allocated parameter data for a share specified
617 static void free_parameters_by_snum(int snum)
621 for (i=0; parm_table[i].label; i++) {
622 free_one_parameter_by_snum(snum, parm_table[i]);
627 * Free the allocated global parameters.
629 static void free_global_parameters(void)
631 free_param_opts(&Globals.param_opt);
632 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
633 TALLOC_FREE(Globals.ctx);
636 static int map_parameter(const char *pszParmName);
638 struct lp_stored_option {
639 struct lp_stored_option *prev, *next;
644 static struct lp_stored_option *stored_options;
647 save options set by lp_set_cmdline() into a list. This list is
648 re-applied when we do a globals reset, so that cmdline set options
649 are sticky across reloads of smb.conf
651 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
653 struct lp_stored_option *entry, *entry_next;
654 for (entry = stored_options; entry != NULL; entry = entry_next) {
655 entry_next = entry->next;
656 if (strcmp(pszParmName, entry->label) == 0) {
657 DLIST_REMOVE(stored_options, entry);
663 entry = talloc(NULL, struct lp_stored_option);
668 entry->label = talloc_strdup(entry, pszParmName);
674 entry->value = talloc_strdup(entry, pszParmValue);
680 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
685 static bool apply_lp_set_cmdline(void)
687 struct lp_stored_option *entry = NULL;
688 for (entry = stored_options; entry != NULL; entry = entry->next) {
689 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
690 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
691 entry->label, entry->value));
698 /***************************************************************************
699 Initialise the global parameter structure.
700 ***************************************************************************/
702 static void init_globals(bool reinit_globals)
704 static bool done_init = false;
708 /* If requested to initialize only once and we've already done it... */
709 if (!reinit_globals && done_init) {
710 /* ... then we have nothing more to do */
715 /* The logfile can be set before this is invoked. Free it if so. */
716 if (Globals.logfile != NULL) {
717 string_free(&Globals.logfile);
718 Globals.logfile = NULL;
722 free_global_parameters();
725 /* This memset and the free_global_parameters() above will
726 * wipe out smb.conf options set with lp_set_cmdline(). The
727 * apply_lp_set_cmdline() call puts these values back in the
728 * table once the defaults are set */
729 ZERO_STRUCT(Globals);
731 Globals.ctx = talloc_new(NULL);
733 for (i = 0; parm_table[i].label; i++) {
734 if ((parm_table[i].type == P_STRING ||
735 parm_table[i].type == P_USTRING))
737 string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
742 string_set(&sDefault.fstype, FSTYPE_STRING);
743 string_set(&sDefault.szPrintjobUsername, "%U");
745 init_printer_values(&sDefault);
748 DEBUG(3, ("Initialising global parameters\n"));
750 /* Must manually force to upper case here, as this does not go via the handler */
751 string_set(&Globals.szNetbiosName, myhostname_upper());
753 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
754 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
756 /* use the new 'hash2' method by default, with a prefix of 1 */
757 string_set(&Globals.szManglingMethod, "hash2");
758 Globals.mangle_prefix = 1;
760 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
762 /* using UTF8 by default allows us to support all chars */
763 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
765 /* Use codepage 850 as a default for the dos character set */
766 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
769 * Allow the default PASSWD_CHAT to be overridden in local.h.
771 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
773 string_set(&Globals.szWorkgroup, DEFAULT_WORKGROUP);
775 string_set(&Globals.szPasswdProgram, "");
776 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
777 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
778 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
779 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
780 string_set(&Globals.nbt_client_socket_address, "0.0.0.0");
782 * By default support explicit binding to broadcast
785 Globals.bNmbdBindExplicitBroadcast = true;
787 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
788 smb_panic("init_globals: ENOMEM");
790 string_set(&Globals.szServerString, s);
793 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
796 string_set(&Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
798 string_set(&Globals.szLogonDrive, "");
799 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
800 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
801 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
803 Globals.szNameResolveOrder = (const char **)str_list_make_v3(NULL, "lmhosts wins host bcast", NULL);
804 string_set(&Globals.szPasswordServer, "*");
806 Globals.AlgorithmicRidBase = BASE_RID;
808 Globals.bLoadPrinters = true;
809 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
811 Globals.ConfigBackend = config_backend;
812 Globals.server_role = ROLE_AUTO;
814 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
815 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
816 Globals.max_xmit = 0x4104;
817 Globals.max_mux = 50; /* This is *needed* for profile support. */
818 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
819 Globals.bDisableSpoolss = false;
820 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
821 Globals.unamelevel = 0;
822 Globals.deadtime = 0;
823 Globals.getwd_cache = true;
824 Globals.bLargeReadwrite = true;
825 Globals.max_log_size = 5000;
826 Globals.max_open_files = max_open_files();
827 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
828 Globals.srv_maxprotocol = PROTOCOL_SMB3_00;
829 Globals.srv_minprotocol = PROTOCOL_LANMAN1;
830 Globals.cli_maxprotocol = PROTOCOL_NT1;
831 Globals.cli_minprotocol = PROTOCOL_CORE;
832 Globals.security = SEC_USER;
833 Globals.bEncryptPasswords = true;
834 Globals.clientSchannel = Auto;
835 Globals.serverSchannel = Auto;
836 Globals.bReadRaw = true;
837 Globals.bWriteRaw = true;
838 Globals.bNullPasswords = false;
839 Globals.bObeyPamRestrictions = false;
841 Globals.bSyslogOnly = false;
842 Globals.bTimestampLogs = true;
843 string_set(&Globals.loglevel, "0");
844 Globals.bDebugPrefixTimestamp = false;
845 Globals.bDebugHiresTimestamp = true;
846 Globals.bDebugPid = false;
847 Globals.bDebugUid = false;
848 Globals.bDebugClass = false;
849 Globals.bEnableCoreFiles = true;
850 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
851 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
852 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
853 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
854 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
855 Globals.lm_interval = 60;
856 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
857 Globals.bNISHomeMap = false;
858 #ifdef WITH_NISPLUS_HOME
859 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
861 string_set(&Globals.szNISHomeMapName, "auto.home");
864 Globals.bTimeServer = false;
865 Globals.bBindInterfacesOnly = false;
866 Globals.bUnixPasswdSync = false;
867 Globals.bPamPasswordChange = false;
868 Globals.bPasswdChatDebug = false;
869 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
870 Globals.bNTPipeSupport = true; /* Do NT pipes by default. */
871 Globals.bNTStatusSupport = true; /* Use NT status by default. */
872 Globals.bStatCache = true; /* use stat cache by default */
873 Globals.iMaxStatCacheSize = 256; /* 256k by default */
874 Globals.restrict_anonymous = 0;
875 Globals.bClientLanManAuth = false; /* Do NOT use the LanMan hash if it is available */
876 Globals.bClientPlaintextAuth = false; /* Do NOT use a plaintext password even if is requested by the server */
877 Globals.bLanmanAuth = false; /* Do NOT use the LanMan hash, even if it is supplied */
878 Globals.bNTLMAuth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
879 Globals.bClientNTLMv2Auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
880 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
882 Globals.map_to_guest = 0; /* By Default, "Never" */
883 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
884 Globals.enhanced_browsing = true;
885 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
886 #ifdef MMAP_BLACKLIST
887 Globals.bUseMmap = false;
889 Globals.bUseMmap = true;
891 Globals.bUnicode = true;
892 Globals.bUnixExtensions = true;
893 Globals.bResetOnZeroVC = false;
894 Globals.bLogWriteableFilesOnExit = false;
895 Globals.bCreateKrb5Conf = true;
896 Globals.winbindMaxDomainConnections = 1;
898 /* hostname lookups can be very expensive and are broken on
899 a large number of sites (tridge) */
900 Globals.bHostnameLookups = false;
902 string_set(&Globals.passdb_backend, "tdbsam");
903 string_set(&Globals.szLdapSuffix, "");
904 string_set(&Globals.szLdapMachineSuffix, "");
905 string_set(&Globals.szLdapUserSuffix, "");
906 string_set(&Globals.szLdapGroupSuffix, "");
907 string_set(&Globals.szLdapIdmapSuffix, "");
909 string_set(&Globals.szLdapAdminDn, "");
910 Globals.ldap_ssl = LDAP_SSL_START_TLS;
911 Globals.ldap_ssl_ads = false;
912 Globals.ldap_deref = -1;
913 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
914 Globals.ldap_delete_dn = false;
915 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
916 Globals.ldap_follow_referral = Auto;
917 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
918 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
919 Globals.ldap_page_size = LDAP_PAGE_SIZE;
921 Globals.ldap_debug_level = 0;
922 Globals.ldap_debug_threshold = 10;
924 /* This is what we tell the afs client. in reality we set the token
925 * to never expire, though, when this runs out the afs client will
926 * forget the token. Set to 0 to get NEVERDATE.*/
927 Globals.iAfsTokenLifetime = 604800;
928 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
930 /* these parameters are set to defaults that are more appropriate
931 for the increasing samba install base:
933 as a member of the workgroup, that will possibly become a
934 _local_ master browser (lm = true). this is opposed to a forced
935 local master browser startup (pm = true).
937 doesn't provide WINS server service by default (wsupp = false),
938 and doesn't provide domain master browser services by default, either.
942 Globals.bMsAddPrinterWizard = true;
943 Globals.os_level = 20;
944 Globals.bLocalMaster = true;
945 Globals.domain_master = Auto; /* depending on bDomainLogons */
946 Globals.bDomainLogons = false;
947 Globals.bBrowseList = true;
948 Globals.bWINSsupport = false;
949 Globals.bWINSproxy = false;
951 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
952 Globals.InitLogonDelay = 100; /* 100 ms default delay */
954 Globals.bWINSdnsProxy = true;
956 Globals.bAllowTrustedDomains = true;
957 string_set(&Globals.szIdmapBackend, "tdb");
959 string_set(&Globals.szTemplateShell, "/bin/false");
960 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
961 string_set(&Globals.szWinbindSeparator, "\\");
962 string_set(&Globals.szWinbinddSocketDirectory, dyn_WINBINDD_SOCKET_DIR);
964 string_set(&Globals.szCupsServer, "");
965 string_set(&Globals.szIPrintServer, "");
967 #ifdef CLUSTER_SUPPORT
968 string_set(&Globals.ctdbdSocket, CTDB_PATH);
970 string_set(&Globals.ctdbdSocket, "");
973 Globals.szClusterAddresses = NULL;
974 Globals.clustering = false;
975 Globals.ctdb_timeout = 0;
976 Globals.ctdb_locktime_warn_threshold = 0;
978 Globals.winbind_cache_time = 300; /* 5 minutes */
979 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
980 Globals.winbind_max_clients = 200;
981 Globals.bWinbindEnumUsers = false;
982 Globals.bWinbindEnumGroups = false;
983 Globals.bWinbindUseDefaultDomain = false;
984 Globals.bWinbindTrustedDomainsOnly = false;
985 Globals.bWinbindNestedGroups = true;
986 Globals.winbind_expand_groups = 1;
987 Globals.szWinbindNssInfo = (const char **)str_list_make_v3(NULL, "template", NULL);
988 Globals.bWinbindRefreshTickets = false;
989 Globals.bWinbindOfflineLogon = false;
991 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
992 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
994 Globals.bPassdbExpandExplicit = false;
996 Globals.name_cache_timeout = 660; /* In seconds */
998 Globals.bUseSpnego = true;
999 Globals.bClientUseSpnego = true;
1001 Globals.client_signing = SMB_SIGNING_DEFAULT;
1002 Globals.server_signing = SMB_SIGNING_DEFAULT;
1004 Globals.bDeferSharingViolations = true;
1005 Globals.smb_ports = (const char **)str_list_make_v3(NULL, SMB_PORTS, NULL);
1007 Globals.bEnablePrivileges = true;
1008 Globals.bHostMSDfs = true;
1009 Globals.bASUSupport = false;
1011 /* User defined shares. */
1012 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
1013 smb_panic("init_globals: ENOMEM");
1015 string_set(&Globals.szUsersharePath, s);
1017 string_set(&Globals.szUsershareTemplateShare, "");
1018 Globals.iUsershareMaxShares = 0;
1019 /* By default disallow sharing of directories not owned by the sharer. */
1020 Globals.bUsershareOwnerOnly = true;
1021 /* By default disallow guest access to usershares. */
1022 Globals.bUsershareAllowGuests = false;
1024 Globals.iKeepalive = DEFAULT_KEEPALIVE;
1026 /* By default no shares out of the registry */
1027 Globals.bRegistryShares = false;
1029 Globals.iminreceivefile = 0;
1031 Globals.bMapUntrustedToDomain = false;
1032 Globals.bMulticastDnsRegister = true;
1034 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
1035 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
1036 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
1037 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1039 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
1041 /* Now put back the settings that were set with lp_set_cmdline() */
1042 apply_lp_set_cmdline();
1045 /*******************************************************************
1046 Convenience routine to grab string parameters into talloced memory
1047 and run standard_sub_basic on them. The buffers can be written to by
1048 callers without affecting the source string.
1049 ********************************************************************/
1051 static char *lp_string(TALLOC_CTX *ctx, const char *s)
1055 /* The follow debug is useful for tracking down memory problems
1056 especially if you have an inner loop that is calling a lp_*()
1057 function that returns a string. Perhaps this debug should be
1058 present all the time? */
1061 DEBUG(10, ("lp_string(%s)\n", s));
1067 ret = talloc_sub_basic(ctx,
1068 get_current_username(),
1069 current_user_info.domain,
1071 if (trim_char(ret, '\"', '\"')) {
1072 if (strchr(ret,'\"') != NULL) {
1074 ret = talloc_sub_basic(ctx,
1075 get_current_username(),
1076 current_user_info.domain,
1084 In this section all the functions that are used to access the
1085 parameters from the rest of the program are defined
1088 #define FN_GLOBAL_STRING(fn_name,ptr) \
1089 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1090 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1091 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1092 #define FN_GLOBAL_LIST(fn_name,ptr) \
1093 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1094 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1095 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1096 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1097 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1098 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1099 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1101 #define FN_LOCAL_STRING(fn_name,val) \
1102 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));}
1103 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1104 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1105 #define FN_LOCAL_LIST(fn_name,val) \
1106 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1107 #define FN_LOCAL_BOOL(fn_name,val) \
1108 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1109 #define FN_LOCAL_INTEGER(fn_name,val) \
1110 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1112 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1113 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1114 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1115 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1116 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1117 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1120 static FN_GLOBAL_BOOL(_readraw, bReadRaw)
1121 static FN_GLOBAL_BOOL(_writeraw, bWriteRaw)
1123 /* If lp_statedir() and lp_cachedir() are explicitely set during the
1124 * build process or in smb.conf, we use that value. Otherwise they
1125 * default to the value of lp_lockdir(). */
1126 const char *lp_statedir(void) {
1127 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
1128 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
1129 return(*(char **)(&Globals.szStateDir) ?
1130 *(char **)(&Globals.szStateDir) : "");
1132 return(*(char **)(&Globals.szLockDir) ?
1133 *(char **)(&Globals.szLockDir) : "");
1135 const char *lp_cachedir(void) {
1136 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
1137 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
1138 return(*(char **)(&Globals.szCacheDir) ?
1139 *(char **)(&Globals.szCacheDir) : "");
1141 return(*(char **)(&Globals.szLockDir) ?
1142 *(char **)(&Globals.szLockDir) : "");
1144 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
1145 winbindMaxDomainConnections)
1147 int lp_winbind_max_domain_connections(void)
1149 if (lp_winbind_offline_logon() &&
1150 lp_winbind_max_domain_connections_int() > 1) {
1151 DEBUG(1, ("offline logons active, restricting max domain "
1152 "connections to 1\n"));
1155 return MAX(1, lp_winbind_max_domain_connections_int());
1158 int lp_smb2_max_credits(void)
1160 if (Globals.ismb2_max_credits == 0) {
1161 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1163 return Globals.ismb2_max_credits;
1165 int lp_cups_encrypt(void)
1168 #ifdef HAVE_HTTPCONNECTENCRYPT
1169 switch (Globals.CupsEncrypt) {
1171 result = HTTP_ENCRYPT_REQUIRED;
1174 result = HTTP_ENCRYPT_ALWAYS;
1177 result = HTTP_ENCRYPT_NEVER;
1184 /* These functions remain in source3/param for now */
1186 FN_GLOBAL_STRING(configfile, szConfigFile)
1188 #include "lib/param/param_functions.c"
1190 FN_LOCAL_STRING(servicename, szService)
1191 FN_LOCAL_CONST_STRING(const_servicename, szService)
1193 /* local prototypes */
1195 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1196 static const char *get_boolean(bool bool_value);
1197 static int getservicebyname(const char *pszServiceName,
1198 struct loadparm_service *pserviceDest);
1199 static void copy_service(struct loadparm_service *pserviceDest,
1200 struct loadparm_service *pserviceSource,
1201 struct bitmap *pcopymapDest);
1202 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1204 static bool do_section(const char *pszSectionName, void *userdata);
1205 static void init_copymap(struct loadparm_service *pservice);
1206 static bool hash_a_service(const char *name, int number);
1207 static void free_service_byindex(int iService);
1208 static void show_parameter(int parmIndex);
1209 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1212 * This is a helper function for parametrical options support. It returns a
1213 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1214 * parametrical functions are quite simple
1216 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
1219 bool global_section = false;
1221 struct parmlist_entry *data;
1223 if (service == NULL) {
1224 data = Globals.param_opt;
1225 global_section = true;
1227 data = service->param_opt;
1230 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
1231 DEBUG(0,("asprintf failed!\n"));
1236 if (strwicmp(data->key, param_key) == 0) {
1237 string_free(¶m_key);
1243 if (!global_section) {
1244 /* Try to fetch the same option but from globals */
1245 /* but only if we are not already working with Globals */
1246 data = Globals.param_opt;
1248 if (strwicmp(data->key, param_key) == 0) {
1249 string_free(¶m_key);
1256 string_free(¶m_key);
1262 * This is a helper function for parametrical options support. It returns a
1263 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1264 * parametrical functions are quite simple
1266 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1269 if (snum >= iNumServices) return NULL;
1272 return get_parametrics_by_service(NULL, type, option);
1274 return get_parametrics_by_service(ServicePtrs[snum], type, option);
1279 #define MISSING_PARAMETER(name) \
1280 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1282 /*******************************************************************
1283 convenience routine to return int parameters.
1284 ********************************************************************/
1285 static int lp_int(const char *s)
1289 MISSING_PARAMETER(lp_int);
1293 return (int)strtol(s, NULL, 0);
1296 /*******************************************************************
1297 convenience routine to return unsigned long parameters.
1298 ********************************************************************/
1299 static unsigned long lp_ulong(const char *s)
1303 MISSING_PARAMETER(lp_ulong);
1307 return strtoul(s, NULL, 0);
1310 /*******************************************************************
1311 convenience routine to return boolean parameters.
1312 ********************************************************************/
1313 static bool lp_bool(const char *s)
1318 MISSING_PARAMETER(lp_bool);
1322 if (!set_boolean(s, &ret)) {
1323 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1330 /*******************************************************************
1331 convenience routine to return enum parameters.
1332 ********************************************************************/
1333 static int lp_enum(const char *s,const struct enum_list *_enum)
1337 if (!s || !*s || !_enum) {
1338 MISSING_PARAMETER(lp_enum);
1342 for (i=0; _enum[i].name; i++) {
1343 if (strequal(_enum[i].name,s))
1344 return _enum[i].value;
1347 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1351 #undef MISSING_PARAMETER
1353 /* Return parametric option from a given service. Type is a part of option before ':' */
1354 /* Parametric option has following syntax: 'Type: option = value' */
1355 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1357 struct parmlist_entry *data = get_parametrics(snum, type, option);
1359 if (data == NULL||data->value==NULL) {
1361 return lp_string(ctx, def);
1367 return lp_string(ctx, data->value);
1370 /* Return parametric option from a given service. Type is a part of option before ':' */
1371 /* Parametric option has following syntax: 'Type: option = value' */
1372 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1374 struct parmlist_entry *data = get_parametrics(snum, type, option);
1376 if (data == NULL||data->value==NULL)
1382 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
1384 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
1386 if (data == NULL||data->value==NULL)
1393 /* Return parametric option from a given service. Type is a part of option before ':' */
1394 /* Parametric option has following syntax: 'Type: option = value' */
1396 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1398 struct parmlist_entry *data = get_parametrics(snum, type, option);
1400 if (data == NULL||data->value==NULL)
1401 return (const char **)def;
1403 if (data->list==NULL) {
1404 data->list = str_list_make_v3(NULL, data->value, NULL);
1407 return (const char **)data->list;
1410 /* Return parametric option from a given service. Type is a part of option before ':' */
1411 /* Parametric option has following syntax: 'Type: option = value' */
1413 int lp_parm_int(int snum, const char *type, const char *option, int def)
1415 struct parmlist_entry *data = get_parametrics(snum, type, option);
1417 if (data && data->value && *data->value)
1418 return lp_int(data->value);
1423 /* Return parametric option from a given service. Type is a part of option before ':' */
1424 /* Parametric option has following syntax: 'Type: option = value' */
1426 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1428 struct parmlist_entry *data = get_parametrics(snum, type, option);
1430 if (data && data->value && *data->value)
1431 return lp_ulong(data->value);
1436 /* Return parametric option from a given service. Type is a part of option before ':' */
1437 /* Parametric option has following syntax: 'Type: option = value' */
1439 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1441 struct parmlist_entry *data = get_parametrics(snum, type, option);
1443 if (data && data->value && *data->value)
1444 return lp_bool(data->value);
1449 /* Return parametric option from a given service. Type is a part of option before ':' */
1450 /* Parametric option has following syntax: 'Type: option = value' */
1452 int lp_parm_enum(int snum, const char *type, const char *option,
1453 const struct enum_list *_enum, int def)
1455 struct parmlist_entry *data = get_parametrics(snum, type, option);
1457 if (data && data->value && *data->value && _enum)
1458 return lp_enum(data->value, _enum);
1464 /***************************************************************************
1465 Initialise a service to the defaults.
1466 ***************************************************************************/
1468 static void init_service(struct loadparm_service *pservice)
1470 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
1471 copy_service(pservice, &sDefault, NULL);
1476 * free a param_opts structure.
1477 * param_opts handling should be moved to talloc;
1478 * then this whole functions reduces to a TALLOC_FREE().
1481 static void free_param_opts(struct parmlist_entry **popts)
1483 struct parmlist_entry *opt, *next_opt;
1485 if (*popts != NULL) {
1486 DEBUG(5, ("Freeing parametrics:\n"));
1489 while (opt != NULL) {
1490 string_free(&opt->key);
1491 string_free(&opt->value);
1492 TALLOC_FREE(opt->list);
1493 next_opt = opt->next;
1500 /***************************************************************************
1501 Free the dynamically allocated parts of a service struct.
1502 ***************************************************************************/
1504 static void free_service(struct loadparm_service *pservice)
1509 if (pservice->szService)
1510 DEBUG(5, ("free_service: Freeing service %s\n",
1511 pservice->szService));
1513 free_parameters(pservice);
1515 string_free(&pservice->szService);
1516 TALLOC_FREE(pservice->copymap);
1518 free_param_opts(&pservice->param_opt);
1520 ZERO_STRUCTP(pservice);
1524 /***************************************************************************
1525 remove a service indexed in the ServicePtrs array from the ServiceHash
1526 and free the dynamically allocated parts
1527 ***************************************************************************/
1529 static void free_service_byindex(int idx)
1531 if ( !LP_SNUM_OK(idx) )
1534 ServicePtrs[idx]->valid = false;
1536 /* we have to cleanup the hash record */
1538 if (ServicePtrs[idx]->szService) {
1539 char *canon_name = canonicalize_servicename(
1541 ServicePtrs[idx]->szService );
1543 dbwrap_delete_bystring(ServiceHash, canon_name );
1544 TALLOC_FREE(canon_name);
1547 free_service(ServicePtrs[idx]);
1548 talloc_free_children(ServicePtrs[idx]);
1551 /***************************************************************************
1552 Add a new service to the services array initialising it with the given
1554 ***************************************************************************/
1556 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1559 struct loadparm_service tservice;
1560 int num_to_alloc = iNumServices + 1;
1561 struct loadparm_service **tsp = NULL;
1563 tservice = *pservice;
1565 /* it might already exist */
1567 i = getservicebyname(name, NULL);
1573 /* if not, then create one */
1575 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
1577 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1581 ServicePtrs[iNumServices] = talloc(NULL, struct loadparm_service);
1582 if (!ServicePtrs[iNumServices]) {
1583 DEBUG(0,("add_a_service: out of memory!\n"));
1588 ServicePtrs[i]->valid = true;
1590 init_service(ServicePtrs[i]);
1591 copy_service(ServicePtrs[i], &tservice, NULL);
1593 string_set(&ServicePtrs[i]->szService, name);
1595 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1596 i, ServicePtrs[i]->szService));
1598 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1605 /***************************************************************************
1606 Convert a string to uppercase and remove whitespaces.
1607 ***************************************************************************/
1609 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1614 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1618 result = talloc_strdup(ctx, src);
1619 SMB_ASSERT(result != NULL);
1621 if (!strlower_m(result)) {
1622 TALLOC_FREE(result);
1628 /***************************************************************************
1629 Add a name/index pair for the services array to the hash table.
1630 ***************************************************************************/
1632 static bool hash_a_service(const char *name, int idx)
1636 if ( !ServiceHash ) {
1637 DEBUG(10,("hash_a_service: creating servicehash\n"));
1638 ServiceHash = db_open_rbt(NULL);
1639 if ( !ServiceHash ) {
1640 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1645 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1648 canon_name = canonicalize_servicename(talloc_tos(), name );
1650 dbwrap_store_bystring(ServiceHash, canon_name,
1651 make_tdb_data((uint8 *)&idx, sizeof(idx)),
1654 TALLOC_FREE(canon_name);
1659 /***************************************************************************
1660 Add a new home service, with the specified home directory, defaults coming
1662 ***************************************************************************/
1664 bool lp_add_home(const char *pszHomename, int iDefaultService,
1665 const char *user, const char *pszHomedir)
1669 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1670 pszHomedir[0] == '\0') {
1674 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1679 if (!(*(ServicePtrs[iDefaultService]->szPath))
1680 || strequal(ServicePtrs[iDefaultService]->szPath,
1681 lp_pathname(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1682 string_set(&ServicePtrs[i]->szPath, pszHomedir);
1685 if (!(*(ServicePtrs[i]->comment))) {
1686 char *comment = NULL;
1687 if (asprintf(&comment, "Home directory of %s", user) < 0) {
1690 string_set(&ServicePtrs[i]->comment, comment);
1694 /* set the browseable flag from the global default */
1696 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1697 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
1699 ServicePtrs[i]->autoloaded = true;
1701 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1702 user, ServicePtrs[i]->szPath ));
1707 /***************************************************************************
1708 Add a new service, based on an old one.
1709 ***************************************************************************/
1711 int lp_add_service(const char *pszService, int iDefaultService)
1713 if (iDefaultService < 0) {
1714 return add_a_service(&sDefault, pszService);
1717 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1720 /***************************************************************************
1721 Add the IPC service.
1722 ***************************************************************************/
1724 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1726 char *comment = NULL;
1727 int i = add_a_service(&sDefault, ipc_name);
1732 if (asprintf(&comment, "IPC Service (%s)",
1733 Globals.szServerString) < 0) {
1737 string_set(&ServicePtrs[i]->szPath, tmpdir());
1738 string_set(&ServicePtrs[i]->szUsername, "");
1739 string_set(&ServicePtrs[i]->comment, comment);
1740 string_set(&ServicePtrs[i]->fstype, "IPC");
1741 ServicePtrs[i]->iMaxConnections = 0;
1742 ServicePtrs[i]->bAvailable = true;
1743 ServicePtrs[i]->bRead_only = true;
1744 ServicePtrs[i]->bGuest_only = false;
1745 ServicePtrs[i]->bAdministrative_share = true;
1746 ServicePtrs[i]->bGuest_ok = guest_ok;
1747 ServicePtrs[i]->bPrint_ok = false;
1748 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1750 DEBUG(3, ("adding IPC service\n"));
1756 /***************************************************************************
1757 Add a new printer service, with defaults coming from service iFrom.
1758 ***************************************************************************/
1760 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1762 const char *comment = "From Printcap";
1763 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1768 /* note that we do NOT default the availability flag to true - */
1769 /* we take it from the default service passed. This allows all */
1770 /* dynamic printers to be disabled by disabling the [printers] */
1771 /* entry (if/when the 'available' keyword is implemented!). */
1773 /* the printer name is set to the service name. */
1774 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1775 string_set(&ServicePtrs[i]->comment, comment);
1777 /* set the browseable flag from the gloabl default */
1778 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1780 /* Printers cannot be read_only. */
1781 ServicePtrs[i]->bRead_only = false;
1782 /* No oplocks on printer services. */
1783 ServicePtrs[i]->bOpLocks = false;
1784 /* Printer services must be printable. */
1785 ServicePtrs[i]->bPrint_ok = true;
1787 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1793 /***************************************************************************
1794 Check whether the given parameter name is valid.
1795 Parametric options (names containing a colon) are considered valid.
1796 ***************************************************************************/
1798 bool lp_parameter_is_valid(const char *pszParmName)
1800 return ((map_parameter(pszParmName) != -1) ||
1801 (strchr(pszParmName, ':') != NULL));
1804 /***************************************************************************
1805 Check whether the given name is the name of a global parameter.
1806 Returns true for strings belonging to parameters of class
1807 P_GLOBAL, false for all other strings, also for parametric options
1808 and strings not belonging to any option.
1809 ***************************************************************************/
1811 bool lp_parameter_is_global(const char *pszParmName)
1813 int num = map_parameter(pszParmName);
1816 return (parm_table[num].p_class == P_GLOBAL);
1822 /**************************************************************************
1823 Check whether the given name is the canonical name of a parameter.
1824 Returns false if it is not a valid parameter Name.
1825 For parametric options, true is returned.
1826 **************************************************************************/
1828 bool lp_parameter_is_canonical(const char *parm_name)
1830 if (!lp_parameter_is_valid(parm_name)) {
1834 return (map_parameter(parm_name) ==
1835 map_parameter_canonical(parm_name, NULL));
1838 /**************************************************************************
1839 Determine the canonical name for a parameter.
1840 Indicate when it is an inverse (boolean) synonym instead of a
1842 **************************************************************************/
1844 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1849 if (!lp_parameter_is_valid(parm_name)) {
1854 num = map_parameter_canonical(parm_name, inverse);
1856 /* parametric option */
1857 *canon_parm = parm_name;
1859 *canon_parm = parm_table[num].label;
1866 /**************************************************************************
1867 Determine the canonical name for a parameter.
1868 Turn the value given into the inverse boolean expression when
1869 the synonym is an invers boolean synonym.
1871 Return true if parm_name is a valid parameter name and
1872 in case it is an invers boolean synonym, if the val string could
1873 successfully be converted to the reverse bool.
1874 Return false in all other cases.
1875 **************************************************************************/
1877 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1879 const char **canon_parm,
1880 const char **canon_val)
1885 if (!lp_parameter_is_valid(parm_name)) {
1891 num = map_parameter_canonical(parm_name, &inverse);
1893 /* parametric option */
1894 *canon_parm = parm_name;
1897 *canon_parm = parm_table[num].label;
1899 if (!lp_invert_boolean(val, canon_val)) {
1911 /***************************************************************************
1912 Map a parameter's string representation to something we can use.
1913 Returns false if the parameter string is not recognised, else TRUE.
1914 ***************************************************************************/
1916 static int map_parameter(const char *pszParmName)
1920 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
1923 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1924 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1927 /* Warn only if it isn't parametric option */
1928 if (strchr(pszParmName, ':') == NULL)
1929 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1930 /* We do return 'fail' for parametric options as well because they are
1931 stored in different storage
1936 /***************************************************************************
1937 Map a parameter's string representation to the index of the canonical
1938 form of the parameter (it might be a synonym).
1939 Returns -1 if the parameter string is not recognised.
1940 ***************************************************************************/
1942 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1944 int parm_num, canon_num;
1945 bool loc_inverse = false;
1947 parm_num = map_parameter(pszParmName);
1948 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
1949 /* invalid, parametric or no canidate for synonyms ... */
1953 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1954 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1955 parm_num = canon_num;
1961 if (inverse != NULL) {
1962 *inverse = loc_inverse;
1967 /***************************************************************************
1968 return true if parameter number parm1 is a synonym of parameter
1969 number parm2 (parm2 being the principal name).
1970 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1972 ***************************************************************************/
1974 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1976 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1977 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1978 (parm_table[parm1].flags & FLAG_HIDE) &&
1979 !(parm_table[parm2].flags & FLAG_HIDE))
1981 if (inverse != NULL) {
1982 if ((parm_table[parm1].type == P_BOOLREV) &&
1983 (parm_table[parm2].type == P_BOOL))
1995 /***************************************************************************
1996 Show one parameter's name, type, [values,] and flags.
1997 (helper functions for show_parameter_list)
1998 ***************************************************************************/
2000 static void show_parameter(int parmIndex)
2002 int enumIndex, flagIndex;
2007 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2008 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
2010 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2011 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2013 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2014 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2015 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
2017 printf("%s=%s", parm_table[parmIndex].label,
2018 type[parm_table[parmIndex].type]);
2019 if (parm_table[parmIndex].type == P_ENUM) {
2022 parm_table[parmIndex].enum_list[enumIndex].name;
2026 enumIndex ? "|" : "",
2027 parm_table[parmIndex].enum_list[enumIndex].name);
2032 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
2033 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2036 flag_names[flagIndex]);
2041 /* output synonyms */
2043 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
2044 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
2045 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
2046 parm_table[parmIndex2].label);
2047 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
2049 printf(" (synonyms: ");
2054 printf("%s%s", parm_table[parmIndex2].label,
2055 inverse ? "[i]" : "");
2065 /***************************************************************************
2066 Show all parameter's name, type, [values,] and flags.
2067 ***************************************************************************/
2069 void show_parameter_list(void)
2071 int classIndex, parmIndex;
2072 const char *section_names[] = { "local", "global", NULL};
2074 for (classIndex=0; section_names[classIndex]; classIndex++) {
2075 printf("[%s]\n", section_names[classIndex]);
2076 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2077 if (parm_table[parmIndex].p_class == classIndex) {
2078 show_parameter(parmIndex);
2084 /***************************************************************************
2085 Check if a given string correctly represents a boolean value.
2086 ***************************************************************************/
2088 bool lp_string_is_valid_boolean(const char *parm_value)
2090 return set_boolean(parm_value, NULL);
2093 /***************************************************************************
2094 Get the standard string representation of a boolean value ("yes" or "no")
2095 ***************************************************************************/
2097 static const char *get_boolean(bool bool_value)
2099 static const char *yes_str = "yes";
2100 static const char *no_str = "no";
2102 return (bool_value ? yes_str : no_str);
2105 /***************************************************************************
2106 Provide the string of the negated boolean value associated to the boolean
2107 given as a string. Returns false if the passed string does not correctly
2108 represent a boolean.
2109 ***************************************************************************/
2111 bool lp_invert_boolean(const char *str, const char **inverse_str)
2115 if (!set_boolean(str, &val)) {
2119 *inverse_str = get_boolean(!val);
2123 /***************************************************************************
2124 Provide the canonical string representation of a boolean value given
2125 as a string. Return true on success, false if the string given does
2126 not correctly represent a boolean.
2127 ***************************************************************************/
2129 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2133 if (!set_boolean(str, &val)) {
2137 *canon_str = get_boolean(val);
2141 /***************************************************************************
2142 Find a service by name. Otherwise works like get_service.
2143 ***************************************************************************/
2145 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2152 if (ServiceHash == NULL) {
2156 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2158 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2161 if (NT_STATUS_IS_OK(status) &&
2162 (data.dptr != NULL) &&
2163 (data.dsize == sizeof(iService)))
2165 iService = *(int *)data.dptr;
2168 TALLOC_FREE(canon_name);
2170 if ((iService != -1) && (LP_SNUM_OK(iService))
2171 && (pserviceDest != NULL)) {
2172 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2178 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2179 struct loadparm_service *lp_service(const char *pszServiceName)
2181 int iService = getservicebyname(pszServiceName, NULL);
2182 if (iService == -1 || !LP_SNUM_OK(iService)) {
2185 return ServicePtrs[iService];
2188 struct loadparm_service *lp_servicebynum(int snum)
2190 if ((snum == -1) || !LP_SNUM_OK(snum)) {
2193 return ServicePtrs[snum];
2196 struct loadparm_service *lp_default_loadparm_service()
2202 /***************************************************************************
2203 Copy a service structure to another.
2204 If pcopymapDest is NULL then copy all fields
2205 ***************************************************************************/
2208 * Add a parametric option to a parmlist_entry,
2209 * replacing old value, if already present.
2211 static void set_param_opt(struct parmlist_entry **opt_list,
2212 const char *opt_name,
2213 const char *opt_value,
2216 struct parmlist_entry *new_opt, *opt;
2222 /* Traverse destination */
2224 /* If we already have same option, override it */
2225 if (strwicmp(opt->key, opt_name) == 0) {
2226 if ((opt->priority & FLAG_CMDLINE) &&
2227 !(priority & FLAG_CMDLINE)) {
2228 /* it's been marked as not to be
2232 string_free(&opt->value);
2233 TALLOC_FREE(opt->list);
2234 opt->value = SMB_STRDUP(opt_value);
2235 opt->priority = priority;
2242 new_opt = SMB_XMALLOC_P(struct parmlist_entry);
2243 new_opt->key = SMB_STRDUP(opt_name);
2244 new_opt->value = SMB_STRDUP(opt_value);
2245 new_opt->list = NULL;
2246 new_opt->priority = priority;
2247 DLIST_ADD(*opt_list, new_opt);
2251 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
2252 struct bitmap *pcopymapDest)
2255 bool bcopyall = (pcopymapDest == NULL);
2256 struct parmlist_entry *data;
2258 for (i = 0; parm_table[i].label; i++)
2259 if (parm_table[i].p_class == P_LOCAL &&
2260 (bcopyall || bitmap_query(pcopymapDest,i))) {
2261 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
2262 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
2264 switch (parm_table[i].type) {
2267 *(bool *)dest_ptr = *(bool *)src_ptr;
2274 *(int *)dest_ptr = *(int *)src_ptr;
2278 *(char *)dest_ptr = *(char *)src_ptr;
2282 string_set((char **)dest_ptr,
2288 char *upper_string = strupper_talloc(talloc_tos(),
2290 string_set((char **)dest_ptr,
2292 TALLOC_FREE(upper_string);
2296 TALLOC_FREE(*((char ***)dest_ptr));
2297 *((char ***)dest_ptr) = str_list_copy(NULL,
2298 *(const char ***)src_ptr);
2306 init_copymap(pserviceDest);
2307 if (pserviceSource->copymap)
2308 bitmap_copy(pserviceDest->copymap,
2309 pserviceSource->copymap);
2312 data = pserviceSource->param_opt;
2314 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
2319 /***************************************************************************
2320 Check a service for consistency. Return false if the service is in any way
2321 incomplete or faulty, else true.
2322 ***************************************************************************/
2324 bool service_ok(int iService)
2329 if (ServicePtrs[iService]->szService[0] == '\0') {
2330 DEBUG(0, ("The following message indicates an internal error:\n"));
2331 DEBUG(0, ("No service name in service entry.\n"));
2335 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2336 /* I can't see why you'd want a non-printable printer service... */
2337 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2338 if (!ServicePtrs[iService]->bPrint_ok) {
2339 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2340 ServicePtrs[iService]->szService));
2341 ServicePtrs[iService]->bPrint_ok = true;
2343 /* [printers] service must also be non-browsable. */
2344 if (ServicePtrs[iService]->bBrowseable)
2345 ServicePtrs[iService]->bBrowseable = false;
2348 if (ServicePtrs[iService]->szPath[0] == '\0' &&
2349 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2350 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
2352 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2353 ServicePtrs[iService]->szService));
2354 ServicePtrs[iService]->bAvailable = false;
2357 /* If a service is flagged unavailable, log the fact at level 1. */
2358 if (!ServicePtrs[iService]->bAvailable)
2359 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2360 ServicePtrs[iService]->szService));
2365 static struct smbconf_ctx *lp_smbconf_ctx(void)
2368 static struct smbconf_ctx *conf_ctx = NULL;
2370 if (conf_ctx == NULL) {
2371 err = smbconf_init(NULL, &conf_ctx, "registry:");
2372 if (!SBC_ERROR_IS_OK(err)) {
2373 DEBUG(1, ("error initializing registry configuration: "
2374 "%s\n", sbcErrorString(err)));
2382 static bool process_smbconf_service(struct smbconf_service *service)
2387 if (service == NULL) {
2391 ret = do_section(service->name, NULL);
2395 for (count = 0; count < service->num_params; count++) {
2396 ret = do_parameter(service->param_names[count],
2397 service->param_values[count],
2403 if (iServiceIndex >= 0) {
2404 return service_ok(iServiceIndex);
2410 * load a service from registry and activate it
2412 bool process_registry_service(const char *service_name)
2415 struct smbconf_service *service = NULL;
2416 TALLOC_CTX *mem_ctx = talloc_stackframe();
2417 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2420 if (conf_ctx == NULL) {
2424 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2426 if (!smbconf_share_exists(conf_ctx, service_name)) {
2428 * Registry does not contain data for this service (yet),
2429 * but make sure lp_load doesn't return false.
2435 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2436 if (!SBC_ERROR_IS_OK(err)) {
2440 ret = process_smbconf_service(service);
2446 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2449 TALLOC_FREE(mem_ctx);
2454 * process_registry_globals
2456 static bool process_registry_globals(void)
2460 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2462 ret = do_parameter("registry shares", "yes", NULL);
2467 return process_registry_service(GLOBAL_NAME);
2470 bool process_registry_shares(void)
2474 struct smbconf_service **service = NULL;
2475 uint32_t num_shares = 0;
2476 TALLOC_CTX *mem_ctx = talloc_stackframe();
2477 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2480 if (conf_ctx == NULL) {
2484 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2485 if (!SBC_ERROR_IS_OK(err)) {
2491 for (count = 0; count < num_shares; count++) {
2492 if (strequal(service[count]->name, GLOBAL_NAME)) {
2495 ret = process_smbconf_service(service[count]);
2502 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2505 TALLOC_FREE(mem_ctx);
2510 * reload those shares from registry that are already
2511 * activated in the services array.
2513 static bool reload_registry_shares(void)
2518 for (i = 0; i < iNumServices; i++) {
2523 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2527 ret = process_registry_service(ServicePtrs[i]->szService);
2538 #define MAX_INCLUDE_DEPTH 100
2540 static uint8_t include_depth;
2542 static struct file_lists {
2543 struct file_lists *next;
2547 } *file_lists = NULL;
2549 /*******************************************************************
2550 Keep a linked list of all config files so we know when one has changed
2551 it's date and needs to be reloaded.
2552 ********************************************************************/
2554 static void add_to_file_list(const char *fname, const char *subfname)
2556 struct file_lists *f = file_lists;
2559 if (f->name && !strcmp(f->name, fname))
2565 f = SMB_MALLOC_P(struct file_lists);
2568 f->next = file_lists;
2569 f->name = SMB_STRDUP(fname);
2574 f->subfname = SMB_STRDUP(subfname);
2581 f->modtime = file_modtime(subfname);
2583 time_t t = file_modtime(subfname);
2591 * Free the file lists
2593 static void free_file_list(void)
2595 struct file_lists *f;
2596 struct file_lists *next;
2601 SAFE_FREE( f->name );
2602 SAFE_FREE( f->subfname );
2611 * Utility function for outsiders to check if we're running on registry.
2613 bool lp_config_backend_is_registry(void)
2615 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2619 * Utility function to check if the config backend is FILE.
2621 bool lp_config_backend_is_file(void)
2623 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2626 /*******************************************************************
2627 Check if a config file has changed date.
2628 ********************************************************************/
2630 bool lp_file_list_changed(void)
2632 struct file_lists *f = file_lists;
2634 DEBUG(6, ("lp_file_list_changed()\n"));
2639 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2640 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2642 if (conf_ctx == NULL) {
2645 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2648 DEBUGADD(6, ("registry config changed\n"));
2653 n2 = talloc_sub_basic(talloc_tos(),
2654 get_current_username(),
2655 current_user_info.domain,
2660 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2661 f->name, n2, ctime(&f->modtime)));
2663 mod_time = file_modtime(n2);
2666 ((f->modtime != mod_time) ||
2667 (f->subfname == NULL) ||
2668 (strcmp(n2, f->subfname) != 0)))
2671 ("file %s modified: %s\n", n2,
2673 f->modtime = mod_time;
2674 SAFE_FREE(f->subfname);
2675 f->subfname = SMB_STRDUP(n2);
2688 * Initialize iconv conversion descriptors.
2690 * This is called the first time it is needed, and also called again
2691 * every time the configuration is reloaded, because the charset or
2692 * codepage might have changed.
2694 static void init_iconv(void)
2696 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2698 true, global_iconv_handle);
2701 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2703 if (strcmp(*ptr, pszParmValue) != 0) {
2704 string_set(ptr, pszParmValue);
2710 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2712 bool is_utf8 = false;
2713 size_t len = strlen(pszParmValue);
2715 if (len == 4 || len == 5) {
2716 /* Don't use StrCaseCmp here as we don't want to
2717 initialize iconv. */
2718 if ((toupper_m(pszParmValue[0]) == 'U') &&
2719 (toupper_m(pszParmValue[1]) == 'T') &&
2720 (toupper_m(pszParmValue[2]) == 'F')) {
2722 if (pszParmValue[3] == '8') {
2726 if (pszParmValue[3] == '-' &&
2727 pszParmValue[4] == '8') {
2734 if (strcmp(*ptr, pszParmValue) != 0) {
2736 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2737 "be UTF8, using (default value) %s instead.\n",
2738 DEFAULT_DOS_CHARSET));
2739 pszParmValue = DEFAULT_DOS_CHARSET;
2741 string_set(ptr, pszParmValue);
2747 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2750 TALLOC_CTX *frame = talloc_stackframe();
2751 char *realm = strupper_talloc(frame, pszParmValue);
2752 char *dnsdomain = strlower_talloc(realm, pszParmValue);
2754 ret &= string_set(&Globals.szRealm, pszParmValue);
2755 ret &= string_set(&Globals.szRealm_upper, realm);
2756 ret &= string_set(&Globals.szRealm_lower, dnsdomain);
2762 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2764 TALLOC_FREE(Globals.szNetbiosAliases);
2765 Globals.szNetbiosAliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
2766 return set_netbios_aliases(Globals.szNetbiosAliases);
2769 /***************************************************************************
2770 Handle the include operation.
2771 ***************************************************************************/
2772 static bool bAllowIncludeRegistry = true;
2774 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2778 if (include_depth >= MAX_INCLUDE_DEPTH) {
2779 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2784 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2785 if (!bAllowIncludeRegistry) {
2788 if (bInGlobalSection) {
2791 ret = process_registry_globals();
2795 DEBUG(1, ("\"include = registry\" only effective "
2796 "in %s section\n", GLOBAL_NAME));
2801 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2802 current_user_info.domain,
2805 add_to_file_list(pszParmValue, fname);
2807 string_set(ptr, fname);
2809 if (file_exist(fname)) {
2812 ret = pm_process(fname, do_section, do_parameter, NULL);
2818 DEBUG(2, ("Can't find include file %s\n", fname));
2823 /***************************************************************************
2824 Handle the interpretation of the copy parameter.
2825 ***************************************************************************/
2827 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2831 struct loadparm_service serviceTemp;
2833 string_set(ptr, pszParmValue);
2835 init_service(&serviceTemp);
2839 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2841 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2842 if (iTemp == iServiceIndex) {
2843 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2845 copy_service(ServicePtrs[iServiceIndex],
2847 ServicePtrs[iServiceIndex]->copymap);
2851 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2855 free_service(&serviceTemp);
2859 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2861 Globals.ldap_debug_level = lp_int(pszParmValue);
2862 init_ldap_debugging();
2867 * idmap related parameters
2870 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2872 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
2877 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2879 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2884 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2886 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2891 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2893 char *config_option = NULL;
2894 const char *range = NULL;
2897 SMB_ASSERT(low != NULL);
2898 SMB_ASSERT(high != NULL);
2900 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2904 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2906 if (config_option == NULL) {
2907 DEBUG(0, ("out of memory\n"));
2911 range = lp_parm_const_string(-1, config_option, "range", NULL);
2912 if (range == NULL) {
2913 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2917 if (sscanf(range, "%u - %u", low, high) != 2) {
2918 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2919 range, domain_name));
2926 talloc_free(config_option);
2931 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2933 return lp_idmap_range("*", low, high);
2936 const char *lp_idmap_backend(const char *domain_name)
2938 char *config_option = NULL;
2939 const char *backend = NULL;
2941 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2945 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2947 if (config_option == NULL) {
2948 DEBUG(0, ("out of memory\n"));
2952 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2953 if (backend == NULL) {
2954 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2959 talloc_free(config_option);
2963 const char *lp_idmap_default_backend(void)
2965 return lp_idmap_backend("*");
2968 /***************************************************************************
2969 Handle the DEBUG level list.
2970 ***************************************************************************/
2972 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
2974 string_set(ptr, pszParmValueIn);
2975 return debug_parse_levels(pszParmValueIn);
2978 /***************************************************************************
2979 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2980 ***************************************************************************/
2982 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2984 const char *suffix_string;
2986 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2987 Globals.szLdapSuffix );
2988 if ( !suffix_string ) {
2989 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2993 return suffix_string;
2996 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2998 if (Globals.szLdapMachineSuffix[0])
2999 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
3001 return lp_string(ctx, Globals.szLdapSuffix);
3004 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
3006 if (Globals.szLdapUserSuffix[0])
3007 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
3009 return lp_string(ctx, Globals.szLdapSuffix);
3012 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
3014 if (Globals.szLdapGroupSuffix[0])
3015 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
3017 return lp_string(ctx, Globals.szLdapSuffix);
3020 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
3022 if (Globals.szLdapIdmapSuffix[0])
3023 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
3025 return lp_string(ctx, Globals.szLdapSuffix);
3028 /****************************************************************************
3029 set the value for a P_ENUM
3030 ***************************************************************************/
3032 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3037 for (i = 0; parm->enum_list[i].name; i++) {
3038 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3039 *ptr = parm->enum_list[i].value;
3043 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
3044 pszParmValue, parm->label));
3047 /***************************************************************************
3048 ***************************************************************************/
3050 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
3052 static int parm_num = -1;
3053 struct loadparm_service *s;
3055 if ( parm_num == -1 )
3056 parm_num = map_parameter( "printing" );
3058 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3063 s = ServicePtrs[snum];
3065 init_printer_values( s );
3071 /***************************************************************************
3072 Initialise a copymap.
3073 ***************************************************************************/
3075 static void init_copymap(struct loadparm_service *pservice)
3079 TALLOC_FREE(pservice->copymap);
3081 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
3082 if (!pservice->copymap)
3084 ("Couldn't allocate copymap!! (size %d)\n",
3085 (int)NUMPARAMETERS));
3087 for (i = 0; i < NUMPARAMETERS; i++)
3088 bitmap_set(pservice->copymap, i);
3092 return the parameter pointer for a parameter
3094 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
3096 if (service == NULL) {
3097 if (parm->p_class == P_LOCAL)
3098 return (void *)(((char *)&sDefault)+parm->offset);
3099 else if (parm->p_class == P_GLOBAL)
3100 return (void *)(((char *)&Globals)+parm->offset);
3103 return (void *)(((char *)service) + parm->offset);
3107 /***************************************************************************
3108 Return the local pointer to a parameter given the service number and parameter
3109 ***************************************************************************/
3111 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
3113 return lp_parm_ptr(ServicePtrs[snum], parm);
3116 /***************************************************************************
3117 Process a parameter for a particular service number. If snum < 0
3118 then assume we are in the globals.
3119 ***************************************************************************/
3121 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3124 void *parm_ptr = NULL; /* where we are going to store the result */
3125 struct parmlist_entry **opt_list;
3127 parmnum = map_parameter(pszParmName);
3130 if (strchr(pszParmName, ':') == NULL) {
3131 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
3137 * We've got a parametric option
3140 opt_list = (snum < 0)
3141 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
3142 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
3147 /* if it's already been set by the command line, then we don't
3149 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
3153 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3154 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3158 /* we might point at a service, the default service or a global */
3160 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
3162 if (parm_table[parmnum].p_class == P_GLOBAL) {
3164 ("Global parameter %s found in service section!\n",
3168 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
3172 if (!ServicePtrs[snum]->copymap)
3173 init_copymap(ServicePtrs[snum]);
3175 /* this handles the aliases - set the copymap for other entries with
3176 the same data pointer */
3177 for (i = 0; parm_table[i].label; i++) {
3178 if ((parm_table[i].offset == parm_table[parmnum].offset)
3179 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
3180 bitmap_clear(ServicePtrs[snum]->copymap, i);
3185 /* if it is a special case then go ahead */
3186 if (parm_table[parmnum].special) {
3187 return parm_table[parmnum].special(NULL, snum, pszParmValue,
3191 /* now switch on the type of variable it is */
3192 switch (parm_table[parmnum].type)
3195 *(bool *)parm_ptr = lp_bool(pszParmValue);
3199 *(bool *)parm_ptr = !lp_bool(pszParmValue);
3203 *(int *)parm_ptr = lp_int(pszParmValue);
3207 *(char *)parm_ptr = *pszParmValue;
3211 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3213 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3220 if (conv_str_size_error(pszParmValue, &val)) {
3221 if (val <= INT_MAX) {
3222 *(int *)parm_ptr = (int)val;
3227 DEBUG(0,("lp_do_parameter(%s): value is not "
3228 "a valid size specifier!\n", pszParmValue));
3234 TALLOC_FREE(*((char ***)parm_ptr));
3235 *(char ***)parm_ptr = str_list_make_v3(
3236 NULL, pszParmValue, NULL);
3240 string_set((char **)parm_ptr, pszParmValue);
3245 char *upper_string = strupper_talloc(talloc_tos(),
3247 string_set((char **)parm_ptr, upper_string);
3248 TALLOC_FREE(upper_string);
3252 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3261 /***************************************************************************
3262 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
3263 FLAG_CMDLINE won't be overridden by loads from smb.conf.
3264 ***************************************************************************/
3266 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
3269 parmnum = map_parameter(pszParmName);
3271 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
3272 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
3275 parm_table[parmnum].flags |= FLAG_CMDLINE;
3277 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
3278 * be grouped in the table, so we don't have to search the
3281 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
3282 && parm_table[i].p_class == parm_table[parmnum].p_class;
3284 parm_table[i].flags |= FLAG_CMDLINE;
3286 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
3287 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
3288 parm_table[i].flags |= FLAG_CMDLINE;
3292 store_lp_set_cmdline(pszParmName, pszParmValue);
3297 /* it might be parametric */
3298 if (strchr(pszParmName, ':') != NULL) {
3299 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
3301 store_lp_set_cmdline(pszParmName, pszParmValue);
3306 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3310 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
3312 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
3315 /***************************************************************************
3316 Process a parameter.
3317 ***************************************************************************/
3319 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
3322 if (!bInGlobalSection && bGlobalOnly)
3325 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3327 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3328 pszParmName, pszParmValue));
3332 set a option from the commandline in 'a=b' format. Use to support --option
3334 bool lp_set_option(const char *option)
3339 s = talloc_strdup(NULL, option);
3352 /* skip white spaces after the = sign */
3355 } while (*p == ' ');
3357 ret = lp_set_cmdline(s, p);
3362 /**************************************************************************
3363 Print a parameter of the specified type.
3364 ***************************************************************************/
3366 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3368 /* For the seperation of lists values that we print below */
3369 const char *list_sep = ", ";
3374 for (i = 0; p->enum_list[i].name; i++) {
3375 if (*(int *)ptr == p->enum_list[i].value) {
3377 p->enum_list[i].name);
3384 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
3388 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
3393 fprintf(f, "%d", *(int *)ptr);
3397 fprintf(f, "%c", *(char *)ptr);
3401 int val = *(int *)ptr;
3405 fprintf(f, "0%o", val);
3414 if ((char ***)ptr && *(char ***)ptr) {
3415 char **list = *(char ***)ptr;
3416 for (; *list; list++) {
3417 /* surround strings with whitespace in double quotes */
3418 if (*(list+1) == NULL) {
3419 /* last item, no extra separator */
3422 if ( strchr_m( *list, ' ' ) ) {
3423 fprintf(f, "\"%s\"%s", *list, list_sep);
3425 fprintf(f, "%s%s", *list, list_sep);
3433 if (*(char **)ptr) {
3434 fprintf(f, "%s", *(char **)ptr);
3442 /***************************************************************************
3443 Check if two parameters are equal.
3444 ***************************************************************************/
3446 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
3451 return (*((bool *)ptr1) == *((bool *)ptr2));
3457 return (*((int *)ptr1) == *((int *)ptr2));
3460 return (*((char *)ptr1) == *((char *)ptr2));
3464 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
3469 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3474 return (p1 == p2 || strequal(p1, p2));
3482 /***************************************************************************
3483 Initialize any local variables in the sDefault table, after parsing a
3485 ***************************************************************************/
3487 static void init_locals(void)
3490 * We run this check once the [globals] is parsed, to force
3491 * the VFS objects and other per-share settings we need for
3492 * the standard way a AD DC is operated. We may change these
3493 * as our code evolves, which is why we force these settings.
3495 * We can't do this at the end of lp_load_ex(), as by that
3496 * point the services have been loaded and they will already
3497 * have "" as their vfs objects.
3499 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3500 const char **vfs_objects = lp_vfs_objects(-1);
3501 if (!vfs_objects || !vfs_objects[0]) {
3502 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
3503 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3504 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
3505 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3507 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3511 lp_do_parameter(-1, "map hidden", "no");
3512 lp_do_parameter(-1, "map system", "no");
3513 lp_do_parameter(-1, "map readonly", "no");
3514 lp_do_parameter(-1, "map archive", "no");
3515 lp_do_parameter(-1, "store dos attributes", "yes");
3519 /***************************************************************************
3520 Process a new section (service). At this stage all sections are services.
3521 Later we'll have special sections that permit server parameters to be set.
3522 Returns true on success, false on failure.
3523 ***************************************************************************/
3525 static bool do_section(const char *pszSectionName, void *userdata)
3528 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3529 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3532 /* if we were in a global section then do the local inits */
3533 if (bInGlobalSection && !isglobal)
3536 /* if we've just struck a global section, note the fact. */
3537 bInGlobalSection = isglobal;
3539 /* check for multiple global sections */
3540 if (bInGlobalSection) {
3541 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3545 if (!bInGlobalSection && bGlobalOnly)
3548 /* if we have a current service, tidy it up before moving on */
3551 if (iServiceIndex >= 0)
3552 bRetval = service_ok(iServiceIndex);
3554 /* if all is still well, move to the next record in the services array */
3556 /* We put this here to avoid an odd message order if messages are */
3557 /* issued by the post-processing of a previous section. */
3558 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3560 iServiceIndex = add_a_service(&sDefault, pszSectionName);
3561 if (iServiceIndex < 0) {
3562 DEBUG(0, ("Failed to add a new service\n"));
3565 /* Clean all parametric options for service */
3566 /* They will be added during parsing again */
3567 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
3574 /***************************************************************************
3575 Determine if a partcular base parameter is currentl set to the default value.
3576 ***************************************************************************/
3578 static bool is_default(int i)
3580 if (!defaults_saved)
3582 switch (parm_table[i].type) {
3585 return str_list_equal((const char **)parm_table[i].def.lvalue,
3586 *(const char ***)lp_parm_ptr(NULL,
3590 return strequal(parm_table[i].def.svalue,
3591 *(char **)lp_parm_ptr(NULL,
3595 return parm_table[i].def.bvalue ==
3596 *(bool *)lp_parm_ptr(NULL,
3599 return parm_table[i].def.cvalue ==
3600 *(char *)lp_parm_ptr(NULL,
3606 return parm_table[i].def.ivalue ==
3607 *(int *)lp_parm_ptr(NULL,
3615 /***************************************************************************
3616 Display the contents of the global structure.
3617 ***************************************************************************/
3619 static void dump_globals(FILE *f)
3622 struct parmlist_entry *data;
3624 fprintf(f, "[global]\n");
3626 for (i = 0; parm_table[i].label; i++)
3627 if (parm_table[i].p_class == P_GLOBAL &&
3628 !(parm_table[i].flags & FLAG_META) &&
3629 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
3630 if (defaults_saved && is_default(i))
3632 fprintf(f, "\t%s = ", parm_table[i].label);
3633 print_parameter(&parm_table[i], lp_parm_ptr(NULL,
3638 if (Globals.param_opt != NULL) {
3639 data = Globals.param_opt;
3641 fprintf(f, "\t%s = %s\n", data->key, data->value);
3648 /***************************************************************************
3649 Return true if a local parameter is currently set to the global default.
3650 ***************************************************************************/
3652 bool lp_is_default(int snum, struct parm_struct *parm)
3654 return equal_parameter(parm->type,
3655 lp_parm_ptr(ServicePtrs[snum], parm),
3656 lp_parm_ptr(NULL, parm));
3659 /***************************************************************************
3660 Display the contents of a single services record.
3661 ***************************************************************************/
3663 static void dump_a_service(struct loadparm_service *pService, FILE * f)
3666 struct parmlist_entry *data;
3668 if (pService != &sDefault)
3669 fprintf(f, "[%s]\n", pService->szService);
3671 for (i = 0; parm_table[i].label; i++) {
3673 if (parm_table[i].p_class == P_LOCAL &&
3674 !(parm_table[i].flags & FLAG_META) &&
3675 (*parm_table[i].label != '-') &&
3676 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
3678 if (pService == &sDefault) {
3679 if (defaults_saved && is_default(i))
3682 if (equal_parameter(parm_table[i].type,
3683 lp_parm_ptr(pService, &parm_table[i]),
3684 lp_parm_ptr(NULL, &parm_table[i])))
3688 fprintf(f, "\t%s = ", parm_table[i].label);
3689 print_parameter(&parm_table[i],
3690 lp_parm_ptr(pService, &parm_table[i]),
3696 if (pService->param_opt != NULL) {
3697 data = pService->param_opt;
3699 fprintf(f, "\t%s = %s\n", data->key, data->value);
3705 /***************************************************************************
3706 Display the contents of a parameter of a single services record.
3707 ***************************************************************************/
3709 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
3712 bool result = false;
3715 fstring local_parm_name;
3717 const char *parm_opt_value;
3719 /* check for parametrical option */
3720 fstrcpy( local_parm_name, parm_name);
3721 parm_opt = strchr( local_parm_name, ':');
3726 if (strlen(parm_opt)) {
3727 parm_opt_value = lp_parm_const_string( snum,
3728 local_parm_name, parm_opt, NULL);
3729 if (parm_opt_value) {
3730 printf( "%s\n", parm_opt_value);
3737 /* check for a key and print the value */
3744 for (i = 0; parm_table[i].label; i++) {
3745 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
3746 !(parm_table[i].flags & FLAG_META) &&
3747 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
3748 (*parm_table[i].label != '-') &&
3749 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
3754 ptr = lp_parm_ptr(NULL,
3757 ptr = lp_parm_ptr(ServicePtrs[snum],
3761 print_parameter(&parm_table[i],
3772 /***************************************************************************
3773 Return info about the requested parameter (given as a string).
3774 Return NULL when the string is not a valid parameter name.
3775 ***************************************************************************/
3777 struct parm_struct *lp_get_parameter(const char *param_name)
3779 int num = map_parameter(param_name);
3785 return &parm_table[num];
3788 /***************************************************************************
3789 Return info about the next parameter in a service.
3790 snum==GLOBAL_SECTION_SNUM gives the globals.
3791 Return NULL when out of parameters.
3792 ***************************************************************************/
3794 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3797 /* do the globals */
3798 for (; parm_table[*i].label; (*i)++) {
3799 if (parm_table[*i].p_class == P_SEPARATOR)
3800 return &parm_table[(*i)++];
3802 if ((*parm_table[*i].label == '-'))
3806 && (parm_table[*i].offset ==
3807 parm_table[(*i) - 1].offset)
3808 && (parm_table[*i].p_class ==
3809 parm_table[(*i) - 1].p_class))
3812 if (is_default(*i) && !allparameters)
3815 return &parm_table[(*i)++];
3818 struct loadparm_service *pService = ServicePtrs[snum];
3820 for (; parm_table[*i].label; (*i)++) {
3821 if (parm_table[*i].p_class == P_SEPARATOR)
3822 return &parm_table[(*i)++];
3824 if (parm_table[*i].p_class == P_LOCAL &&
3825 (*parm_table[*i].label != '-') &&
3827 (parm_table[*i].offset !=
3828 parm_table[(*i) - 1].offset)))
3830 if (allparameters ||
3831 !equal_parameter(parm_table[*i].type,
3832 lp_parm_ptr(pService,
3837 return &parm_table[(*i)++];
3848 /***************************************************************************
3849 Display the contents of a single copy structure.
3850 ***************************************************************************/
3851 static void dump_copy_map(bool *pcopymap)
3857 printf("\n\tNon-Copied parameters:\n");
3859 for (i = 0; parm_table[i].label; i++)
3860 if (parm_table[i].p_class == P_LOCAL &&
3861 parm_table[i].ptr && !pcopymap[i] &&
3862 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3864 printf("\t\t%s\n", parm_table[i].label);
3869 /***************************************************************************
3870 Return TRUE if the passed service number is within range.
3871 ***************************************************************************/
3873 bool lp_snum_ok(int iService)
3875 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3878 /***************************************************************************
3879 Auto-load some home services.
3880 ***************************************************************************/
3882 static void lp_add_auto_services(char *str)
3892 s = SMB_STRDUP(str);
3896 homes = lp_servicenumber(HOMES_NAME);
3898 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3899 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3902 if (lp_servicenumber(p) >= 0)
3905 home = get_user_home_dir(talloc_tos(), p);
3907 if (home && home[0] && homes >= 0)
3908 lp_add_home(p, homes, p, home);
3915 /***************************************************************************
3916 Auto-load one printer.
3917 ***************************************************************************/
3919 void lp_add_one_printer(const char *name, const char *comment,
3920 const char *location, void *pdata)
3922 int printers = lp_servicenumber(PRINTERS_NAME);
3925 if (lp_servicenumber(name) < 0) {
3926 lp_add_printer(name, printers);
3927 if ((i = lp_servicenumber(name)) >= 0) {
3928 string_set(&ServicePtrs[i]->comment, comment);
3929 ServicePtrs[i]->autoloaded = true;
3934 /***************************************************************************
3935 Have we loaded a services file yet?
3936 ***************************************************************************/
3938 bool lp_loaded(void)
3943 /***************************************************************************
3944 Unload unused services.
3945 ***************************************************************************/
3947 void lp_killunused(struct smbd_server_connection *sconn,
3948 bool (*snumused) (struct smbd_server_connection *, int))
3951 for (i = 0; i < iNumServices; i++) {
3955 /* don't kill autoloaded or usershare services */
3956 if ( ServicePtrs[i]->autoloaded ||
3957 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3961 if (!snumused || !snumused(sconn, i)) {
3962 free_service_byindex(i);
3968 * Kill all except autoloaded and usershare services - convenience wrapper
3970 void lp_kill_all_services(void)
3972 lp_killunused(NULL, NULL);
3975 /***************************************************************************
3977 ***************************************************************************/
3979 void lp_killservice(int iServiceIn)
3981 if (VALID(iServiceIn)) {
3982 free_service_byindex(iServiceIn);
3986 /***************************************************************************
3987 Save the curent values of all global and sDefault parameters into the
3988 defaults union. This allows testparm to show only the
3989 changed (ie. non-default) parameters.
3990 ***************************************************************************/
3992 static void lp_save_defaults(void)
3995 for (i = 0; parm_table[i].label; i++) {
3996 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3997 && parm_table[i].p_class == parm_table[i - 1].p_class)
3999 switch (parm_table[i].type) {
4002 parm_table[i].def.lvalue = str_list_copy(
4003 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
4007 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
4011 parm_table[i].def.bvalue =
4012 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
4015 parm_table[i].def.cvalue =
4016 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
4022 parm_table[i].def.ivalue =
4023 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
4029 defaults_saved = true;
4032 /***********************************************************
4033 If we should send plaintext/LANMAN passwords in the clinet
4034 ************************************************************/
4036 static void set_allowed_client_auth(void)
4038 if (Globals.bClientNTLMv2Auth) {
4039 Globals.bClientLanManAuth = false;
4041 if (!Globals.bClientLanManAuth) {
4042 Globals.bClientPlaintextAuth = false;
4046 /***************************************************************************
4048 The following code allows smbd to read a user defined share file.
4049 Yes, this is my intent. Yes, I'm comfortable with that...
4051 THE FOLLOWING IS SECURITY CRITICAL CODE.
4053 It washes your clothes, it cleans your house, it guards you while you sleep...
4054 Do not f%^k with it....
4055 ***************************************************************************/
4057 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4059 /***************************************************************************
4060 Check allowed stat state of a usershare file.
4061 Ensure we print out who is dicking with us so the admin can
4062 get their sorry ass fired.
4063 ***************************************************************************/
4065 static bool check_usershare_stat(const char *fname,
4066 const SMB_STRUCT_STAT *psbuf)
4068 if (!S_ISREG(psbuf->st_ex_mode)) {
4069 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4070 "not a regular file\n",
4071 fname, (unsigned int)psbuf->st_ex_uid ));
4075 /* Ensure this doesn't have the other write bit set. */
4076 if (psbuf->st_ex_mode & S_IWOTH) {
4077 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4078 "public write. Refusing to allow as a usershare file.\n",
4079 fname, (unsigned int)psbuf->st_ex_uid ));
4083 /* Should be 10k or less. */
4084 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
4085 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4086 "too large (%u) to be a user share file.\n",
4087 fname, (unsigned int)psbuf->st_ex_uid,
4088 (unsigned int)psbuf->st_ex_size ));
4095 /***************************************************************************
4096 Parse the contents of a usershare file.
4097 ***************************************************************************/
4099 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4100 SMB_STRUCT_STAT *psbuf,
4101 const char *servicename,
4105 char **pp_sharepath,
4107 char **pp_cp_servicename,
4108 struct security_descriptor **ppsd,
4111 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4112 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4115 SMB_STRUCT_STAT sbuf;
4116 char *sharepath = NULL;
4117 char *comment = NULL;
4119 *pp_sharepath = NULL;
4122 *pallow_guest = false;
4125 return USERSHARE_MALFORMED_FILE;
4128 if (strcmp(lines[0], "#VERSION 1") == 0) {
4130 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4133 return USERSHARE_MALFORMED_FILE;
4136 return USERSHARE_BAD_VERSION;
4139 if (strncmp(lines[1], "path=", 5) != 0) {
4140 return USERSHARE_MALFORMED_PATH;
4143 sharepath = talloc_strdup(ctx, &lines[1][5]);
4145 return USERSHARE_POSIX_ERR;
4147 trim_string(sharepath, " ", " ");
4149 if (strncmp(lines[2], "comment=", 8) != 0) {
4150 return USERSHARE_MALFORMED_COMMENT_DEF;
4153 comment = talloc_strdup(ctx, &lines[2][8]);
4155 return USERSHARE_POSIX_ERR;
4157 trim_string(comment, " ", " ");
4158 trim_char(comment, '"', '"');
4160 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4161 return USERSHARE_MALFORMED_ACL_DEF;
4164 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4165 return USERSHARE_ACL_ERR;
4169 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4170 return USERSHARE_MALFORMED_ACL_DEF;
4172 if (lines[4][9] == 'y') {
4173 *pallow_guest = true;
4176 /* Backwards compatible extension to file version #2. */
4178 if (strncmp(lines[5], "sharename=", 10) != 0) {
4179 return USERSHARE_MALFORMED_SHARENAME_DEF;
4181 if (!strequal(&lines[5][10], servicename)) {
4182 return USERSHARE_BAD_SHARENAME;
4184 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
4185 if (!*pp_cp_servicename) {
4186 return USERSHARE_POSIX_ERR;
4191 if (*pp_cp_servicename == NULL) {
4192 *pp_cp_servicename = talloc_strdup(ctx, servicename);
4193 if (!*pp_cp_servicename) {
4194 return USERSHARE_POSIX_ERR;
4198 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4199 /* Path didn't change, no checks needed. */
4200 *pp_sharepath = sharepath;
4201 *pp_comment = comment;
4202 return USERSHARE_OK;
4205 /* The path *must* be absolute. */
4206 if (sharepath[0] != '/') {
4207 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4208 servicename, sharepath));
4209 return USERSHARE_PATH_NOT_ABSOLUTE;
4212 /* If there is a usershare prefix deny list ensure one of these paths
4213 doesn't match the start of the user given path. */
4214 if (prefixdenylist) {
4216 for ( i=0; prefixdenylist[i]; i++ ) {
4217 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4218 servicename, i, prefixdenylist[i], sharepath ));
4219 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4220 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4221 "usershare prefix deny list entries.\n",
4222 servicename, sharepath));
4223 return USERSHARE_PATH_IS_DENIED;
4228 /* If there is a usershare prefix allow list ensure one of these paths
4229 does match the start of the user given path. */
4231 if (prefixallowlist) {
4233 for ( i=0; prefixallowlist[i]; i++ ) {
4234 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4235 servicename, i, prefixallowlist[i], sharepath ));
4236 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4240 if (prefixallowlist[i] == NULL) {
4241 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4242 "usershare prefix allow list entries.\n",
4243 servicename, sharepath));
4244 return USERSHARE_PATH_NOT_ALLOWED;
4248 /* Ensure this is pointing to a directory. */
4249 dp = opendir(sharepath);
4252 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4253 servicename, sharepath));
4254 return USERSHARE_PATH_NOT_DIRECTORY;
4257 /* Ensure the owner of the usershare file has permission to share
4260 if (sys_stat(sharepath, &sbuf, false) == -1) {
4261 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4262 servicename, sharepath, strerror(errno) ));
4264 return USERSHARE_POSIX_ERR;
4269 if (!S_ISDIR(sbuf.st_ex_mode)) {
4270 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4271 servicename, sharepath ));
4272 return USERSHARE_PATH_NOT_DIRECTORY;
4275 /* Check if sharing is restricted to owner-only. */
4276 /* psbuf is the stat of the usershare definition file,
4277 sbuf is the stat of the target directory to be shared. */
4279 if (lp_usershare_owner_only()) {
4280 /* root can share anything. */
4281 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
4282 return USERSHARE_PATH_NOT_ALLOWED;
4286 *pp_sharepath = sharepath;
4287 *pp_comment = comment;
4288 return USERSHARE_OK;
4291 /***************************************************************************
4292 Deal with a usershare file.
4295 -1 - Bad name, invalid contents.
4296 - service name already existed and not a usershare, problem
4297 with permissions to share directory etc.
4298 ***************************************************************************/
4300 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4302 SMB_STRUCT_STAT sbuf;
4303 SMB_STRUCT_STAT lsbuf;
4305 char *sharepath = NULL;
4306 char *comment = NULL;
4307 char *cp_service_name = NULL;
4308 char **lines = NULL;
4312 TALLOC_CTX *ctx = talloc_stackframe();
4313 struct security_descriptor *psd = NULL;
4314 bool guest_ok = false;
4315 char *canon_name = NULL;
4316 bool added_service = false;
4319 /* Ensure share name doesn't contain invalid characters. */
4320 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4321 DEBUG(0,("process_usershare_file: share name %s contains "
4322 "invalid characters (any of %s)\n",
4323 file_name, INVALID_SHARENAME_CHARS ));
4327 canon_name = canonicalize_servicename(ctx, file_name);
4332 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
4337 /* Minimize the race condition by doing an lstat before we
4338 open and fstat. Ensure this isn't a symlink link. */
4340 if (sys_lstat(fname, &lsbuf, false) != 0) {
4341 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4342 fname, strerror(errno) ));
4346 /* This must be a regular file, not a symlink, directory or
4347 other strange filetype. */
4348 if (!check_usershare_stat(fname, &lsbuf)) {
4356 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
4361 if (NT_STATUS_IS_OK(status) &&
4362 (data.dptr != NULL) &&
4363 (data.dsize == sizeof(iService))) {
4364 memcpy(&iService, data.dptr, sizeof(iService));
4368 if (iService != -1 &&
4369 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4370 &lsbuf.st_ex_mtime) == 0) {
4371 /* Nothing changed - Mark valid and return. */
4372 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4374 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4379 /* Try and open the file read only - no symlinks allowed. */
4381 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
4383 fd = open(fname, O_RDONLY, 0);
4387 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4388 fname, strerror(errno) ));
4392 /* Now fstat to be *SURE* it's a regular file. */
4393 if (sys_fstat(fd, &sbuf, false) != 0) {
4395 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4396 fname, strerror(errno) ));
4400 /* Is it the same dev/inode as was lstated ? */
4401 if (!check_same_stat(&lsbuf, &sbuf)) {
4403 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4404 "Symlink spoofing going on ?\n", fname ));
4408 /* This must be a regular file, not a symlink, directory or
4409 other strange filetype. */
4410 if (!check_usershare_stat(fname, &sbuf)) {
4415 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
4418 if (lines == NULL) {
4419 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4420 fname, (unsigned int)sbuf.st_ex_uid ));
4424 if (parse_usershare_file(ctx, &sbuf, file_name,
4425 iService, lines, numlines, &sharepath,
4426 &comment, &cp_service_name,
4427 &psd, &guest_ok) != USERSHARE_OK) {
4431 /* Everything ok - add the service possibly using a template. */
4433 const struct loadparm_service *sp = &sDefault;
4434 if (snum_template != -1) {
4435 sp = ServicePtrs[snum_template];
4438 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
4439 DEBUG(0, ("process_usershare_file: Failed to add "
4440 "new service %s\n", cp_service_name));
4444 added_service = true;
4446 /* Read only is controlled by usershare ACL below. */
4447 ServicePtrs[iService]->bRead_only = false;
4450 /* Write the ACL of the new/modified share. */
4451 if (!set_share_security(canon_name, psd)) {
4452 DEBUG(0, ("process_usershare_file: Failed to set share "
4453 "security for user share %s\n",
4458 /* If from a template it may be marked invalid. */
4459 ServicePtrs[iService]->valid = true;
4461 /* Set the service as a valid usershare. */
4462 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4464 /* Set guest access. */
4465 if (lp_usershare_allow_guests()) {
4466 ServicePtrs[iService]->bGuest_ok = guest_ok;
4469 /* And note when it was loaded. */
4470 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
4471 string_set(&ServicePtrs[iService]->szPath, sharepath);
4472 string_set(&ServicePtrs[iService]->comment, comment);
4478 if (ret == -1 && iService != -1 && added_service) {
4479 lp_remove_service(iService);
4487 /***************************************************************************
4488 Checks if a usershare entry has been modified since last load.
4489 ***************************************************************************/
4491 static bool usershare_exists(int iService, struct timespec *last_mod)
4493 SMB_STRUCT_STAT lsbuf;
4494 const char *usersharepath = Globals.szUsersharePath;
4497 if (asprintf(&fname, "%s/%s",
4499 ServicePtrs[iService]->szService) < 0) {
4503 if (sys_lstat(fname, &lsbuf, false) != 0) {
4508 if (!S_ISREG(lsbuf.st_ex_mode)) {
4514 *last_mod = lsbuf.st_ex_mtime;
4518 /***************************************************************************
4519 Load a usershare service by name. Returns a valid servicenumber or -1.
4520 ***************************************************************************/
4522 int load_usershare_service(const char *servicename)
4524 SMB_STRUCT_STAT sbuf;
4525 const char *usersharepath = Globals.szUsersharePath;
4526 int max_user_shares = Globals.iUsershareMaxShares;
4527 int snum_template = -1;
4529 if (*usersharepath == 0 || max_user_shares == 0) {
4533 if (sys_stat(usersharepath, &sbuf, false) != 0) {
4534 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4535 usersharepath, strerror(errno) ));
4539 if (!S_ISDIR(sbuf.st_ex_mode)) {
4540 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4546 * This directory must be owned by root, and have the 't' bit set.
4547 * It also must not be writable by "other".
4551 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4553 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4555 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4556 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4561 /* Ensure the template share exists if it's set. */
4562 if (Globals.szUsershareTemplateShare[0]) {
4563 /* We can't use lp_servicenumber here as we are recommending that
4564 template shares have -valid=false set. */
4565 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4566 if (ServicePtrs[snum_template]->szService &&
4567 strequal(ServicePtrs[snum_template]->szService,
4568 Globals.szUsershareTemplateShare)) {
4573 if (snum_template == -1) {
4574 DEBUG(0,("load_usershare_service: usershare template share %s "
4575 "does not exist.\n",
4576 Globals.szUsershareTemplateShare ));
4581 return process_usershare_file(usersharepath, servicename, snum_template);
4584 /***************************************************************************
4585 Load all user defined shares from the user share directory.
4586 We only do this if we're enumerating the share list.
4587 This is the function that can delete usershares that have
4589 ***************************************************************************/
4591 int load_usershare_shares(struct smbd_server_connection *sconn,
4592 bool (*snumused) (struct smbd_server_connection *, int))
4595 SMB_STRUCT_STAT sbuf;
4597 int num_usershares = 0;
4598 int max_user_shares = Globals.iUsershareMaxShares;
4599 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4600 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4601 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4603 int snum_template = -1;
4604 const char *usersharepath = Globals.szUsersharePath;
4605 int ret = lp_numservices();
4606 TALLOC_CTX *tmp_ctx;
4608 if (max_user_shares == 0 || *usersharepath == '\0') {
4609 return lp_numservices();
4612 if (sys_stat(usersharepath, &sbuf, false) != 0) {
4613 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4614 usersharepath, strerror(errno) ));
4619 * This directory must be owned by root, and have the 't' bit set.
4620 * It also must not be writable by "other".
4624 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4626 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4628 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4629 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4634 /* Ensure the template share exists if it's set. */
4635 if (Globals.szUsershareTemplateShare[0]) {
4636 /* We can't use lp_servicenumber here as we are recommending that
4637 template shares have -valid=false set. */
4638 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4639 if (ServicePtrs[snum_template]->szService &&
4640 strequal(ServicePtrs[snum_template]->szService,
4641 Globals.szUsershareTemplateShare)) {
4646 if (snum_template == -1) {
4647 DEBUG(0,("load_usershare_shares: usershare template share %s "
4648 "does not exist.\n",
4649 Globals.szUsershareTemplateShare ));
4654 /* Mark all existing usershares as pending delete. */
4655 for (iService = iNumServices - 1; iService >= 0; iService--) {
4656 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4657 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4661 dp = opendir(usersharepath);
4663 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4664 usersharepath, strerror(errno) ));
4668 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4670 num_dir_entries++ ) {
4672 const char *n = de->d_name;
4674 /* Ignore . and .. */
4676 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4682 /* Temporary file used when creating a share. */
4683 num_tmp_dir_entries++;
4686 /* Allow 20% tmp entries. */
4687 if (num_tmp_dir_entries > allowed_tmp_entries) {
4688 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4689 "in directory %s\n",
4690 num_tmp_dir_entries, usersharepath));
4694 r = process_usershare_file(usersharepath, n, snum_template);
4696 /* Update the services count. */
4698 if (num_usershares >= max_user_shares) {
4699 DEBUG(0,("load_usershare_shares: max user shares reached "
4700 "on file %s in directory %s\n",
4701 n, usersharepath ));
4704 } else if (r == -1) {
4705 num_bad_dir_entries++;
4708 /* Allow 20% bad entries. */
4709 if (num_bad_dir_entries > allowed_bad_entries) {
4710 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4711 "in directory %s\n",
4712 num_bad_dir_entries, usersharepath));
4716 /* Allow 20% bad entries. */
4717 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4718 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4719 "in directory %s\n",
4720 num_dir_entries, usersharepath));
4727 /* Sweep through and delete any non-refreshed usershares that are
4728 not currently in use. */
4729 tmp_ctx = talloc_stackframe();
4730 for (iService = iNumServices - 1; iService >= 0; iService--) {
4731 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4734 if (snumused && snumused(sconn, iService)) {
4738 servname = lp_servicename(tmp_ctx, iService);
4740 /* Remove from the share ACL db. */
4741 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4743 delete_share_security(servname);
4744 free_service_byindex(iService);
4747 talloc_free(tmp_ctx);
4749 return lp_numservices();
4752 /********************************************************
4753 Destroy global resources allocated in this file
4754 ********************************************************/
4756 void gfree_loadparm(void)
4762 /* Free resources allocated to services */
4764 for ( i = 0; i < iNumServices; i++ ) {
4766 free_service_byindex(i);
4770 SAFE_FREE( ServicePtrs );
4773 /* Now release all resources allocated to global
4774 parameters and the default service */
4776 free_global_parameters();
4780 /***************************************************************************
4781 Allow client apps to specify that they are a client
4782 ***************************************************************************/
4783 static void lp_set_in_client(bool b)
4789 /***************************************************************************
4790 Determine if we're running in a client app
4791 ***************************************************************************/
4792 static bool lp_is_in_client(void)
4797 /***************************************************************************
4798 Load the services array from the services file. Return true on success,
4800 ***************************************************************************/
4802 static bool lp_load_ex(const char *pszFname,
4806 bool initialize_globals,
4807 bool allow_include_registry,
4808 bool load_all_shares)
4815 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4817 bInGlobalSection = true;
4818 bGlobalOnly = global_only;
4819 bAllowIncludeRegistry = allow_include_registry;
4821 init_globals(initialize_globals);
4825 if (save_defaults) {
4830 if (!initialize_globals) {
4831 free_param_opts(&Globals.param_opt);
4832 apply_lp_set_cmdline();
4835 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
4837 /* We get sections first, so have to start 'behind' to make up */
4840 if (lp_config_backend_is_file()) {
4841 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4842 current_user_info.domain,
4845 smb_panic("lp_load_ex: out of memory");
4848 add_to_file_list(pszFname, n2);
4850 bRetval = pm_process(n2, do_section, do_parameter, NULL);
4853 /* finish up the last section */
4854 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4856 if (iServiceIndex >= 0) {
4857 bRetval = service_ok(iServiceIndex);
4861 if (lp_config_backend_is_registry()) {
4862 /* config backend changed to registry in config file */
4864 * We need to use this extra global variable here to
4865 * survive restart: init_globals uses this as a default
4866 * for ConfigBackend. Otherwise, init_globals would
4867 * send us into an endless loop here.
4869 config_backend = CONFIG_BACKEND_REGISTRY;
4871 DEBUG(1, ("lp_load_ex: changing to config backend "
4874 lp_kill_all_services();
4875 return lp_load_ex(pszFname, global_only, save_defaults,
4876 add_ipc, initialize_globals,
4877 allow_include_registry,
4880 } else if (lp_config_backend_is_registry()) {
4881 bRetval = process_registry_globals();
4883 DEBUG(0, ("Illegal config backend given: %d\n",
4884 lp_config_backend()));
4888 if (bRetval && lp_registry_shares()) {
4889 if (load_all_shares) {
4890 bRetval = process_registry_shares();
4892 bRetval = reload_registry_shares();
4897 char *serv = lp_auto_services(talloc_tos());
4898 lp_add_auto_services(serv);
4903 /* When 'restrict anonymous = 2' guest connections to ipc$
4905 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4906 if ( lp_enable_asu_support() ) {
4907 lp_add_ipc("ADMIN$", false);
4911 set_allowed_client_auth();
4913 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
4914 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4915 lp_passwordserver()));
4920 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
4921 /* if bWINSsupport is true and we are in the client */
4922 if (lp_is_in_client() && Globals.bWINSsupport) {
4923 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4928 fault_configure(smb_panic_s3);
4931 * We run this check once the whole smb.conf is parsed, to
4932 * force some settings for the standard way a AD DC is
4933 * operated. We may changed these as our code evolves, which
4934 * is why we force these settings.
4936 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4937 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4939 lp_do_parameter(-1, "rpc_server:default", "external");
4940 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4941 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4942 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4943 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4944 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4945 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4946 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4947 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4950 bAllowIncludeRegistry = true;
4955 bool lp_load(const char *pszFname,
4959 bool initialize_globals)
4961 return lp_load_ex(pszFname,
4966 true, /* allow_include_registry */
4967 false); /* load_all_shares*/
4970 bool lp_load_initial_only(const char *pszFname)
4972 return lp_load_ex(pszFname,
4973 true, /* global only */
4974 false, /* save_defaults */
4975 false, /* add_ipc */
4976 true, /* initialize_globals */
4977 false, /* allow_include_registry */
4978 false); /* load_all_shares*/
4982 * most common lp_load wrapper, loading only the globals
4984 bool lp_load_global(const char *file_name)
4986 return lp_load_ex(file_name,
4987 true, /* global_only */
4988 false, /* save_defaults */
4989 false, /* add_ipc */
4990 true, /* initialize_globals */
4991 true, /* allow_include_registry */
4992 false); /* load_all_shares*/
4996 * lp_load wrapper, especially for clients
4998 bool lp_load_client(const char *file_name)
5000 lp_set_in_client(true);
5002 return lp_load_global(file_name);
5006 * lp_load wrapper, loading only globals, but intended
5007 * for subsequent calls, not reinitializing the globals
5010 bool lp_load_global_no_reinit(const char *file_name)
5012 return lp_load_ex(file_name,
5013 true, /* global_only */
5014 false, /* save_defaults */
5015 false, /* add_ipc */
5016 false, /* initialize_globals */
5017 true, /* allow_include_registry */
5018 false); /* load_all_shares*/
5022 * lp_load wrapper, especially for clients, no reinitialization
5024 bool lp_load_client_no_reinit(const char *file_name)
5026 lp_set_in_client(true);
5028 return lp_load_global_no_reinit(file_name);
5031 bool lp_load_with_registry_shares(const char *pszFname,
5035 bool initialize_globals)
5037 return lp_load_ex(pszFname,
5042 true, /* allow_include_registry */
5043 true); /* load_all_shares*/
5046 /***************************************************************************
5047 Return the max number of services.
5048 ***************************************************************************/
5050 int lp_numservices(void)
5052 return (iNumServices);
5055 /***************************************************************************
5056 Display the contents of the services array in human-readable form.
5057 ***************************************************************************/
5059 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
5064 defaults_saved = false;
5068 dump_a_service(&sDefault, f);
5070 for (iService = 0; iService < maxtoprint; iService++) {
5072 lp_dump_one(f, show_defaults, iService);
5076 /***************************************************************************
5077 Display the contents of one service in human-readable form.
5078 ***************************************************************************/
5080 void lp_dump_one(FILE * f, bool show_defaults, int snum)
5083 if (ServicePtrs[snum]->szService[0] == '\0')
5085 dump_a_service(ServicePtrs[snum], f);
5089 /***************************************************************************
5090 Return the number of the service with the given name, or -1 if it doesn't
5091 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5092 getservicebyname()! This works ONLY if all services have been loaded, and
5093 does not copy the found service.
5094 ***************************************************************************/
5096 int lp_servicenumber(const char *pszServiceName)
5099 fstring serviceName;
5101 if (!pszServiceName) {
5102 return GLOBAL_SECTION_SNUM;
5105 for (iService = iNumServices - 1; iService >= 0; iService--) {
5106 if (VALID(iService) && ServicePtrs[iService]->szService) {
5108 * The substitution here is used to support %U is
5111 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5112 standard_sub_basic(get_current_username(),
5113 current_user_info.domain,
5114 serviceName,sizeof(serviceName));
5115 if (strequal(serviceName, pszServiceName)) {
5121 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5122 struct timespec last_mod;
5124 if (!usershare_exists(iService, &last_mod)) {
5125 /* Remove the share security tdb entry for it. */
5126 delete_share_security(lp_servicename(talloc_tos(), iService));
5127 /* Remove it from the array. */
5128 free_service_byindex(iService);
5129 /* Doesn't exist anymore. */
5130 return GLOBAL_SECTION_SNUM;
5133 /* Has it been modified ? If so delete and reload. */
5134 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
5136 /* Remove it from the array. */
5137 free_service_byindex(iService);
5138 /* and now reload it. */
5139 iService = load_usershare_service(pszServiceName);
5144 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5145 return GLOBAL_SECTION_SNUM;
5151 /*******************************************************************
5152 A useful volume label function.
5153 ********************************************************************/
5155 const char *volume_label(TALLOC_CTX *ctx, int snum)
5158 const char *label = lp_volume(ctx, snum);
5160 label = lp_servicename(ctx, snum);
5163 /* This returns a 33 byte guarenteed null terminated string. */
5164 ret = talloc_strndup(ctx, label, 32);
5171 /*******************************************************************
5172 Get the default server type we will announce as via nmbd.
5173 ********************************************************************/
5175 int lp_default_server_announce(void)
5177 int default_server_announce = 0;
5178 default_server_announce |= SV_TYPE_WORKSTATION;
5179 default_server_announce |= SV_TYPE_SERVER;
5180 default_server_announce |= SV_TYPE_SERVER_UNIX;
5182 /* note that the flag should be set only if we have a
5183 printer service but nmbd doesn't actually load the
5184 services so we can't tell --jerry */
5186 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5188 default_server_announce |= SV_TYPE_SERVER_NT;
5189 default_server_announce |= SV_TYPE_NT;
5191 switch (lp_server_role()) {
5192 case ROLE_DOMAIN_MEMBER:
5193 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5195 case ROLE_DOMAIN_PDC:
5196 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5198 case ROLE_DOMAIN_BDC:
5199 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5201 case ROLE_STANDALONE:
5205 if (lp_time_server())
5206 default_server_announce |= SV_TYPE_TIME_SOURCE;
5208 if (lp_host_msdfs())
5209 default_server_announce |= SV_TYPE_DFS_SERVER;
5211 return default_server_announce;
5214 /***********************************************************
5215 If we are PDC then prefer us as DMB
5216 ************************************************************/
5218 bool lp_domain_master(void)
5220 if (Globals.domain_master == Auto)
5221 return (lp_server_role() == ROLE_DOMAIN_PDC);
5223 return (bool)Globals.domain_master;
5226 /***********************************************************
5227 If we are PDC then prefer us as DMB
5228 ************************************************************/
5230 static bool lp_domain_master_true_or_auto(void)
5232 if (Globals.domain_master) /* auto or yes */
5238 /***********************************************************
5239 If we are DMB then prefer us as LMB
5240 ************************************************************/
5242 bool lp_preferred_master(void)
5244 if (Globals.iPreferredMaster == Auto)
5245 return (lp_local_master() && lp_domain_master());
5247 return (bool)Globals.iPreferredMaster;
5250 /*******************************************************************
5252 ********************************************************************/
5254 void lp_remove_service(int snum)
5256 ServicePtrs[snum]->valid = false;
5259 /*******************************************************************
5261 ********************************************************************/
5263 void lp_copy_service(int snum, const char *new_name)
5265 do_section(new_name, NULL);
5267 snum = lp_servicenumber(new_name);
5269 char *name = lp_servicename(talloc_tos(), snum);
5270 lp_do_parameter(snum, "copy", name);
5275 const char *lp_printername(TALLOC_CTX *ctx, int snum)
5277 const char *ret = lp__printername(talloc_tos(), snum);
5278 if (ret == NULL || *ret == '\0') {
5279 ret = lp_const_servicename(snum);
5286 /***********************************************************
5287 Allow daemons such as winbindd to fix their logfile name.
5288 ************************************************************/
5290 void lp_set_logfile(const char *name)
5292 string_set(&Globals.logfile, name);
5293 debug_set_logfile(name);
5296 /*******************************************************************
5297 Return the max print jobs per queue.
5298 ********************************************************************/
5300 int lp_maxprintjobs(int snum)
5302 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5303 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5304 maxjobs = PRINT_MAX_JOBID - 1;
5309 const char *lp_printcapname(void)
5311 if ((Globals.szPrintcapname != NULL) &&
5312 (Globals.szPrintcapname[0] != '\0'))
5313 return Globals.szPrintcapname;
5315 if (sDefault.iPrinting == PRINT_CUPS) {
5319 if (sDefault.iPrinting == PRINT_BSD)
5320 return "/etc/printcap";
5322 return PRINTCAP_NAME;
5325 static uint32 spoolss_state;
5327 bool lp_disable_spoolss( void )
5329 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5330 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5332 return spoolss_state == SVCCTL_STOPPED ? true : false;
5335 void lp_set_spoolss_state( uint32 state )
5337 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5339 spoolss_state = state;
5342 uint32 lp_get_spoolss_state( void )
5344 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5347 /*******************************************************************
5348 Ensure we don't use sendfile if server smb signing is active.
5349 ********************************************************************/
5351 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
5353 bool sign_active = false;
5355 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5356 if (get_Protocol() < PROTOCOL_NT1) {
5359 if (signing_state) {
5360 sign_active = smb_signing_is_active(signing_state);
5362 return (lp__use_sendfile(snum) &&
5363 (get_remote_arch() != RA_WIN95) &&
5367 /*******************************************************************
5368 Turn off sendfile if we find the underlying OS doesn't support it.
5369 ********************************************************************/
5371 void set_use_sendfile(int snum, bool val)
5373 if (LP_SNUM_OK(snum))
5374 ServicePtrs[snum]->bUseSendfile = val;
5376 sDefault.bUseSendfile = val;
5379 /*******************************************************************
5380 Turn off storing DOS attributes if this share doesn't support it.
5381 ********************************************************************/
5383 void set_store_dos_attributes(int snum, bool val)
5385 if (!LP_SNUM_OK(snum))
5387 ServicePtrs[(snum)]->bStoreDosAttributes = val;
5390 void lp_set_mangling_method(const char *new_method)
5392 string_set(&Globals.szManglingMethod, new_method);
5395 /*******************************************************************
5396 Global state for POSIX pathname processing.
5397 ********************************************************************/
5399 static bool posix_pathnames;
5401 bool lp_posix_pathnames(void)
5403 return posix_pathnames;
5406 /*******************************************************************
5407 Change everything needed to ensure POSIX pathname processing (currently
5409 ********************************************************************/
5411 void lp_set_posix_pathnames(void)
5413 posix_pathnames = true;
5416 /*******************************************************************
5417 Global state for POSIX lock processing - CIFS unix extensions.
5418 ********************************************************************/
5420 bool posix_default_lock_was_set;
5421 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5423 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5425 if (posix_default_lock_was_set) {
5426 return posix_cifsx_locktype;
5428 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5432 /*******************************************************************
5433 ********************************************************************/
5435 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5437 posix_default_lock_was_set = true;
5438 posix_cifsx_locktype = val;
5441 int lp_min_receive_file_size(void)
5443 if (Globals.iminreceivefile < 0) {
5446 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
5449 /*******************************************************************
5450 Safe wide links checks.
5451 This helper function always verify the validity of wide links,
5452 even after a configuration file reload.
5453 ********************************************************************/
5455 static bool lp_widelinks_internal(int snum)
5457 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
5458 sDefault.bWidelinks);
5461 void widelinks_warning(int snum)
5463 if (lp_allow_insecure_widelinks()) {
5467 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
5468 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
5469 "These parameters are incompatible. "
5470 "Wide links will be disabled for this share.\n",
5471 lp_servicename(talloc_tos(), snum) ));
5475 bool lp_widelinks(int snum)
5477 /* wide links is always incompatible with unix extensions */
5478 if (lp_unix_extensions()) {
5480 * Unless we have "allow insecure widelinks"
5483 if (!lp_allow_insecure_widelinks()) {
5488 return lp_widelinks_internal(snum);
5491 bool lp_writeraw(void)
5493 if (lp_async_smb_echo_handler()) {
5496 return lp__writeraw();
5499 bool lp_readraw(void)
5501 if (lp_async_smb_echo_handler()) {
5504 return lp__readraw();
5507 int lp_server_role(void)
5509 return lp_find_server_role(lp__server_role(),
5511 lp__domain_logons(),
5512 lp_domain_master_true_or_auto());
5515 int lp_security(void)
5517 return lp_find_security(lp__server_role(),