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"
60 #include "lib/smbconf/smbconf.h"
61 #include "lib/smbconf/smbconf_init.h"
62 #include "lib/param/loadparm.h"
65 #include "../librpc/gen_ndr/svcctl.h"
67 #include "smb_signing.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>
82 extern userdom_struct current_user_info;
84 /* the special value for the include parameter
85 * to be interpreted not as a file name but to
86 * trigger loading of the global smb.conf options
88 #ifndef INCLUDE_REGISTRY_NAME
89 #define INCLUDE_REGISTRY_NAME "registry"
92 static bool in_client = false; /* Not in the client by default */
93 static struct smbconf_csn conf_last_csn;
95 #define CONFIG_BACKEND_FILE 0
96 #define CONFIG_BACKEND_REGISTRY 1
98 static int config_backend = CONFIG_BACKEND_FILE;
100 /* some helpful bits */
101 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
102 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
104 #define USERSHARE_VALID 1
105 #define USERSHARE_PENDING_DELETE 2
107 static bool defaults_saved = false;
109 #define LOADPARM_EXTRA_GLOBALS \
110 struct parmlist_entry *param_opt; \
113 int iminreceivefile; \
114 char *szPrintcapname; \
116 int iPreferredMaster; \
118 char *szLdapMachineSuffix; \
119 char *szLdapUserSuffix; \
120 char *szLdapIdmapSuffix; \
121 char *szLdapGroupSuffix; \
124 char *szSocketAddress; \
125 char *szUsershareTemplateShare; \
128 int winbindMaxDomainConnections; \
129 int ismb2_max_credits;
131 #include "param/param_global.h"
133 static struct loadparm_global Globals;
135 /* This is a default service used to prime a services structure */
136 static struct loadparm_service sDefault =
141 .usershare_last_mod = {0, 0},
145 .szInvalidUsers = NULL,
146 .szValidUsers = NULL,
147 .szAdminUsers = NULL,
152 .szRootPreExec = NULL,
153 .szRootPostExec = NULL,
154 .szCupsOptions = NULL,
155 .szPrintcommand = NULL,
156 .szLpqcommand = NULL,
157 .szLprmcommand = NULL,
158 .szLppausecommand = NULL,
159 .szLpresumecommand = NULL,
160 .szQueuepausecommand = NULL,
161 .szQueueresumecommand = NULL,
162 .szPrintername = NULL,
163 .szPrintjobUsername = NULL,
164 .szDontdescend = NULL,
165 .szHostsallow = NULL,
167 .szMagicScript = NULL,
168 .szMagicOutput = NULL,
171 .szVetoOplockFiles = NULL,
177 .printer_admin = NULL,
180 .szVfsObjects = NULL,
181 .szMSDfsProxy = NULL,
182 .szAioWriteBehind = NULL,
185 .iMaxPrintJobs = 1000,
186 .iMaxReportedPrintJobs = 0,
187 .iWriteCacheSize = 0,
188 .iCreate_mask = 0744,
189 .iCreate_force_mode = 0,
190 .iSecurity_mask = 0777,
191 .iSecurity_force_mode = 0,
193 .iDir_force_mode = 0,
194 .iDir_Security_mask = 0777,
195 .iDir_Security_force_mode = 0,
196 .iMaxConnections = 0,
197 .iDefaultCase = CASE_LOWER,
198 .iPrinting = DEFAULT_PRINTING,
199 .iOplockContentionLimit = 2,
202 .iDfreeCacheTime = 0,
203 .bPreexecClose = false,
204 .bRootpreexecClose = false,
205 .iCaseSensitive = Auto,
206 .bCasePreserve = true,
207 .bShortCasePreserve = true,
208 .bHideDotFiles = true,
209 .bHideSpecialFiles = false,
210 .bHideUnReadable = false,
211 .bHideUnWriteableFiles = false,
213 .bAccessBasedShareEnum = false,
217 .bGuest_only = false,
218 .bAdministrative_share = false,
221 .bPrintNotifyBackchannel = true,
222 .bMap_system = false,
223 .bMap_hidden = false,
224 .bMap_archive = true,
225 .bStoreDosAttributes = false,
226 .bDmapiSupport = false,
228 .iStrictLocking = Auto,
229 .bPosixLocking = true,
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 .bChangeNotify = true,
268 .bKernelChangeNotify = true,
269 .iallocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
272 .iMap_readonly = MAP_READONLY_YES,
273 #ifdef BROKEN_DIRECTORY_HANDLING
274 .iDirectoryNameCacheSize = 0,
276 .iDirectoryNameCacheSize = 100,
278 .ismb_encrypt = Auto,
283 /* local variables */
284 static struct loadparm_service **ServicePtrs = NULL;
285 static int iNumServices = 0;
286 static int iServiceIndex = 0;
287 static struct db_context *ServiceHash;
288 static int *invalid_services = NULL;
289 static int num_invalid_services = 0;
290 static bool bInGlobalSection = true;
291 static bool bGlobalOnly = false;
293 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
295 /* prototypes for the special type handlers */
296 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
297 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
298 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
299 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
300 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
301 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
302 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
303 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
304 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
305 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
306 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
307 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
309 static void set_allowed_client_auth(void);
311 static void add_to_file_list(const char *fname, const char *subfname);
312 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
314 static const struct enum_list enum_protocol[] = {
315 {PROTOCOL_SMB2, "SMB2"},
316 {PROTOCOL_NT1, "NT1"},
317 {PROTOCOL_LANMAN2, "LANMAN2"},
318 {PROTOCOL_LANMAN1, "LANMAN1"},
319 {PROTOCOL_CORE, "CORE"},
320 {PROTOCOL_COREPLUS, "COREPLUS"},
321 {PROTOCOL_COREPLUS, "CORE+"},
325 static const struct enum_list enum_security[] = {
326 {SEC_SHARE, "SHARE"},
328 {SEC_SERVER, "SERVER"},
329 {SEC_DOMAIN, "DOMAIN"},
336 static const struct enum_list enum_printing[] = {
337 {PRINT_SYSV, "sysv"},
339 {PRINT_HPUX, "hpux"},
343 {PRINT_LPRNG, "lprng"},
344 {PRINT_CUPS, "cups"},
345 {PRINT_IPRINT, "iprint"},
347 {PRINT_LPROS2, "os2"},
348 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
349 {PRINT_TEST, "test"},
351 #endif /* DEVELOPER */
355 static const struct enum_list enum_ldap_sasl_wrapping[] = {
357 {ADS_AUTH_SASL_SIGN, "sign"},
358 {ADS_AUTH_SASL_SEAL, "seal"},
362 static const struct enum_list enum_ldap_ssl[] = {
363 {LDAP_SSL_OFF, "no"},
364 {LDAP_SSL_OFF, "off"},
365 {LDAP_SSL_START_TLS, "start tls"},
366 {LDAP_SSL_START_TLS, "start_tls"},
370 /* LDAP Dereferencing Alias types */
371 #define SAMBA_LDAP_DEREF_NEVER 0
372 #define SAMBA_LDAP_DEREF_SEARCHING 1
373 #define SAMBA_LDAP_DEREF_FINDING 2
374 #define SAMBA_LDAP_DEREF_ALWAYS 3
376 static const struct enum_list enum_ldap_deref[] = {
377 {SAMBA_LDAP_DEREF_NEVER, "never"},
378 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
379 {SAMBA_LDAP_DEREF_FINDING, "finding"},
380 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
384 static const struct enum_list enum_ldap_passwd_sync[] = {
385 {LDAP_PASSWD_SYNC_OFF, "no"},
386 {LDAP_PASSWD_SYNC_OFF, "off"},
387 {LDAP_PASSWD_SYNC_ON, "yes"},
388 {LDAP_PASSWD_SYNC_ON, "on"},
389 {LDAP_PASSWD_SYNC_ONLY, "only"},
393 static const struct enum_list enum_map_readonly[] = {
394 {MAP_READONLY_NO, "no"},
395 {MAP_READONLY_NO, "false"},
396 {MAP_READONLY_NO, "0"},
397 {MAP_READONLY_YES, "yes"},
398 {MAP_READONLY_YES, "true"},
399 {MAP_READONLY_YES, "1"},
400 {MAP_READONLY_PERMISSIONS, "permissions"},
401 {MAP_READONLY_PERMISSIONS, "perms"},
405 static const struct enum_list enum_case[] = {
406 {CASE_LOWER, "lower"},
407 {CASE_UPPER, "upper"},
413 static const struct enum_list enum_bool_auto[] = {
424 static const struct enum_list enum_csc_policy[] = {
425 {CSC_POLICY_MANUAL, "manual"},
426 {CSC_POLICY_DOCUMENTS, "documents"},
427 {CSC_POLICY_PROGRAMS, "programs"},
428 {CSC_POLICY_DISABLE, "disable"},
432 /* SMB signing types. */
433 static const struct enum_list enum_smb_signing_vals[] = {
445 {Required, "required"},
446 {Required, "mandatory"},
448 {Required, "forced"},
449 {Required, "enforced"},
453 /* ACL compatibility options. */
454 static const struct enum_list enum_acl_compat_vals[] = {
455 { ACL_COMPAT_AUTO, "auto" },
456 { ACL_COMPAT_WINNT, "winnt" },
457 { ACL_COMPAT_WIN2K, "win2k" },
462 Do you want session setups at user level security with a invalid
463 password to be rejected or allowed in as guest? WinNT rejects them
464 but it can be a pain as it means "net view" needs to use a password
466 You have 3 choices in the setting of map_to_guest:
468 "Never" means session setups with an invalid password
469 are rejected. This is the default.
471 "Bad User" means session setups with an invalid password
472 are rejected, unless the username does not exist, in which case it
473 is treated as a guest login
475 "Bad Password" means session setups with an invalid password
476 are treated as a guest login
478 Note that map_to_guest only has an effect in user or server
482 static const struct enum_list enum_map_to_guest[] = {
483 {NEVER_MAP_TO_GUEST, "Never"},
484 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
485 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
486 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
490 /* Config backend options */
492 static const struct enum_list enum_config_backend[] = {
493 {CONFIG_BACKEND_FILE, "file"},
494 {CONFIG_BACKEND_REGISTRY, "registry"},
498 /* ADS kerberos ticket verification options */
500 static const struct enum_list enum_kerberos_method[] = {
501 {KERBEROS_VERIFY_SECRETS, "default"},
502 {KERBEROS_VERIFY_SECRETS, "secrets only"},
503 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
504 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
505 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
509 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
511 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
512 * screen in SWAT. This is used to exclude parameters as well as to squash all
513 * parameters that have been duplicated by pseudonyms.
515 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
516 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
517 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
520 * NOTE2: Handling of duplicated (synonym) parameters:
521 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
522 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
523 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
524 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
527 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
528 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
530 static struct parm_struct parm_table[] = {
531 {N_("Base Options"), P_SEP, P_SEPARATOR},
534 .label = "dos charset",
537 .offset = GLOBAL_VAR(dos_charset),
538 .special = handle_dos_charset,
540 .flags = FLAG_ADVANCED
543 .label = "unix charset",
546 .offset = GLOBAL_VAR(unix_charset),
547 .special = handle_charset,
549 .flags = FLAG_ADVANCED
555 .offset = LOCAL_VAR(comment),
558 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
564 .offset = LOCAL_VAR(szPath),
567 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
570 .label = "directory",
573 .offset = LOCAL_VAR(szPath),
579 .label = "workgroup",
582 .offset = GLOBAL_VAR(szWorkgroup),
585 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
591 .offset = GLOBAL_VAR(szRealm),
592 .special = handle_realm,
594 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
597 .label = "netbios name",
600 .offset = GLOBAL_VAR(szNetbiosName),
603 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
606 .label = "netbios aliases",
609 .offset = GLOBAL_VAR(szNetbiosAliases),
610 .special = handle_netbios_aliases,
612 .flags = FLAG_ADVANCED,
615 .label = "netbios scope",
618 .offset = GLOBAL_VAR(szNetbiosScope),
621 .flags = FLAG_ADVANCED,
624 .label = "server string",
627 .offset = GLOBAL_VAR(szServerString),
630 .flags = FLAG_BASIC | FLAG_ADVANCED,
633 .label = "interfaces",
636 .offset = GLOBAL_VAR(szInterfaces),
639 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
642 .label = "bind interfaces only",
645 .offset = GLOBAL_VAR(bBindInterfacesOnly),
648 .flags = FLAG_ADVANCED | FLAG_WIZARD,
651 .label = "config backend",
654 .offset = GLOBAL_VAR(ConfigBackend),
656 .enum_list = enum_config_backend,
657 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
660 {N_("Security Options"), P_SEP, P_SEPARATOR},
666 .offset = GLOBAL_VAR(security),
668 .enum_list = enum_security,
669 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
672 .label = "auth methods",
675 .offset = GLOBAL_VAR(AuthMethods),
678 .flags = FLAG_ADVANCED,
681 .label = "encrypt passwords",
684 .offset = GLOBAL_VAR(bEncryptPasswords),
687 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
690 .label = "client schannel",
693 .offset = GLOBAL_VAR(clientSchannel),
695 .enum_list = enum_bool_auto,
696 .flags = FLAG_BASIC | FLAG_ADVANCED,
699 .label = "server schannel",
702 .offset = GLOBAL_VAR(serverSchannel),
704 .enum_list = enum_bool_auto,
705 .flags = FLAG_BASIC | FLAG_ADVANCED,
708 .label = "allow trusted domains",
711 .offset = GLOBAL_VAR(bAllowTrustedDomains),
714 .flags = FLAG_ADVANCED,
717 .label = "map to guest",
720 .offset = GLOBAL_VAR(map_to_guest),
722 .enum_list = enum_map_to_guest,
723 .flags = FLAG_ADVANCED,
726 .label = "null passwords",
729 .offset = GLOBAL_VAR(bNullPasswords),
732 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
735 .label = "obey pam restrictions",
738 .offset = GLOBAL_VAR(bObeyPamRestrictions),
741 .flags = FLAG_ADVANCED,
744 .label = "password server",
747 .offset = GLOBAL_VAR(szPasswordServer),
750 .flags = FLAG_ADVANCED | FLAG_WIZARD,
753 .label = "smb passwd file",
756 .offset = GLOBAL_VAR(szSMBPasswdFile),
759 .flags = FLAG_ADVANCED,
762 .label = "private dir",
765 .offset = GLOBAL_VAR(szPrivateDir),
768 .flags = FLAG_ADVANCED,
771 .label = "passdb backend",
774 .offset = GLOBAL_VAR(szPassdbBackend),
777 .flags = FLAG_ADVANCED | FLAG_WIZARD,
780 .label = "algorithmic rid base",
783 .offset = GLOBAL_VAR(AlgorithmicRidBase),
786 .flags = FLAG_ADVANCED,
789 .label = "root directory",
792 .offset = GLOBAL_VAR(szRootdir),
795 .flags = FLAG_ADVANCED,
801 .offset = GLOBAL_VAR(szRootdir),
810 .offset = GLOBAL_VAR(szRootdir),
816 .label = "guest account",
819 .offset = GLOBAL_VAR(szGuestaccount),
822 .flags = FLAG_BASIC | FLAG_ADVANCED,
825 .label = "enable privileges",
828 .offset = GLOBAL_VAR(bEnablePrivileges),
831 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
835 .label = "pam password change",
838 .offset = GLOBAL_VAR(bPamPasswordChange),
841 .flags = FLAG_ADVANCED,
844 .label = "passwd program",
847 .offset = GLOBAL_VAR(szPasswdProgram),
850 .flags = FLAG_ADVANCED,
853 .label = "passwd chat",
856 .offset = GLOBAL_VAR(szPasswdChat),
859 .flags = FLAG_ADVANCED,
862 .label = "passwd chat debug",
865 .offset = GLOBAL_VAR(bPasswdChatDebug),
868 .flags = FLAG_ADVANCED,
871 .label = "passwd chat timeout",
874 .offset = GLOBAL_VAR(iPasswdChatTimeout),
877 .flags = FLAG_ADVANCED,
880 .label = "check password script",
883 .offset = GLOBAL_VAR(szCheckPasswordScript),
886 .flags = FLAG_ADVANCED,
889 .label = "username map",
892 .offset = GLOBAL_VAR(szUsernameMap),
895 .flags = FLAG_ADVANCED,
898 .label = "password level",
901 .offset = GLOBAL_VAR(pwordlevel),
904 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
907 .label = "username level",
910 .offset = GLOBAL_VAR(unamelevel),
913 .flags = FLAG_ADVANCED,
916 .label = "unix password sync",
919 .offset = GLOBAL_VAR(bUnixPasswdSync),
922 .flags = FLAG_ADVANCED,
925 .label = "restrict anonymous",
928 .offset = GLOBAL_VAR(restrict_anonymous),
931 .flags = FLAG_ADVANCED,
934 .label = "lanman auth",
937 .offset = GLOBAL_VAR(bLanmanAuth),
940 .flags = FLAG_ADVANCED,
943 .label = "ntlm auth",
946 .offset = GLOBAL_VAR(bNTLMAuth),
949 .flags = FLAG_ADVANCED,
952 .label = "client NTLMv2 auth",
955 .offset = GLOBAL_VAR(bClientNTLMv2Auth),
958 .flags = FLAG_ADVANCED,
961 .label = "client lanman auth",
964 .offset = GLOBAL_VAR(bClientLanManAuth),
967 .flags = FLAG_ADVANCED,
970 .label = "client plaintext auth",
973 .offset = GLOBAL_VAR(bClientPlaintextAuth),
976 .flags = FLAG_ADVANCED,
979 .label = "client use spnego principal",
982 .offset = GLOBAL_VAR(client_use_spnego_principal),
985 .flags = FLAG_ADVANCED,
988 .label = "send spnego principal",
991 .offset = GLOBAL_VAR(send_spnego_principal),
994 .flags = FLAG_ADVANCED,
1000 .offset = LOCAL_VAR(szUsername),
1003 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1009 .offset = LOCAL_VAR(szUsername),
1018 .offset = LOCAL_VAR(szUsername),
1024 .label = "invalid users",
1027 .offset = LOCAL_VAR(szInvalidUsers),
1030 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1033 .label = "valid users",
1036 .offset = LOCAL_VAR(szValidUsers),
1039 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1042 .label = "admin users",
1045 .offset = LOCAL_VAR(szAdminUsers),
1048 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1051 .label = "read list",
1054 .offset = LOCAL_VAR(readlist),
1057 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1060 .label = "write list",
1063 .offset = LOCAL_VAR(writelist),
1066 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1069 .label = "printer admin",
1072 .offset = LOCAL_VAR(printer_admin),
1075 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1078 .label = "force user",
1081 .offset = LOCAL_VAR(force_user),
1084 .flags = FLAG_ADVANCED | FLAG_SHARE,
1087 .label = "force group",
1090 .offset = LOCAL_VAR(force_group),
1093 .flags = FLAG_ADVANCED | FLAG_SHARE,
1099 .offset = LOCAL_VAR(force_group),
1102 .flags = FLAG_ADVANCED,
1105 .label = "read only",
1108 .offset = LOCAL_VAR(bRead_only),
1111 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1114 .label = "write ok",
1117 .offset = LOCAL_VAR(bRead_only),
1123 .label = "writeable",
1126 .offset = LOCAL_VAR(bRead_only),
1132 .label = "writable",
1135 .offset = LOCAL_VAR(bRead_only),
1141 .label = "acl check permissions",
1144 .offset = LOCAL_VAR(bAclCheckPermissions),
1147 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1150 .label = "acl group control",
1153 .offset = LOCAL_VAR(bAclGroupControl),
1156 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1159 .label = "acl map full control",
1162 .offset = LOCAL_VAR(bAclMapFullControl),
1165 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1168 .label = "create mask",
1171 .offset = LOCAL_VAR(iCreate_mask),
1174 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1177 .label = "create mode",
1180 .offset = LOCAL_VAR(iCreate_mask),
1186 .label = "force create mode",
1189 .offset = LOCAL_VAR(iCreate_force_mode),
1192 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1195 .label = "security mask",
1198 .offset = LOCAL_VAR(iSecurity_mask),
1201 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1204 .label = "force security mode",
1207 .offset = LOCAL_VAR(iSecurity_force_mode),
1210 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1213 .label = "directory mask",
1216 .offset = LOCAL_VAR(iDir_mask),
1219 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1222 .label = "directory mode",
1225 .offset = LOCAL_VAR(iDir_mask),
1228 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1231 .label = "force directory mode",
1234 .offset = LOCAL_VAR(iDir_force_mode),
1237 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1240 .label = "directory security mask",
1243 .offset = LOCAL_VAR(iDir_Security_mask),
1246 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1249 .label = "force directory security mode",
1252 .offset = LOCAL_VAR(iDir_Security_force_mode),
1255 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1258 .label = "force unknown acl user",
1261 .offset = LOCAL_VAR(bForceUnknownAclUser),
1264 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1267 .label = "inherit permissions",
1270 .offset = LOCAL_VAR(bInheritPerms),
1273 .flags = FLAG_ADVANCED | FLAG_SHARE,
1276 .label = "inherit acls",
1279 .offset = LOCAL_VAR(bInheritACLS),
1282 .flags = FLAG_ADVANCED | FLAG_SHARE,
1285 .label = "inherit owner",
1288 .offset = LOCAL_VAR(bInheritOwner),
1291 .flags = FLAG_ADVANCED | FLAG_SHARE,
1294 .label = "guest only",
1297 .offset = LOCAL_VAR(bGuest_only),
1300 .flags = FLAG_ADVANCED | FLAG_SHARE,
1303 .label = "only guest",
1306 .offset = LOCAL_VAR(bGuest_only),
1312 .label = "administrative share",
1315 .offset = LOCAL_VAR(bAdministrative_share),
1318 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1322 .label = "guest ok",
1325 .offset = LOCAL_VAR(bGuest_ok),
1328 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1334 .offset = LOCAL_VAR(bGuest_ok),
1340 .label = "only user",
1343 .offset = LOCAL_VAR(bOnlyUser),
1346 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1349 .label = "hosts allow",
1352 .offset = LOCAL_VAR(szHostsallow),
1355 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1358 .label = "allow hosts",
1361 .offset = LOCAL_VAR(szHostsallow),
1367 .label = "hosts deny",
1370 .offset = LOCAL_VAR(szHostsdeny),
1373 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1376 .label = "deny hosts",
1379 .offset = LOCAL_VAR(szHostsdeny),
1385 .label = "preload modules",
1387 .p_class = P_GLOBAL,
1388 .offset = GLOBAL_VAR(szPreloadModules),
1391 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1394 .label = "dedicated keytab file",
1396 .p_class = P_GLOBAL,
1397 .offset = GLOBAL_VAR(szDedicatedKeytabFile),
1400 .flags = FLAG_ADVANCED,
1403 .label = "kerberos method",
1405 .p_class = P_GLOBAL,
1406 .offset = GLOBAL_VAR(iKerberosMethod),
1408 .enum_list = enum_kerberos_method,
1409 .flags = FLAG_ADVANCED,
1412 .label = "map untrusted to domain",
1414 .p_class = P_GLOBAL,
1415 .offset = GLOBAL_VAR(bMapUntrustedToDomain),
1418 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1422 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1425 .label = "log level",
1427 .p_class = P_GLOBAL,
1428 .offset = GLOBAL_VAR(szLogLevel),
1429 .special = handle_debug_list,
1431 .flags = FLAG_ADVANCED,
1434 .label = "debuglevel",
1436 .p_class = P_GLOBAL,
1437 .offset = GLOBAL_VAR(szLogLevel),
1438 .special = handle_debug_list,
1445 .p_class = P_GLOBAL,
1446 .offset = GLOBAL_VAR(syslog),
1449 .flags = FLAG_ADVANCED,
1452 .label = "syslog only",
1454 .p_class = P_GLOBAL,
1455 .offset = GLOBAL_VAR(bSyslogOnly),
1458 .flags = FLAG_ADVANCED,
1461 .label = "log file",
1463 .p_class = P_GLOBAL,
1464 .offset = GLOBAL_VAR(szLogFile),
1467 .flags = FLAG_ADVANCED,
1470 .label = "max log size",
1472 .p_class = P_GLOBAL,
1473 .offset = GLOBAL_VAR(max_log_size),
1476 .flags = FLAG_ADVANCED,
1479 .label = "debug timestamp",
1481 .p_class = P_GLOBAL,
1482 .offset = GLOBAL_VAR(bTimestampLogs),
1485 .flags = FLAG_ADVANCED,
1488 .label = "timestamp logs",
1490 .p_class = P_GLOBAL,
1491 .offset = GLOBAL_VAR(bTimestampLogs),
1494 .flags = FLAG_ADVANCED,
1497 .label = "debug prefix timestamp",
1499 .p_class = P_GLOBAL,
1500 .offset = GLOBAL_VAR(bDebugPrefixTimestamp),
1503 .flags = FLAG_ADVANCED,
1506 .label = "debug hires timestamp",
1508 .p_class = P_GLOBAL,
1509 .offset = GLOBAL_VAR(bDebugHiresTimestamp),
1512 .flags = FLAG_ADVANCED,
1515 .label = "debug pid",
1517 .p_class = P_GLOBAL,
1518 .offset = GLOBAL_VAR(bDebugPid),
1521 .flags = FLAG_ADVANCED,
1524 .label = "debug uid",
1526 .p_class = P_GLOBAL,
1527 .offset = GLOBAL_VAR(bDebugUid),
1530 .flags = FLAG_ADVANCED,
1533 .label = "debug class",
1535 .p_class = P_GLOBAL,
1536 .offset = GLOBAL_VAR(bDebugClass),
1539 .flags = FLAG_ADVANCED,
1542 .label = "enable core files",
1544 .p_class = P_GLOBAL,
1545 .offset = GLOBAL_VAR(bEnableCoreFiles),
1548 .flags = FLAG_ADVANCED,
1551 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1554 .label = "allocation roundup size",
1557 .offset = LOCAL_VAR(iallocation_roundup_size),
1560 .flags = FLAG_ADVANCED,
1563 .label = "aio read size",
1566 .offset = LOCAL_VAR(iAioReadSize),
1569 .flags = FLAG_ADVANCED,
1572 .label = "aio write size",
1575 .offset = LOCAL_VAR(iAioWriteSize),
1578 .flags = FLAG_ADVANCED,
1581 .label = "aio write behind",
1584 .offset = LOCAL_VAR(szAioWriteBehind),
1587 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1590 .label = "smb ports",
1592 .p_class = P_GLOBAL,
1593 .offset = GLOBAL_VAR(smb_ports),
1596 .flags = FLAG_ADVANCED,
1599 .label = "large readwrite",
1601 .p_class = P_GLOBAL,
1602 .offset = GLOBAL_VAR(bLargeReadwrite),
1605 .flags = FLAG_ADVANCED,
1608 .label = "max protocol",
1610 .p_class = P_GLOBAL,
1611 .offset = GLOBAL_VAR(maxprotocol),
1613 .enum_list = enum_protocol,
1614 .flags = FLAG_ADVANCED,
1617 .label = "protocol",
1619 .p_class = P_GLOBAL,
1620 .offset = GLOBAL_VAR(maxprotocol),
1622 .enum_list = enum_protocol,
1623 .flags = FLAG_ADVANCED,
1626 .label = "min protocol",
1628 .p_class = P_GLOBAL,
1629 .offset = GLOBAL_VAR(minprotocol),
1631 .enum_list = enum_protocol,
1632 .flags = FLAG_ADVANCED,
1635 .label = "min receivefile size",
1637 .p_class = P_GLOBAL,
1638 .offset = GLOBAL_VAR(iminreceivefile),
1641 .flags = FLAG_ADVANCED,
1644 .label = "read raw",
1646 .p_class = P_GLOBAL,
1647 .offset = GLOBAL_VAR(bReadRaw),
1650 .flags = FLAG_ADVANCED,
1653 .label = "write raw",
1655 .p_class = P_GLOBAL,
1656 .offset = GLOBAL_VAR(bWriteRaw),
1659 .flags = FLAG_ADVANCED,
1662 .label = "disable netbios",
1664 .p_class = P_GLOBAL,
1665 .offset = GLOBAL_VAR(bDisableNetbios),
1668 .flags = FLAG_ADVANCED,
1671 .label = "reset on zero vc",
1673 .p_class = P_GLOBAL,
1674 .offset = GLOBAL_VAR(bResetOnZeroVC),
1677 .flags = FLAG_ADVANCED,
1680 .label = "log writeable files on exit",
1682 .p_class = P_GLOBAL,
1683 .offset = GLOBAL_VAR(bLogWriteableFilesOnExit),
1686 .flags = FLAG_ADVANCED,
1689 .label = "acl compatibility",
1691 .p_class = P_GLOBAL,
1692 .offset = GLOBAL_VAR(iAclCompat),
1694 .enum_list = enum_acl_compat_vals,
1695 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1698 .label = "defer sharing violations",
1700 .p_class = P_GLOBAL,
1701 .offset = GLOBAL_VAR(bDeferSharingViolations),
1704 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1707 .label = "ea support",
1710 .offset = LOCAL_VAR(bEASupport),
1713 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1716 .label = "nt acl support",
1719 .offset = LOCAL_VAR(bNTAclSupport),
1722 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1725 .label = "nt pipe support",
1727 .p_class = P_GLOBAL,
1728 .offset = GLOBAL_VAR(bNTPipeSupport),
1731 .flags = FLAG_ADVANCED,
1734 .label = "nt status support",
1736 .p_class = P_GLOBAL,
1737 .offset = GLOBAL_VAR(bNTStatusSupport),
1740 .flags = FLAG_ADVANCED,
1743 .label = "profile acls",
1746 .offset = LOCAL_VAR(bProfileAcls),
1749 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1752 .label = "map acl inherit",
1755 .offset = LOCAL_VAR(bMap_acl_inherit),
1758 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1761 .label = "afs share",
1764 .offset = LOCAL_VAR(bAfs_Share),
1767 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1772 .p_class = P_GLOBAL,
1773 .offset = GLOBAL_VAR(max_mux),
1776 .flags = FLAG_ADVANCED,
1779 .label = "max xmit",
1781 .p_class = P_GLOBAL,
1782 .offset = GLOBAL_VAR(max_xmit),
1785 .flags = FLAG_ADVANCED,
1788 .label = "name resolve order",
1790 .p_class = P_GLOBAL,
1791 .offset = GLOBAL_VAR(szNameResolveOrder),
1794 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1799 .p_class = P_GLOBAL,
1800 .offset = GLOBAL_VAR(max_ttl),
1803 .flags = FLAG_ADVANCED,
1806 .label = "max wins ttl",
1808 .p_class = P_GLOBAL,
1809 .offset = GLOBAL_VAR(max_wins_ttl),
1812 .flags = FLAG_ADVANCED,
1815 .label = "min wins ttl",
1817 .p_class = P_GLOBAL,
1818 .offset = GLOBAL_VAR(min_wins_ttl),
1821 .flags = FLAG_ADVANCED,
1824 .label = "time server",
1826 .p_class = P_GLOBAL,
1827 .offset = GLOBAL_VAR(bTimeServer),
1830 .flags = FLAG_ADVANCED,
1833 .label = "unix extensions",
1835 .p_class = P_GLOBAL,
1836 .offset = GLOBAL_VAR(bUnixExtensions),
1839 .flags = FLAG_ADVANCED,
1842 .label = "use spnego",
1844 .p_class = P_GLOBAL,
1845 .offset = GLOBAL_VAR(bUseSpnego),
1848 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1851 .label = "client signing",
1853 .p_class = P_GLOBAL,
1854 .offset = GLOBAL_VAR(client_signing),
1856 .enum_list = enum_smb_signing_vals,
1857 .flags = FLAG_ADVANCED,
1860 .label = "server signing",
1862 .p_class = P_GLOBAL,
1863 .offset = GLOBAL_VAR(server_signing),
1865 .enum_list = enum_smb_signing_vals,
1866 .flags = FLAG_ADVANCED,
1869 .label = "smb encrypt",
1872 .offset = LOCAL_VAR(ismb_encrypt),
1874 .enum_list = enum_smb_signing_vals,
1875 .flags = FLAG_ADVANCED,
1878 .label = "client use spnego",
1880 .p_class = P_GLOBAL,
1881 .offset = GLOBAL_VAR(bClientUseSpnego),
1884 .flags = FLAG_ADVANCED,
1887 .label = "client ldap sasl wrapping",
1889 .p_class = P_GLOBAL,
1890 .offset = GLOBAL_VAR(client_ldap_sasl_wrapping),
1892 .enum_list = enum_ldap_sasl_wrapping,
1893 .flags = FLAG_ADVANCED,
1896 .label = "enable asu support",
1898 .p_class = P_GLOBAL,
1899 .offset = GLOBAL_VAR(bASUSupport),
1902 .flags = FLAG_ADVANCED,
1905 .label = "svcctl list",
1907 .p_class = P_GLOBAL,
1908 .offset = GLOBAL_VAR(szServicesList),
1911 .flags = FLAG_ADVANCED,
1914 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1917 .label = "block size",
1920 .offset = LOCAL_VAR(iBlock_size),
1923 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1926 .label = "deadtime",
1928 .p_class = P_GLOBAL,
1929 .offset = GLOBAL_VAR(deadtime),
1932 .flags = FLAG_ADVANCED,
1935 .label = "getwd cache",
1937 .p_class = P_GLOBAL,
1938 .offset = GLOBAL_VAR(getwd_cache),
1941 .flags = FLAG_ADVANCED,
1944 .label = "keepalive",
1946 .p_class = P_GLOBAL,
1947 .offset = GLOBAL_VAR(iKeepalive),
1950 .flags = FLAG_ADVANCED,
1953 .label = "change notify",
1956 .offset = LOCAL_VAR(bChangeNotify),
1959 .flags = FLAG_ADVANCED | FLAG_SHARE,
1962 .label = "directory name cache size",
1965 .offset = LOCAL_VAR(iDirectoryNameCacheSize),
1968 .flags = FLAG_ADVANCED | FLAG_SHARE,
1971 .label = "kernel change notify",
1974 .offset = LOCAL_VAR(bKernelChangeNotify),
1977 .flags = FLAG_ADVANCED | FLAG_SHARE,
1980 .label = "lpq cache time",
1982 .p_class = P_GLOBAL,
1983 .offset = GLOBAL_VAR(lpqcachetime),
1986 .flags = FLAG_ADVANCED,
1989 .label = "max smbd processes",
1991 .p_class = P_GLOBAL,
1992 .offset = GLOBAL_VAR(iMaxSmbdProcesses),
1995 .flags = FLAG_ADVANCED,
1998 .label = "max connections",
2001 .offset = LOCAL_VAR(iMaxConnections),
2004 .flags = FLAG_ADVANCED | FLAG_SHARE,
2007 .label = "paranoid server security",
2009 .p_class = P_GLOBAL,
2010 .offset = GLOBAL_VAR(paranoid_server_security),
2013 .flags = FLAG_ADVANCED,
2016 .label = "max disk size",
2018 .p_class = P_GLOBAL,
2019 .offset = GLOBAL_VAR(maxdisksize),
2022 .flags = FLAG_ADVANCED,
2025 .label = "max open files",
2027 .p_class = P_GLOBAL,
2028 .offset = GLOBAL_VAR(max_open_files),
2031 .flags = FLAG_ADVANCED,
2034 .label = "min print space",
2037 .offset = LOCAL_VAR(iMinPrintSpace),
2040 .flags = FLAG_ADVANCED | FLAG_PRINT,
2043 .label = "socket options",
2045 .p_class = P_GLOBAL,
2046 .offset = GLOBAL_VAR(szSocketOptions),
2049 .flags = FLAG_ADVANCED,
2052 .label = "strict allocate",
2055 .offset = LOCAL_VAR(bStrictAllocate),
2058 .flags = FLAG_ADVANCED | FLAG_SHARE,
2061 .label = "strict sync",
2064 .offset = LOCAL_VAR(bStrictSync),
2067 .flags = FLAG_ADVANCED | FLAG_SHARE,
2070 .label = "sync always",
2073 .offset = LOCAL_VAR(bSyncAlways),
2076 .flags = FLAG_ADVANCED | FLAG_SHARE,
2079 .label = "use mmap",
2081 .p_class = P_GLOBAL,
2082 .offset = GLOBAL_VAR(bUseMmap),
2085 .flags = FLAG_ADVANCED,
2088 .label = "use sendfile",
2091 .offset = LOCAL_VAR(bUseSendfile),
2094 .flags = FLAG_ADVANCED | FLAG_SHARE,
2097 .label = "hostname lookups",
2099 .p_class = P_GLOBAL,
2100 .offset = GLOBAL_VAR(bHostnameLookups),
2103 .flags = FLAG_ADVANCED,
2106 .label = "write cache size",
2109 .offset = LOCAL_VAR(iWriteCacheSize),
2112 .flags = FLAG_ADVANCED | FLAG_SHARE,
2115 .label = "name cache timeout",
2117 .p_class = P_GLOBAL,
2118 .offset = GLOBAL_VAR(name_cache_timeout),
2121 .flags = FLAG_ADVANCED,
2124 .label = "ctdbd socket",
2126 .p_class = P_GLOBAL,
2127 .offset = GLOBAL_VAR(ctdbdSocket),
2130 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2133 .label = "cluster addresses",
2135 .p_class = P_GLOBAL,
2136 .offset = GLOBAL_VAR(szClusterAddresses),
2139 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2142 .label = "clustering",
2144 .p_class = P_GLOBAL,
2145 .offset = GLOBAL_VAR(clustering),
2148 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2151 .label = "ctdb timeout",
2153 .p_class = P_GLOBAL,
2154 .offset = GLOBAL_VAR(ctdb_timeout),
2157 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2160 .label = "ctdb locktime warn threshold",
2162 .p_class = P_GLOBAL,
2163 .offset = GLOBAL_VAR(ctdb_locktime_warn_threshold),
2166 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2169 .label = "smb2 max read",
2171 .p_class = P_GLOBAL,
2172 .offset = GLOBAL_VAR(ismb2_max_read),
2175 .flags = FLAG_ADVANCED,
2178 .label = "smb2 max write",
2180 .p_class = P_GLOBAL,
2181 .offset = GLOBAL_VAR(ismb2_max_write),
2184 .flags = FLAG_ADVANCED,
2187 .label = "smb2 max trans",
2189 .p_class = P_GLOBAL,
2190 .offset = GLOBAL_VAR(ismb2_max_trans),
2193 .flags = FLAG_ADVANCED,
2196 .label = "smb2 max credits",
2198 .p_class = P_GLOBAL,
2199 .offset = GLOBAL_VAR(ismb2_max_credits),
2202 .flags = FLAG_ADVANCED,
2205 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2208 .label = "max reported print jobs",
2211 .offset = LOCAL_VAR(iMaxReportedPrintJobs),
2214 .flags = FLAG_ADVANCED | FLAG_PRINT,
2217 .label = "max print jobs",
2220 .offset = LOCAL_VAR(iMaxPrintJobs),
2223 .flags = FLAG_ADVANCED | FLAG_PRINT,
2226 .label = "load printers",
2228 .p_class = P_GLOBAL,
2229 .offset = GLOBAL_VAR(bLoadPrinters),
2232 .flags = FLAG_ADVANCED | FLAG_PRINT,
2235 .label = "printcap cache time",
2237 .p_class = P_GLOBAL,
2238 .offset = GLOBAL_VAR(PrintcapCacheTime),
2241 .flags = FLAG_ADVANCED | FLAG_PRINT,
2244 .label = "printcap name",
2246 .p_class = P_GLOBAL,
2247 .offset = GLOBAL_VAR(szPrintcapname),
2250 .flags = FLAG_ADVANCED | FLAG_PRINT,
2253 .label = "printcap",
2255 .p_class = P_GLOBAL,
2256 .offset = GLOBAL_VAR(szPrintcapname),
2262 .label = "printable",
2265 .offset = LOCAL_VAR(bPrint_ok),
2268 .flags = FLAG_ADVANCED | FLAG_PRINT,
2271 .label = "print notify backchannel",
2274 .offset = LOCAL_VAR(bPrintNotifyBackchannel),
2277 .flags = FLAG_ADVANCED,
2280 .label = "print ok",
2283 .offset = LOCAL_VAR(bPrint_ok),
2289 .label = "printing",
2292 .offset = LOCAL_VAR(iPrinting),
2293 .special = handle_printing,
2294 .enum_list = enum_printing,
2295 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2298 .label = "cups options",
2301 .offset = LOCAL_VAR(szCupsOptions),
2304 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2307 .label = "cups server",
2309 .p_class = P_GLOBAL,
2310 .offset = GLOBAL_VAR(szCupsServer),
2313 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2316 .label = "cups encrypt",
2318 .p_class = P_GLOBAL,
2319 .offset = GLOBAL_VAR(CupsEncrypt),
2321 .enum_list = enum_bool_auto,
2322 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2326 .label = "cups connection timeout",
2328 .p_class = P_GLOBAL,
2329 .offset = GLOBAL_VAR(cups_connection_timeout),
2332 .flags = FLAG_ADVANCED,
2335 .label = "iprint server",
2337 .p_class = P_GLOBAL,
2338 .offset = GLOBAL_VAR(szIPrintServer),
2341 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2344 .label = "print command",
2347 .offset = LOCAL_VAR(szPrintcommand),
2350 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2353 .label = "disable spoolss",
2355 .p_class = P_GLOBAL,
2356 .offset = GLOBAL_VAR(bDisableSpoolss),
2359 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2362 .label = "enable spoolss",
2364 .p_class = P_GLOBAL,
2365 .offset = GLOBAL_VAR(bDisableSpoolss),
2371 .label = "lpq command",
2374 .offset = LOCAL_VAR(szLpqcommand),
2377 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2380 .label = "lprm command",
2383 .offset = LOCAL_VAR(szLprmcommand),
2386 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2389 .label = "lppause command",
2392 .offset = LOCAL_VAR(szLppausecommand),
2395 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2398 .label = "lpresume command",
2401 .offset = LOCAL_VAR(szLpresumecommand),
2404 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2407 .label = "queuepause command",
2410 .offset = LOCAL_VAR(szQueuepausecommand),
2413 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2416 .label = "queueresume command",
2419 .offset = LOCAL_VAR(szQueueresumecommand),
2422 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2425 .label = "addport command",
2427 .p_class = P_GLOBAL,
2428 .offset = GLOBAL_VAR(szAddPortCommand),
2431 .flags = FLAG_ADVANCED,
2434 .label = "enumports command",
2436 .p_class = P_GLOBAL,
2437 .offset = GLOBAL_VAR(szEnumPortsCommand),
2440 .flags = FLAG_ADVANCED,
2443 .label = "addprinter command",
2445 .p_class = P_GLOBAL,
2446 .offset = GLOBAL_VAR(szAddPrinterCommand),
2449 .flags = FLAG_ADVANCED,
2452 .label = "deleteprinter command",
2454 .p_class = P_GLOBAL,
2455 .offset = GLOBAL_VAR(szDeletePrinterCommand),
2458 .flags = FLAG_ADVANCED,
2461 .label = "show add printer wizard",
2463 .p_class = P_GLOBAL,
2464 .offset = GLOBAL_VAR(bMsAddPrinterWizard),
2467 .flags = FLAG_ADVANCED,
2470 .label = "os2 driver map",
2472 .p_class = P_GLOBAL,
2473 .offset = GLOBAL_VAR(szOs2DriverMap),
2476 .flags = FLAG_ADVANCED,
2480 .label = "printer name",
2483 .offset = LOCAL_VAR(szPrintername),
2486 .flags = FLAG_ADVANCED | FLAG_PRINT,
2492 .offset = LOCAL_VAR(szPrintername),
2498 .label = "use client driver",
2501 .offset = LOCAL_VAR(bUseClientDriver),
2504 .flags = FLAG_ADVANCED | FLAG_PRINT,
2507 .label = "default devmode",
2510 .offset = LOCAL_VAR(bDefaultDevmode),
2513 .flags = FLAG_ADVANCED | FLAG_PRINT,
2516 .label = "force printername",
2519 .offset = LOCAL_VAR(bForcePrintername),
2522 .flags = FLAG_ADVANCED | FLAG_PRINT,
2525 .label = "printjob username",
2528 .offset = LOCAL_VAR(szPrintjobUsername),
2531 .flags = FLAG_ADVANCED | FLAG_PRINT,
2534 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2537 .label = "mangling method",
2539 .p_class = P_GLOBAL,
2540 .offset = GLOBAL_VAR(szManglingMethod),
2543 .flags = FLAG_ADVANCED,
2546 .label = "mangle prefix",
2548 .p_class = P_GLOBAL,
2549 .offset = GLOBAL_VAR(mangle_prefix),
2552 .flags = FLAG_ADVANCED,
2556 .label = "default case",
2559 .offset = LOCAL_VAR(iDefaultCase),
2561 .enum_list = enum_case,
2562 .flags = FLAG_ADVANCED | FLAG_SHARE,
2565 .label = "case sensitive",
2568 .offset = LOCAL_VAR(iCaseSensitive),
2570 .enum_list = enum_bool_auto,
2571 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2574 .label = "casesignames",
2577 .offset = LOCAL_VAR(iCaseSensitive),
2579 .enum_list = enum_bool_auto,
2580 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2583 .label = "preserve case",
2586 .offset = LOCAL_VAR(bCasePreserve),
2589 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2592 .label = "short preserve case",
2595 .offset = LOCAL_VAR(bShortCasePreserve),
2598 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2601 .label = "mangling char",
2604 .offset = LOCAL_VAR(magic_char),
2607 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2610 .label = "hide dot files",
2613 .offset = LOCAL_VAR(bHideDotFiles),
2616 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2619 .label = "hide special files",
2622 .offset = LOCAL_VAR(bHideSpecialFiles),
2625 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2628 .label = "hide unreadable",
2631 .offset = LOCAL_VAR(bHideUnReadable),
2634 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2637 .label = "hide unwriteable files",
2640 .offset = LOCAL_VAR(bHideUnWriteableFiles),
2643 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2646 .label = "delete veto files",
2649 .offset = LOCAL_VAR(bDeleteVetoFiles),
2652 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2655 .label = "veto files",
2658 .offset = LOCAL_VAR(szVetoFiles),
2661 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2664 .label = "hide files",
2667 .offset = LOCAL_VAR(szHideFiles),
2670 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2673 .label = "veto oplock files",
2676 .offset = LOCAL_VAR(szVetoOplockFiles),
2679 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2682 .label = "map archive",
2685 .offset = LOCAL_VAR(bMap_archive),
2688 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2691 .label = "map hidden",
2694 .offset = LOCAL_VAR(bMap_hidden),
2697 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2700 .label = "map system",
2703 .offset = LOCAL_VAR(bMap_system),
2706 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2709 .label = "map readonly",
2712 .offset = LOCAL_VAR(iMap_readonly),
2714 .enum_list = enum_map_readonly,
2715 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2718 .label = "mangled names",
2721 .offset = LOCAL_VAR(bMangledNames),
2724 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2727 .label = "max stat cache size",
2729 .p_class = P_GLOBAL,
2730 .offset = GLOBAL_VAR(iMaxStatCacheSize),
2733 .flags = FLAG_ADVANCED,
2736 .label = "stat cache",
2738 .p_class = P_GLOBAL,
2739 .offset = GLOBAL_VAR(bStatCache),
2742 .flags = FLAG_ADVANCED,
2745 .label = "store dos attributes",
2748 .offset = LOCAL_VAR(bStoreDosAttributes),
2751 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2754 .label = "dmapi support",
2757 .offset = LOCAL_VAR(bDmapiSupport),
2760 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2764 {N_("Domain Options"), P_SEP, P_SEPARATOR},
2767 .label = "machine password timeout",
2769 .p_class = P_GLOBAL,
2770 .offset = GLOBAL_VAR(machine_password_timeout),
2773 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2776 {N_("Logon Options"), P_SEP, P_SEPARATOR},
2779 .label = "add user script",
2781 .p_class = P_GLOBAL,
2782 .offset = GLOBAL_VAR(szAddUserScript),
2785 .flags = FLAG_ADVANCED,
2788 .label = "rename user script",
2790 .p_class = P_GLOBAL,
2791 .offset = GLOBAL_VAR(szRenameUserScript),
2794 .flags = FLAG_ADVANCED,
2797 .label = "delete user script",
2799 .p_class = P_GLOBAL,
2800 .offset = GLOBAL_VAR(szDelUserScript),
2803 .flags = FLAG_ADVANCED,
2806 .label = "add group script",
2808 .p_class = P_GLOBAL,
2809 .offset = GLOBAL_VAR(szAddGroupScript),
2812 .flags = FLAG_ADVANCED,
2815 .label = "delete group script",
2817 .p_class = P_GLOBAL,
2818 .offset = GLOBAL_VAR(szDelGroupScript),
2821 .flags = FLAG_ADVANCED,
2824 .label = "add user to group script",
2826 .p_class = P_GLOBAL,
2827 .offset = GLOBAL_VAR(szAddUserToGroupScript),
2830 .flags = FLAG_ADVANCED,
2833 .label = "delete user from group script",
2835 .p_class = P_GLOBAL,
2836 .offset = GLOBAL_VAR(szDelUserFromGroupScript),
2839 .flags = FLAG_ADVANCED,
2842 .label = "set primary group script",
2844 .p_class = P_GLOBAL,
2845 .offset = GLOBAL_VAR(szSetPrimaryGroupScript),
2848 .flags = FLAG_ADVANCED,
2851 .label = "add machine script",
2853 .p_class = P_GLOBAL,
2854 .offset = GLOBAL_VAR(szAddMachineScript),
2857 .flags = FLAG_ADVANCED,
2860 .label = "shutdown script",
2862 .p_class = P_GLOBAL,
2863 .offset = GLOBAL_VAR(szShutdownScript),
2866 .flags = FLAG_ADVANCED,
2869 .label = "abort shutdown script",
2871 .p_class = P_GLOBAL,
2872 .offset = GLOBAL_VAR(szAbortShutdownScript),
2875 .flags = FLAG_ADVANCED,
2878 .label = "username map script",
2880 .p_class = P_GLOBAL,
2881 .offset = GLOBAL_VAR(szUsernameMapScript),
2884 .flags = FLAG_ADVANCED,
2887 .label = "username map cache time",
2889 .p_class = P_GLOBAL,
2890 .offset = GLOBAL_VAR(iUsernameMapCacheTime),
2893 .flags = FLAG_ADVANCED,
2896 .label = "logon script",
2898 .p_class = P_GLOBAL,
2899 .offset = GLOBAL_VAR(szLogonScript),
2902 .flags = FLAG_ADVANCED,
2905 .label = "logon path",
2907 .p_class = P_GLOBAL,
2908 .offset = GLOBAL_VAR(szLogonPath),
2911 .flags = FLAG_ADVANCED,
2914 .label = "logon drive",
2916 .p_class = P_GLOBAL,
2917 .offset = GLOBAL_VAR(szLogonDrive),
2920 .flags = FLAG_ADVANCED,
2923 .label = "logon home",
2925 .p_class = P_GLOBAL,
2926 .offset = GLOBAL_VAR(szLogonHome),
2929 .flags = FLAG_ADVANCED,
2932 .label = "domain logons",
2934 .p_class = P_GLOBAL,
2935 .offset = GLOBAL_VAR(bDomainLogons),
2938 .flags = FLAG_ADVANCED,
2942 .label = "init logon delayed hosts",
2944 .p_class = P_GLOBAL,
2945 .offset = GLOBAL_VAR(szInitLogonDelayedHosts),
2948 .flags = FLAG_ADVANCED,
2952 .label = "init logon delay",
2954 .p_class = P_GLOBAL,
2955 .offset = GLOBAL_VAR(InitLogonDelay),
2958 .flags = FLAG_ADVANCED,
2962 {N_("Browse Options"), P_SEP, P_SEPARATOR},
2965 .label = "os level",
2967 .p_class = P_GLOBAL,
2968 .offset = GLOBAL_VAR(os_level),
2971 .flags = FLAG_BASIC | FLAG_ADVANCED,
2974 .label = "lm announce",
2976 .p_class = P_GLOBAL,
2977 .offset = GLOBAL_VAR(lm_announce),
2979 .enum_list = enum_bool_auto,
2980 .flags = FLAG_ADVANCED,
2983 .label = "lm interval",
2985 .p_class = P_GLOBAL,
2986 .offset = GLOBAL_VAR(lm_interval),
2989 .flags = FLAG_ADVANCED,
2992 .label = "preferred master",
2994 .p_class = P_GLOBAL,
2995 .offset = GLOBAL_VAR(iPreferredMaster),
2997 .enum_list = enum_bool_auto,
2998 .flags = FLAG_BASIC | FLAG_ADVANCED,
3001 .label = "prefered master",
3003 .p_class = P_GLOBAL,
3004 .offset = GLOBAL_VAR(iPreferredMaster),
3006 .enum_list = enum_bool_auto,
3010 .label = "local master",
3012 .p_class = P_GLOBAL,
3013 .offset = GLOBAL_VAR(bLocalMaster),
3016 .flags = FLAG_BASIC | FLAG_ADVANCED,
3019 .label = "domain master",
3021 .p_class = P_GLOBAL,
3022 .offset = GLOBAL_VAR(iDomainMaster),
3024 .enum_list = enum_bool_auto,
3025 .flags = FLAG_BASIC | FLAG_ADVANCED,
3028 .label = "browse list",
3030 .p_class = P_GLOBAL,
3031 .offset = GLOBAL_VAR(bBrowseList),
3034 .flags = FLAG_ADVANCED,
3037 .label = "browseable",
3040 .offset = LOCAL_VAR(bBrowseable),
3043 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3046 .label = "browsable",
3049 .offset = LOCAL_VAR(bBrowseable),
3055 .label = "access based share enum",
3058 .offset = LOCAL_VAR(bAccessBasedShareEnum),
3061 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3064 .label = "enhanced browsing",
3066 .p_class = P_GLOBAL,
3067 .offset = GLOBAL_VAR(enhanced_browsing),
3070 .flags = FLAG_ADVANCED,
3073 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3076 .label = "dns proxy",
3078 .p_class = P_GLOBAL,
3079 .offset = GLOBAL_VAR(bDNSproxy),
3082 .flags = FLAG_ADVANCED,
3085 .label = "wins proxy",
3087 .p_class = P_GLOBAL,
3088 .offset = GLOBAL_VAR(bWINSproxy),
3091 .flags = FLAG_ADVANCED,
3094 .label = "wins server",
3096 .p_class = P_GLOBAL,
3097 .offset = GLOBAL_VAR(szWINSservers),
3100 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3103 .label = "wins support",
3105 .p_class = P_GLOBAL,
3106 .offset = GLOBAL_VAR(bWINSsupport),
3109 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3112 .label = "wins hook",
3114 .p_class = P_GLOBAL,
3115 .offset = GLOBAL_VAR(szWINSHook),
3118 .flags = FLAG_ADVANCED,
3121 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3124 .label = "blocking locks",
3127 .offset = LOCAL_VAR(bBlockingLocks),
3130 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3133 .label = "csc policy",
3136 .offset = LOCAL_VAR(iCSCPolicy),
3138 .enum_list = enum_csc_policy,
3139 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3142 .label = "fake oplocks",
3145 .offset = LOCAL_VAR(bFakeOplocks),
3148 .flags = FLAG_ADVANCED | FLAG_SHARE,
3151 .label = "kernel oplocks",
3153 .p_class = P_GLOBAL,
3154 .offset = GLOBAL_VAR(bKernelOplocks),
3157 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3163 .offset = LOCAL_VAR(bLocking),
3166 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3169 .label = "lock spin time",
3171 .p_class = P_GLOBAL,
3172 .offset = GLOBAL_VAR(iLockSpinTime),
3175 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3181 .offset = LOCAL_VAR(bOpLocks),
3184 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3187 .label = "level2 oplocks",
3190 .offset = LOCAL_VAR(bLevel2OpLocks),
3193 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3196 .label = "oplock break wait time",
3198 .p_class = P_GLOBAL,
3199 .offset = GLOBAL_VAR(oplock_break_wait_time),
3202 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3205 .label = "oplock contention limit",
3208 .offset = LOCAL_VAR(iOplockContentionLimit),
3211 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3214 .label = "posix locking",
3217 .offset = LOCAL_VAR(bPosixLocking),
3220 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3223 .label = "strict locking",
3226 .offset = LOCAL_VAR(iStrictLocking),
3228 .enum_list = enum_bool_auto,
3229 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3232 .label = "share modes",
3235 .offset = LOCAL_VAR(bShareModes),
3238 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3241 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3244 .label = "ldap admin dn",
3246 .p_class = P_GLOBAL,
3247 .offset = GLOBAL_VAR(szLdapAdminDn),
3250 .flags = FLAG_ADVANCED,
3253 .label = "ldap delete dn",
3255 .p_class = P_GLOBAL,
3256 .offset = GLOBAL_VAR(ldap_delete_dn),
3259 .flags = FLAG_ADVANCED,
3262 .label = "ldap group suffix",
3264 .p_class = P_GLOBAL,
3265 .offset = GLOBAL_VAR(szLdapGroupSuffix),
3268 .flags = FLAG_ADVANCED,
3271 .label = "ldap idmap suffix",
3273 .p_class = P_GLOBAL,
3274 .offset = GLOBAL_VAR(szLdapIdmapSuffix),
3277 .flags = FLAG_ADVANCED,
3280 .label = "ldap machine suffix",
3282 .p_class = P_GLOBAL,
3283 .offset = GLOBAL_VAR(szLdapMachineSuffix),
3286 .flags = FLAG_ADVANCED,
3289 .label = "ldap passwd sync",
3291 .p_class = P_GLOBAL,
3292 .offset = GLOBAL_VAR(ldap_passwd_sync),
3294 .enum_list = enum_ldap_passwd_sync,
3295 .flags = FLAG_ADVANCED,
3298 .label = "ldap password sync",
3300 .p_class = P_GLOBAL,
3301 .offset = GLOBAL_VAR(ldap_passwd_sync),
3303 .enum_list = enum_ldap_passwd_sync,
3307 .label = "ldap replication sleep",
3309 .p_class = P_GLOBAL,
3310 .offset = GLOBAL_VAR(ldap_replication_sleep),
3313 .flags = FLAG_ADVANCED,
3316 .label = "ldap suffix",
3318 .p_class = P_GLOBAL,
3319 .offset = GLOBAL_VAR(szLdapSuffix),
3322 .flags = FLAG_ADVANCED,
3325 .label = "ldap ssl",
3327 .p_class = P_GLOBAL,
3328 .offset = GLOBAL_VAR(ldap_ssl),
3330 .enum_list = enum_ldap_ssl,
3331 .flags = FLAG_ADVANCED,
3334 .label = "ldap ssl ads",
3336 .p_class = P_GLOBAL,
3337 .offset = GLOBAL_VAR(ldap_ssl_ads),
3340 .flags = FLAG_ADVANCED,
3343 .label = "ldap deref",
3345 .p_class = P_GLOBAL,
3346 .offset = GLOBAL_VAR(ldap_deref),
3348 .enum_list = enum_ldap_deref,
3349 .flags = FLAG_ADVANCED,
3352 .label = "ldap follow referral",
3354 .p_class = P_GLOBAL,
3355 .offset = GLOBAL_VAR(ldap_follow_referral),
3357 .enum_list = enum_bool_auto,
3358 .flags = FLAG_ADVANCED,
3361 .label = "ldap timeout",
3363 .p_class = P_GLOBAL,
3364 .offset = GLOBAL_VAR(ldap_timeout),
3367 .flags = FLAG_ADVANCED,
3370 .label = "ldap connection timeout",
3372 .p_class = P_GLOBAL,
3373 .offset = GLOBAL_VAR(ldap_connection_timeout),
3376 .flags = FLAG_ADVANCED,
3379 .label = "ldap page size",
3381 .p_class = P_GLOBAL,
3382 .offset = GLOBAL_VAR(ldap_page_size),
3385 .flags = FLAG_ADVANCED,
3388 .label = "ldap user suffix",
3390 .p_class = P_GLOBAL,
3391 .offset = GLOBAL_VAR(szLdapUserSuffix),
3394 .flags = FLAG_ADVANCED,
3397 .label = "ldap debug level",
3399 .p_class = P_GLOBAL,
3400 .offset = GLOBAL_VAR(ldap_debug_level),
3401 .special = handle_ldap_debug_level,
3403 .flags = FLAG_ADVANCED,
3406 .label = "ldap debug threshold",
3408 .p_class = P_GLOBAL,
3409 .offset = GLOBAL_VAR(ldap_debug_threshold),
3412 .flags = FLAG_ADVANCED,
3415 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3418 .label = "eventlog list",
3420 .p_class = P_GLOBAL,
3421 .offset = GLOBAL_VAR(szEventLogs),
3424 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3427 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3430 .label = "add share command",
3432 .p_class = P_GLOBAL,
3433 .offset = GLOBAL_VAR(szAddShareCommand),
3436 .flags = FLAG_ADVANCED,
3439 .label = "change share command",
3441 .p_class = P_GLOBAL,
3442 .offset = GLOBAL_VAR(szChangeShareCommand),
3445 .flags = FLAG_ADVANCED,
3448 .label = "delete share command",
3450 .p_class = P_GLOBAL,
3451 .offset = GLOBAL_VAR(szDeleteShareCommand),
3454 .flags = FLAG_ADVANCED,
3457 .label = "config file",
3459 .p_class = P_GLOBAL,
3460 .offset = GLOBAL_VAR(szConfigFile),
3463 .flags = FLAG_HIDE|FLAG_META,
3468 .p_class = P_GLOBAL,
3469 .offset = GLOBAL_VAR(szAutoServices),
3472 .flags = FLAG_ADVANCED,
3475 .label = "auto services",
3477 .p_class = P_GLOBAL,
3478 .offset = GLOBAL_VAR(szAutoServices),
3481 .flags = FLAG_ADVANCED,
3484 .label = "lock directory",
3486 .p_class = P_GLOBAL,
3487 .offset = GLOBAL_VAR(szLockDir),
3490 .flags = FLAG_ADVANCED,
3493 .label = "lock dir",
3495 .p_class = P_GLOBAL,
3496 .offset = GLOBAL_VAR(szLockDir),
3502 .label = "state directory",
3504 .p_class = P_GLOBAL,
3505 .offset = GLOBAL_VAR(szStateDir),
3508 .flags = FLAG_ADVANCED,
3511 .label = "cache directory",
3513 .p_class = P_GLOBAL,
3514 .offset = GLOBAL_VAR(szCacheDir),
3517 .flags = FLAG_ADVANCED,
3520 .label = "pid directory",
3522 .p_class = P_GLOBAL,
3523 .offset = GLOBAL_VAR(szPidDir),
3526 .flags = FLAG_ADVANCED,
3530 .label = "utmp directory",
3532 .p_class = P_GLOBAL,
3533 .offset = GLOBAL_VAR(szUtmpDir),
3536 .flags = FLAG_ADVANCED,
3539 .label = "wtmp directory",
3541 .p_class = P_GLOBAL,
3542 .offset = GLOBAL_VAR(szWtmpDir),
3545 .flags = FLAG_ADVANCED,
3550 .p_class = P_GLOBAL,
3551 .offset = GLOBAL_VAR(bUtmp),
3554 .flags = FLAG_ADVANCED,
3558 .label = "default service",
3560 .p_class = P_GLOBAL,
3561 .offset = GLOBAL_VAR(szDefaultService),
3564 .flags = FLAG_ADVANCED,
3569 .p_class = P_GLOBAL,
3570 .offset = GLOBAL_VAR(szDefaultService),
3573 .flags = FLAG_ADVANCED,
3576 .label = "message command",
3578 .p_class = P_GLOBAL,
3579 .offset = GLOBAL_VAR(szMsgCommand),
3582 .flags = FLAG_ADVANCED,
3585 .label = "dfree cache time",
3588 .offset = LOCAL_VAR(iDfreeCacheTime),
3591 .flags = FLAG_ADVANCED,
3594 .label = "dfree command",
3597 .offset = LOCAL_VAR(szDfree),
3600 .flags = FLAG_ADVANCED,
3603 .label = "get quota command",
3605 .p_class = P_GLOBAL,
3606 .offset = GLOBAL_VAR(szGetQuota),
3609 .flags = FLAG_ADVANCED,
3612 .label = "set quota command",
3614 .p_class = P_GLOBAL,
3615 .offset = GLOBAL_VAR(szSetQuota),
3618 .flags = FLAG_ADVANCED,
3621 .label = "remote announce",
3623 .p_class = P_GLOBAL,
3624 .offset = GLOBAL_VAR(szRemoteAnnounce),
3627 .flags = FLAG_ADVANCED,
3630 .label = "remote browse sync",
3632 .p_class = P_GLOBAL,
3633 .offset = GLOBAL_VAR(szRemoteBrowseSync),
3636 .flags = FLAG_ADVANCED,
3639 .label = "socket address",
3641 .p_class = P_GLOBAL,
3642 .offset = GLOBAL_VAR(szSocketAddress),
3645 .flags = FLAG_ADVANCED,
3648 .label = "nmbd bind explicit broadcast",
3650 .p_class = P_GLOBAL,
3651 .offset = GLOBAL_VAR(bNmbdBindExplicitBroadcast),
3654 .flags = FLAG_ADVANCED,
3657 .label = "homedir map",
3659 .p_class = P_GLOBAL,
3660 .offset = GLOBAL_VAR(szNISHomeMapName),
3663 .flags = FLAG_ADVANCED,
3666 .label = "afs username map",
3668 .p_class = P_GLOBAL,
3669 .offset = GLOBAL_VAR(szAfsUsernameMap),
3672 .flags = FLAG_ADVANCED,
3675 .label = "afs token lifetime",
3677 .p_class = P_GLOBAL,
3678 .offset = GLOBAL_VAR(iAfsTokenLifetime),
3681 .flags = FLAG_ADVANCED,
3684 .label = "log nt token command",
3686 .p_class = P_GLOBAL,
3687 .offset = GLOBAL_VAR(szLogNtTokenCommand),
3690 .flags = FLAG_ADVANCED,
3693 .label = "NIS homedir",
3695 .p_class = P_GLOBAL,
3696 .offset = GLOBAL_VAR(bNISHomeMap),
3699 .flags = FLAG_ADVANCED,
3705 .offset = LOCAL_VAR(valid),
3714 .offset = LOCAL_VAR(szCopy),
3715 .special = handle_copy,
3723 .offset = LOCAL_VAR(szInclude),
3724 .special = handle_include,
3726 .flags = FLAG_HIDE|FLAG_META,
3732 .offset = LOCAL_VAR(szPreExec),
3735 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3741 .offset = LOCAL_VAR(szPreExec),
3744 .flags = FLAG_ADVANCED,
3747 .label = "preexec close",
3750 .offset = LOCAL_VAR(bPreexecClose),
3753 .flags = FLAG_ADVANCED | FLAG_SHARE,
3756 .label = "postexec",
3759 .offset = LOCAL_VAR(szPostExec),
3762 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3765 .label = "root preexec",
3768 .offset = LOCAL_VAR(szRootPreExec),
3771 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3774 .label = "root preexec close",
3777 .offset = LOCAL_VAR(bRootpreexecClose),
3780 .flags = FLAG_ADVANCED | FLAG_SHARE,
3783 .label = "root postexec",
3786 .offset = LOCAL_VAR(szRootPostExec),
3789 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3792 .label = "available",
3795 .offset = LOCAL_VAR(bAvailable),
3798 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3801 .label = "registry shares",
3803 .p_class = P_GLOBAL,
3804 .offset = GLOBAL_VAR(bRegistryShares),
3807 .flags = FLAG_ADVANCED,
3810 .label = "usershare allow guests",
3812 .p_class = P_GLOBAL,
3813 .offset = GLOBAL_VAR(bUsershareAllowGuests),
3816 .flags = FLAG_ADVANCED,
3819 .label = "usershare max shares",
3821 .p_class = P_GLOBAL,
3822 .offset = GLOBAL_VAR(iUsershareMaxShares),
3825 .flags = FLAG_ADVANCED,
3828 .label = "usershare owner only",
3830 .p_class = P_GLOBAL,
3831 .offset = GLOBAL_VAR(bUsershareOwnerOnly),
3834 .flags = FLAG_ADVANCED,
3837 .label = "usershare path",
3839 .p_class = P_GLOBAL,
3840 .offset = GLOBAL_VAR(szUsersharePath),
3843 .flags = FLAG_ADVANCED,
3846 .label = "usershare prefix allow list",
3848 .p_class = P_GLOBAL,
3849 .offset = GLOBAL_VAR(szUsersharePrefixAllowList),
3852 .flags = FLAG_ADVANCED,
3855 .label = "usershare prefix deny list",
3857 .p_class = P_GLOBAL,
3858 .offset = GLOBAL_VAR(szUsersharePrefixDenyList),
3861 .flags = FLAG_ADVANCED,
3864 .label = "usershare template share",
3866 .p_class = P_GLOBAL,
3867 .offset = GLOBAL_VAR(szUsershareTemplateShare),
3870 .flags = FLAG_ADVANCED,
3876 .offset = LOCAL_VAR(volume),
3879 .flags = FLAG_ADVANCED | FLAG_SHARE,
3885 .offset = LOCAL_VAR(fstype),
3888 .flags = FLAG_ADVANCED | FLAG_SHARE,
3891 .label = "set directory",
3894 .offset = LOCAL_VAR(bNo_set_dir),
3897 .flags = FLAG_ADVANCED | FLAG_SHARE,
3900 .label = "wide links",
3903 .offset = LOCAL_VAR(bWidelinks),
3906 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3909 .label = "follow symlinks",
3912 .offset = LOCAL_VAR(bSymlinks),
3915 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3918 .label = "dont descend",
3921 .offset = LOCAL_VAR(szDontdescend),
3924 .flags = FLAG_ADVANCED | FLAG_SHARE,
3927 .label = "magic script",
3930 .offset = LOCAL_VAR(szMagicScript),
3933 .flags = FLAG_ADVANCED | FLAG_SHARE,
3936 .label = "magic output",
3939 .offset = LOCAL_VAR(szMagicOutput),
3942 .flags = FLAG_ADVANCED | FLAG_SHARE,
3945 .label = "delete readonly",
3948 .offset = LOCAL_VAR(bDeleteReadonly),
3951 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3954 .label = "dos filemode",
3957 .offset = LOCAL_VAR(bDosFilemode),
3960 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3963 .label = "dos filetimes",
3966 .offset = LOCAL_VAR(bDosFiletimes),
3969 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3972 .label = "dos filetime resolution",
3975 .offset = LOCAL_VAR(bDosFiletimeResolution),
3978 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3981 .label = "fake directory create times",
3984 .offset = LOCAL_VAR(bFakeDirCreateTimes),
3987 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3990 .label = "async smb echo handler",
3992 .p_class = P_GLOBAL,
3993 .offset = GLOBAL_VAR(bAsyncSMBEchoHandler),
3996 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3999 .label = "multicast dns register",
4001 .p_class = P_GLOBAL,
4002 .offset = GLOBAL_VAR(bMulticastDnsRegister),
4005 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4008 .label = "panic action",
4010 .p_class = P_GLOBAL,
4011 .offset = GLOBAL_VAR(szPanicAction),
4014 .flags = FLAG_ADVANCED,
4017 .label = "perfcount module",
4019 .p_class = P_GLOBAL,
4020 .offset = GLOBAL_VAR(szSMBPerfcountModule),
4023 .flags = FLAG_ADVANCED,
4026 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4029 .label = "vfs objects",
4032 .offset = LOCAL_VAR(szVfsObjects),
4035 .flags = FLAG_ADVANCED | FLAG_SHARE,
4038 .label = "vfs object",
4041 .offset = LOCAL_VAR(szVfsObjects),
4048 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4051 .label = "msdfs root",
4054 .offset = LOCAL_VAR(bMSDfsRoot),
4057 .flags = FLAG_ADVANCED | FLAG_SHARE,
4060 .label = "msdfs proxy",
4063 .offset = LOCAL_VAR(szMSDfsProxy),
4066 .flags = FLAG_ADVANCED | FLAG_SHARE,
4069 .label = "host msdfs",
4071 .p_class = P_GLOBAL,
4072 .offset = GLOBAL_VAR(bHostMSDfs),
4075 .flags = FLAG_ADVANCED,
4078 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4081 .label = "passdb expand explicit",
4083 .p_class = P_GLOBAL,
4084 .offset = GLOBAL_VAR(bPassdbExpandExplicit),
4087 .flags = FLAG_ADVANCED,
4090 .label = "idmap backend",
4092 .p_class = P_GLOBAL,
4093 .offset = GLOBAL_VAR(szIdmapBackend),
4094 .special = handle_idmap_backend,
4096 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4099 .label = "idmap cache time",
4101 .p_class = P_GLOBAL,
4102 .offset = GLOBAL_VAR(iIdmapCacheTime),
4105 .flags = FLAG_ADVANCED,
4108 .label = "idmap negative cache time",
4110 .p_class = P_GLOBAL,
4111 .offset = GLOBAL_VAR(iIdmapNegativeCacheTime),
4114 .flags = FLAG_ADVANCED,
4117 .label = "idmap uid",
4119 .p_class = P_GLOBAL,
4120 .offset = GLOBAL_VAR(szIdmapUID),
4121 .special = handle_idmap_uid,
4123 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4126 .label = "winbind uid",
4128 .p_class = P_GLOBAL,
4129 .offset = GLOBAL_VAR(szIdmapUID),
4130 .special = handle_idmap_uid,
4135 .label = "idmap gid",
4137 .p_class = P_GLOBAL,
4138 .offset = GLOBAL_VAR(szIdmapGID),
4139 .special = handle_idmap_gid,
4141 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4144 .label = "winbind gid",
4146 .p_class = P_GLOBAL,
4147 .offset = GLOBAL_VAR(szIdmapGID),
4148 .special = handle_idmap_gid,
4153 .label = "template homedir",
4155 .p_class = P_GLOBAL,
4156 .offset = GLOBAL_VAR(szTemplateHomedir),
4159 .flags = FLAG_ADVANCED,
4162 .label = "template shell",
4164 .p_class = P_GLOBAL,
4165 .offset = GLOBAL_VAR(szTemplateShell),
4168 .flags = FLAG_ADVANCED,
4171 .label = "winbind separator",
4173 .p_class = P_GLOBAL,
4174 .offset = GLOBAL_VAR(szWinbindSeparator),
4177 .flags = FLAG_ADVANCED,
4180 .label = "winbind cache time",
4182 .p_class = P_GLOBAL,
4183 .offset = GLOBAL_VAR(winbind_cache_time),
4186 .flags = FLAG_ADVANCED,
4189 .label = "winbind reconnect delay",
4191 .p_class = P_GLOBAL,
4192 .offset = GLOBAL_VAR(winbind_reconnect_delay),
4195 .flags = FLAG_ADVANCED,
4198 .label = "winbind max clients",
4200 .p_class = P_GLOBAL,
4201 .offset = GLOBAL_VAR(winbind_max_clients),
4204 .flags = FLAG_ADVANCED,
4207 .label = "winbind enum users",
4209 .p_class = P_GLOBAL,
4210 .offset = GLOBAL_VAR(bWinbindEnumUsers),
4213 .flags = FLAG_ADVANCED,
4216 .label = "winbind enum groups",
4218 .p_class = P_GLOBAL,
4219 .offset = GLOBAL_VAR(bWinbindEnumGroups),
4222 .flags = FLAG_ADVANCED,
4225 .label = "winbind use default domain",
4227 .p_class = P_GLOBAL,
4228 .offset = GLOBAL_VAR(bWinbindUseDefaultDomain),
4231 .flags = FLAG_ADVANCED,
4234 .label = "winbind trusted domains only",
4236 .p_class = P_GLOBAL,
4237 .offset = GLOBAL_VAR(bWinbindTrustedDomainsOnly),
4240 .flags = FLAG_ADVANCED,
4243 .label = "winbind nested groups",
4245 .p_class = P_GLOBAL,
4246 .offset = GLOBAL_VAR(bWinbindNestedGroups),
4249 .flags = FLAG_ADVANCED,
4252 .label = "winbind expand groups",
4254 .p_class = P_GLOBAL,
4255 .offset = GLOBAL_VAR(winbind_expand_groups),
4258 .flags = FLAG_ADVANCED,
4261 .label = "winbind nss info",
4263 .p_class = P_GLOBAL,
4264 .offset = GLOBAL_VAR(szWinbindNssInfo),
4267 .flags = FLAG_ADVANCED,
4270 .label = "winbind refresh tickets",
4272 .p_class = P_GLOBAL,
4273 .offset = GLOBAL_VAR(bWinbindRefreshTickets),
4276 .flags = FLAG_ADVANCED,
4279 .label = "winbind offline logon",
4281 .p_class = P_GLOBAL,
4282 .offset = GLOBAL_VAR(bWinbindOfflineLogon),
4285 .flags = FLAG_ADVANCED,
4288 .label = "winbind normalize names",
4290 .p_class = P_GLOBAL,
4291 .offset = GLOBAL_VAR(bWinbindNormalizeNames),
4294 .flags = FLAG_ADVANCED,
4297 .label = "winbind rpc only",
4299 .p_class = P_GLOBAL,
4300 .offset = GLOBAL_VAR(bWinbindRpcOnly),
4303 .flags = FLAG_ADVANCED,
4306 .label = "create krb5 conf",
4308 .p_class = P_GLOBAL,
4309 .offset = GLOBAL_VAR(bCreateKrb5Conf),
4312 .flags = FLAG_ADVANCED,
4315 .label = "ncalrpc dir",
4317 .p_class = P_GLOBAL,
4318 .offset = GLOBAL_VAR(ncalrpc_dir),
4321 .flags = FLAG_ADVANCED,
4324 .label = "winbind max domain connections",
4326 .p_class = P_GLOBAL,
4327 .offset = GLOBAL_VAR(winbindMaxDomainConnections),
4330 .flags = FLAG_ADVANCED,
4333 {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0}
4336 /***************************************************************************
4337 Initialise the sDefault parameter structure for the printer values.
4338 ***************************************************************************/
4340 static void init_printer_values(struct loadparm_service *pService)
4342 /* choose defaults depending on the type of printing */
4343 switch (pService->iPrinting) {
4348 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4349 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4350 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4355 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4356 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4357 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4358 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4359 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4360 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4361 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4367 /* set the lpq command to contain the destination printer
4368 name only. This is used by cups_queue_get() */
4369 string_set(&pService->szLpqcommand, "%p");
4370 string_set(&pService->szLprmcommand, "");
4371 string_set(&pService->szPrintcommand, "");
4372 string_set(&pService->szLppausecommand, "");
4373 string_set(&pService->szLpresumecommand, "");
4374 string_set(&pService->szQueuepausecommand, "");
4375 string_set(&pService->szQueueresumecommand, "");
4377 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4378 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4379 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4380 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4381 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4382 string_set(&pService->szQueuepausecommand, "disable '%p'");
4383 string_set(&pService->szQueueresumecommand, "enable '%p'");
4384 #endif /* HAVE_CUPS */
4389 string_set(&pService->szLpqcommand, "lpstat -o%p");
4390 string_set(&pService->szLprmcommand, "cancel %p-%j");
4391 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4392 string_set(&pService->szQueuepausecommand, "disable %p");
4393 string_set(&pService->szQueueresumecommand, "enable %p");
4395 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4396 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4401 string_set(&pService->szLpqcommand, "lpq -P%p");
4402 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4403 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4406 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4410 const char *tdbfile;
4413 tdbfile = talloc_asprintf(
4414 talloc_tos(), "tdbfile=%s",
4415 lp_parm_const_string(-1, "vlp", "tdbfile",
4417 if (tdbfile == NULL) {
4418 tdbfile="tdbfile=/tmp/vlp.tdb";
4421 tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
4423 string_set(&pService->szPrintcommand,
4424 tmp ? tmp : "vlp print %p %s");
4427 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
4429 string_set(&pService->szLpqcommand,
4430 tmp ? tmp : "vlp lpq %p");
4433 tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
4435 string_set(&pService->szLprmcommand,
4436 tmp ? tmp : "vlp lprm %p %j");
4439 tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
4441 string_set(&pService->szLppausecommand,
4442 tmp ? tmp : "vlp lppause %p %j");
4445 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
4447 string_set(&pService->szLpresumecommand,
4448 tmp ? tmp : "vlp lpresume %p %j");
4451 tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
4453 string_set(&pService->szQueuepausecommand,
4454 tmp ? tmp : "vlp queuepause %p");
4457 tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
4459 string_set(&pService->szQueueresumecommand,
4460 tmp ? tmp : "vlp queueresume %p");
4465 #endif /* DEVELOPER */
4470 * Function to return the default value for the maximum number of open
4471 * file descriptors permitted. This function tries to consult the
4472 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4473 * the smaller of those.
4475 static int max_open_files(void)
4477 int sysctl_max = MAX_OPEN_FILES;
4478 int rlimit_max = MAX_OPEN_FILES;
4480 #ifdef HAVE_SYSCTLBYNAME
4482 size_t size = sizeof(sysctl_max);
4483 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4488 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4494 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4495 rlimit_max = rl.rlim_cur;
4497 #if defined(RLIM_INFINITY)
4498 if(rl.rlim_cur == RLIM_INFINITY)
4499 rlimit_max = MAX_OPEN_FILES;
4504 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4505 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4506 "minimum Windows limit (%d)\n",
4508 MIN_OPEN_FILES_WINDOWS));
4509 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4512 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4513 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4514 "minimum Windows limit (%d)\n",
4516 MIN_OPEN_FILES_WINDOWS));
4517 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4520 return MIN(sysctl_max, rlimit_max);
4524 * Common part of freeing allocated data for one parameter.
4526 static void free_one_parameter_common(void *parm_ptr,
4527 struct parm_struct parm)
4529 if ((parm.type == P_STRING) ||
4530 (parm.type == P_USTRING))
4532 string_free((char**)parm_ptr);
4533 } else if (parm.type == P_LIST) {
4534 TALLOC_FREE(*((char***)parm_ptr));
4539 * Free the allocated data for one parameter for a share
4540 * given as a service struct.
4542 static void free_one_parameter(struct loadparm_service *service,
4543 struct parm_struct parm)
4547 if (parm.p_class != P_LOCAL) {
4551 parm_ptr = lp_parm_ptr(service, &parm);
4553 free_one_parameter_common(parm_ptr, parm);
4557 * Free the allocated parameter data of a share given
4558 * as a service struct.
4560 static void free_parameters(struct loadparm_service *service)
4564 for (i=0; parm_table[i].label; i++) {
4565 free_one_parameter(service, parm_table[i]);
4570 * Free the allocated data for one parameter for a given share
4571 * specified by an snum.
4573 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4578 parm_ptr = lp_parm_ptr(NULL, &parm);
4579 } else if (parm.p_class != P_LOCAL) {
4582 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
4585 free_one_parameter_common(parm_ptr, parm);
4589 * Free the allocated parameter data for a share specified
4592 static void free_parameters_by_snum(int snum)
4596 for (i=0; parm_table[i].label; i++) {
4597 free_one_parameter_by_snum(snum, parm_table[i]);
4602 * Free the allocated global parameters.
4604 static void free_global_parameters(void)
4606 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4609 static int map_parameter(const char *pszParmName);
4611 struct lp_stored_option {
4612 struct lp_stored_option *prev, *next;
4617 static struct lp_stored_option *stored_options;
4620 save options set by lp_set_cmdline() into a list. This list is
4621 re-applied when we do a globals reset, so that cmdline set options
4622 are sticky across reloads of smb.conf
4624 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
4626 struct lp_stored_option *entry, *entry_next;
4627 for (entry = stored_options; entry != NULL; entry = entry_next) {
4628 entry_next = entry->next;
4629 if (strcmp(pszParmName, entry->label) == 0) {
4630 DLIST_REMOVE(stored_options, entry);
4636 entry = talloc(NULL, struct lp_stored_option);
4641 entry->label = talloc_strdup(entry, pszParmName);
4642 if (!entry->label) {
4647 entry->value = talloc_strdup(entry, pszParmValue);
4648 if (!entry->value) {
4653 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
4658 static bool apply_lp_set_cmdline(void)
4660 struct lp_stored_option *entry = NULL;
4661 for (entry = stored_options; entry != NULL; entry = entry->next) {
4662 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
4663 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
4664 entry->label, entry->value));
4671 /***************************************************************************
4672 Initialise the global parameter structure.
4673 ***************************************************************************/
4675 static void init_globals(bool reinit_globals)
4677 static bool done_init = false;
4681 /* If requested to initialize only once and we've already done it... */
4682 if (!reinit_globals && done_init) {
4683 /* ... then we have nothing more to do */
4688 /* The logfile can be set before this is invoked. Free it if so. */
4689 if (Globals.szLogFile != NULL) {
4690 string_free(&Globals.szLogFile);
4691 Globals.szLogFile = NULL;
4695 free_global_parameters();
4698 /* This memset and the free_global_parameters() above will
4699 * wipe out smb.conf options set with lp_set_cmdline(). The
4700 * apply_lp_set_cmdline() call puts these values back in the
4701 * table once the defaults are set */
4702 memset((void *)&Globals, '\0', sizeof(Globals));
4704 for (i = 0; parm_table[i].label; i++) {
4705 if ((parm_table[i].type == P_STRING ||
4706 parm_table[i].type == P_USTRING))
4708 string_set(lp_parm_ptr(NULL, &parm_table[i]), "");
4713 string_set(&sDefault.fstype, FSTYPE_STRING);
4714 string_set(&sDefault.szPrintjobUsername, "%U");
4716 init_printer_values(&sDefault);
4719 DEBUG(3, ("Initialising global parameters\n"));
4721 /* Must manually force to upper case here, as this does not go via the handler */
4722 string_set(&Globals.szNetbiosName, myhostname_upper());
4724 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4725 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4727 /* use the new 'hash2' method by default, with a prefix of 1 */
4728 string_set(&Globals.szManglingMethod, "hash2");
4729 Globals.mangle_prefix = 1;
4731 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4733 /* using UTF8 by default allows us to support all chars */
4734 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4736 /* Use codepage 850 as a default for the dos character set */
4737 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4740 * Allow the default PASSWD_CHAT to be overridden in local.h.
4742 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4744 string_set(&Globals.szWorkgroup, DEFAULT_WORKGROUP);
4746 string_set(&Globals.szPasswdProgram, "");
4747 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4748 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4749 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4750 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4751 string_set(&Globals.szSocketAddress, "0.0.0.0");
4753 * By default support explicit binding to broadcast
4756 Globals.bNmbdBindExplicitBroadcast = true;
4758 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4759 smb_panic("init_globals: ENOMEM");
4761 string_set(&Globals.szServerString, s);
4764 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4767 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4769 string_set(&Globals.szLogonDrive, "");
4770 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4771 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4772 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4774 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4775 string_set(&Globals.szPasswordServer, "*");
4777 Globals.AlgorithmicRidBase = BASE_RID;
4779 Globals.bLoadPrinters = true;
4780 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4782 Globals.ConfigBackend = config_backend;
4784 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4785 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4786 Globals.max_xmit = 0x4104;
4787 Globals.max_mux = 50; /* This is *needed* for profile support. */
4788 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4789 Globals.bDisableSpoolss = false;
4790 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4791 Globals.pwordlevel = 0;
4792 Globals.unamelevel = 0;
4793 Globals.deadtime = 0;
4794 Globals.getwd_cache = true;
4795 Globals.bLargeReadwrite = true;
4796 Globals.max_log_size = 5000;
4797 Globals.max_open_files = max_open_files();
4798 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4799 Globals.maxprotocol = PROTOCOL_NT1;
4800 Globals.minprotocol = PROTOCOL_CORE;
4801 Globals.security = SEC_USER;
4802 Globals.paranoid_server_security = true;
4803 Globals.bEncryptPasswords = true;
4804 Globals.clientSchannel = Auto;
4805 Globals.serverSchannel = Auto;
4806 Globals.bReadRaw = true;
4807 Globals.bWriteRaw = true;
4808 Globals.bNullPasswords = false;
4809 Globals.bObeyPamRestrictions = false;
4811 Globals.bSyslogOnly = false;
4812 Globals.bTimestampLogs = true;
4813 string_set(&Globals.szLogLevel, "0");
4814 Globals.bDebugPrefixTimestamp = false;
4815 Globals.bDebugHiresTimestamp = true;
4816 Globals.bDebugPid = false;
4817 Globals.bDebugUid = false;
4818 Globals.bDebugClass = false;
4819 Globals.bEnableCoreFiles = true;
4820 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4821 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4822 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4823 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4824 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4825 Globals.lm_interval = 60;
4826 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4827 Globals.bNISHomeMap = false;
4828 #ifdef WITH_NISPLUS_HOME
4829 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4831 string_set(&Globals.szNISHomeMapName, "auto.home");
4834 Globals.bTimeServer = false;
4835 Globals.bBindInterfacesOnly = false;
4836 Globals.bUnixPasswdSync = false;
4837 Globals.bPamPasswordChange = false;
4838 Globals.bPasswdChatDebug = false;
4839 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4840 Globals.bNTPipeSupport = true; /* Do NT pipes by default. */
4841 Globals.bNTStatusSupport = true; /* Use NT status by default. */
4842 Globals.bStatCache = true; /* use stat cache by default */
4843 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4844 Globals.restrict_anonymous = 0;
4845 Globals.bClientLanManAuth = false; /* Do NOT use the LanMan hash if it is available */
4846 Globals.bClientPlaintextAuth = false; /* Do NOT use a plaintext password even if is requested by the server */
4847 Globals.bLanmanAuth = false; /* Do NOT use the LanMan hash, even if it is supplied */
4848 Globals.bNTLMAuth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4849 Globals.bClientNTLMv2Auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
4850 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
4852 Globals.map_to_guest = 0; /* By Default, "Never" */
4853 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4854 Globals.enhanced_browsing = true;
4855 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4856 #ifdef MMAP_BLACKLIST
4857 Globals.bUseMmap = false;
4859 Globals.bUseMmap = true;
4861 Globals.bUnixExtensions = true;
4862 Globals.bResetOnZeroVC = false;
4863 Globals.bLogWriteableFilesOnExit = false;
4864 Globals.bCreateKrb5Conf = true;
4865 Globals.winbindMaxDomainConnections = 1;
4867 /* hostname lookups can be very expensive and are broken on
4868 a large number of sites (tridge) */
4869 Globals.bHostnameLookups = false;
4871 string_set(&Globals.szPassdbBackend, "tdbsam");
4872 string_set(&Globals.szLdapSuffix, "");
4873 string_set(&Globals.szLdapMachineSuffix, "");
4874 string_set(&Globals.szLdapUserSuffix, "");
4875 string_set(&Globals.szLdapGroupSuffix, "");
4876 string_set(&Globals.szLdapIdmapSuffix, "");
4878 string_set(&Globals.szLdapAdminDn, "");
4879 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4880 Globals.ldap_ssl_ads = false;
4881 Globals.ldap_deref = -1;
4882 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4883 Globals.ldap_delete_dn = false;
4884 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4885 Globals.ldap_follow_referral = Auto;
4886 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4887 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4888 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4890 Globals.ldap_debug_level = 0;
4891 Globals.ldap_debug_threshold = 10;
4893 /* This is what we tell the afs client. in reality we set the token
4894 * to never expire, though, when this runs out the afs client will
4895 * forget the token. Set to 0 to get NEVERDATE.*/
4896 Globals.iAfsTokenLifetime = 604800;
4897 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
4899 /* these parameters are set to defaults that are more appropriate
4900 for the increasing samba install base:
4902 as a member of the workgroup, that will possibly become a
4903 _local_ master browser (lm = true). this is opposed to a forced
4904 local master browser startup (pm = true).
4906 doesn't provide WINS server service by default (wsupp = false),
4907 and doesn't provide domain master browser services by default, either.
4911 Globals.bMsAddPrinterWizard = true;
4912 Globals.os_level = 20;
4913 Globals.bLocalMaster = true;
4914 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4915 Globals.bDomainLogons = false;
4916 Globals.bBrowseList = true;
4917 Globals.bWINSsupport = false;
4918 Globals.bWINSproxy = false;
4920 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
4921 Globals.InitLogonDelay = 100; /* 100 ms default delay */
4923 Globals.bDNSproxy = true;
4925 /* this just means to use them if they exist */
4926 Globals.bKernelOplocks = true;
4928 Globals.bAllowTrustedDomains = true;
4929 string_set(&Globals.szIdmapBackend, "tdb");
4931 string_set(&Globals.szTemplateShell, "/bin/false");
4932 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4933 string_set(&Globals.szWinbindSeparator, "\\");
4935 string_set(&Globals.szCupsServer, "");
4936 string_set(&Globals.szIPrintServer, "");
4938 string_set(&Globals.ctdbdSocket, "");
4939 Globals.szClusterAddresses = NULL;
4940 Globals.clustering = false;
4941 Globals.ctdb_timeout = 0;
4942 Globals.ctdb_locktime_warn_threshold = 0;
4944 Globals.winbind_cache_time = 300; /* 5 minutes */
4945 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
4946 Globals.winbind_max_clients = 200;
4947 Globals.bWinbindEnumUsers = false;
4948 Globals.bWinbindEnumGroups = false;
4949 Globals.bWinbindUseDefaultDomain = false;
4950 Globals.bWinbindTrustedDomainsOnly = false;
4951 Globals.bWinbindNestedGroups = true;
4952 Globals.winbind_expand_groups = 1;
4953 Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
4954 Globals.bWinbindRefreshTickets = false;
4955 Globals.bWinbindOfflineLogon = false;
4957 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
4958 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4960 Globals.bPassdbExpandExplicit = false;
4962 Globals.name_cache_timeout = 660; /* In seconds */
4964 Globals.bUseSpnego = true;
4965 Globals.bClientUseSpnego = true;
4967 Globals.client_signing = Auto;
4968 Globals.server_signing = false;
4970 Globals.bDeferSharingViolations = true;
4971 string_set(&Globals.smb_ports, SMB_PORTS);
4973 Globals.bEnablePrivileges = true;
4974 Globals.bHostMSDfs = true;
4975 Globals.bASUSupport = false;
4977 /* User defined shares. */
4978 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4979 smb_panic("init_globals: ENOMEM");
4981 string_set(&Globals.szUsersharePath, s);
4983 string_set(&Globals.szUsershareTemplateShare, "");
4984 Globals.iUsershareMaxShares = 0;
4985 /* By default disallow sharing of directories not owned by the sharer. */
4986 Globals.bUsershareOwnerOnly = true;
4987 /* By default disallow guest access to usershares. */
4988 Globals.bUsershareAllowGuests = false;
4990 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4992 /* By default no shares out of the registry */
4993 Globals.bRegistryShares = false;
4995 Globals.iminreceivefile = 0;
4997 Globals.bMapUntrustedToDomain = false;
4998 Globals.bMulticastDnsRegister = true;
5000 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
5001 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
5002 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
5003 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5005 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5007 /* Now put back the settings that were set with lp_set_cmdline() */
5008 apply_lp_set_cmdline();
5011 /*******************************************************************
5012 Convenience routine to grab string parameters into temporary memory
5013 and run standard_sub_basic on them. The buffers can be written to by
5014 callers without affecting the source string.
5015 ********************************************************************/
5017 static char *lp_string(const char *s)
5020 TALLOC_CTX *ctx = talloc_tos();
5022 /* The follow debug is useful for tracking down memory problems
5023 especially if you have an inner loop that is calling a lp_*()
5024 function that returns a string. Perhaps this debug should be
5025 present all the time? */
5028 DEBUG(10, ("lp_string(%s)\n", s));
5034 ret = talloc_sub_basic(ctx,
5035 get_current_username(),
5036 current_user_info.domain,
5038 if (trim_char(ret, '\"', '\"')) {
5039 if (strchr(ret,'\"') != NULL) {
5041 ret = talloc_sub_basic(ctx,
5042 get_current_username(),
5043 current_user_info.domain,
5051 In this section all the functions that are used to access the
5052 parameters from the rest of the program are defined
5055 #define FN_GLOBAL_STRING(fn_name,ptr) \
5056 char *fn_name(void) {return(lp_string(*(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5057 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5058 const char *fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5059 #define FN_GLOBAL_LIST(fn_name,ptr) \
5060 const char **fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5061 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5062 bool fn_name(void) {return(*(bool *)(&Globals.ptr));}
5063 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5064 char fn_name(void) {return(*(char *)(&Globals.ptr));}
5065 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5066 int fn_name(void) {return(*(int *)(&Globals.ptr));}
5068 #define FN_LOCAL_STRING(fn_name,val) \
5069 char *lp_ ## fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5070 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5071 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5072 #define FN_LOCAL_LIST(fn_name,val) \
5073 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5074 #define FN_LOCAL_BOOL(fn_name,val) \
5075 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5076 #define FN_LOCAL_INTEGER(fn_name,val) \
5077 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5079 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5080 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5081 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5082 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5083 #define FN_LOCAL_CHAR(fn_name,val) \
5084 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5086 FN_GLOBAL_CONST_STRING(lp_smb_ports, smb_ports)
5087 FN_GLOBAL_CONST_STRING(lp_dos_charset, dos_charset)
5088 FN_GLOBAL_CONST_STRING(lp_unix_charset, unix_charset)
5089 FN_GLOBAL_STRING(lp_logfile, szLogFile)
5090 FN_GLOBAL_STRING(lp_configfile, szConfigFile)
5091 FN_GLOBAL_CONST_STRING(lp_smb_passwd_file, szSMBPasswdFile)
5092 FN_GLOBAL_CONST_STRING(lp_private_dir, szPrivateDir)
5093 FN_GLOBAL_STRING(lp_serverstring, szServerString)
5094 FN_GLOBAL_INTEGER(lp_printcap_cache_time, PrintcapCacheTime)
5095 FN_GLOBAL_STRING(lp_addport_cmd, szAddPortCommand)
5096 FN_GLOBAL_STRING(lp_enumports_cmd, szEnumPortsCommand)
5097 FN_GLOBAL_STRING(lp_addprinter_cmd, szAddPrinterCommand)
5098 FN_GLOBAL_STRING(lp_deleteprinter_cmd, szDeletePrinterCommand)
5099 FN_GLOBAL_STRING(lp_os2_driver_map, szOs2DriverMap)
5100 FN_GLOBAL_CONST_STRING(lp_lockdir, szLockDir)
5101 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5102 * build process or in smb.conf, we use that value. Otherwise they
5103 * default to the value of lp_lockdir(). */
5104 const char *lp_statedir(void) {
5105 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5106 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5107 return(*(char **)(&Globals.szStateDir) ?
5108 *(char **)(&Globals.szStateDir) : "");
5110 return(*(char **)(&Globals.szLockDir) ?
5111 *(char **)(&Globals.szLockDir) : "");
5113 const char *lp_cachedir(void) {
5114 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5115 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5116 return(*(char **)(&Globals.szCacheDir) ?
5117 *(char **)(&Globals.szCacheDir) : "");
5119 return(*(char **)(&Globals.szLockDir) ?
5120 *(char **)(&Globals.szLockDir) : "");
5122 FN_GLOBAL_CONST_STRING(lp_piddir, szPidDir)
5123 FN_GLOBAL_STRING(lp_mangling_method, szManglingMethod)
5124 FN_GLOBAL_INTEGER(lp_mangle_prefix, mangle_prefix)
5125 FN_GLOBAL_CONST_STRING(lp_utmpdir, szUtmpDir)
5126 FN_GLOBAL_CONST_STRING(lp_wtmpdir, szWtmpDir)
5127 FN_GLOBAL_BOOL(lp_utmp, bUtmp)
5128 FN_GLOBAL_STRING(lp_rootdir, szRootdir)
5129 FN_GLOBAL_STRING(lp_perfcount_module, szSMBPerfcountModule)
5130 FN_GLOBAL_STRING(lp_defaultservice, szDefaultService)
5131 FN_GLOBAL_STRING(lp_msg_command, szMsgCommand)
5132 FN_GLOBAL_STRING(lp_get_quota_command, szGetQuota)
5133 FN_GLOBAL_STRING(lp_set_quota_command, szSetQuota)
5134 FN_GLOBAL_STRING(lp_auto_services, szAutoServices)
5135 FN_GLOBAL_STRING(lp_passwd_program, szPasswdProgram)
5136 FN_GLOBAL_STRING(lp_passwd_chat, szPasswdChat)
5137 FN_GLOBAL_CONST_STRING(lp_passwordserver, szPasswordServer)
5138 FN_GLOBAL_CONST_STRING(lp_name_resolve_order, szNameResolveOrder)
5139 FN_GLOBAL_CONST_STRING(lp_workgroup, szWorkgroup)
5140 FN_GLOBAL_CONST_STRING(lp_netbios_name, szNetbiosName)
5141 FN_GLOBAL_CONST_STRING(lp_netbios_scope, szNetbiosScope)
5142 FN_GLOBAL_CONST_STRING(lp_realm, szRealmUpper)
5143 FN_GLOBAL_CONST_STRING(lp_dnsdomain, szDnsDomain)
5144 FN_GLOBAL_CONST_STRING(lp_afs_username_map, szAfsUsernameMap)
5145 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, iAfsTokenLifetime)
5146 FN_GLOBAL_STRING(lp_log_nt_token_command, szLogNtTokenCommand)
5147 FN_GLOBAL_STRING(lp_username_map, szUsernameMap)
5148 FN_GLOBAL_CONST_STRING(lp_logon_script, szLogonScript)
5149 FN_GLOBAL_CONST_STRING(lp_logon_path, szLogonPath)
5150 FN_GLOBAL_CONST_STRING(lp_logon_drive, szLogonDrive)
5151 FN_GLOBAL_CONST_STRING(lp_logon_home, szLogonHome)
5152 FN_GLOBAL_STRING(lp_remote_announce, szRemoteAnnounce)
5153 FN_GLOBAL_STRING(lp_remote_browse_sync, szRemoteBrowseSync)
5154 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, bNmbdBindExplicitBroadcast)
5155 FN_GLOBAL_LIST(lp_wins_server_list, szWINSservers)
5156 FN_GLOBAL_LIST(lp_interfaces, szInterfaces)
5157 FN_GLOBAL_STRING(lp_nis_home_map_name, szNISHomeMapName)
5158 FN_GLOBAL_LIST(lp_netbios_aliases, szNetbiosAliases)
5159 FN_GLOBAL_CONST_STRING(lp_passdb_backend, szPassdbBackend)
5160 FN_GLOBAL_LIST(lp_preload_modules, szPreloadModules)
5161 FN_GLOBAL_STRING(lp_panic_action, szPanicAction)
5162 FN_GLOBAL_STRING(lp_adduser_script, szAddUserScript)
5163 FN_GLOBAL_STRING(lp_renameuser_script, szRenameUserScript)
5164 FN_GLOBAL_STRING(lp_deluser_script, szDelUserScript)
5166 FN_GLOBAL_CONST_STRING(lp_guestaccount, szGuestaccount)
5167 FN_GLOBAL_STRING(lp_addgroup_script, szAddGroupScript)
5168 FN_GLOBAL_STRING(lp_delgroup_script, szDelGroupScript)
5169 FN_GLOBAL_STRING(lp_addusertogroup_script, szAddUserToGroupScript)
5170 FN_GLOBAL_STRING(lp_deluserfromgroup_script, szDelUserFromGroupScript)
5171 FN_GLOBAL_STRING(lp_setprimarygroup_script, szSetPrimaryGroupScript)
5173 FN_GLOBAL_STRING(lp_addmachine_script, szAddMachineScript)
5175 FN_GLOBAL_STRING(lp_shutdown_script, szShutdownScript)
5176 FN_GLOBAL_STRING(lp_abort_shutdown_script, szAbortShutdownScript)
5177 FN_GLOBAL_STRING(lp_username_map_script, szUsernameMapScript)
5178 FN_GLOBAL_INTEGER(lp_username_map_cache_time, iUsernameMapCacheTime)
5180 FN_GLOBAL_STRING(lp_check_password_script, szCheckPasswordScript)
5182 FN_GLOBAL_STRING(lp_wins_hook, szWINSHook)
5183 FN_GLOBAL_CONST_STRING(lp_template_homedir, szTemplateHomedir)
5184 FN_GLOBAL_CONST_STRING(lp_template_shell, szTemplateShell)
5185 FN_GLOBAL_CONST_STRING(lp_winbind_separator, szWinbindSeparator)
5186 FN_GLOBAL_INTEGER(lp_acl_compatibility, iAclCompat)
5187 FN_GLOBAL_BOOL(lp_winbind_enum_users, bWinbindEnumUsers)
5188 FN_GLOBAL_BOOL(lp_winbind_enum_groups, bWinbindEnumGroups)
5189 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, bWinbindUseDefaultDomain)
5190 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, bWinbindTrustedDomainsOnly)
5191 FN_GLOBAL_BOOL(lp_winbind_nested_groups, bWinbindNestedGroups)
5192 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, winbind_expand_groups)
5193 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, bWinbindRefreshTickets)
5194 FN_GLOBAL_BOOL(lp_winbind_offline_logon, bWinbindOfflineLogon)
5195 FN_GLOBAL_BOOL(lp_winbind_normalize_names, bWinbindNormalizeNames)
5196 FN_GLOBAL_BOOL(lp_winbind_rpc_only, bWinbindRpcOnly)
5197 FN_GLOBAL_BOOL(lp_create_krb5_conf, bCreateKrb5Conf)
5198 static FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections_int,
5199 winbindMaxDomainConnections)
5201 int lp_winbind_max_domain_connections(void)
5203 if (lp_winbind_offline_logon() &&
5204 lp_winbind_max_domain_connections_int() > 1) {
5205 DEBUG(1, ("offline logons active, restricting max domain "
5206 "connections to 1\n"));
5209 return MAX(1, lp_winbind_max_domain_connections_int());
5212 FN_GLOBAL_CONST_STRING(lp_idmap_backend, szIdmapBackend)
5213 FN_GLOBAL_INTEGER(lp_idmap_cache_time, iIdmapCacheTime)
5214 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, iIdmapNegativeCacheTime)
5215 FN_GLOBAL_INTEGER(lp_keepalive, iKeepalive)
5216 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, bPassdbExpandExplicit)
5218 FN_GLOBAL_STRING(lp_ldap_suffix, szLdapSuffix)
5219 FN_GLOBAL_STRING(lp_ldap_admin_dn, szLdapAdminDn)
5220 FN_GLOBAL_INTEGER(lp_ldap_ssl, ldap_ssl)
5221 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, ldap_ssl_ads)
5222 FN_GLOBAL_INTEGER(lp_ldap_deref, ldap_deref)
5223 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, ldap_follow_referral)
5224 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, ldap_passwd_sync)
5225 FN_GLOBAL_BOOL(lp_ldap_delete_dn, ldap_delete_dn)
5226 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, ldap_replication_sleep)
5227 FN_GLOBAL_INTEGER(lp_ldap_timeout, ldap_timeout)
5228 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, ldap_connection_timeout)
5229 FN_GLOBAL_INTEGER(lp_ldap_page_size, ldap_page_size)
5230 FN_GLOBAL_INTEGER(lp_ldap_debug_level, ldap_debug_level)
5231 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, ldap_debug_threshold)
5232 FN_GLOBAL_STRING(lp_add_share_cmd, szAddShareCommand)
5233 FN_GLOBAL_STRING(lp_change_share_cmd, szChangeShareCommand)
5234 FN_GLOBAL_STRING(lp_delete_share_cmd, szDeleteShareCommand)
5235 FN_GLOBAL_STRING(lp_usershare_path, szUsersharePath)
5236 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, szUsersharePrefixAllowList)
5237 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, szUsersharePrefixDenyList)
5239 FN_GLOBAL_LIST(lp_eventlog_list, szEventLogs)
5241 FN_GLOBAL_BOOL(lp_registry_shares, bRegistryShares)
5242 FN_GLOBAL_BOOL(lp_usershare_allow_guests, bUsershareAllowGuests)
5243 FN_GLOBAL_BOOL(lp_usershare_owner_only, bUsershareOwnerOnly)
5244 FN_GLOBAL_BOOL(lp_disable_netbios, bDisableNetbios)
5245 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, bResetOnZeroVC)
5246 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit, bLogWriteableFilesOnExit)
5247 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, bMsAddPrinterWizard)
5248 FN_GLOBAL_BOOL(lp_dns_proxy, bDNSproxy)
5249 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, bWINSsupport)
5250 FN_GLOBAL_BOOL(lp_wins_proxy, bWINSproxy)
5251 FN_GLOBAL_BOOL(lp_local_master, bLocalMaster)
5252 FN_GLOBAL_BOOL(lp_domain_logons, bDomainLogons)
5253 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, szInitLogonDelayedHosts)
5254 FN_GLOBAL_INTEGER(lp_init_logon_delay, InitLogonDelay)
5255 FN_GLOBAL_BOOL(lp_load_printers, bLoadPrinters)
5256 FN_GLOBAL_BOOL(_lp_readraw, bReadRaw)
5257 FN_GLOBAL_BOOL(lp_large_readwrite, bLargeReadwrite)
5258 FN_GLOBAL_BOOL(_lp_writeraw, bWriteRaw)
5259 FN_GLOBAL_BOOL(lp_null_passwords, bNullPasswords)
5260 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, bObeyPamRestrictions)
5261 FN_GLOBAL_BOOL(lp_encrypted_passwords, bEncryptPasswords)
5262 FN_GLOBAL_INTEGER(lp_client_schannel, clientSchannel)
5263 FN_GLOBAL_INTEGER(lp_server_schannel, serverSchannel)
5264 FN_GLOBAL_BOOL(lp_syslog_only, bSyslogOnly)
5265 FN_GLOBAL_BOOL(lp_timestamp_logs, bTimestampLogs)
5266 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, bDebugPrefixTimestamp)
5267 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, bDebugHiresTimestamp)
5268 FN_GLOBAL_BOOL(lp_debug_pid, bDebugPid)
5269 FN_GLOBAL_BOOL(lp_debug_uid, bDebugUid)
5270 FN_GLOBAL_BOOL(lp_debug_class, bDebugClass)
5271 FN_GLOBAL_BOOL(lp_enable_core_files, bEnableCoreFiles)
5272 FN_GLOBAL_BOOL(lp_browse_list, bBrowseList)
5273 FN_GLOBAL_BOOL(lp_nis_home_map, bNISHomeMap)
5274 static FN_GLOBAL_BOOL(lp_time_server, bTimeServer)
5275 FN_GLOBAL_BOOL(lp_bind_interfaces_only, bBindInterfacesOnly)
5276 FN_GLOBAL_BOOL(lp_pam_password_change, bPamPasswordChange)
5277 FN_GLOBAL_BOOL(lp_unix_password_sync, bUnixPasswdSync)
5278 FN_GLOBAL_BOOL(lp_passwd_chat_debug, bPasswdChatDebug)
5279 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, iPasswdChatTimeout)
5280 FN_GLOBAL_BOOL(lp_nt_pipe_support, bNTPipeSupport)
5281 FN_GLOBAL_BOOL(lp_nt_status_support, bNTStatusSupport)
5282 FN_GLOBAL_BOOL(lp_stat_cache, bStatCache)
5283 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, iMaxStatCacheSize)
5284 FN_GLOBAL_BOOL(lp_allow_trusted_domains, bAllowTrustedDomains)
5285 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, bMapUntrustedToDomain)
5286 FN_GLOBAL_INTEGER(lp_restrict_anonymous, restrict_anonymous)
5287 FN_GLOBAL_BOOL(lp_lanman_auth, bLanmanAuth)
5288 FN_GLOBAL_BOOL(lp_ntlm_auth, bNTLMAuth)
5289 FN_GLOBAL_BOOL(lp_client_plaintext_auth, bClientPlaintextAuth)
5290 FN_GLOBAL_BOOL(lp_client_lanman_auth, bClientLanManAuth)
5291 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, bClientNTLMv2Auth)
5292 FN_GLOBAL_BOOL(lp_host_msdfs, bHostMSDfs)
5293 FN_GLOBAL_BOOL(lp_kernel_oplocks, bKernelOplocks)
5294 FN_GLOBAL_BOOL(lp_enhanced_browsing, enhanced_browsing)
5295 FN_GLOBAL_BOOL(lp_use_mmap, bUseMmap)
5296 FN_GLOBAL_BOOL(lp_unix_extensions, bUnixExtensions)
5297 FN_GLOBAL_BOOL(lp_use_spnego, bUseSpnego)
5298 FN_GLOBAL_BOOL(lp_client_use_spnego, bClientUseSpnego)
5299 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, client_use_spnego_principal)
5300 FN_GLOBAL_BOOL(lp_send_spnego_principal, send_spnego_principal)
5301 FN_GLOBAL_BOOL(lp_hostname_lookups, bHostnameLookups)
5302 FN_GLOBAL_CONST_STRING(lp_dedicated_keytab_file, szDedicatedKeytabFile)
5303 FN_GLOBAL_INTEGER(lp_kerberos_method, iKerberosMethod)
5304 FN_GLOBAL_BOOL(lp_defer_sharing_violations, bDeferSharingViolations)
5305 FN_GLOBAL_BOOL(lp_enable_privileges, bEnablePrivileges)
5306 FN_GLOBAL_BOOL(lp_enable_asu_support, bASUSupport)
5307 FN_GLOBAL_INTEGER(lp_os_level, os_level)
5308 FN_GLOBAL_INTEGER(lp_max_ttl, max_ttl)
5309 FN_GLOBAL_INTEGER(lp_max_wins_ttl, max_wins_ttl)
5310 FN_GLOBAL_INTEGER(lp_min_wins_ttl, min_wins_ttl)
5311 FN_GLOBAL_INTEGER(lp_max_log_size, max_log_size)
5312 FN_GLOBAL_INTEGER(lp_max_open_files, max_open_files)
5313 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, open_files_db_hash_size)
5314 FN_GLOBAL_INTEGER(lp_maxxmit, max_xmit)
5315 FN_GLOBAL_INTEGER(lp_maxmux, max_mux)
5316 FN_GLOBAL_INTEGER(lp_passwordlevel, pwordlevel)
5317 FN_GLOBAL_INTEGER(lp_usernamelevel, unamelevel)
5318 FN_GLOBAL_INTEGER(lp_deadtime, deadtime)
5319 FN_GLOBAL_BOOL(lp_getwd_cache, getwd_cache)
5320 static FN_GLOBAL_INTEGER(_lp_maxprotocol, maxprotocol)
5321 int lp_maxprotocol(void)
5323 int ret = _lp_maxprotocol();
5324 if ((ret == PROTOCOL_SMB2) && (lp_security() == SEC_SHARE)) {
5325 DEBUG(2,("WARNING!!: \"security = share\" is incompatible "
5326 "with the SMB2 protocol. Resetting to SMB1.\n" ));
5327 lp_do_parameter(-1, "max protocol", "NT1");
5328 return PROTOCOL_NT1;
5332 FN_GLOBAL_INTEGER(lp_minprotocol, minprotocol)
5333 FN_GLOBAL_INTEGER(lp_security, security)
5334 FN_GLOBAL_LIST(lp_auth_methods, AuthMethods)
5335 FN_GLOBAL_BOOL(lp_paranoid_server_security, paranoid_server_security)
5336 FN_GLOBAL_INTEGER(lp_maxdisksize, maxdisksize)
5337 FN_GLOBAL_INTEGER(lp_lpqcachetime, lpqcachetime)
5338 FN_GLOBAL_INTEGER(lp_max_smbd_processes, iMaxSmbdProcesses)
5339 FN_GLOBAL_BOOL(_lp_disable_spoolss, bDisableSpoolss)
5340 FN_GLOBAL_INTEGER(lp_syslog, syslog)
5341 FN_GLOBAL_INTEGER(lp_lm_announce, lm_announce)
5342 FN_GLOBAL_INTEGER(lp_lm_interval, lm_interval)
5343 FN_GLOBAL_INTEGER(lp_machine_password_timeout, machine_password_timeout)
5344 FN_GLOBAL_INTEGER(lp_map_to_guest, map_to_guest)
5345 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, oplock_break_wait_time)
5346 FN_GLOBAL_INTEGER(lp_lock_spin_time, iLockSpinTime)
5347 FN_GLOBAL_INTEGER(lp_usershare_max_shares, iUsershareMaxShares)
5348 FN_GLOBAL_CONST_STRING(lp_socket_options, szSocketOptions)
5349 FN_GLOBAL_INTEGER(lp_config_backend, ConfigBackend)
5350 FN_GLOBAL_INTEGER(lp_smb2_max_read, ismb2_max_read)
5351 FN_GLOBAL_INTEGER(lp_smb2_max_write, ismb2_max_write)
5352 FN_GLOBAL_INTEGER(lp_smb2_max_trans, ismb2_max_trans)
5353 int lp_smb2_max_credits(void)
5355 if (Globals.ismb2_max_credits == 0) {
5356 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5358 return Globals.ismb2_max_credits;
5360 FN_GLOBAL_LIST(lp_svcctl_list, szServicesList)
5361 FN_GLOBAL_STRING(lp_cups_server, szCupsServer)
5362 int lp_cups_encrypt(void)
5365 #ifdef HAVE_HTTPCONNECTENCRYPT
5366 switch (Globals.CupsEncrypt) {
5368 result = HTTP_ENCRYPT_REQUIRED;
5371 result = HTTP_ENCRYPT_ALWAYS;
5374 result = HTTP_ENCRYPT_NEVER;
5380 FN_GLOBAL_STRING(lp_iprint_server, szIPrintServer)
5381 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, cups_connection_timeout)
5382 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, ctdbdSocket)
5383 FN_GLOBAL_LIST(lp_cluster_addresses, szClusterAddresses)
5384 FN_GLOBAL_BOOL(lp_clustering, clustering)
5385 FN_GLOBAL_INTEGER(lp_ctdb_timeout, ctdb_timeout)
5386 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, ctdb_locktime_warn_threshold)
5387 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, bAsyncSMBEchoHandler)
5388 FN_GLOBAL_BOOL(lp_multicast_dns_register, bMulticastDnsRegister)
5389 FN_GLOBAL_INTEGER(lp_winbind_cache_time, winbind_cache_time)
5390 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, winbind_reconnect_delay)
5391 FN_GLOBAL_INTEGER(lp_winbind_max_clients, winbind_max_clients)
5392 FN_GLOBAL_LIST(lp_winbind_nss_info, szWinbindNssInfo)
5393 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, AlgorithmicRidBase)
5394 FN_GLOBAL_INTEGER(lp_name_cache_timeout, name_cache_timeout)
5395 FN_GLOBAL_INTEGER(lp_client_signing, client_signing)
5396 FN_GLOBAL_INTEGER(lp_server_signing, server_signing)
5397 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, client_ldap_sasl_wrapping)
5399 FN_GLOBAL_CONST_STRING(lp_ncalrpc_dir, ncalrpc_dir)
5401 #include "lib/param/param_functions.c"
5403 FN_LOCAL_STRING(servicename, szService)
5404 FN_LOCAL_CONST_STRING(const_servicename, szService)
5406 /* local prototypes */
5408 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5409 static const char *get_boolean(bool bool_value);
5410 static int getservicebyname(const char *pszServiceName,
5411 struct loadparm_service *pserviceDest);
5412 static void copy_service(struct loadparm_service *pserviceDest,
5413 struct loadparm_service *pserviceSource,
5414 struct bitmap *pcopymapDest);
5415 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5417 static bool do_section(const char *pszSectionName, void *userdata);
5418 static void init_copymap(struct loadparm_service *pservice);
5419 static bool hash_a_service(const char *name, int number);
5420 static void free_service_byindex(int iService);
5421 static void free_param_opts(struct parmlist_entry **popts);
5422 static void show_parameter(int parmIndex);
5423 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5426 * This is a helper function for parametrical options support. It returns a
5427 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5428 * parametrical functions are quite simple
5430 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
5433 bool global_section = false;
5435 struct parmlist_entry *data;
5437 if (service == NULL) {
5438 data = Globals.param_opt;
5439 global_section = true;
5441 data = service->param_opt;
5444 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5445 DEBUG(0,("asprintf failed!\n"));
5450 if (strwicmp(data->key, param_key) == 0) {
5451 string_free(¶m_key);
5457 if (!global_section) {
5458 /* Try to fetch the same option but from globals */
5459 /* but only if we are not already working with Globals */
5460 data = Globals.param_opt;
5462 if (strwicmp(data->key, param_key) == 0) {
5463 string_free(¶m_key);
5470 string_free(¶m_key);
5476 * This is a helper function for parametrical options support. It returns a
5477 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5478 * parametrical functions are quite simple
5480 static struct parmlist_entry *get_parametrics(int snum, const char *type,
5483 if (snum >= iNumServices) return NULL;
5486 return get_parametrics_by_service(NULL, type, option);
5488 return get_parametrics_by_service(ServicePtrs[snum], type, option);
5493 #define MISSING_PARAMETER(name) \
5494 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5496 /*******************************************************************
5497 convenience routine to return int parameters.
5498 ********************************************************************/
5499 static int lp_int(const char *s)
5503 MISSING_PARAMETER(lp_int);
5507 return (int)strtol(s, NULL, 0);
5510 /*******************************************************************
5511 convenience routine to return unsigned long parameters.
5512 ********************************************************************/
5513 static unsigned long lp_ulong(const char *s)
5517 MISSING_PARAMETER(lp_ulong);
5521 return strtoul(s, NULL, 0);
5524 /*******************************************************************
5525 convenience routine to return boolean parameters.
5526 ********************************************************************/
5527 static bool lp_bool(const char *s)
5532 MISSING_PARAMETER(lp_bool);
5536 if (!set_boolean(s, &ret)) {
5537 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5544 /*******************************************************************
5545 convenience routine to return enum parameters.
5546 ********************************************************************/
5547 static int lp_enum(const char *s,const struct enum_list *_enum)
5551 if (!s || !*s || !_enum) {
5552 MISSING_PARAMETER(lp_enum);
5556 for (i=0; _enum[i].name; i++) {
5557 if (strequal(_enum[i].name,s))
5558 return _enum[i].value;
5561 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5565 #undef MISSING_PARAMETER
5567 /* Return parametric option from a given service. Type is a part of option before ':' */
5568 /* Parametric option has following syntax: 'Type: option = value' */
5569 /* the returned value is talloced on the talloc_tos() */
5570 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5572 struct parmlist_entry *data = get_parametrics(snum, type, option);
5574 if (data == NULL||data->value==NULL) {
5576 return lp_string(def);
5582 return lp_string(data->value);
5585 /* Return parametric option from a given service. Type is a part of option before ':' */
5586 /* Parametric option has following syntax: 'Type: option = value' */
5587 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5589 struct parmlist_entry *data = get_parametrics(snum, type, option);
5591 if (data == NULL||data->value==NULL)
5597 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
5599 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
5601 if (data == NULL||data->value==NULL)
5608 /* Return parametric option from a given service. Type is a part of option before ':' */
5609 /* Parametric option has following syntax: 'Type: option = value' */
5611 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5613 struct parmlist_entry *data = get_parametrics(snum, type, option);
5615 if (data == NULL||data->value==NULL)
5616 return (const char **)def;
5618 if (data->list==NULL) {
5619 data->list = str_list_make_v3(NULL, data->value, NULL);
5622 return (const char **)data->list;
5625 /* Return parametric option from a given service. Type is a part of option before ':' */
5626 /* Parametric option has following syntax: 'Type: option = value' */
5628 int lp_parm_int(int snum, const char *type, const char *option, int def)
5630 struct parmlist_entry *data = get_parametrics(snum, type, option);
5632 if (data && data->value && *data->value)
5633 return lp_int(data->value);
5638 /* Return parametric option from a given service. Type is a part of option before ':' */
5639 /* Parametric option has following syntax: 'Type: option = value' */
5641 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5643 struct parmlist_entry *data = get_parametrics(snum, type, option);
5645 if (data && data->value && *data->value)
5646 return lp_ulong(data->value);
5651 /* Return parametric option from a given service. Type is a part of option before ':' */
5652 /* Parametric option has following syntax: 'Type: option = value' */
5654 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5656 struct parmlist_entry *data = get_parametrics(snum, type, option);
5658 if (data && data->value && *data->value)
5659 return lp_bool(data->value);
5664 /* Return parametric option from a given service. Type is a part of option before ':' */
5665 /* Parametric option has following syntax: 'Type: option = value' */
5667 int lp_parm_enum(int snum, const char *type, const char *option,
5668 const struct enum_list *_enum, int def)
5670 struct parmlist_entry *data = get_parametrics(snum, type, option);
5672 if (data && data->value && *data->value && _enum)
5673 return lp_enum(data->value, _enum);
5679 /***************************************************************************
5680 Initialise a service to the defaults.
5681 ***************************************************************************/
5683 static void init_service(struct loadparm_service *pservice)
5685 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
5686 copy_service(pservice, &sDefault, NULL);
5691 * free a param_opts structure.
5692 * param_opts handling should be moved to talloc;
5693 * then this whole functions reduces to a TALLOC_FREE().
5696 static void free_param_opts(struct parmlist_entry **popts)
5698 struct parmlist_entry *opt, *next_opt;
5700 if (popts == NULL) {
5704 if (*popts != NULL) {
5705 DEBUG(5, ("Freeing parametrics:\n"));
5708 while (opt != NULL) {
5709 string_free(&opt->key);
5710 string_free(&opt->value);
5711 TALLOC_FREE(opt->list);
5712 next_opt = opt->next;
5719 /***************************************************************************
5720 Free the dynamically allocated parts of a service struct.
5721 ***************************************************************************/
5723 static void free_service(struct loadparm_service *pservice)
5728 if (pservice->szService)
5729 DEBUG(5, ("free_service: Freeing service %s\n",
5730 pservice->szService));
5732 free_parameters(pservice);
5734 string_free(&pservice->szService);
5735 TALLOC_FREE(pservice->copymap);
5737 free_param_opts(&pservice->param_opt);
5739 ZERO_STRUCTP(pservice);
5743 /***************************************************************************
5744 remove a service indexed in the ServicePtrs array from the ServiceHash
5745 and free the dynamically allocated parts
5746 ***************************************************************************/
5748 static void free_service_byindex(int idx)
5750 if ( !LP_SNUM_OK(idx) )
5753 ServicePtrs[idx]->valid = false;
5754 invalid_services[num_invalid_services++] = idx;
5756 /* we have to cleanup the hash record */
5758 if (ServicePtrs[idx]->szService) {
5759 char *canon_name = canonicalize_servicename(
5761 ServicePtrs[idx]->szService );
5763 dbwrap_delete_bystring(ServiceHash, canon_name );
5764 TALLOC_FREE(canon_name);
5767 free_service(ServicePtrs[idx]);
5770 /***************************************************************************
5771 Add a new service to the services array initialising it with the given
5773 ***************************************************************************/
5775 static int add_a_service(const struct loadparm_service *pservice, const char *name)
5778 struct loadparm_service tservice;
5779 int num_to_alloc = iNumServices + 1;
5781 tservice = *pservice;
5783 /* it might already exist */
5785 i = getservicebyname(name, NULL);
5791 /* find an invalid one */
5793 if (num_invalid_services > 0) {
5794 i = invalid_services[--num_invalid_services];
5797 /* if not, then create one */
5798 if (i == iNumServices) {
5799 struct loadparm_service **tsp;
5802 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
5804 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5808 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct loadparm_service);
5809 if (!ServicePtrs[iNumServices]) {
5810 DEBUG(0,("add_a_service: out of memory!\n"));
5815 /* enlarge invalid_services here for now... */
5816 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5818 if (tinvalid == NULL) {
5819 DEBUG(0,("add_a_service: failed to enlarge "
5820 "invalid_services!\n"));
5823 invalid_services = tinvalid;
5825 free_service_byindex(i);
5828 ServicePtrs[i]->valid = true;
5830 init_service(ServicePtrs[i]);
5831 copy_service(ServicePtrs[i], &tservice, NULL);
5833 string_set(&ServicePtrs[i]->szService, name);
5835 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5836 i, ServicePtrs[i]->szService));
5838 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5845 /***************************************************************************
5846 Convert a string to uppercase and remove whitespaces.
5847 ***************************************************************************/
5849 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
5854 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5858 result = talloc_strdup(ctx, src);
5859 SMB_ASSERT(result != NULL);
5865 /***************************************************************************
5866 Add a name/index pair for the services array to the hash table.
5867 ***************************************************************************/
5869 static bool hash_a_service(const char *name, int idx)
5873 if ( !ServiceHash ) {
5874 DEBUG(10,("hash_a_service: creating servicehash\n"));
5875 ServiceHash = db_open_rbt(NULL);
5876 if ( !ServiceHash ) {
5877 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5882 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5885 canon_name = canonicalize_servicename(talloc_tos(), name );
5887 dbwrap_store_bystring(ServiceHash, canon_name,
5888 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5891 TALLOC_FREE(canon_name);
5896 /***************************************************************************
5897 Add a new home service, with the specified home directory, defaults coming
5899 ***************************************************************************/
5901 bool lp_add_home(const char *pszHomename, int iDefaultService,
5902 const char *user, const char *pszHomedir)
5906 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
5907 pszHomedir[0] == '\0') {
5911 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5916 if (!(*(ServicePtrs[iDefaultService]->szPath))
5917 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5918 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5921 if (!(*(ServicePtrs[i]->comment))) {
5922 char *comment = NULL;
5923 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5926 string_set(&ServicePtrs[i]->comment, comment);
5930 /* set the browseable flag from the global default */
5932 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5933 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
5935 ServicePtrs[i]->autoloaded = true;
5937 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5938 user, ServicePtrs[i]->szPath ));
5943 /***************************************************************************
5944 Add a new service, based on an old one.
5945 ***************************************************************************/
5947 int lp_add_service(const char *pszService, int iDefaultService)
5949 if (iDefaultService < 0) {
5950 return add_a_service(&sDefault, pszService);
5953 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5956 /***************************************************************************
5957 Add the IPC service.
5958 ***************************************************************************/
5960 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5962 char *comment = NULL;
5963 int i = add_a_service(&sDefault, ipc_name);
5968 if (asprintf(&comment, "IPC Service (%s)",
5969 Globals.szServerString) < 0) {
5973 string_set(&ServicePtrs[i]->szPath, tmpdir());
5974 string_set(&ServicePtrs[i]->szUsername, "");
5975 string_set(&ServicePtrs[i]->comment, comment);
5976 string_set(&ServicePtrs[i]->fstype, "IPC");
5977 ServicePtrs[i]->iMaxConnections = 0;
5978 ServicePtrs[i]->bAvailable = true;
5979 ServicePtrs[i]->bRead_only = true;
5980 ServicePtrs[i]->bGuest_only = false;
5981 ServicePtrs[i]->bAdministrative_share = true;
5982 ServicePtrs[i]->bGuest_ok = guest_ok;
5983 ServicePtrs[i]->bPrint_ok = false;
5984 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5986 DEBUG(3, ("adding IPC service\n"));
5992 /***************************************************************************
5993 Add a new printer service, with defaults coming from service iFrom.
5994 ***************************************************************************/
5996 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5998 const char *comment = "From Printcap";
5999 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6004 /* note that we do NOT default the availability flag to true - */
6005 /* we take it from the default service passed. This allows all */
6006 /* dynamic printers to be disabled by disabling the [printers] */
6007 /* entry (if/when the 'available' keyword is implemented!). */
6009 /* the printer name is set to the service name. */
6010 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6011 string_set(&ServicePtrs[i]->comment, comment);
6013 /* set the browseable flag from the gloabl default */
6014 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6016 /* Printers cannot be read_only. */
6017 ServicePtrs[i]->bRead_only = false;
6018 /* No share modes on printer services. */
6019 ServicePtrs[i]->bShareModes = false;
6020 /* No oplocks on printer services. */
6021 ServicePtrs[i]->bOpLocks = false;
6022 /* Printer services must be printable. */
6023 ServicePtrs[i]->bPrint_ok = true;
6025 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6031 /***************************************************************************
6032 Check whether the given parameter name is valid.
6033 Parametric options (names containing a colon) are considered valid.
6034 ***************************************************************************/
6036 bool lp_parameter_is_valid(const char *pszParmName)
6038 return ((map_parameter(pszParmName) != -1) ||
6039 (strchr(pszParmName, ':') != NULL));
6042 /***************************************************************************
6043 Check whether the given name is the name of a global parameter.
6044 Returns true for strings belonging to parameters of class
6045 P_GLOBAL, false for all other strings, also for parametric options
6046 and strings not belonging to any option.
6047 ***************************************************************************/
6049 bool lp_parameter_is_global(const char *pszParmName)
6051 int num = map_parameter(pszParmName);
6054 return (parm_table[num].p_class == P_GLOBAL);
6060 /**************************************************************************
6061 Check whether the given name is the canonical name of a parameter.
6062 Returns false if it is not a valid parameter Name.
6063 For parametric options, true is returned.
6064 **************************************************************************/
6066 bool lp_parameter_is_canonical(const char *parm_name)
6068 if (!lp_parameter_is_valid(parm_name)) {
6072 return (map_parameter(parm_name) ==
6073 map_parameter_canonical(parm_name, NULL));
6076 /**************************************************************************
6077 Determine the canonical name for a parameter.
6078 Indicate when it is an inverse (boolean) synonym instead of a
6080 **************************************************************************/
6082 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6087 if (!lp_parameter_is_valid(parm_name)) {
6092 num = map_parameter_canonical(parm_name, inverse);
6094 /* parametric option */
6095 *canon_parm = parm_name;
6097 *canon_parm = parm_table[num].label;
6104 /**************************************************************************
6105 Determine the canonical name for a parameter.
6106 Turn the value given into the inverse boolean expression when
6107 the synonym is an invers boolean synonym.
6109 Return true if parm_name is a valid parameter name and
6110 in case it is an invers boolean synonym, if the val string could
6111 successfully be converted to the reverse bool.
6112 Return false in all other cases.
6113 **************************************************************************/
6115 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6117 const char **canon_parm,
6118 const char **canon_val)
6123 if (!lp_parameter_is_valid(parm_name)) {
6129 num = map_parameter_canonical(parm_name, &inverse);
6131 /* parametric option */
6132 *canon_parm = parm_name;
6135 *canon_parm = parm_table[num].label;
6137 if (!lp_invert_boolean(val, canon_val)) {
6149 /***************************************************************************
6150 Map a parameter's string representation to something we can use.
6151 Returns false if the parameter string is not recognised, else TRUE.
6152 ***************************************************************************/
6154 static int map_parameter(const char *pszParmName)
6158 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6161 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6162 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6165 /* Warn only if it isn't parametric option */
6166 if (strchr(pszParmName, ':') == NULL)
6167 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6168 /* We do return 'fail' for parametric options as well because they are
6169 stored in different storage
6174 /***************************************************************************
6175 Map a parameter's string representation to the index of the canonical
6176 form of the parameter (it might be a synonym).
6177 Returns -1 if the parameter string is not recognised.
6178 ***************************************************************************/
6180 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6182 int parm_num, canon_num;
6183 bool loc_inverse = false;
6185 parm_num = map_parameter(pszParmName);
6186 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6187 /* invalid, parametric or no canidate for synonyms ... */
6191 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6192 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6193 parm_num = canon_num;
6199 if (inverse != NULL) {
6200 *inverse = loc_inverse;
6205 /***************************************************************************
6206 return true if parameter number parm1 is a synonym of parameter
6207 number parm2 (parm2 being the principal name).
6208 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
6210 ***************************************************************************/
6212 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6214 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
6215 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
6216 (parm_table[parm1].flags & FLAG_HIDE) &&
6217 !(parm_table[parm2].flags & FLAG_HIDE))
6219 if (inverse != NULL) {
6220 if ((parm_table[parm1].type == P_BOOLREV) &&
6221 (parm_table[parm2].type == P_BOOL))
6233 /***************************************************************************
6234 Show one parameter's name, type, [values,] and flags.
6235 (helper functions for show_parameter_list)
6236 ***************************************************************************/
6238 static void show_parameter(int parmIndex)
6240 int enumIndex, flagIndex;
6245 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6246 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6248 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6249 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6251 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6252 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6253 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
6255 printf("%s=%s", parm_table[parmIndex].label,
6256 type[parm_table[parmIndex].type]);
6257 if (parm_table[parmIndex].type == P_ENUM) {
6260 parm_table[parmIndex].enum_list[enumIndex].name;
6264 enumIndex ? "|" : "",
6265 parm_table[parmIndex].enum_list[enumIndex].name);
6270 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6271 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6274 flag_names[flagIndex]);
6279 /* output synonyms */
6281 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6282 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6283 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6284 parm_table[parmIndex2].label);
6285 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6287 printf(" (synonyms: ");
6292 printf("%s%s", parm_table[parmIndex2].label,
6293 inverse ? "[i]" : "");
6303 /***************************************************************************
6304 Show all parameter's name, type, [values,] and flags.
6305 ***************************************************************************/
6307 void show_parameter_list(void)
6309 int classIndex, parmIndex;
6310 const char *section_names[] = { "local", "global", NULL};
6312 for (classIndex=0; section_names[classIndex]; classIndex++) {
6313 printf("[%s]\n", section_names[classIndex]);
6314 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6315 if (parm_table[parmIndex].p_class == classIndex) {
6316 show_parameter(parmIndex);
6322 /***************************************************************************
6323 Check if a given string correctly represents a boolean value.
6324 ***************************************************************************/
6326 bool lp_string_is_valid_boolean(const char *parm_value)
6328 return set_boolean(parm_value, NULL);
6331 /***************************************************************************
6332 Get the standard string representation of a boolean value ("yes" or "no")
6333 ***************************************************************************/
6335 static const char *get_boolean(bool bool_value)
6337 static const char *yes_str = "yes";
6338 static const char *no_str = "no";
6340 return (bool_value ? yes_str : no_str);
6343 /***************************************************************************
6344 Provide the string of the negated boolean value associated to the boolean
6345 given as a string. Returns false if the passed string does not correctly
6346 represent a boolean.
6347 ***************************************************************************/
6349 bool lp_invert_boolean(const char *str, const char **inverse_str)
6353 if (!set_boolean(str, &val)) {
6357 *inverse_str = get_boolean(!val);
6361 /***************************************************************************
6362 Provide the canonical string representation of a boolean value given
6363 as a string. Return true on success, false if the string given does
6364 not correctly represent a boolean.
6365 ***************************************************************************/
6367 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6371 if (!set_boolean(str, &val)) {
6375 *canon_str = get_boolean(val);
6379 /***************************************************************************
6380 Find a service by name. Otherwise works like get_service.
6381 ***************************************************************************/
6383 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
6389 if (ServiceHash == NULL) {
6393 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6395 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6397 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6398 iService = *(int *)data.dptr;
6401 TALLOC_FREE(canon_name);
6403 if ((iService != -1) && (LP_SNUM_OK(iService))
6404 && (pserviceDest != NULL)) {
6405 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6411 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
6412 struct loadparm_service *lp_service(const char *pszServiceName)
6414 int iService = getservicebyname(pszServiceName, NULL);
6415 if (iService == -1 || !LP_SNUM_OK(iService)) {
6418 return ServicePtrs[iService];
6422 /***************************************************************************
6423 Copy a service structure to another.
6424 If pcopymapDest is NULL then copy all fields
6425 ***************************************************************************/
6428 * Add a parametric option to a parmlist_entry,
6429 * replacing old value, if already present.
6431 static void set_param_opt(struct parmlist_entry **opt_list,
6432 const char *opt_name,
6433 const char *opt_value,
6436 struct parmlist_entry *new_opt, *opt;
6439 if (opt_list == NULL) {
6446 /* Traverse destination */
6448 /* If we already have same option, override it */
6449 if (strwicmp(opt->key, opt_name) == 0) {
6450 if ((opt->priority & FLAG_CMDLINE) &&
6451 !(priority & FLAG_CMDLINE)) {
6452 /* it's been marked as not to be
6456 string_free(&opt->value);
6457 TALLOC_FREE(opt->list);
6458 opt->value = SMB_STRDUP(opt_value);
6459 opt->priority = priority;
6466 new_opt = SMB_XMALLOC_P(struct parmlist_entry);
6467 new_opt->key = SMB_STRDUP(opt_name);
6468 new_opt->value = SMB_STRDUP(opt_value);
6469 new_opt->list = NULL;
6470 new_opt->priority = priority;
6471 DLIST_ADD(*opt_list, new_opt);
6475 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
6476 struct bitmap *pcopymapDest)
6479 bool bcopyall = (pcopymapDest == NULL);
6480 struct parmlist_entry *data;
6482 for (i = 0; parm_table[i].label; i++)
6483 if (parm_table[i].p_class == P_LOCAL &&
6484 (bcopyall || bitmap_query(pcopymapDest,i))) {
6485 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
6486 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
6488 switch (parm_table[i].type) {
6491 *(bool *)dest_ptr = *(bool *)src_ptr;
6497 *(int *)dest_ptr = *(int *)src_ptr;
6501 *(char *)dest_ptr = *(char *)src_ptr;
6505 string_set((char **)dest_ptr,
6511 char *upper_string = strupper_talloc(talloc_tos(),
6513 string_set((char **)dest_ptr,
6515 TALLOC_FREE(upper_string);
6519 TALLOC_FREE(*((char ***)dest_ptr));
6520 *((char ***)dest_ptr) = str_list_copy(NULL,
6521 *(const char ***)src_ptr);
6529 init_copymap(pserviceDest);
6530 if (pserviceSource->copymap)
6531 bitmap_copy(pserviceDest->copymap,
6532 pserviceSource->copymap);
6535 data = pserviceSource->param_opt;
6537 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
6542 /***************************************************************************
6543 Check a service for consistency. Return false if the service is in any way
6544 incomplete or faulty, else true.
6545 ***************************************************************************/
6547 bool service_ok(int iService)
6552 if (ServicePtrs[iService]->szService[0] == '\0') {
6553 DEBUG(0, ("The following message indicates an internal error:\n"));
6554 DEBUG(0, ("No service name in service entry.\n"));
6558 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6559 /* I can't see why you'd want a non-printable printer service... */
6560 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6561 if (!ServicePtrs[iService]->bPrint_ok) {
6562 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6563 ServicePtrs[iService]->szService));
6564 ServicePtrs[iService]->bPrint_ok = true;
6566 /* [printers] service must also be non-browsable. */
6567 if (ServicePtrs[iService]->bBrowseable)
6568 ServicePtrs[iService]->bBrowseable = false;
6571 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6572 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6573 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6575 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6576 ServicePtrs[iService]->szService));
6577 ServicePtrs[iService]->bAvailable = false;
6580 /* If a service is flagged unavailable, log the fact at level 1. */
6581 if (!ServicePtrs[iService]->bAvailable)
6582 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6583 ServicePtrs[iService]->szService));
6588 static struct smbconf_ctx *lp_smbconf_ctx(void)
6591 static struct smbconf_ctx *conf_ctx = NULL;
6593 if (conf_ctx == NULL) {
6594 err = smbconf_init(NULL, &conf_ctx, "registry:");
6595 if (!SBC_ERROR_IS_OK(err)) {
6596 DEBUG(1, ("error initializing registry configuration: "
6597 "%s\n", sbcErrorString(err)));
6605 static bool process_smbconf_service(struct smbconf_service *service)
6610 if (service == NULL) {
6614 ret = do_section(service->name, NULL);
6618 for (count = 0; count < service->num_params; count++) {
6619 ret = do_parameter(service->param_names[count],
6620 service->param_values[count],
6626 if (iServiceIndex >= 0) {
6627 return service_ok(iServiceIndex);
6633 * load a service from registry and activate it
6635 bool process_registry_service(const char *service_name)
6638 struct smbconf_service *service = NULL;
6639 TALLOC_CTX *mem_ctx = talloc_stackframe();
6640 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6643 if (conf_ctx == NULL) {
6647 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6649 if (!smbconf_share_exists(conf_ctx, service_name)) {
6651 * Registry does not contain data for this service (yet),
6652 * but make sure lp_load doesn't return false.
6658 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6659 if (!SBC_ERROR_IS_OK(err)) {
6663 ret = process_smbconf_service(service);
6669 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6672 TALLOC_FREE(mem_ctx);
6677 * process_registry_globals
6679 static bool process_registry_globals(void)
6683 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6685 ret = do_parameter("registry shares", "yes", NULL);
6690 return process_registry_service(GLOBAL_NAME);
6693 bool process_registry_shares(void)
6697 struct smbconf_service **service = NULL;
6698 uint32_t num_shares = 0;
6699 TALLOC_CTX *mem_ctx = talloc_stackframe();
6700 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6703 if (conf_ctx == NULL) {
6707 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6708 if (!SBC_ERROR_IS_OK(err)) {
6714 for (count = 0; count < num_shares; count++) {
6715 if (strequal(service[count]->name, GLOBAL_NAME)) {
6718 ret = process_smbconf_service(service[count]);
6725 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6728 TALLOC_FREE(mem_ctx);
6732 #define MAX_INCLUDE_DEPTH 100
6734 static uint8_t include_depth;
6736 static struct file_lists {
6737 struct file_lists *next;
6741 } *file_lists = NULL;
6743 /*******************************************************************
6744 Keep a linked list of all config files so we know when one has changed
6745 it's date and needs to be reloaded.
6746 ********************************************************************/
6748 static void add_to_file_list(const char *fname, const char *subfname)
6750 struct file_lists *f = file_lists;
6753 if (f->name && !strcmp(f->name, fname))
6759 f = SMB_MALLOC_P(struct file_lists);
6762 f->next = file_lists;
6763 f->name = SMB_STRDUP(fname);
6768 f->subfname = SMB_STRDUP(subfname);
6775 f->modtime = file_modtime(subfname);
6777 time_t t = file_modtime(subfname);
6785 * Free the file lists
6787 static void free_file_list(void)
6789 struct file_lists *f;
6790 struct file_lists *next;
6795 SAFE_FREE( f->name );
6796 SAFE_FREE( f->subfname );
6805 * Utility function for outsiders to check if we're running on registry.
6807 bool lp_config_backend_is_registry(void)
6809 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6813 * Utility function to check if the config backend is FILE.
6815 bool lp_config_backend_is_file(void)
6817 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6820 /*******************************************************************
6821 Check if a config file has changed date.
6822 ********************************************************************/
6824 bool lp_file_list_changed(void)
6826 struct file_lists *f = file_lists;
6828 DEBUG(6, ("lp_file_list_changed()\n"));
6833 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
6834 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6836 if (conf_ctx == NULL) {
6839 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
6842 DEBUGADD(6, ("registry config changed\n"));
6847 n2 = talloc_sub_basic(talloc_tos(),
6848 get_current_username(),
6849 current_user_info.domain,
6854 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6855 f->name, n2, ctime(&f->modtime)));
6857 mod_time = file_modtime(n2);
6860 ((f->modtime != mod_time) ||
6861 (f->subfname == NULL) ||
6862 (strcmp(n2, f->subfname) != 0)))
6865 ("file %s modified: %s\n", n2,
6867 f->modtime = mod_time;
6868 SAFE_FREE(f->subfname);
6869 f->subfname = SMB_STRDUP(n2);
6882 * Initialize iconv conversion descriptors.
6884 * This is called the first time it is needed, and also called again
6885 * every time the configuration is reloaded, because the charset or
6886 * codepage might have changed.
6888 static void init_iconv(void)
6890 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
6892 true, global_iconv_handle);
6895 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6897 if (strcmp(*ptr, pszParmValue) != 0) {
6898 string_set(ptr, pszParmValue);
6904 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6906 bool is_utf8 = false;
6907 size_t len = strlen(pszParmValue);
6909 if (len == 4 || len == 5) {
6910 /* Don't use StrCaseCmp here as we don't want to
6911 initialize iconv. */
6912 if ((toupper_ascii(pszParmValue[0]) == 'U') &&
6913 (toupper_ascii(pszParmValue[1]) == 'T') &&
6914 (toupper_ascii(pszParmValue[2]) == 'F')) {
6916 if (pszParmValue[3] == '8') {
6920 if (pszParmValue[3] == '-' &&
6921 pszParmValue[4] == '8') {
6928 if (strcmp(*ptr, pszParmValue) != 0) {
6930 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
6931 "be UTF8, using (default value) %s instead.\n",
6932 DEFAULT_DOS_CHARSET));
6933 pszParmValue = DEFAULT_DOS_CHARSET;
6935 string_set(ptr, pszParmValue);
6941 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6944 char *realm = strupper_talloc(talloc_tos(), pszParmValue);
6945 char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
6947 ret &= string_set(&Globals.szRealm, pszParmValue);
6948 ret &= string_set(&Globals.szRealmUpper, realm);
6949 ret &= string_set(&Globals.szDnsDomain, dnsdomain);
6951 TALLOC_FREE(dnsdomain);
6956 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6958 TALLOC_FREE(Globals.szNetbiosAliases);
6959 Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
6960 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6963 /***************************************************************************
6964 Handle the include operation.
6965 ***************************************************************************/
6966 static bool bAllowIncludeRegistry = true;
6968 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6972 if (include_depth >= MAX_INCLUDE_DEPTH) {
6973 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
6978 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6979 if (!bAllowIncludeRegistry) {
6982 if (bInGlobalSection) {
6985 ret = process_registry_globals();
6989 DEBUG(1, ("\"include = registry\" only effective "
6990 "in %s section\n", GLOBAL_NAME));
6995 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
6996 current_user_info.domain,
6999 add_to_file_list(pszParmValue, fname);
7001 string_set(ptr, fname);
7003 if (file_exist(fname)) {
7006 ret = pm_process(fname, do_section, do_parameter, NULL);
7012 DEBUG(2, ("Can't find include file %s\n", fname));
7017 /***************************************************************************
7018 Handle the interpretation of the copy parameter.
7019 ***************************************************************************/
7021 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7025 struct loadparm_service serviceTemp;
7027 string_set(ptr, pszParmValue);
7029 init_service(&serviceTemp);
7033 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7035 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7036 if (iTemp == iServiceIndex) {
7037 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7039 copy_service(ServicePtrs[iServiceIndex],
7041 ServicePtrs[iServiceIndex]->copymap);
7045 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7049 free_service(&serviceTemp);
7053 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7055 Globals.ldap_debug_level = lp_int(pszParmValue);
7056 init_ldap_debugging();
7060 /***************************************************************************
7061 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7066 idmap uid = 1000-1999
7069 We only do simple parsing checks here. The strings are parsed into useful
7070 structures in the idmap daemon code.
7072 ***************************************************************************/
7074 /* Some lp_ routines to return idmap [ug]id information */
7076 static uid_t idmap_uid_low, idmap_uid_high;
7077 static gid_t idmap_gid_low, idmap_gid_high;
7079 bool lp_idmap_uid(uid_t *low, uid_t *high)
7081 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7085 *low = idmap_uid_low;
7088 *high = idmap_uid_high;
7093 bool lp_idmap_gid(gid_t *low, gid_t *high)
7095 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7099 *low = idmap_gid_low;
7102 *high = idmap_gid_high;
7107 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7109 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7114 /* Do some simple checks on "idmap [ug]id" parameter values */
7116 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7118 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7123 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7125 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7130 /***************************************************************************
7131 Handle the DEBUG level list.
7132 ***************************************************************************/
7134 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
7136 string_set(ptr, pszParmValueIn);
7137 return debug_parse_levels(pszParmValueIn);
7140 /***************************************************************************
7141 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7142 ***************************************************************************/
7144 static const char *append_ldap_suffix( const char *str )
7146 const char *suffix_string;
7149 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7150 Globals.szLdapSuffix );
7151 if ( !suffix_string ) {
7152 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7156 return suffix_string;
7159 const char *lp_ldap_machine_suffix(void)
7161 if (Globals.szLdapMachineSuffix[0])
7162 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7164 return lp_string(Globals.szLdapSuffix);
7167 const char *lp_ldap_user_suffix(void)
7169 if (Globals.szLdapUserSuffix[0])
7170 return append_ldap_suffix(Globals.szLdapUserSuffix);
7172 return lp_string(Globals.szLdapSuffix);
7175 const char *lp_ldap_group_suffix(void)
7177 if (Globals.szLdapGroupSuffix[0])
7178 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7180 return lp_string(Globals.szLdapSuffix);
7183 const char *lp_ldap_idmap_suffix(void)
7185 if (Globals.szLdapIdmapSuffix[0])
7186 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7188 return lp_string(Globals.szLdapSuffix);
7191 /****************************************************************************
7192 set the value for a P_ENUM
7193 ***************************************************************************/
7195 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7200 for (i = 0; parm->enum_list[i].name; i++) {
7201 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7202 *ptr = parm->enum_list[i].value;
7206 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7207 pszParmValue, parm->label));
7210 /***************************************************************************
7211 ***************************************************************************/
7213 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7215 static int parm_num = -1;
7216 struct loadparm_service *s;
7218 if ( parm_num == -1 )
7219 parm_num = map_parameter( "printing" );
7221 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7226 s = ServicePtrs[snum];
7228 init_printer_values( s );
7234 /***************************************************************************
7235 Initialise a copymap.
7236 ***************************************************************************/
7238 static void init_copymap(struct loadparm_service *pservice)
7242 TALLOC_FREE(pservice->copymap);
7244 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7245 if (!pservice->copymap)
7247 ("Couldn't allocate copymap!! (size %d)\n",
7248 (int)NUMPARAMETERS));
7250 for (i = 0; i < NUMPARAMETERS; i++)
7251 bitmap_set(pservice->copymap, i);
7255 return the parameter pointer for a parameter
7257 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
7259 if (service == NULL) {
7260 if (parm->p_class == P_LOCAL)
7261 return (void *)(((char *)&sDefault)+parm->offset);
7262 else if (parm->p_class == P_GLOBAL)
7263 return (void *)(((char *)&Globals)+parm->offset);
7266 return (void *)(((char *)service) + parm->offset);
7270 /***************************************************************************
7271 Return the local pointer to a parameter given the service number and parameter
7272 ***************************************************************************/
7274 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
7276 return lp_parm_ptr(ServicePtrs[snum], parm);
7279 /***************************************************************************
7280 Process a parameter for a particular service number. If snum < 0
7281 then assume we are in the globals.
7282 ***************************************************************************/
7284 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7287 void *parm_ptr = NULL; /* where we are going to store the result */
7288 struct parmlist_entry **opt_list;
7290 parmnum = map_parameter(pszParmName);
7293 if (strchr(pszParmName, ':') == NULL) {
7294 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7300 * We've got a parametric option
7303 opt_list = (snum < 0)
7304 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7305 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7310 /* if it's already been set by the command line, then we don't
7312 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7316 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7317 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7321 /* we might point at a service, the default service or a global */
7323 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
7325 if (parm_table[parmnum].p_class == P_GLOBAL) {
7327 ("Global parameter %s found in service section!\n",
7331 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
7335 if (!ServicePtrs[snum]->copymap)
7336 init_copymap(ServicePtrs[snum]);
7338 /* this handles the aliases - set the copymap for other entries with
7339 the same data pointer */
7340 for (i = 0; parm_table[i].label; i++) {
7341 if ((parm_table[i].offset == parm_table[parmnum].offset)
7342 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
7343 bitmap_clear(ServicePtrs[snum]->copymap, i);
7348 /* if it is a special case then go ahead */
7349 if (parm_table[parmnum].special) {
7350 return parm_table[parmnum].special(NULL, snum, pszParmValue,
7354 /* now switch on the type of variable it is */
7355 switch (parm_table[parmnum].type)
7358 *(bool *)parm_ptr = lp_bool(pszParmValue);
7362 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7366 *(int *)parm_ptr = lp_int(pszParmValue);
7370 *(char *)parm_ptr = *pszParmValue;
7374 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7376 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7381 TALLOC_FREE(*((char ***)parm_ptr));
7382 *(char ***)parm_ptr = str_list_make_v3(
7383 NULL, pszParmValue, NULL);
7387 string_set((char **)parm_ptr, pszParmValue);
7392 char *upper_string = strupper_talloc(talloc_tos(),
7394 string_set((char **)parm_ptr, upper_string);
7395 TALLOC_FREE(upper_string);
7399 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7408 /***************************************************************************
7409 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7410 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7411 ***************************************************************************/
7413 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7416 parmnum = map_parameter(pszParmName);
7418 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7419 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7422 parm_table[parmnum].flags |= FLAG_CMDLINE;
7424 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7425 * be grouped in the table, so we don't have to search the
7428 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
7429 && parm_table[i].p_class == parm_table[parmnum].p_class;
7431 parm_table[i].flags |= FLAG_CMDLINE;
7433 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
7434 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
7435 parm_table[i].flags |= FLAG_CMDLINE;
7439 store_lp_set_cmdline(pszParmName, pszParmValue);
7444 /* it might be parametric */
7445 if (strchr(pszParmName, ':') != NULL) {
7446 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7448 store_lp_set_cmdline(pszParmName, pszParmValue);
7453 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7457 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7459 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7462 /***************************************************************************
7463 Process a parameter.
7464 ***************************************************************************/
7466 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7469 if (!bInGlobalSection && bGlobalOnly)
7472 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7474 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7475 pszParmName, pszParmValue));
7479 set a option from the commandline in 'a=b' format. Use to support --option
7481 bool lp_set_option(const char *option)
7486 s = talloc_strdup(NULL, option);
7499 /* skip white spaces after the = sign */
7502 } while (*p == ' ');
7504 ret = lp_set_cmdline(s, p);
7509 /**************************************************************************
7510 Print a parameter of the specified type.
7511 ***************************************************************************/
7513 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7519 for (i = 0; p->enum_list[i].name; i++) {
7520 if (*(int *)ptr == p->enum_list[i].value) {
7522 p->enum_list[i].name);
7529 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7533 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7537 fprintf(f, "%d", *(int *)ptr);
7541 fprintf(f, "%c", *(char *)ptr);
7545 char *o = octal_string(*(int *)ptr);
7546 fprintf(f, "%s", o);
7552 if ((char ***)ptr && *(char ***)ptr) {
7553 char **list = *(char ***)ptr;
7554 for (; *list; list++) {
7555 /* surround strings with whitespace in double quotes */
7556 if ( strchr_m( *list, ' ' ) )
7557 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7559 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7566 if (*(char **)ptr) {
7567 fprintf(f, "%s", *(char **)ptr);
7575 /***************************************************************************
7576 Check if two parameters are equal.
7577 ***************************************************************************/
7579 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7584 return (*((bool *)ptr1) == *((bool *)ptr2));
7589 return (*((int *)ptr1) == *((int *)ptr2));
7592 return (*((char *)ptr1) == *((char *)ptr2));
7595 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7600 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7605 return (p1 == p2 || strequal(p1, p2));
7613 /***************************************************************************
7614 Initialize any local varients in the sDefault table.
7615 ***************************************************************************/
7617 void init_locals(void)
7622 /***************************************************************************
7623 Process a new section (service). At this stage all sections are services.
7624 Later we'll have special sections that permit server parameters to be set.
7625 Returns true on success, false on failure.
7626 ***************************************************************************/
7628 static bool do_section(const char *pszSectionName, void *userdata)
7631 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7632 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7635 /* if we were in a global section then do the local inits */
7636 if (bInGlobalSection && !isglobal)
7639 /* if we've just struck a global section, note the fact. */
7640 bInGlobalSection = isglobal;
7642 /* check for multiple global sections */
7643 if (bInGlobalSection) {
7644 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7648 if (!bInGlobalSection && bGlobalOnly)
7651 /* if we have a current service, tidy it up before moving on */
7654 if (iServiceIndex >= 0)
7655 bRetval = service_ok(iServiceIndex);
7657 /* if all is still well, move to the next record in the services array */
7659 /* We put this here to avoid an odd message order if messages are */
7660 /* issued by the post-processing of a previous section. */
7661 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7663 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7665 DEBUG(0, ("Failed to add a new service\n"));
7668 /* Clean all parametric options for service */
7669 /* They will be added during parsing again */
7670 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
7677 /***************************************************************************
7678 Determine if a partcular base parameter is currentl set to the default value.
7679 ***************************************************************************/
7681 static bool is_default(int i)
7683 if (!defaults_saved)
7685 switch (parm_table[i].type) {
7687 return str_list_equal((const char **)parm_table[i].def.lvalue,
7688 *(const char ***)lp_parm_ptr(NULL,
7692 return strequal(parm_table[i].def.svalue,
7693 *(char **)lp_parm_ptr(NULL,
7697 return parm_table[i].def.bvalue ==
7698 *(bool *)lp_parm_ptr(NULL,
7701 return parm_table[i].def.cvalue ==
7702 *(char *)lp_parm_ptr(NULL,
7707 return parm_table[i].def.ivalue ==
7708 *(int *)lp_parm_ptr(NULL,
7716 /***************************************************************************
7717 Display the contents of the global structure.
7718 ***************************************************************************/
7720 static void dump_globals(FILE *f)
7723 struct parmlist_entry *data;
7725 fprintf(f, "[global]\n");
7727 for (i = 0; parm_table[i].label; i++)
7728 if (parm_table[i].p_class == P_GLOBAL &&
7729 !(parm_table[i].flags & FLAG_META) &&
7730 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
7731 if (defaults_saved && is_default(i))
7733 fprintf(f, "\t%s = ", parm_table[i].label);
7734 print_parameter(&parm_table[i], lp_parm_ptr(NULL,
7739 if (Globals.param_opt != NULL) {
7740 data = Globals.param_opt;
7742 fprintf(f, "\t%s = %s\n", data->key, data->value);
7749 /***************************************************************************
7750 Return true if a local parameter is currently set to the global default.
7751 ***************************************************************************/
7753 bool lp_is_default(int snum, struct parm_struct *parm)
7755 return equal_parameter(parm->type,
7756 lp_parm_ptr(ServicePtrs[snum], parm),
7757 lp_parm_ptr(NULL, parm));
7760 /***************************************************************************
7761 Display the contents of a single services record.
7762 ***************************************************************************/
7764 static void dump_a_service(struct loadparm_service *pService, FILE * f)
7767 struct parmlist_entry *data;
7769 if (pService != &sDefault)
7770 fprintf(f, "[%s]\n", pService->szService);
7772 for (i = 0; parm_table[i].label; i++) {
7774 if (parm_table[i].p_class == P_LOCAL &&
7775 !(parm_table[i].flags & FLAG_META) &&
7776 (*parm_table[i].label != '-') &&
7777 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7779 if (pService == &sDefault) {
7780 if (defaults_saved && is_default(i))
7783 if (equal_parameter(parm_table[i].type,
7784 lp_parm_ptr(pService, &parm_table[i]),
7785 lp_parm_ptr(NULL, &parm_table[i])))
7789 fprintf(f, "\t%s = ", parm_table[i].label);
7790 print_parameter(&parm_table[i],
7791 lp_parm_ptr(pService, &parm_table[i]),
7797 if (pService->param_opt != NULL) {
7798 data = pService->param_opt;
7800 fprintf(f, "\t%s = %s\n", data->key, data->value);
7806 /***************************************************************************
7807 Display the contents of a parameter of a single services record.
7808 ***************************************************************************/
7810 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7813 bool result = false;
7816 fstring local_parm_name;
7818 const char *parm_opt_value;
7820 /* check for parametrical option */
7821 fstrcpy( local_parm_name, parm_name);
7822 parm_opt = strchr( local_parm_name, ':');
7827 if (strlen(parm_opt)) {
7828 parm_opt_value = lp_parm_const_string( snum,
7829 local_parm_name, parm_opt, NULL);
7830 if (parm_opt_value) {
7831 printf( "%s\n", parm_opt_value);
7838 /* check for a key and print the value */
7845 for (i = 0; parm_table[i].label; i++) {
7846 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7847 !(parm_table[i].flags & FLAG_META) &&
7848 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7849 (*parm_table[i].label != '-') &&
7850 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7855 ptr = lp_parm_ptr(NULL,
7858 ptr = lp_parm_ptr(ServicePtrs[snum],
7862 print_parameter(&parm_table[i],
7873 /***************************************************************************
7874 Return info about the requested parameter (given as a string).
7875 Return NULL when the string is not a valid parameter name.
7876 ***************************************************************************/
7878 struct parm_struct *lp_get_parameter(const char *param_name)
7880 int num = map_parameter(param_name);
7886 return &parm_table[num];
7889 /***************************************************************************
7890 Return info about the next parameter in a service.
7891 snum==GLOBAL_SECTION_SNUM gives the globals.
7892 Return NULL when out of parameters.
7893 ***************************************************************************/
7895 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7898 /* do the globals */
7899 for (; parm_table[*i].label; (*i)++) {
7900 if (parm_table[*i].p_class == P_SEPARATOR)
7901 return &parm_table[(*i)++];
7903 if ((*parm_table[*i].label == '-'))
7907 && (parm_table[*i].offset ==
7908 parm_table[(*i) - 1].offset)
7909 && (parm_table[*i].p_class ==
7910 parm_table[(*i) - 1].p_class))
7913 if (is_default(*i) && !allparameters)
7916 return &parm_table[(*i)++];
7919 struct loadparm_service *pService = ServicePtrs[snum];
7921 for (; parm_table[*i].label; (*i)++) {
7922 if (parm_table[*i].p_class == P_SEPARATOR)
7923 return &parm_table[(*i)++];
7925 if (parm_table[*i].p_class == P_LOCAL &&
7926 (*parm_table[*i].label != '-') &&
7928 (parm_table[*i].offset !=
7929 parm_table[(*i) - 1].offset)))
7931 if (allparameters ||
7932 !equal_parameter(parm_table[*i].type,
7933 lp_parm_ptr(pService,
7938 return &parm_table[(*i)++];
7949 /***************************************************************************
7950 Display the contents of a single copy structure.
7951 ***************************************************************************/
7952 static void dump_copy_map(bool *pcopymap)
7958 printf("\n\tNon-Copied parameters:\n");
7960 for (i = 0; parm_table[i].label; i++)
7961 if (parm_table[i].p_class == P_LOCAL &&
7962 parm_table[i].ptr && !pcopymap[i] &&
7963 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7965 printf("\t\t%s\n", parm_table[i].label);
7970 /***************************************************************************
7971 Return TRUE if the passed service number is within range.
7972 ***************************************************************************/
7974 bool lp_snum_ok(int iService)
7976 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7979 /***************************************************************************
7980 Auto-load some home services.
7981 ***************************************************************************/
7983 static void lp_add_auto_services(char *str)
7993 s = SMB_STRDUP(str);
7997 homes = lp_servicenumber(HOMES_NAME);
7999 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8000 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8003 if (lp_servicenumber(p) >= 0)
8006 home = get_user_home_dir(talloc_tos(), p);
8008 if (home && home[0] && homes >= 0)
8009 lp_add_home(p, homes, p, home);
8016 /***************************************************************************
8017 Auto-load one printer.
8018 ***************************************************************************/
8020 void lp_add_one_printer(const char *name, const char *comment,
8021 const char *location, void *pdata)
8023 int printers = lp_servicenumber(PRINTERS_NAME);
8026 if (lp_servicenumber(name) < 0) {
8027 lp_add_printer(name, printers);
8028 if ((i = lp_servicenumber(name)) >= 0) {
8029 string_set(&ServicePtrs[i]->comment, comment);
8030 ServicePtrs[i]->autoloaded = true;
8035 /***************************************************************************
8036 Have we loaded a services file yet?
8037 ***************************************************************************/
8039 bool lp_loaded(void)
8044 /***************************************************************************
8045 Unload unused services.
8046 ***************************************************************************/
8048 void lp_killunused(struct smbd_server_connection *sconn,
8049 bool (*snumused) (struct smbd_server_connection *, int))
8052 for (i = 0; i < iNumServices; i++) {
8056 /* don't kill autoloaded or usershare services */
8057 if ( ServicePtrs[i]->autoloaded ||
8058 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8062 if (!snumused || !snumused(sconn, i)) {
8063 free_service_byindex(i);
8069 * Kill all except autoloaded and usershare services - convenience wrapper
8071 void lp_kill_all_services(void)
8073 lp_killunused(NULL, NULL);
8076 /***************************************************************************
8078 ***************************************************************************/
8080 void lp_killservice(int iServiceIn)
8082 if (VALID(iServiceIn)) {
8083 free_service_byindex(iServiceIn);
8087 /***************************************************************************
8088 Save the curent values of all global and sDefault parameters into the
8089 defaults union. This allows swat and testparm to show only the
8090 changed (ie. non-default) parameters.
8091 ***************************************************************************/
8093 static void lp_save_defaults(void)
8096 for (i = 0; parm_table[i].label; i++) {
8097 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
8098 && parm_table[i].p_class == parm_table[i - 1].p_class)
8100 switch (parm_table[i].type) {
8102 parm_table[i].def.lvalue = str_list_copy(
8103 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
8107 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
8111 parm_table[i].def.bvalue =
8112 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
8115 parm_table[i].def.cvalue =
8116 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
8121 parm_table[i].def.ivalue =
8122 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
8128 defaults_saved = true;
8131 /***********************************************************
8132 If we should send plaintext/LANMAN passwords in the clinet
8133 ************************************************************/
8135 static void set_allowed_client_auth(void)
8137 if (Globals.bClientNTLMv2Auth) {
8138 Globals.bClientLanManAuth = false;
8140 if (!Globals.bClientLanManAuth) {
8141 Globals.bClientPlaintextAuth = false;
8145 /***************************************************************************
8147 The following code allows smbd to read a user defined share file.
8148 Yes, this is my intent. Yes, I'm comfortable with that...
8150 THE FOLLOWING IS SECURITY CRITICAL CODE.
8152 It washes your clothes, it cleans your house, it guards you while you sleep...
8153 Do not f%^k with it....
8154 ***************************************************************************/
8156 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8158 /***************************************************************************
8159 Check allowed stat state of a usershare file.
8160 Ensure we print out who is dicking with us so the admin can
8161 get their sorry ass fired.
8162 ***************************************************************************/
8164 static bool check_usershare_stat(const char *fname,
8165 const SMB_STRUCT_STAT *psbuf)
8167 if (!S_ISREG(psbuf->st_ex_mode)) {
8168 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8169 "not a regular file\n",
8170 fname, (unsigned int)psbuf->st_ex_uid ));
8174 /* Ensure this doesn't have the other write bit set. */
8175 if (psbuf->st_ex_mode & S_IWOTH) {
8176 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8177 "public write. Refusing to allow as a usershare file.\n",
8178 fname, (unsigned int)psbuf->st_ex_uid ));
8182 /* Should be 10k or less. */
8183 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8184 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8185 "too large (%u) to be a user share file.\n",
8186 fname, (unsigned int)psbuf->st_ex_uid,
8187 (unsigned int)psbuf->st_ex_size ));
8194 /***************************************************************************
8195 Parse the contents of a usershare file.
8196 ***************************************************************************/
8198 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8199 SMB_STRUCT_STAT *psbuf,
8200 const char *servicename,
8204 char **pp_sharepath,
8206 char **pp_cp_servicename,
8207 struct security_descriptor **ppsd,
8210 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8211 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8214 SMB_STRUCT_STAT sbuf;
8215 char *sharepath = NULL;
8216 char *comment = NULL;
8218 *pp_sharepath = NULL;
8221 *pallow_guest = false;
8224 return USERSHARE_MALFORMED_FILE;
8227 if (strcmp(lines[0], "#VERSION 1") == 0) {
8229 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8232 return USERSHARE_MALFORMED_FILE;
8235 return USERSHARE_BAD_VERSION;
8238 if (strncmp(lines[1], "path=", 5) != 0) {
8239 return USERSHARE_MALFORMED_PATH;
8242 sharepath = talloc_strdup(ctx, &lines[1][5]);
8244 return USERSHARE_POSIX_ERR;
8246 trim_string(sharepath, " ", " ");
8248 if (strncmp(lines[2], "comment=", 8) != 0) {
8249 return USERSHARE_MALFORMED_COMMENT_DEF;
8252 comment = talloc_strdup(ctx, &lines[2][8]);
8254 return USERSHARE_POSIX_ERR;
8256 trim_string(comment, " ", " ");
8257 trim_char(comment, '"', '"');
8259 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8260 return USERSHARE_MALFORMED_ACL_DEF;
8263 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8264 return USERSHARE_ACL_ERR;
8268 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8269 return USERSHARE_MALFORMED_ACL_DEF;
8271 if (lines[4][9] == 'y') {
8272 *pallow_guest = true;
8275 /* Backwards compatible extension to file version #2. */
8277 if (strncmp(lines[5], "sharename=", 10) != 0) {
8278 return USERSHARE_MALFORMED_SHARENAME_DEF;
8280 if (!strequal(&lines[5][10], servicename)) {
8281 return USERSHARE_BAD_SHARENAME;
8283 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8284 if (!*pp_cp_servicename) {
8285 return USERSHARE_POSIX_ERR;
8290 if (*pp_cp_servicename == NULL) {
8291 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8292 if (!*pp_cp_servicename) {
8293 return USERSHARE_POSIX_ERR;
8297 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8298 /* Path didn't change, no checks needed. */
8299 *pp_sharepath = sharepath;
8300 *pp_comment = comment;
8301 return USERSHARE_OK;
8304 /* The path *must* be absolute. */
8305 if (sharepath[0] != '/') {
8306 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8307 servicename, sharepath));
8308 return USERSHARE_PATH_NOT_ABSOLUTE;
8311 /* If there is a usershare prefix deny list ensure one of these paths
8312 doesn't match the start of the user given path. */
8313 if (prefixdenylist) {
8315 for ( i=0; prefixdenylist[i]; i++ ) {
8316 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8317 servicename, i, prefixdenylist[i], sharepath ));
8318 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8319 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8320 "usershare prefix deny list entries.\n",
8321 servicename, sharepath));
8322 return USERSHARE_PATH_IS_DENIED;
8327 /* If there is a usershare prefix allow list ensure one of these paths
8328 does match the start of the user given path. */
8330 if (prefixallowlist) {
8332 for ( i=0; prefixallowlist[i]; i++ ) {
8333 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8334 servicename, i, prefixallowlist[i], sharepath ));
8335 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8339 if (prefixallowlist[i] == NULL) {
8340 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8341 "usershare prefix allow list entries.\n",
8342 servicename, sharepath));
8343 return USERSHARE_PATH_NOT_ALLOWED;
8347 /* Ensure this is pointing to a directory. */
8348 dp = sys_opendir(sharepath);
8351 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8352 servicename, sharepath));
8353 return USERSHARE_PATH_NOT_DIRECTORY;
8356 /* Ensure the owner of the usershare file has permission to share
8359 if (sys_stat(sharepath, &sbuf, false) == -1) {
8360 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8361 servicename, sharepath, strerror(errno) ));
8363 return USERSHARE_POSIX_ERR;
8368 if (!S_ISDIR(sbuf.st_ex_mode)) {
8369 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8370 servicename, sharepath ));
8371 return USERSHARE_PATH_NOT_DIRECTORY;
8374 /* Check if sharing is restricted to owner-only. */
8375 /* psbuf is the stat of the usershare definition file,
8376 sbuf is the stat of the target directory to be shared. */
8378 if (lp_usershare_owner_only()) {
8379 /* root can share anything. */
8380 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8381 return USERSHARE_PATH_NOT_ALLOWED;
8385 *pp_sharepath = sharepath;
8386 *pp_comment = comment;
8387 return USERSHARE_OK;
8390 /***************************************************************************
8391 Deal with a usershare file.
8394 -1 - Bad name, invalid contents.
8395 - service name already existed and not a usershare, problem
8396 with permissions to share directory etc.
8397 ***************************************************************************/
8399 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8401 SMB_STRUCT_STAT sbuf;
8402 SMB_STRUCT_STAT lsbuf;
8404 char *sharepath = NULL;
8405 char *comment = NULL;
8406 char *cp_service_name = NULL;
8407 char **lines = NULL;
8411 TALLOC_CTX *ctx = talloc_stackframe();
8412 struct security_descriptor *psd = NULL;
8413 bool guest_ok = false;
8414 char *canon_name = NULL;
8415 bool added_service = false;
8418 /* Ensure share name doesn't contain invalid characters. */
8419 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8420 DEBUG(0,("process_usershare_file: share name %s contains "
8421 "invalid characters (any of %s)\n",
8422 file_name, INVALID_SHARENAME_CHARS ));
8426 canon_name = canonicalize_servicename(ctx, file_name);
8431 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8436 /* Minimize the race condition by doing an lstat before we
8437 open and fstat. Ensure this isn't a symlink link. */
8439 if (sys_lstat(fname, &lsbuf, false) != 0) {
8440 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8441 fname, strerror(errno) ));
8445 /* This must be a regular file, not a symlink, directory or
8446 other strange filetype. */
8447 if (!check_usershare_stat(fname, &lsbuf)) {
8452 TDB_DATA data = dbwrap_fetch_bystring(
8453 ServiceHash, canon_name, canon_name);
8457 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8458 iService = *(int *)data.dptr;
8462 if (iService != -1 &&
8463 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8464 &lsbuf.st_ex_mtime) == 0) {
8465 /* Nothing changed - Mark valid and return. */
8466 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8468 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8473 /* Try and open the file read only - no symlinks allowed. */
8475 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8477 fd = sys_open(fname, O_RDONLY, 0);
8481 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8482 fname, strerror(errno) ));
8486 /* Now fstat to be *SURE* it's a regular file. */
8487 if (sys_fstat(fd, &sbuf, false) != 0) {
8489 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8490 fname, strerror(errno) ));
8494 /* Is it the same dev/inode as was lstated ? */
8495 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8497 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8498 "Symlink spoofing going on ?\n", fname ));
8502 /* This must be a regular file, not a symlink, directory or
8503 other strange filetype. */
8504 if (!check_usershare_stat(fname, &sbuf)) {
8508 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8511 if (lines == NULL) {
8512 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8513 fname, (unsigned int)sbuf.st_ex_uid ));
8517 if (parse_usershare_file(ctx, &sbuf, file_name,
8518 iService, lines, numlines, &sharepath,
8519 &comment, &cp_service_name,
8520 &psd, &guest_ok) != USERSHARE_OK) {
8524 /* Everything ok - add the service possibly using a template. */
8526 const struct loadparm_service *sp = &sDefault;
8527 if (snum_template != -1) {
8528 sp = ServicePtrs[snum_template];
8531 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8532 DEBUG(0, ("process_usershare_file: Failed to add "
8533 "new service %s\n", cp_service_name));
8537 added_service = true;
8539 /* Read only is controlled by usershare ACL below. */
8540 ServicePtrs[iService]->bRead_only = false;
8543 /* Write the ACL of the new/modified share. */
8544 if (!set_share_security(canon_name, psd)) {
8545 DEBUG(0, ("process_usershare_file: Failed to set share "
8546 "security for user share %s\n",
8551 /* If from a template it may be marked invalid. */
8552 ServicePtrs[iService]->valid = true;
8554 /* Set the service as a valid usershare. */
8555 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8557 /* Set guest access. */
8558 if (lp_usershare_allow_guests()) {
8559 ServicePtrs[iService]->bGuest_ok = guest_ok;
8562 /* And note when it was loaded. */
8563 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8564 string_set(&ServicePtrs[iService]->szPath, sharepath);
8565 string_set(&ServicePtrs[iService]->comment, comment);
8571 if (ret == -1 && iService != -1 && added_service) {
8572 lp_remove_service(iService);
8580 /***************************************************************************
8581 Checks if a usershare entry has been modified since last load.
8582 ***************************************************************************/
8584 static bool usershare_exists(int iService, struct timespec *last_mod)
8586 SMB_STRUCT_STAT lsbuf;
8587 const char *usersharepath = Globals.szUsersharePath;
8590 if (asprintf(&fname, "%s/%s",
8592 ServicePtrs[iService]->szService) < 0) {
8596 if (sys_lstat(fname, &lsbuf, false) != 0) {
8601 if (!S_ISREG(lsbuf.st_ex_mode)) {
8607 *last_mod = lsbuf.st_ex_mtime;
8611 /***************************************************************************
8612 Load a usershare service by name. Returns a valid servicenumber or -1.
8613 ***************************************************************************/
8615 int load_usershare_service(const char *servicename)
8617 SMB_STRUCT_STAT sbuf;
8618 const char *usersharepath = Globals.szUsersharePath;
8619 int max_user_shares = Globals.iUsershareMaxShares;
8620 int snum_template = -1;
8622 if (*usersharepath == 0 || max_user_shares == 0) {
8626 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8627 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8628 usersharepath, strerror(errno) ));
8632 if (!S_ISDIR(sbuf.st_ex_mode)) {
8633 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8639 * This directory must be owned by root, and have the 't' bit set.
8640 * It also must not be writable by "other".
8644 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8646 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8648 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8649 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8654 /* Ensure the template share exists if it's set. */
8655 if (Globals.szUsershareTemplateShare[0]) {
8656 /* We can't use lp_servicenumber here as we are recommending that
8657 template shares have -valid=false set. */
8658 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8659 if (ServicePtrs[snum_template]->szService &&
8660 strequal(ServicePtrs[snum_template]->szService,
8661 Globals.szUsershareTemplateShare)) {
8666 if (snum_template == -1) {
8667 DEBUG(0,("load_usershare_service: usershare template share %s "
8668 "does not exist.\n",
8669 Globals.szUsershareTemplateShare ));
8674 return process_usershare_file(usersharepath, servicename, snum_template);
8677 /***************************************************************************
8678 Load all user defined shares from the user share directory.
8679 We only do this if we're enumerating the share list.
8680 This is the function that can delete usershares that have
8682 ***************************************************************************/
8684 int load_usershare_shares(struct smbd_server_connection *sconn)
8687 SMB_STRUCT_STAT sbuf;
8688 SMB_STRUCT_DIRENT *de;
8689 int num_usershares = 0;
8690 int max_user_shares = Globals.iUsershareMaxShares;
8691 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8692 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8693 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8695 int snum_template = -1;
8696 const char *usersharepath = Globals.szUsersharePath;
8697 int ret = lp_numservices();
8699 if (max_user_shares == 0 || *usersharepath == '\0') {
8700 return lp_numservices();
8703 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8704 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8705 usersharepath, strerror(errno) ));
8710 * This directory must be owned by root, and have the 't' bit set.
8711 * It also must not be writable by "other".
8715 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8717 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8719 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8720 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8725 /* Ensure the template share exists if it's set. */
8726 if (Globals.szUsershareTemplateShare[0]) {
8727 /* We can't use lp_servicenumber here as we are recommending that
8728 template shares have -valid=false set. */
8729 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8730 if (ServicePtrs[snum_template]->szService &&
8731 strequal(ServicePtrs[snum_template]->szService,
8732 Globals.szUsershareTemplateShare)) {
8737 if (snum_template == -1) {
8738 DEBUG(0,("load_usershare_shares: usershare template share %s "
8739 "does not exist.\n",
8740 Globals.szUsershareTemplateShare ));
8745 /* Mark all existing usershares as pending delete. */
8746 for (iService = iNumServices - 1; iService >= 0; iService--) {
8747 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8748 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8752 dp = sys_opendir(usersharepath);
8754 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8755 usersharepath, strerror(errno) ));
8759 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8760 (de = sys_readdir(dp));
8761 num_dir_entries++ ) {
8763 const char *n = de->d_name;
8765 /* Ignore . and .. */
8767 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8773 /* Temporary file used when creating a share. */
8774 num_tmp_dir_entries++;
8777 /* Allow 20% tmp entries. */
8778 if (num_tmp_dir_entries > allowed_tmp_entries) {
8779 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8780 "in directory %s\n",
8781 num_tmp_dir_entries, usersharepath));
8785 r = process_usershare_file(usersharepath, n, snum_template);
8787 /* Update the services count. */
8789 if (num_usershares >= max_user_shares) {
8790 DEBUG(0,("load_usershare_shares: max user shares reached "
8791 "on file %s in directory %s\n",
8792 n, usersharepath ));
8795 } else if (r == -1) {
8796 num_bad_dir_entries++;
8799 /* Allow 20% bad entries. */
8800 if (num_bad_dir_entries > allowed_bad_entries) {
8801 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8802 "in directory %s\n",
8803 num_bad_dir_entries, usersharepath));
8807 /* Allow 20% bad entries. */
8808 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8809 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8810 "in directory %s\n",
8811 num_dir_entries, usersharepath));
8818 /* Sweep through and delete any non-refreshed usershares that are
8819 not currently in use. */
8820 for (iService = iNumServices - 1; iService >= 0; iService--) {
8821 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8822 if (conn_snum_used(sconn, iService)) {
8825 /* Remove from the share ACL db. */
8826 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8827 lp_servicename(iService) ));
8828 delete_share_security(lp_servicename(iService));
8829 free_service_byindex(iService);
8833 return lp_numservices();
8836 /********************************************************
8837 Destroy global resources allocated in this file
8838 ********************************************************/
8840 void gfree_loadparm(void)
8846 /* Free resources allocated to services */
8848 for ( i = 0; i < iNumServices; i++ ) {
8850 free_service_byindex(i);
8854 SAFE_FREE( ServicePtrs );
8857 /* Now release all resources allocated to global
8858 parameters and the default service */
8860 free_global_parameters();
8864 /***************************************************************************
8865 Allow client apps to specify that they are a client
8866 ***************************************************************************/
8867 void lp_set_in_client(bool b)
8873 /***************************************************************************
8874 Determine if we're running in a client app
8875 ***************************************************************************/
8876 bool lp_is_in_client(void)
8881 /***************************************************************************
8882 Load the services array from the services file. Return true on success,
8884 ***************************************************************************/
8886 static bool lp_load_ex(const char *pszFname,
8890 bool initialize_globals,
8891 bool allow_include_registry,
8892 bool allow_registry_shares)
8899 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8901 bInGlobalSection = true;
8902 bGlobalOnly = global_only;
8903 bAllowIncludeRegistry = allow_include_registry;
8905 init_globals(initialize_globals);
8909 if (save_defaults) {
8914 free_param_opts(&Globals.param_opt);
8916 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
8918 /* We get sections first, so have to start 'behind' to make up */
8921 if (lp_config_backend_is_file()) {
8922 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
8923 current_user_info.domain,
8926 smb_panic("lp_load_ex: out of memory");
8929 add_to_file_list(pszFname, n2);
8931 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8934 /* finish up the last section */
8935 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8937 if (iServiceIndex >= 0) {
8938 bRetval = service_ok(iServiceIndex);
8942 if (lp_config_backend_is_registry()) {
8943 /* config backend changed to registry in config file */
8945 * We need to use this extra global variable here to
8946 * survive restart: init_globals uses this as a default
8947 * for ConfigBackend. Otherwise, init_globals would
8948 * send us into an endless loop here.
8950 config_backend = CONFIG_BACKEND_REGISTRY;
8952 DEBUG(1, ("lp_load_ex: changing to config backend "
8955 lp_kill_all_services();
8956 return lp_load_ex(pszFname, global_only, save_defaults,
8957 add_ipc, initialize_globals,
8958 allow_include_registry,
8959 allow_registry_shares);
8961 } else if (lp_config_backend_is_registry()) {
8962 bRetval = process_registry_globals();
8964 DEBUG(0, ("Illegal config backend given: %d\n",
8965 lp_config_backend()));
8969 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8970 bRetval = process_registry_shares();
8973 lp_add_auto_services(lp_auto_services());
8976 /* When 'restrict anonymous = 2' guest connections to ipc$
8978 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8979 if ( lp_enable_asu_support() ) {
8980 lp_add_ipc("ADMIN$", false);
8985 set_allowed_client_auth();
8987 if (lp_security() == SEC_SHARE) {
8988 DEBUG(1, ("WARNING: The security=share option is deprecated\n"));
8989 } else if (lp_security() == SEC_SERVER) {
8990 DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
8993 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
8994 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
8995 lp_passwordserver()));
9000 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9001 /* if bWINSsupport is true and we are in the client */
9002 if (lp_is_in_client() && Globals.bWINSsupport) {
9003 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9008 fault_configure(smb_panic_s3);
9010 bAllowIncludeRegistry = true;
9015 bool lp_load(const char *pszFname,
9019 bool initialize_globals)
9021 return lp_load_ex(pszFname,
9026 true, /* allow_include_registry */
9027 false); /* allow_registry_shares*/
9030 bool lp_load_initial_only(const char *pszFname)
9032 return lp_load_ex(pszFname,
9033 true, /* global only */
9034 false, /* save_defaults */
9035 false, /* add_ipc */
9036 true, /* initialize_globals */
9037 false, /* allow_include_registry */
9038 false); /* allow_registry_shares*/
9041 bool lp_load_with_registry_shares(const char *pszFname,
9045 bool initialize_globals)
9047 return lp_load_ex(pszFname,
9052 true, /* allow_include_registry */
9053 true); /* allow_registry_shares*/
9056 /***************************************************************************
9057 Return the max number of services.
9058 ***************************************************************************/
9060 int lp_numservices(void)
9062 return (iNumServices);
9065 /***************************************************************************
9066 Display the contents of the services array in human-readable form.
9067 ***************************************************************************/
9069 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9074 defaults_saved = false;
9078 dump_a_service(&sDefault, f);
9080 for (iService = 0; iService < maxtoprint; iService++) {
9082 lp_dump_one(f, show_defaults, iService);
9086 /***************************************************************************
9087 Display the contents of one service in human-readable form.
9088 ***************************************************************************/
9090 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9093 if (ServicePtrs[snum]->szService[0] == '\0')
9095 dump_a_service(ServicePtrs[snum], f);
9099 /***************************************************************************
9100 Return the number of the service with the given name, or -1 if it doesn't
9101 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9102 getservicebyname()! This works ONLY if all services have been loaded, and
9103 does not copy the found service.
9104 ***************************************************************************/
9106 int lp_servicenumber(const char *pszServiceName)
9109 fstring serviceName;
9111 if (!pszServiceName) {
9112 return GLOBAL_SECTION_SNUM;
9115 for (iService = iNumServices - 1; iService >= 0; iService--) {
9116 if (VALID(iService) && ServicePtrs[iService]->szService) {
9118 * The substitution here is used to support %U is
9121 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9122 standard_sub_basic(get_current_username(),
9123 current_user_info.domain,
9124 serviceName,sizeof(serviceName));
9125 if (strequal(serviceName, pszServiceName)) {
9131 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9132 struct timespec last_mod;
9134 if (!usershare_exists(iService, &last_mod)) {
9135 /* Remove the share security tdb entry for it. */
9136 delete_share_security(lp_servicename(iService));
9137 /* Remove it from the array. */
9138 free_service_byindex(iService);
9139 /* Doesn't exist anymore. */
9140 return GLOBAL_SECTION_SNUM;
9143 /* Has it been modified ? If so delete and reload. */
9144 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9146 /* Remove it from the array. */
9147 free_service_byindex(iService);
9148 /* and now reload it. */
9149 iService = load_usershare_service(pszServiceName);
9154 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9155 return GLOBAL_SECTION_SNUM;
9161 bool share_defined(const char *service_name)
9163 return (lp_servicenumber(service_name) != -1);
9166 /*******************************************************************
9167 A useful volume label function.
9168 ********************************************************************/
9170 const char *volume_label(int snum)
9173 const char *label = lp_volume(snum);
9175 label = lp_servicename(snum);
9178 /* This returns a 33 byte guarenteed null terminated string. */
9179 ret = talloc_strndup(talloc_tos(), label, 32);
9186 /*******************************************************************
9187 Get the default server type we will announce as via nmbd.
9188 ********************************************************************/
9190 int lp_default_server_announce(void)
9192 int default_server_announce = 0;
9193 default_server_announce |= SV_TYPE_WORKSTATION;
9194 default_server_announce |= SV_TYPE_SERVER;
9195 default_server_announce |= SV_TYPE_SERVER_UNIX;
9197 /* note that the flag should be set only if we have a
9198 printer service but nmbd doesn't actually load the
9199 services so we can't tell --jerry */
9201 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9203 default_server_announce |= SV_TYPE_SERVER_NT;
9204 default_server_announce |= SV_TYPE_NT;
9206 switch (lp_server_role()) {
9207 case ROLE_DOMAIN_MEMBER:
9208 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9210 case ROLE_DOMAIN_PDC:
9211 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9213 case ROLE_DOMAIN_BDC:
9214 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9216 case ROLE_STANDALONE:
9220 if (lp_time_server())
9221 default_server_announce |= SV_TYPE_TIME_SOURCE;
9223 if (lp_host_msdfs())
9224 default_server_announce |= SV_TYPE_DFS_SERVER;
9226 return default_server_announce;
9229 /***********************************************************
9230 If we are PDC then prefer us as DMB
9231 ************************************************************/
9233 bool lp_domain_master(void)
9235 if (Globals.iDomainMaster == Auto)
9236 return (lp_server_role() == ROLE_DOMAIN_PDC);
9238 return (bool)Globals.iDomainMaster;
9241 /***********************************************************
9242 If we are PDC then prefer us as DMB
9243 ************************************************************/
9245 bool lp_domain_master_true_or_auto(void)
9247 if (Globals.iDomainMaster) /* auto or yes */
9253 /***********************************************************
9254 If we are DMB then prefer us as LMB
9255 ************************************************************/
9257 bool lp_preferred_master(void)
9259 if (Globals.iPreferredMaster == Auto)
9260 return (lp_local_master() && lp_domain_master());
9262 return (bool)Globals.iPreferredMaster;
9265 /*******************************************************************
9267 ********************************************************************/
9269 void lp_remove_service(int snum)
9271 ServicePtrs[snum]->valid = false;
9272 invalid_services[num_invalid_services++] = snum;
9275 /*******************************************************************
9277 ********************************************************************/
9279 void lp_copy_service(int snum, const char *new_name)
9281 do_section(new_name, NULL);
9283 snum = lp_servicenumber(new_name);
9285 lp_do_parameter(snum, "copy", lp_servicename(snum));
9290 /***********************************************************
9291 Set the global name resolution order (used in smbclient).
9292 ************************************************************/
9294 void lp_set_name_resolve_order(const char *new_order)
9296 string_set(&Globals.szNameResolveOrder, new_order);
9299 const char *lp_printername(int snum)
9301 const char *ret = lp__printername(snum);
9302 if (ret == NULL || (ret != NULL && *ret == '\0'))
9303 ret = lp_const_servicename(snum);
9309 /***********************************************************
9310 Allow daemons such as winbindd to fix their logfile name.
9311 ************************************************************/
9313 void lp_set_logfile(const char *name)
9315 string_set(&Globals.szLogFile, name);
9316 debug_set_logfile(name);
9319 /*******************************************************************
9320 Return the max print jobs per queue.
9321 ********************************************************************/
9323 int lp_maxprintjobs(int snum)
9325 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9326 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9327 maxjobs = PRINT_MAX_JOBID - 1;
9332 const char *lp_printcapname(void)
9334 if ((Globals.szPrintcapname != NULL) &&
9335 (Globals.szPrintcapname[0] != '\0'))
9336 return Globals.szPrintcapname;
9338 if (sDefault.iPrinting == PRINT_CUPS) {
9346 if (sDefault.iPrinting == PRINT_BSD)
9347 return "/etc/printcap";
9349 return PRINTCAP_NAME;
9352 static uint32 spoolss_state;
9354 bool lp_disable_spoolss( void )
9356 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9357 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9359 return spoolss_state == SVCCTL_STOPPED ? true : false;
9362 void lp_set_spoolss_state( uint32 state )
9364 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9366 spoolss_state = state;
9369 uint32 lp_get_spoolss_state( void )
9371 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9374 /*******************************************************************
9375 Ensure we don't use sendfile if server smb signing is active.
9376 ********************************************************************/
9378 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9380 bool sign_active = false;
9382 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9383 if (get_Protocol() < PROTOCOL_NT1) {
9386 if (signing_state) {
9387 sign_active = smb_signing_is_active(signing_state);
9389 return (lp__use_sendfile(snum) &&
9390 (get_remote_arch() != RA_WIN95) &&
9394 /*******************************************************************
9395 Turn off sendfile if we find the underlying OS doesn't support it.
9396 ********************************************************************/
9398 void set_use_sendfile(int snum, bool val)
9400 if (LP_SNUM_OK(snum))
9401 ServicePtrs[snum]->bUseSendfile = val;
9403 sDefault.bUseSendfile = val;
9406 /*******************************************************************
9407 Turn off storing DOS attributes if this share doesn't support it.
9408 ********************************************************************/
9410 void set_store_dos_attributes(int snum, bool val)
9412 if (!LP_SNUM_OK(snum))
9414 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9417 void lp_set_mangling_method(const char *new_method)
9419 string_set(&Globals.szManglingMethod, new_method);
9422 /*******************************************************************
9423 Global state for POSIX pathname processing.
9424 ********************************************************************/
9426 static bool posix_pathnames;
9428 bool lp_posix_pathnames(void)
9430 return posix_pathnames;
9433 /*******************************************************************
9434 Change everything needed to ensure POSIX pathname processing (currently
9436 ********************************************************************/
9438 void lp_set_posix_pathnames(void)
9440 posix_pathnames = true;
9443 /*******************************************************************
9444 Global state for POSIX lock processing - CIFS unix extensions.
9445 ********************************************************************/
9447 bool posix_default_lock_was_set;
9448 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9450 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9452 if (posix_default_lock_was_set) {
9453 return posix_cifsx_locktype;
9455 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9459 /*******************************************************************
9460 ********************************************************************/
9462 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9464 posix_default_lock_was_set = true;
9465 posix_cifsx_locktype = val;
9468 int lp_min_receive_file_size(void)
9470 if (Globals.iminreceivefile < 0) {
9473 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9476 /*******************************************************************
9477 If socket address is an empty character string, it is necessary to
9478 define it as "0.0.0.0".
9479 ********************************************************************/
9481 const char *lp_socket_address(void)
9483 char *sock_addr = Globals.szSocketAddress;
9485 if (sock_addr[0] == '\0'){
9486 string_set(&Globals.szSocketAddress, "0.0.0.0");
9488 return Globals.szSocketAddress;
9491 /*******************************************************************
9492 Safe wide links checks.
9493 This helper function always verify the validity of wide links,
9494 even after a configuration file reload.
9495 ********************************************************************/
9497 static bool lp_widelinks_internal(int snum)
9499 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9500 sDefault.bWidelinks);
9503 void widelinks_warning(int snum)
9505 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9506 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9507 "These parameters are incompatible. "
9508 "Wide links will be disabled for this share.\n",
9509 lp_servicename(snum) ));
9513 bool lp_widelinks(int snum)
9515 /* wide links is always incompatible with unix extensions */
9516 if (lp_unix_extensions()) {
9520 return lp_widelinks_internal(snum);
9523 bool lp_writeraw(void)
9525 if (lp_async_smb_echo_handler()) {
9528 return _lp_writeraw();
9531 bool lp_readraw(void)
9533 if (lp_async_smb_echo_handler()) {
9536 return _lp_readraw();