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"
71 #ifdef HAVE_SYS_SYSCTL_H
72 #include <sys/sysctl.h>
75 #ifdef HAVE_HTTPCONNECTENCRYPT
76 #include <cups/http.h>
81 extern userdom_struct current_user_info;
84 #define GLOBAL_NAME "global"
88 #define PRINTERS_NAME "printers"
92 #define HOMES_NAME "homes"
95 /* the special value for the include parameter
96 * to be interpreted not as a file name but to
97 * trigger loading of the global smb.conf options
99 #ifndef INCLUDE_REGISTRY_NAME
100 #define INCLUDE_REGISTRY_NAME "registry"
103 static bool in_client = false; /* Not in the client by default */
104 static struct smbconf_csn conf_last_csn;
106 #define CONFIG_BACKEND_FILE 0
107 #define CONFIG_BACKEND_REGISTRY 1
109 static int config_backend = CONFIG_BACKEND_FILE;
111 /* some helpful bits */
112 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
113 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
115 #define USERSHARE_VALID 1
116 #define USERSHARE_PENDING_DELETE 2
118 static bool defaults_saved = false;
120 struct param_opt_struct {
121 struct param_opt_struct *prev, *next;
129 * This structure describes global (ie., server-wide) parameters.
131 struct loadparm_global {
136 char *szPrintcapname;
137 char *szAddPortCommand;
138 char *szEnumPortsCommand;
139 char *szAddPrinterCommand;
140 char *szDeletePrinterCommand;
141 char *szOs2DriverMap;
147 char *szDefaultService;
151 char *szServerString;
152 char *szAutoServices;
153 char *szPasswdProgram;
157 char *szSMBPasswdFile;
159 char *szPassdbBackend;
160 char **szPreloadModules;
161 char *szPasswordServer;
162 char *szSocketOptions;
166 char *szAfsUsernameMap;
167 int iAfsTokenLifetime;
168 char *szLogNtTokenCommand;
174 char **szWINSservers;
176 char *szRemoteAnnounce;
177 char *szRemoteBrowseSync;
178 char *szSocketAddress;
179 bool bNmbdBindExplicitBroadcast;
180 char *szNISHomeMapName;
183 char **szNetbiosAliases;
184 char *szNetbiosScope;
185 char *szNameResolveOrder;
187 char *szAddUserScript;
188 char *szRenameUserScript;
189 char *szDelUserScript;
190 char *szAddGroupScript;
191 char *szDelGroupScript;
192 char *szAddUserToGroupScript;
193 char *szDelUserFromGroupScript;
194 char *szSetPrimaryGroupScript;
195 char *szAddMachineScript;
196 char *szShutdownScript;
197 char *szAbortShutdownScript;
198 char *szUsernameMapScript;
199 int iUsernameMapCacheTime;
200 char *szCheckPasswordScript;
207 bool bPassdbExpandExplicit;
208 int AlgorithmicRidBase;
209 char *szTemplateHomedir;
210 char *szTemplateShell;
211 char *szWinbindSeparator;
212 bool bWinbindEnumUsers;
213 bool bWinbindEnumGroups;
214 bool bWinbindUseDefaultDomain;
215 bool bWinbindTrustedDomainsOnly;
216 bool bWinbindNestedGroups;
217 int winbind_expand_groups;
218 bool bWinbindRefreshTickets;
219 bool bWinbindOfflineLogon;
220 bool bWinbindNormalizeNames;
221 bool bWinbindRpcOnly;
222 bool bCreateKrb5Conf;
223 int winbindMaxDomainConnections;
224 char *szIdmapBackend;
225 char *szAddShareCommand;
226 char *szChangeShareCommand;
227 char *szDeleteShareCommand;
229 char *szGuestaccount;
230 char *szManglingMethod;
231 char **szServicesList;
232 char *szUsersharePath;
233 char *szUsershareTemplateShare;
234 char **szUsersharePrefixAllowList;
235 char **szUsersharePrefixDenyList;
242 int open_files_db_hash_size;
251 bool paranoid_server_security;
254 int iMaxSmbdProcesses;
255 bool bDisableSpoolss;
258 bool enhanced_browsing;
264 int machine_password_timeout;
266 int oplock_break_wait_time;
267 int winbind_cache_time;
268 int winbind_reconnect_delay;
269 int winbind_max_clients;
270 char **szWinbindNssInfo;
272 char *szLdapMachineSuffix;
273 char *szLdapUserSuffix;
274 char *szLdapIdmapSuffix;
275 char *szLdapGroupSuffix;
279 int ldap_follow_referral;
282 int ldap_debug_level;
283 int ldap_debug_threshold;
287 char *szIPrintServer;
289 char **szClusterAddresses;
292 int ctdb_locktime_warn_threshold;
293 int ldap_passwd_sync;
294 int ldap_replication_sleep;
295 int ldap_timeout; /* This is initialised in init_globals */
296 int ldap_connection_timeout;
299 bool bMsAddPrinterWizard;
304 int iPreferredMaster;
307 char **szInitLogonDelayedHosts;
309 bool bEncryptPasswords;
313 bool bObeyPamRestrictions;
315 int PrintcapCacheTime;
316 bool bLargeReadwrite;
323 bool bBindInterfacesOnly;
324 bool bPamPasswordChange;
325 bool bUnixPasswdSync;
326 bool bPasswdChatDebug;
327 int iPasswdChatTimeout;
331 bool bNTStatusSupport;
333 int iMaxStatCacheSize;
335 bool bAllowTrustedDomains;
339 bool bClientLanManAuth;
340 bool bClientNTLMv2Auth;
341 bool bClientPlaintextAuth;
342 bool bClientUseSpnego;
343 bool client_use_spnego_principal;
344 bool send_spnego_principal;
345 bool bDebugPrefixTimestamp;
346 bool bDebugHiresTimestamp;
350 bool bEnableCoreFiles;
353 bool bHostnameLookups;
354 bool bUnixExtensions;
355 bool bDisableNetbios;
356 char * szDedicatedKeytabFile;
358 bool bDeferSharingViolations;
359 bool bEnablePrivileges;
361 bool bUsershareOwnerOnly;
362 bool bUsershareAllowGuests;
363 bool bRegistryShares;
364 int restrict_anonymous;
365 int name_cache_timeout;
368 int client_ldap_sasl_wrapping;
369 int iUsershareMaxShares;
371 int iIdmapNegativeCacheTime;
373 bool bLogWriteableFilesOnExit;
376 struct param_opt_struct *param_opt;
377 int cups_connection_timeout;
378 char *szSMBPerfcountModule;
379 bool bMapUntrustedToDomain;
380 bool bAsyncSMBEchoHandler;
381 bool bMulticastDnsRegister;
385 int ismb2_max_credits;
389 static struct loadparm_global Globals;
392 * This structure describes a single service.
394 struct loadparm_service {
398 struct timespec usershare_last_mod;
402 char **szInvalidUsers;
410 char *szRootPostExec;
412 char *szPrintcommand;
415 char *szLppausecommand;
416 char *szLpresumecommand;
417 char *szQueuepausecommand;
418 char *szQueueresumecommand;
420 char *szPrintjobUsername;
428 char *szVetoOplockFiles;
434 char **printer_admin;
439 char *szAioWriteBehind;
443 int iMaxReportedPrintJobs;
446 int iCreate_force_mode;
448 int iSecurity_force_mode;
451 int iDir_Security_mask;
452 int iDir_Security_force_mode;
456 int iOplockContentionLimit;
461 bool bRootpreexecClose;
464 bool bShortCasePreserve;
466 bool bHideSpecialFiles;
467 bool bHideUnReadable;
468 bool bHideUnWriteableFiles;
470 bool bAccessBasedShareEnum;
475 bool bAdministrative_share;
478 bool bPrintNotifyBackchannel;
482 bool bStoreDosAttributes;
495 bool bStrictAllocate;
498 struct bitmap *copymap;
499 bool bDeleteReadonly;
501 bool bDeleteVetoFiles;
504 bool bDosFiletimeResolution;
505 bool bFakeDirCreateTimes;
511 bool bUseClientDriver;
512 bool bDefaultDevmode;
513 bool bForcePrintername;
515 bool bForceUnknownAclUser;
518 bool bMap_acl_inherit;
521 bool bAclCheckPermissions;
522 bool bAclMapFullControl;
523 bool bAclGroupControl;
525 bool bKernelChangeNotify;
526 int iallocation_roundup_size;
530 int iDirectoryNameCacheSize;
532 struct param_opt_struct *param_opt;
534 char dummy[3]; /* for alignment */
538 /* This is a default service used to prime a services structure */
539 static struct loadparm_service sDefault =
544 .usershare_last_mod = {0, 0},
548 .szInvalidUsers = NULL,
549 .szValidUsers = NULL,
550 .szAdminUsers = NULL,
555 .szRootPreExec = NULL,
556 .szRootPostExec = NULL,
557 .szCupsOptions = NULL,
558 .szPrintcommand = NULL,
559 .szLpqcommand = NULL,
560 .szLprmcommand = NULL,
561 .szLppausecommand = NULL,
562 .szLpresumecommand = NULL,
563 .szQueuepausecommand = NULL,
564 .szQueueresumecommand = NULL,
565 .szPrintername = NULL,
566 .szPrintjobUsername = NULL,
567 .szDontdescend = NULL,
568 .szHostsallow = NULL,
570 .szMagicScript = NULL,
571 .szMagicOutput = NULL,
574 .szVetoOplockFiles = NULL,
580 .printer_admin = NULL,
583 .szVfsObjects = NULL,
584 .szMSDfsProxy = NULL,
585 .szAioWriteBehind = NULL,
588 .iMaxPrintJobs = 1000,
589 .iMaxReportedPrintJobs = 0,
590 .iWriteCacheSize = 0,
591 .iCreate_mask = 0744,
592 .iCreate_force_mode = 0,
593 .iSecurity_mask = 0777,
594 .iSecurity_force_mode = 0,
596 .iDir_force_mode = 0,
597 .iDir_Security_mask = 0777,
598 .iDir_Security_force_mode = 0,
599 .iMaxConnections = 0,
600 .iDefaultCase = CASE_LOWER,
601 .iPrinting = DEFAULT_PRINTING,
602 .iOplockContentionLimit = 2,
605 .iDfreeCacheTime = 0,
606 .bPreexecClose = false,
607 .bRootpreexecClose = false,
608 .iCaseSensitive = Auto,
609 .bCasePreserve = true,
610 .bShortCasePreserve = true,
611 .bHideDotFiles = true,
612 .bHideSpecialFiles = false,
613 .bHideUnReadable = false,
614 .bHideUnWriteableFiles = false,
616 .bAccessBasedShareEnum = false,
620 .bGuest_only = false,
621 .bAdministrative_share = false,
624 .bPrintNotifyBackchannel = true,
625 .bMap_system = false,
626 .bMap_hidden = false,
627 .bMap_archive = true,
628 .bStoreDosAttributes = false,
629 .bDmapiSupport = false,
631 .iStrictLocking = Auto,
632 .bPosixLocking = true,
635 .bLevel2OpLocks = true,
637 .bMangledNames = true,
640 .bSyncAlways = false,
641 .bStrictAllocate = false,
642 .bStrictSync = false,
645 .bDeleteReadonly = false,
646 .bFakeOplocks = false,
647 .bDeleteVetoFiles = false,
648 .bDosFilemode = false,
649 .bDosFiletimes = true,
650 .bDosFiletimeResolution = false,
651 .bFakeDirCreateTimes = false,
652 .bBlockingLocks = true,
653 .bInheritPerms = false,
654 .bInheritACLS = false,
655 .bInheritOwner = false,
657 .bUseClientDriver = false,
658 .bDefaultDevmode = true,
659 .bForcePrintername = false,
660 .bNTAclSupport = true,
661 .bForceUnknownAclUser = false,
662 .bUseSendfile = false,
663 .bProfileAcls = false,
664 .bMap_acl_inherit = false,
667 .bAclCheckPermissions = true,
668 .bAclMapFullControl = true,
669 .bAclGroupControl = false,
670 .bChangeNotify = true,
671 .bKernelChangeNotify = true,
672 .iallocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
675 .iMap_readonly = MAP_READONLY_YES,
676 #ifdef BROKEN_DIRECTORY_HANDLING
677 .iDirectoryNameCacheSize = 0,
679 .iDirectoryNameCacheSize = 100,
681 .ismb_encrypt = Auto,
686 /* local variables */
687 static struct loadparm_service **ServicePtrs = NULL;
688 static int iNumServices = 0;
689 static int iServiceIndex = 0;
690 static struct db_context *ServiceHash;
691 static int *invalid_services = NULL;
692 static int num_invalid_services = 0;
693 static bool bInGlobalSection = true;
694 static bool bGlobalOnly = false;
695 static int default_server_announce;
697 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
699 /* prototypes for the special type handlers */
700 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
701 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
702 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
703 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
704 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
705 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
706 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
707 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
708 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
709 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
710 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
711 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
713 static void set_default_server_announce_type(void);
714 static void set_allowed_client_auth(void);
716 static void add_to_file_list(const char *fname, const char *subfname);
717 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
719 static const struct enum_list enum_protocol[] = {
720 {PROTOCOL_SMB2, "SMB2"},
721 {PROTOCOL_NT1, "NT1"},
722 {PROTOCOL_LANMAN2, "LANMAN2"},
723 {PROTOCOL_LANMAN1, "LANMAN1"},
724 {PROTOCOL_CORE, "CORE"},
725 {PROTOCOL_COREPLUS, "COREPLUS"},
726 {PROTOCOL_COREPLUS, "CORE+"},
730 static const struct enum_list enum_security[] = {
731 {SEC_SHARE, "SHARE"},
733 {SEC_SERVER, "SERVER"},
734 {SEC_DOMAIN, "DOMAIN"},
741 static const struct enum_list enum_printing[] = {
742 {PRINT_SYSV, "sysv"},
744 {PRINT_HPUX, "hpux"},
748 {PRINT_LPRNG, "lprng"},
749 {PRINT_CUPS, "cups"},
750 {PRINT_IPRINT, "iprint"},
752 {PRINT_LPROS2, "os2"},
753 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
754 {PRINT_TEST, "test"},
756 #endif /* DEVELOPER */
760 static const struct enum_list enum_ldap_sasl_wrapping[] = {
762 {ADS_AUTH_SASL_SIGN, "sign"},
763 {ADS_AUTH_SASL_SEAL, "seal"},
767 static const struct enum_list enum_ldap_ssl[] = {
768 {LDAP_SSL_OFF, "no"},
769 {LDAP_SSL_OFF, "off"},
770 {LDAP_SSL_START_TLS, "start tls"},
771 {LDAP_SSL_START_TLS, "start_tls"},
775 /* LDAP Dereferencing Alias types */
776 #define SAMBA_LDAP_DEREF_NEVER 0
777 #define SAMBA_LDAP_DEREF_SEARCHING 1
778 #define SAMBA_LDAP_DEREF_FINDING 2
779 #define SAMBA_LDAP_DEREF_ALWAYS 3
781 static const struct enum_list enum_ldap_deref[] = {
782 {SAMBA_LDAP_DEREF_NEVER, "never"},
783 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
784 {SAMBA_LDAP_DEREF_FINDING, "finding"},
785 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
789 static const struct enum_list enum_ldap_passwd_sync[] = {
790 {LDAP_PASSWD_SYNC_OFF, "no"},
791 {LDAP_PASSWD_SYNC_OFF, "off"},
792 {LDAP_PASSWD_SYNC_ON, "yes"},
793 {LDAP_PASSWD_SYNC_ON, "on"},
794 {LDAP_PASSWD_SYNC_ONLY, "only"},
798 static const struct enum_list enum_map_readonly[] = {
799 {MAP_READONLY_NO, "no"},
800 {MAP_READONLY_NO, "false"},
801 {MAP_READONLY_NO, "0"},
802 {MAP_READONLY_YES, "yes"},
803 {MAP_READONLY_YES, "true"},
804 {MAP_READONLY_YES, "1"},
805 {MAP_READONLY_PERMISSIONS, "permissions"},
806 {MAP_READONLY_PERMISSIONS, "perms"},
810 static const struct enum_list enum_case[] = {
811 {CASE_LOWER, "lower"},
812 {CASE_UPPER, "upper"},
818 static const struct enum_list enum_bool_auto[] = {
829 static const struct enum_list enum_csc_policy[] = {
830 {CSC_POLICY_MANUAL, "manual"},
831 {CSC_POLICY_DOCUMENTS, "documents"},
832 {CSC_POLICY_PROGRAMS, "programs"},
833 {CSC_POLICY_DISABLE, "disable"},
837 /* SMB signing types. */
838 static const struct enum_list enum_smb_signing_vals[] = {
850 {Required, "required"},
851 {Required, "mandatory"},
853 {Required, "forced"},
854 {Required, "enforced"},
858 /* ACL compatibility options. */
859 static const struct enum_list enum_acl_compat_vals[] = {
860 { ACL_COMPAT_AUTO, "auto" },
861 { ACL_COMPAT_WINNT, "winnt" },
862 { ACL_COMPAT_WIN2K, "win2k" },
867 Do you want session setups at user level security with a invalid
868 password to be rejected or allowed in as guest? WinNT rejects them
869 but it can be a pain as it means "net view" needs to use a password
871 You have 3 choices in the setting of map_to_guest:
873 "Never" means session setups with an invalid password
874 are rejected. This is the default.
876 "Bad User" means session setups with an invalid password
877 are rejected, unless the username does not exist, in which case it
878 is treated as a guest login
880 "Bad Password" means session setups with an invalid password
881 are treated as a guest login
883 Note that map_to_guest only has an effect in user or server
887 static const struct enum_list enum_map_to_guest[] = {
888 {NEVER_MAP_TO_GUEST, "Never"},
889 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
890 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
891 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
895 /* Config backend options */
897 static const struct enum_list enum_config_backend[] = {
898 {CONFIG_BACKEND_FILE, "file"},
899 {CONFIG_BACKEND_REGISTRY, "registry"},
903 /* ADS kerberos ticket verification options */
905 static const struct enum_list enum_kerberos_method[] = {
906 {KERBEROS_VERIFY_SECRETS, "default"},
907 {KERBEROS_VERIFY_SECRETS, "secrets only"},
908 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
909 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
910 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
914 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
916 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
917 * screen in SWAT. This is used to exclude parameters as well as to squash all
918 * parameters that have been duplicated by pseudonyms.
920 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
921 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
922 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
925 * NOTE2: Handling of duplicated (synonym) parameters:
926 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
927 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
928 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
929 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
932 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
933 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
935 static struct parm_struct parm_table[] = {
936 {N_("Base Options"), P_SEP, P_SEPARATOR},
939 .label = "dos charset",
942 .offset = GLOBAL_VAR(dos_charset),
943 .special = handle_dos_charset,
945 .flags = FLAG_ADVANCED
948 .label = "unix charset",
951 .offset = GLOBAL_VAR(unix_charset),
952 .special = handle_charset,
954 .flags = FLAG_ADVANCED
960 .offset = LOCAL_VAR(comment),
963 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
969 .offset = LOCAL_VAR(szPath),
972 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
975 .label = "directory",
978 .offset = LOCAL_VAR(szPath),
984 .label = "workgroup",
987 .offset = GLOBAL_VAR(szWorkgroup),
990 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
996 .offset = GLOBAL_VAR(szRealm),
997 .special = handle_realm,
999 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1002 .label = "netbios name",
1004 .p_class = P_GLOBAL,
1005 .offset = GLOBAL_VAR(szNetbiosName),
1008 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1011 .label = "netbios aliases",
1013 .p_class = P_GLOBAL,
1014 .offset = GLOBAL_VAR(szNetbiosAliases),
1015 .special = handle_netbios_aliases,
1017 .flags = FLAG_ADVANCED,
1020 .label = "netbios scope",
1022 .p_class = P_GLOBAL,
1023 .offset = GLOBAL_VAR(szNetbiosScope),
1026 .flags = FLAG_ADVANCED,
1029 .label = "server string",
1031 .p_class = P_GLOBAL,
1032 .offset = GLOBAL_VAR(szServerString),
1035 .flags = FLAG_BASIC | FLAG_ADVANCED,
1038 .label = "interfaces",
1040 .p_class = P_GLOBAL,
1041 .offset = GLOBAL_VAR(szInterfaces),
1044 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1047 .label = "bind interfaces only",
1049 .p_class = P_GLOBAL,
1050 .offset = GLOBAL_VAR(bBindInterfacesOnly),
1053 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1056 .label = "config backend",
1058 .p_class = P_GLOBAL,
1059 .offset = GLOBAL_VAR(ConfigBackend),
1061 .enum_list = enum_config_backend,
1062 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1065 {N_("Security Options"), P_SEP, P_SEPARATOR},
1068 .label = "security",
1070 .p_class = P_GLOBAL,
1071 .offset = GLOBAL_VAR(security),
1073 .enum_list = enum_security,
1074 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1077 .label = "auth methods",
1079 .p_class = P_GLOBAL,
1080 .offset = GLOBAL_VAR(AuthMethods),
1083 .flags = FLAG_ADVANCED,
1086 .label = "encrypt passwords",
1088 .p_class = P_GLOBAL,
1089 .offset = GLOBAL_VAR(bEncryptPasswords),
1092 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1095 .label = "client schannel",
1097 .p_class = P_GLOBAL,
1098 .offset = GLOBAL_VAR(clientSchannel),
1100 .enum_list = enum_bool_auto,
1101 .flags = FLAG_BASIC | FLAG_ADVANCED,
1104 .label = "server schannel",
1106 .p_class = P_GLOBAL,
1107 .offset = GLOBAL_VAR(serverSchannel),
1109 .enum_list = enum_bool_auto,
1110 .flags = FLAG_BASIC | FLAG_ADVANCED,
1113 .label = "allow trusted domains",
1115 .p_class = P_GLOBAL,
1116 .offset = GLOBAL_VAR(bAllowTrustedDomains),
1119 .flags = FLAG_ADVANCED,
1122 .label = "map to guest",
1124 .p_class = P_GLOBAL,
1125 .offset = GLOBAL_VAR(map_to_guest),
1127 .enum_list = enum_map_to_guest,
1128 .flags = FLAG_ADVANCED,
1131 .label = "null passwords",
1133 .p_class = P_GLOBAL,
1134 .offset = GLOBAL_VAR(bNullPasswords),
1137 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1140 .label = "obey pam restrictions",
1142 .p_class = P_GLOBAL,
1143 .offset = GLOBAL_VAR(bObeyPamRestrictions),
1146 .flags = FLAG_ADVANCED,
1149 .label = "password server",
1151 .p_class = P_GLOBAL,
1152 .offset = GLOBAL_VAR(szPasswordServer),
1155 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1158 .label = "smb passwd file",
1160 .p_class = P_GLOBAL,
1161 .offset = GLOBAL_VAR(szSMBPasswdFile),
1164 .flags = FLAG_ADVANCED,
1167 .label = "private dir",
1169 .p_class = P_GLOBAL,
1170 .offset = GLOBAL_VAR(szPrivateDir),
1173 .flags = FLAG_ADVANCED,
1176 .label = "passdb backend",
1178 .p_class = P_GLOBAL,
1179 .offset = GLOBAL_VAR(szPassdbBackend),
1182 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1185 .label = "algorithmic rid base",
1187 .p_class = P_GLOBAL,
1188 .offset = GLOBAL_VAR(AlgorithmicRidBase),
1191 .flags = FLAG_ADVANCED,
1194 .label = "root directory",
1196 .p_class = P_GLOBAL,
1197 .offset = GLOBAL_VAR(szRootdir),
1200 .flags = FLAG_ADVANCED,
1203 .label = "root dir",
1205 .p_class = P_GLOBAL,
1206 .offset = GLOBAL_VAR(szRootdir),
1214 .p_class = P_GLOBAL,
1215 .offset = GLOBAL_VAR(szRootdir),
1221 .label = "guest account",
1223 .p_class = P_GLOBAL,
1224 .offset = GLOBAL_VAR(szGuestaccount),
1227 .flags = FLAG_BASIC | FLAG_ADVANCED,
1230 .label = "enable privileges",
1232 .p_class = P_GLOBAL,
1233 .offset = GLOBAL_VAR(bEnablePrivileges),
1236 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1240 .label = "pam password change",
1242 .p_class = P_GLOBAL,
1243 .offset = GLOBAL_VAR(bPamPasswordChange),
1246 .flags = FLAG_ADVANCED,
1249 .label = "passwd program",
1251 .p_class = P_GLOBAL,
1252 .offset = GLOBAL_VAR(szPasswdProgram),
1255 .flags = FLAG_ADVANCED,
1258 .label = "passwd chat",
1260 .p_class = P_GLOBAL,
1261 .offset = GLOBAL_VAR(szPasswdChat),
1264 .flags = FLAG_ADVANCED,
1267 .label = "passwd chat debug",
1269 .p_class = P_GLOBAL,
1270 .offset = GLOBAL_VAR(bPasswdChatDebug),
1273 .flags = FLAG_ADVANCED,
1276 .label = "passwd chat timeout",
1278 .p_class = P_GLOBAL,
1279 .offset = GLOBAL_VAR(iPasswdChatTimeout),
1282 .flags = FLAG_ADVANCED,
1285 .label = "check password script",
1287 .p_class = P_GLOBAL,
1288 .offset = GLOBAL_VAR(szCheckPasswordScript),
1291 .flags = FLAG_ADVANCED,
1294 .label = "username map",
1296 .p_class = P_GLOBAL,
1297 .offset = GLOBAL_VAR(szUsernameMap),
1300 .flags = FLAG_ADVANCED,
1303 .label = "password level",
1305 .p_class = P_GLOBAL,
1306 .offset = GLOBAL_VAR(pwordlevel),
1309 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1312 .label = "username level",
1314 .p_class = P_GLOBAL,
1315 .offset = GLOBAL_VAR(unamelevel),
1318 .flags = FLAG_ADVANCED,
1321 .label = "unix password sync",
1323 .p_class = P_GLOBAL,
1324 .offset = GLOBAL_VAR(bUnixPasswdSync),
1327 .flags = FLAG_ADVANCED,
1330 .label = "restrict anonymous",
1332 .p_class = P_GLOBAL,
1333 .offset = GLOBAL_VAR(restrict_anonymous),
1336 .flags = FLAG_ADVANCED,
1339 .label = "lanman auth",
1341 .p_class = P_GLOBAL,
1342 .offset = GLOBAL_VAR(bLanmanAuth),
1345 .flags = FLAG_ADVANCED,
1348 .label = "ntlm auth",
1350 .p_class = P_GLOBAL,
1351 .offset = GLOBAL_VAR(bNTLMAuth),
1354 .flags = FLAG_ADVANCED,
1357 .label = "client NTLMv2 auth",
1359 .p_class = P_GLOBAL,
1360 .offset = GLOBAL_VAR(bClientNTLMv2Auth),
1363 .flags = FLAG_ADVANCED,
1366 .label = "client lanman auth",
1368 .p_class = P_GLOBAL,
1369 .offset = GLOBAL_VAR(bClientLanManAuth),
1372 .flags = FLAG_ADVANCED,
1375 .label = "client plaintext auth",
1377 .p_class = P_GLOBAL,
1378 .offset = GLOBAL_VAR(bClientPlaintextAuth),
1381 .flags = FLAG_ADVANCED,
1384 .label = "client use spnego principal",
1386 .p_class = P_GLOBAL,
1387 .offset = GLOBAL_VAR(client_use_spnego_principal),
1390 .flags = FLAG_ADVANCED,
1393 .label = "send spnego principal",
1395 .p_class = P_GLOBAL,
1396 .offset = GLOBAL_VAR(send_spnego_principal),
1399 .flags = FLAG_ADVANCED,
1402 .label = "username",
1405 .offset = LOCAL_VAR(szUsername),
1408 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1414 .offset = LOCAL_VAR(szUsername),
1423 .offset = LOCAL_VAR(szUsername),
1429 .label = "invalid users",
1432 .offset = LOCAL_VAR(szInvalidUsers),
1435 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1438 .label = "valid users",
1441 .offset = LOCAL_VAR(szValidUsers),
1444 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1447 .label = "admin users",
1450 .offset = LOCAL_VAR(szAdminUsers),
1453 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1456 .label = "read list",
1459 .offset = LOCAL_VAR(readlist),
1462 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1465 .label = "write list",
1468 .offset = LOCAL_VAR(writelist),
1471 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1474 .label = "printer admin",
1477 .offset = LOCAL_VAR(printer_admin),
1480 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1483 .label = "force user",
1486 .offset = LOCAL_VAR(force_user),
1489 .flags = FLAG_ADVANCED | FLAG_SHARE,
1492 .label = "force group",
1495 .offset = LOCAL_VAR(force_group),
1498 .flags = FLAG_ADVANCED | FLAG_SHARE,
1504 .offset = LOCAL_VAR(force_group),
1507 .flags = FLAG_ADVANCED,
1510 .label = "read only",
1513 .offset = LOCAL_VAR(bRead_only),
1516 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1519 .label = "write ok",
1522 .offset = LOCAL_VAR(bRead_only),
1528 .label = "writeable",
1531 .offset = LOCAL_VAR(bRead_only),
1537 .label = "writable",
1540 .offset = LOCAL_VAR(bRead_only),
1546 .label = "acl check permissions",
1549 .offset = LOCAL_VAR(bAclCheckPermissions),
1552 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1555 .label = "acl group control",
1558 .offset = LOCAL_VAR(bAclGroupControl),
1561 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1564 .label = "acl map full control",
1567 .offset = LOCAL_VAR(bAclMapFullControl),
1570 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1573 .label = "create mask",
1576 .offset = LOCAL_VAR(iCreate_mask),
1579 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1582 .label = "create mode",
1585 .offset = LOCAL_VAR(iCreate_mask),
1591 .label = "force create mode",
1594 .offset = LOCAL_VAR(iCreate_force_mode),
1597 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1600 .label = "security mask",
1603 .offset = LOCAL_VAR(iSecurity_mask),
1606 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1609 .label = "force security mode",
1612 .offset = LOCAL_VAR(iSecurity_force_mode),
1615 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1618 .label = "directory mask",
1621 .offset = LOCAL_VAR(iDir_mask),
1624 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1627 .label = "directory mode",
1630 .offset = LOCAL_VAR(iDir_mask),
1633 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1636 .label = "force directory mode",
1639 .offset = LOCAL_VAR(iDir_force_mode),
1642 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1645 .label = "directory security mask",
1648 .offset = LOCAL_VAR(iDir_Security_mask),
1651 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1654 .label = "force directory security mode",
1657 .offset = LOCAL_VAR(iDir_Security_force_mode),
1660 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1663 .label = "force unknown acl user",
1666 .offset = LOCAL_VAR(bForceUnknownAclUser),
1669 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1672 .label = "inherit permissions",
1675 .offset = LOCAL_VAR(bInheritPerms),
1678 .flags = FLAG_ADVANCED | FLAG_SHARE,
1681 .label = "inherit acls",
1684 .offset = LOCAL_VAR(bInheritACLS),
1687 .flags = FLAG_ADVANCED | FLAG_SHARE,
1690 .label = "inherit owner",
1693 .offset = LOCAL_VAR(bInheritOwner),
1696 .flags = FLAG_ADVANCED | FLAG_SHARE,
1699 .label = "guest only",
1702 .offset = LOCAL_VAR(bGuest_only),
1705 .flags = FLAG_ADVANCED | FLAG_SHARE,
1708 .label = "only guest",
1711 .offset = LOCAL_VAR(bGuest_only),
1717 .label = "administrative share",
1720 .offset = LOCAL_VAR(bAdministrative_share),
1723 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1727 .label = "guest ok",
1730 .offset = LOCAL_VAR(bGuest_ok),
1733 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1739 .offset = LOCAL_VAR(bGuest_ok),
1745 .label = "only user",
1748 .offset = LOCAL_VAR(bOnlyUser),
1751 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1754 .label = "hosts allow",
1757 .offset = LOCAL_VAR(szHostsallow),
1760 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1763 .label = "allow hosts",
1766 .offset = LOCAL_VAR(szHostsallow),
1772 .label = "hosts deny",
1775 .offset = LOCAL_VAR(szHostsdeny),
1778 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1781 .label = "deny hosts",
1784 .offset = LOCAL_VAR(szHostsdeny),
1790 .label = "preload modules",
1792 .p_class = P_GLOBAL,
1793 .offset = GLOBAL_VAR(szPreloadModules),
1796 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1799 .label = "dedicated keytab file",
1801 .p_class = P_GLOBAL,
1802 .offset = GLOBAL_VAR(szDedicatedKeytabFile),
1805 .flags = FLAG_ADVANCED,
1808 .label = "kerberos method",
1810 .p_class = P_GLOBAL,
1811 .offset = GLOBAL_VAR(iKerberosMethod),
1813 .enum_list = enum_kerberos_method,
1814 .flags = FLAG_ADVANCED,
1817 .label = "map untrusted to domain",
1819 .p_class = P_GLOBAL,
1820 .offset = GLOBAL_VAR(bMapUntrustedToDomain),
1823 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1827 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1830 .label = "log level",
1832 .p_class = P_GLOBAL,
1833 .offset = GLOBAL_VAR(szLogLevel),
1834 .special = handle_debug_list,
1836 .flags = FLAG_ADVANCED,
1839 .label = "debuglevel",
1841 .p_class = P_GLOBAL,
1842 .offset = GLOBAL_VAR(szLogLevel),
1843 .special = handle_debug_list,
1850 .p_class = P_GLOBAL,
1851 .offset = GLOBAL_VAR(syslog),
1854 .flags = FLAG_ADVANCED,
1857 .label = "syslog only",
1859 .p_class = P_GLOBAL,
1860 .offset = GLOBAL_VAR(bSyslogOnly),
1863 .flags = FLAG_ADVANCED,
1866 .label = "log file",
1868 .p_class = P_GLOBAL,
1869 .offset = GLOBAL_VAR(szLogFile),
1872 .flags = FLAG_ADVANCED,
1875 .label = "max log size",
1877 .p_class = P_GLOBAL,
1878 .offset = GLOBAL_VAR(max_log_size),
1881 .flags = FLAG_ADVANCED,
1884 .label = "debug timestamp",
1886 .p_class = P_GLOBAL,
1887 .offset = GLOBAL_VAR(bTimestampLogs),
1890 .flags = FLAG_ADVANCED,
1893 .label = "timestamp logs",
1895 .p_class = P_GLOBAL,
1896 .offset = GLOBAL_VAR(bTimestampLogs),
1899 .flags = FLAG_ADVANCED,
1902 .label = "debug prefix timestamp",
1904 .p_class = P_GLOBAL,
1905 .offset = GLOBAL_VAR(bDebugPrefixTimestamp),
1908 .flags = FLAG_ADVANCED,
1911 .label = "debug hires timestamp",
1913 .p_class = P_GLOBAL,
1914 .offset = GLOBAL_VAR(bDebugHiresTimestamp),
1917 .flags = FLAG_ADVANCED,
1920 .label = "debug pid",
1922 .p_class = P_GLOBAL,
1923 .offset = GLOBAL_VAR(bDebugPid),
1926 .flags = FLAG_ADVANCED,
1929 .label = "debug uid",
1931 .p_class = P_GLOBAL,
1932 .offset = GLOBAL_VAR(bDebugUid),
1935 .flags = FLAG_ADVANCED,
1938 .label = "debug class",
1940 .p_class = P_GLOBAL,
1941 .offset = GLOBAL_VAR(bDebugClass),
1944 .flags = FLAG_ADVANCED,
1947 .label = "enable core files",
1949 .p_class = P_GLOBAL,
1950 .offset = GLOBAL_VAR(bEnableCoreFiles),
1953 .flags = FLAG_ADVANCED,
1956 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1959 .label = "allocation roundup size",
1962 .offset = LOCAL_VAR(iallocation_roundup_size),
1965 .flags = FLAG_ADVANCED,
1968 .label = "aio read size",
1971 .offset = LOCAL_VAR(iAioReadSize),
1974 .flags = FLAG_ADVANCED,
1977 .label = "aio write size",
1980 .offset = LOCAL_VAR(iAioWriteSize),
1983 .flags = FLAG_ADVANCED,
1986 .label = "aio write behind",
1989 .offset = LOCAL_VAR(szAioWriteBehind),
1992 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1995 .label = "smb ports",
1997 .p_class = P_GLOBAL,
1998 .offset = GLOBAL_VAR(smb_ports),
2001 .flags = FLAG_ADVANCED,
2004 .label = "large readwrite",
2006 .p_class = P_GLOBAL,
2007 .offset = GLOBAL_VAR(bLargeReadwrite),
2010 .flags = FLAG_ADVANCED,
2013 .label = "max protocol",
2015 .p_class = P_GLOBAL,
2016 .offset = GLOBAL_VAR(maxprotocol),
2018 .enum_list = enum_protocol,
2019 .flags = FLAG_ADVANCED,
2022 .label = "protocol",
2024 .p_class = P_GLOBAL,
2025 .offset = GLOBAL_VAR(maxprotocol),
2027 .enum_list = enum_protocol,
2028 .flags = FLAG_ADVANCED,
2031 .label = "min protocol",
2033 .p_class = P_GLOBAL,
2034 .offset = GLOBAL_VAR(minprotocol),
2036 .enum_list = enum_protocol,
2037 .flags = FLAG_ADVANCED,
2040 .label = "min receivefile size",
2042 .p_class = P_GLOBAL,
2043 .offset = GLOBAL_VAR(iminreceivefile),
2046 .flags = FLAG_ADVANCED,
2049 .label = "read raw",
2051 .p_class = P_GLOBAL,
2052 .offset = GLOBAL_VAR(bReadRaw),
2055 .flags = FLAG_ADVANCED,
2058 .label = "write raw",
2060 .p_class = P_GLOBAL,
2061 .offset = GLOBAL_VAR(bWriteRaw),
2064 .flags = FLAG_ADVANCED,
2067 .label = "disable netbios",
2069 .p_class = P_GLOBAL,
2070 .offset = GLOBAL_VAR(bDisableNetbios),
2073 .flags = FLAG_ADVANCED,
2076 .label = "reset on zero vc",
2078 .p_class = P_GLOBAL,
2079 .offset = GLOBAL_VAR(bResetOnZeroVC),
2082 .flags = FLAG_ADVANCED,
2085 .label = "log writeable files on exit",
2087 .p_class = P_GLOBAL,
2088 .offset = GLOBAL_VAR(bLogWriteableFilesOnExit),
2091 .flags = FLAG_ADVANCED,
2094 .label = "acl compatibility",
2096 .p_class = P_GLOBAL,
2097 .offset = GLOBAL_VAR(iAclCompat),
2099 .enum_list = enum_acl_compat_vals,
2100 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2103 .label = "defer sharing violations",
2105 .p_class = P_GLOBAL,
2106 .offset = GLOBAL_VAR(bDeferSharingViolations),
2109 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2112 .label = "ea support",
2115 .offset = LOCAL_VAR(bEASupport),
2118 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2121 .label = "nt acl support",
2124 .offset = LOCAL_VAR(bNTAclSupport),
2127 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2130 .label = "nt pipe support",
2132 .p_class = P_GLOBAL,
2133 .offset = GLOBAL_VAR(bNTPipeSupport),
2136 .flags = FLAG_ADVANCED,
2139 .label = "nt status support",
2141 .p_class = P_GLOBAL,
2142 .offset = GLOBAL_VAR(bNTStatusSupport),
2145 .flags = FLAG_ADVANCED,
2148 .label = "profile acls",
2151 .offset = LOCAL_VAR(bProfileAcls),
2154 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2157 .label = "map acl inherit",
2160 .offset = LOCAL_VAR(bMap_acl_inherit),
2163 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2166 .label = "afs share",
2169 .offset = LOCAL_VAR(bAfs_Share),
2172 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2177 .p_class = P_GLOBAL,
2178 .offset = GLOBAL_VAR(max_mux),
2181 .flags = FLAG_ADVANCED,
2184 .label = "max xmit",
2186 .p_class = P_GLOBAL,
2187 .offset = GLOBAL_VAR(max_xmit),
2190 .flags = FLAG_ADVANCED,
2193 .label = "name resolve order",
2195 .p_class = P_GLOBAL,
2196 .offset = GLOBAL_VAR(szNameResolveOrder),
2199 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2204 .p_class = P_GLOBAL,
2205 .offset = GLOBAL_VAR(max_ttl),
2208 .flags = FLAG_ADVANCED,
2211 .label = "max wins ttl",
2213 .p_class = P_GLOBAL,
2214 .offset = GLOBAL_VAR(max_wins_ttl),
2217 .flags = FLAG_ADVANCED,
2220 .label = "min wins ttl",
2222 .p_class = P_GLOBAL,
2223 .offset = GLOBAL_VAR(min_wins_ttl),
2226 .flags = FLAG_ADVANCED,
2229 .label = "time server",
2231 .p_class = P_GLOBAL,
2232 .offset = GLOBAL_VAR(bTimeServer),
2235 .flags = FLAG_ADVANCED,
2238 .label = "unix extensions",
2240 .p_class = P_GLOBAL,
2241 .offset = GLOBAL_VAR(bUnixExtensions),
2244 .flags = FLAG_ADVANCED,
2247 .label = "use spnego",
2249 .p_class = P_GLOBAL,
2250 .offset = GLOBAL_VAR(bUseSpnego),
2253 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
2256 .label = "client signing",
2258 .p_class = P_GLOBAL,
2259 .offset = GLOBAL_VAR(client_signing),
2261 .enum_list = enum_smb_signing_vals,
2262 .flags = FLAG_ADVANCED,
2265 .label = "server signing",
2267 .p_class = P_GLOBAL,
2268 .offset = GLOBAL_VAR(server_signing),
2270 .enum_list = enum_smb_signing_vals,
2271 .flags = FLAG_ADVANCED,
2274 .label = "smb encrypt",
2277 .offset = LOCAL_VAR(ismb_encrypt),
2279 .enum_list = enum_smb_signing_vals,
2280 .flags = FLAG_ADVANCED,
2283 .label = "client use spnego",
2285 .p_class = P_GLOBAL,
2286 .offset = GLOBAL_VAR(bClientUseSpnego),
2289 .flags = FLAG_ADVANCED,
2292 .label = "client ldap sasl wrapping",
2294 .p_class = P_GLOBAL,
2295 .offset = GLOBAL_VAR(client_ldap_sasl_wrapping),
2297 .enum_list = enum_ldap_sasl_wrapping,
2298 .flags = FLAG_ADVANCED,
2301 .label = "enable asu support",
2303 .p_class = P_GLOBAL,
2304 .offset = GLOBAL_VAR(bASUSupport),
2307 .flags = FLAG_ADVANCED,
2310 .label = "svcctl list",
2312 .p_class = P_GLOBAL,
2313 .offset = GLOBAL_VAR(szServicesList),
2316 .flags = FLAG_ADVANCED,
2319 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2322 .label = "block size",
2325 .offset = LOCAL_VAR(iBlock_size),
2328 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2331 .label = "deadtime",
2333 .p_class = P_GLOBAL,
2334 .offset = GLOBAL_VAR(deadtime),
2337 .flags = FLAG_ADVANCED,
2340 .label = "getwd cache",
2342 .p_class = P_GLOBAL,
2343 .offset = GLOBAL_VAR(getwd_cache),
2346 .flags = FLAG_ADVANCED,
2349 .label = "keepalive",
2351 .p_class = P_GLOBAL,
2352 .offset = GLOBAL_VAR(iKeepalive),
2355 .flags = FLAG_ADVANCED,
2358 .label = "change notify",
2361 .offset = LOCAL_VAR(bChangeNotify),
2364 .flags = FLAG_ADVANCED | FLAG_SHARE,
2367 .label = "directory name cache size",
2370 .offset = LOCAL_VAR(iDirectoryNameCacheSize),
2373 .flags = FLAG_ADVANCED | FLAG_SHARE,
2376 .label = "kernel change notify",
2379 .offset = LOCAL_VAR(bKernelChangeNotify),
2382 .flags = FLAG_ADVANCED | FLAG_SHARE,
2385 .label = "lpq cache time",
2387 .p_class = P_GLOBAL,
2388 .offset = GLOBAL_VAR(lpqcachetime),
2391 .flags = FLAG_ADVANCED,
2394 .label = "max smbd processes",
2396 .p_class = P_GLOBAL,
2397 .offset = GLOBAL_VAR(iMaxSmbdProcesses),
2400 .flags = FLAG_ADVANCED,
2403 .label = "max connections",
2406 .offset = LOCAL_VAR(iMaxConnections),
2409 .flags = FLAG_ADVANCED | FLAG_SHARE,
2412 .label = "paranoid server security",
2414 .p_class = P_GLOBAL,
2415 .offset = GLOBAL_VAR(paranoid_server_security),
2418 .flags = FLAG_ADVANCED,
2421 .label = "max disk size",
2423 .p_class = P_GLOBAL,
2424 .offset = GLOBAL_VAR(maxdisksize),
2427 .flags = FLAG_ADVANCED,
2430 .label = "max open files",
2432 .p_class = P_GLOBAL,
2433 .offset = GLOBAL_VAR(max_open_files),
2436 .flags = FLAG_ADVANCED,
2439 .label = "min print space",
2442 .offset = LOCAL_VAR(iMinPrintSpace),
2445 .flags = FLAG_ADVANCED | FLAG_PRINT,
2448 .label = "socket options",
2450 .p_class = P_GLOBAL,
2451 .offset = GLOBAL_VAR(szSocketOptions),
2454 .flags = FLAG_ADVANCED,
2457 .label = "strict allocate",
2460 .offset = LOCAL_VAR(bStrictAllocate),
2463 .flags = FLAG_ADVANCED | FLAG_SHARE,
2466 .label = "strict sync",
2469 .offset = LOCAL_VAR(bStrictSync),
2472 .flags = FLAG_ADVANCED | FLAG_SHARE,
2475 .label = "sync always",
2478 .offset = LOCAL_VAR(bSyncAlways),
2481 .flags = FLAG_ADVANCED | FLAG_SHARE,
2484 .label = "use mmap",
2486 .p_class = P_GLOBAL,
2487 .offset = GLOBAL_VAR(bUseMmap),
2490 .flags = FLAG_ADVANCED,
2493 .label = "use sendfile",
2496 .offset = LOCAL_VAR(bUseSendfile),
2499 .flags = FLAG_ADVANCED | FLAG_SHARE,
2502 .label = "hostname lookups",
2504 .p_class = P_GLOBAL,
2505 .offset = GLOBAL_VAR(bHostnameLookups),
2508 .flags = FLAG_ADVANCED,
2511 .label = "write cache size",
2514 .offset = LOCAL_VAR(iWriteCacheSize),
2517 .flags = FLAG_ADVANCED | FLAG_SHARE,
2520 .label = "name cache timeout",
2522 .p_class = P_GLOBAL,
2523 .offset = GLOBAL_VAR(name_cache_timeout),
2526 .flags = FLAG_ADVANCED,
2529 .label = "ctdbd socket",
2531 .p_class = P_GLOBAL,
2532 .offset = GLOBAL_VAR(ctdbdSocket),
2535 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2538 .label = "cluster addresses",
2540 .p_class = P_GLOBAL,
2541 .offset = GLOBAL_VAR(szClusterAddresses),
2544 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2547 .label = "clustering",
2549 .p_class = P_GLOBAL,
2550 .offset = GLOBAL_VAR(clustering),
2553 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2556 .label = "ctdb timeout",
2558 .p_class = P_GLOBAL,
2559 .offset = GLOBAL_VAR(ctdb_timeout),
2562 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2565 .label = "ctdb locktime warn threshold",
2567 .p_class = P_GLOBAL,
2568 .offset = GLOBAL_VAR(ctdb_locktime_warn_threshold),
2571 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2574 .label = "smb2 max read",
2576 .p_class = P_GLOBAL,
2577 .offset = GLOBAL_VAR(ismb2_max_read),
2580 .flags = FLAG_ADVANCED,
2583 .label = "smb2 max write",
2585 .p_class = P_GLOBAL,
2586 .offset = GLOBAL_VAR(ismb2_max_write),
2589 .flags = FLAG_ADVANCED,
2592 .label = "smb2 max trans",
2594 .p_class = P_GLOBAL,
2595 .offset = GLOBAL_VAR(ismb2_max_trans),
2598 .flags = FLAG_ADVANCED,
2601 .label = "smb2 max credits",
2603 .p_class = P_GLOBAL,
2604 .offset = GLOBAL_VAR(ismb2_max_credits),
2607 .flags = FLAG_ADVANCED,
2610 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2613 .label = "max reported print jobs",
2616 .offset = LOCAL_VAR(iMaxReportedPrintJobs),
2619 .flags = FLAG_ADVANCED | FLAG_PRINT,
2622 .label = "max print jobs",
2625 .offset = LOCAL_VAR(iMaxPrintJobs),
2628 .flags = FLAG_ADVANCED | FLAG_PRINT,
2631 .label = "load printers",
2633 .p_class = P_GLOBAL,
2634 .offset = GLOBAL_VAR(bLoadPrinters),
2637 .flags = FLAG_ADVANCED | FLAG_PRINT,
2640 .label = "printcap cache time",
2642 .p_class = P_GLOBAL,
2643 .offset = GLOBAL_VAR(PrintcapCacheTime),
2646 .flags = FLAG_ADVANCED | FLAG_PRINT,
2649 .label = "printcap name",
2651 .p_class = P_GLOBAL,
2652 .offset = GLOBAL_VAR(szPrintcapname),
2655 .flags = FLAG_ADVANCED | FLAG_PRINT,
2658 .label = "printcap",
2660 .p_class = P_GLOBAL,
2661 .offset = GLOBAL_VAR(szPrintcapname),
2667 .label = "printable",
2670 .offset = LOCAL_VAR(bPrint_ok),
2673 .flags = FLAG_ADVANCED | FLAG_PRINT,
2676 .label = "print notify backchannel",
2679 .offset = LOCAL_VAR(bPrintNotifyBackchannel),
2682 .flags = FLAG_ADVANCED,
2685 .label = "print ok",
2688 .offset = LOCAL_VAR(bPrint_ok),
2694 .label = "printing",
2697 .offset = LOCAL_VAR(iPrinting),
2698 .special = handle_printing,
2699 .enum_list = enum_printing,
2700 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2703 .label = "cups options",
2706 .offset = LOCAL_VAR(szCupsOptions),
2709 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2712 .label = "cups server",
2714 .p_class = P_GLOBAL,
2715 .offset = GLOBAL_VAR(szCupsServer),
2718 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2721 .label = "cups encrypt",
2723 .p_class = P_GLOBAL,
2724 .offset = GLOBAL_VAR(CupsEncrypt),
2726 .enum_list = enum_bool_auto,
2727 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2731 .label = "cups connection timeout",
2733 .p_class = P_GLOBAL,
2734 .offset = GLOBAL_VAR(cups_connection_timeout),
2737 .flags = FLAG_ADVANCED,
2740 .label = "iprint server",
2742 .p_class = P_GLOBAL,
2743 .offset = GLOBAL_VAR(szIPrintServer),
2746 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2749 .label = "print command",
2752 .offset = LOCAL_VAR(szPrintcommand),
2755 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2758 .label = "disable spoolss",
2760 .p_class = P_GLOBAL,
2761 .offset = GLOBAL_VAR(bDisableSpoolss),
2764 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2767 .label = "enable spoolss",
2769 .p_class = P_GLOBAL,
2770 .offset = GLOBAL_VAR(bDisableSpoolss),
2776 .label = "lpq command",
2779 .offset = LOCAL_VAR(szLpqcommand),
2782 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2785 .label = "lprm command",
2788 .offset = LOCAL_VAR(szLprmcommand),
2791 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2794 .label = "lppause command",
2797 .offset = LOCAL_VAR(szLppausecommand),
2800 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2803 .label = "lpresume command",
2806 .offset = LOCAL_VAR(szLpresumecommand),
2809 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2812 .label = "queuepause command",
2815 .offset = LOCAL_VAR(szQueuepausecommand),
2818 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2821 .label = "queueresume command",
2824 .offset = LOCAL_VAR(szQueueresumecommand),
2827 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2830 .label = "addport command",
2832 .p_class = P_GLOBAL,
2833 .offset = GLOBAL_VAR(szAddPortCommand),
2836 .flags = FLAG_ADVANCED,
2839 .label = "enumports command",
2841 .p_class = P_GLOBAL,
2842 .offset = GLOBAL_VAR(szEnumPortsCommand),
2845 .flags = FLAG_ADVANCED,
2848 .label = "addprinter command",
2850 .p_class = P_GLOBAL,
2851 .offset = GLOBAL_VAR(szAddPrinterCommand),
2854 .flags = FLAG_ADVANCED,
2857 .label = "deleteprinter command",
2859 .p_class = P_GLOBAL,
2860 .offset = GLOBAL_VAR(szDeletePrinterCommand),
2863 .flags = FLAG_ADVANCED,
2866 .label = "show add printer wizard",
2868 .p_class = P_GLOBAL,
2869 .offset = GLOBAL_VAR(bMsAddPrinterWizard),
2872 .flags = FLAG_ADVANCED,
2875 .label = "os2 driver map",
2877 .p_class = P_GLOBAL,
2878 .offset = GLOBAL_VAR(szOs2DriverMap),
2881 .flags = FLAG_ADVANCED,
2885 .label = "printer name",
2888 .offset = LOCAL_VAR(szPrintername),
2891 .flags = FLAG_ADVANCED | FLAG_PRINT,
2897 .offset = LOCAL_VAR(szPrintername),
2903 .label = "use client driver",
2906 .offset = LOCAL_VAR(bUseClientDriver),
2909 .flags = FLAG_ADVANCED | FLAG_PRINT,
2912 .label = "default devmode",
2915 .offset = LOCAL_VAR(bDefaultDevmode),
2918 .flags = FLAG_ADVANCED | FLAG_PRINT,
2921 .label = "force printername",
2924 .offset = LOCAL_VAR(bForcePrintername),
2927 .flags = FLAG_ADVANCED | FLAG_PRINT,
2930 .label = "printjob username",
2933 .offset = LOCAL_VAR(szPrintjobUsername),
2936 .flags = FLAG_ADVANCED | FLAG_PRINT,
2939 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2942 .label = "mangling method",
2944 .p_class = P_GLOBAL,
2945 .offset = GLOBAL_VAR(szManglingMethod),
2948 .flags = FLAG_ADVANCED,
2951 .label = "mangle prefix",
2953 .p_class = P_GLOBAL,
2954 .offset = GLOBAL_VAR(mangle_prefix),
2957 .flags = FLAG_ADVANCED,
2961 .label = "default case",
2964 .offset = LOCAL_VAR(iDefaultCase),
2966 .enum_list = enum_case,
2967 .flags = FLAG_ADVANCED | FLAG_SHARE,
2970 .label = "case sensitive",
2973 .offset = LOCAL_VAR(iCaseSensitive),
2975 .enum_list = enum_bool_auto,
2976 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2979 .label = "casesignames",
2982 .offset = LOCAL_VAR(iCaseSensitive),
2984 .enum_list = enum_bool_auto,
2985 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2988 .label = "preserve case",
2991 .offset = LOCAL_VAR(bCasePreserve),
2994 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2997 .label = "short preserve case",
3000 .offset = LOCAL_VAR(bShortCasePreserve),
3003 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3006 .label = "mangling char",
3009 .offset = LOCAL_VAR(magic_char),
3012 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3015 .label = "hide dot files",
3018 .offset = LOCAL_VAR(bHideDotFiles),
3021 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3024 .label = "hide special files",
3027 .offset = LOCAL_VAR(bHideSpecialFiles),
3030 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3033 .label = "hide unreadable",
3036 .offset = LOCAL_VAR(bHideUnReadable),
3039 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3042 .label = "hide unwriteable files",
3045 .offset = LOCAL_VAR(bHideUnWriteableFiles),
3048 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3051 .label = "delete veto files",
3054 .offset = LOCAL_VAR(bDeleteVetoFiles),
3057 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3060 .label = "veto files",
3063 .offset = LOCAL_VAR(szVetoFiles),
3066 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3069 .label = "hide files",
3072 .offset = LOCAL_VAR(szHideFiles),
3075 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3078 .label = "veto oplock files",
3081 .offset = LOCAL_VAR(szVetoOplockFiles),
3084 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3087 .label = "map archive",
3090 .offset = LOCAL_VAR(bMap_archive),
3093 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3096 .label = "map hidden",
3099 .offset = LOCAL_VAR(bMap_hidden),
3102 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3105 .label = "map system",
3108 .offset = LOCAL_VAR(bMap_system),
3111 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3114 .label = "map readonly",
3117 .offset = LOCAL_VAR(iMap_readonly),
3119 .enum_list = enum_map_readonly,
3120 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3123 .label = "mangled names",
3126 .offset = LOCAL_VAR(bMangledNames),
3129 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3132 .label = "max stat cache size",
3134 .p_class = P_GLOBAL,
3135 .offset = GLOBAL_VAR(iMaxStatCacheSize),
3138 .flags = FLAG_ADVANCED,
3141 .label = "stat cache",
3143 .p_class = P_GLOBAL,
3144 .offset = GLOBAL_VAR(bStatCache),
3147 .flags = FLAG_ADVANCED,
3150 .label = "store dos attributes",
3153 .offset = LOCAL_VAR(bStoreDosAttributes),
3156 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3159 .label = "dmapi support",
3162 .offset = LOCAL_VAR(bDmapiSupport),
3165 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3169 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3172 .label = "machine password timeout",
3174 .p_class = P_GLOBAL,
3175 .offset = GLOBAL_VAR(machine_password_timeout),
3178 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3181 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3184 .label = "add user script",
3186 .p_class = P_GLOBAL,
3187 .offset = GLOBAL_VAR(szAddUserScript),
3190 .flags = FLAG_ADVANCED,
3193 .label = "rename user script",
3195 .p_class = P_GLOBAL,
3196 .offset = GLOBAL_VAR(szRenameUserScript),
3199 .flags = FLAG_ADVANCED,
3202 .label = "delete user script",
3204 .p_class = P_GLOBAL,
3205 .offset = GLOBAL_VAR(szDelUserScript),
3208 .flags = FLAG_ADVANCED,
3211 .label = "add group script",
3213 .p_class = P_GLOBAL,
3214 .offset = GLOBAL_VAR(szAddGroupScript),
3217 .flags = FLAG_ADVANCED,
3220 .label = "delete group script",
3222 .p_class = P_GLOBAL,
3223 .offset = GLOBAL_VAR(szDelGroupScript),
3226 .flags = FLAG_ADVANCED,
3229 .label = "add user to group script",
3231 .p_class = P_GLOBAL,
3232 .offset = GLOBAL_VAR(szAddUserToGroupScript),
3235 .flags = FLAG_ADVANCED,
3238 .label = "delete user from group script",
3240 .p_class = P_GLOBAL,
3241 .offset = GLOBAL_VAR(szDelUserFromGroupScript),
3244 .flags = FLAG_ADVANCED,
3247 .label = "set primary group script",
3249 .p_class = P_GLOBAL,
3250 .offset = GLOBAL_VAR(szSetPrimaryGroupScript),
3253 .flags = FLAG_ADVANCED,
3256 .label = "add machine script",
3258 .p_class = P_GLOBAL,
3259 .offset = GLOBAL_VAR(szAddMachineScript),
3262 .flags = FLAG_ADVANCED,
3265 .label = "shutdown script",
3267 .p_class = P_GLOBAL,
3268 .offset = GLOBAL_VAR(szShutdownScript),
3271 .flags = FLAG_ADVANCED,
3274 .label = "abort shutdown script",
3276 .p_class = P_GLOBAL,
3277 .offset = GLOBAL_VAR(szAbortShutdownScript),
3280 .flags = FLAG_ADVANCED,
3283 .label = "username map script",
3285 .p_class = P_GLOBAL,
3286 .offset = GLOBAL_VAR(szUsernameMapScript),
3289 .flags = FLAG_ADVANCED,
3292 .label = "username map cache time",
3294 .p_class = P_GLOBAL,
3295 .offset = GLOBAL_VAR(iUsernameMapCacheTime),
3298 .flags = FLAG_ADVANCED,
3301 .label = "logon script",
3303 .p_class = P_GLOBAL,
3304 .offset = GLOBAL_VAR(szLogonScript),
3307 .flags = FLAG_ADVANCED,
3310 .label = "logon path",
3312 .p_class = P_GLOBAL,
3313 .offset = GLOBAL_VAR(szLogonPath),
3316 .flags = FLAG_ADVANCED,
3319 .label = "logon drive",
3321 .p_class = P_GLOBAL,
3322 .offset = GLOBAL_VAR(szLogonDrive),
3325 .flags = FLAG_ADVANCED,
3328 .label = "logon home",
3330 .p_class = P_GLOBAL,
3331 .offset = GLOBAL_VAR(szLogonHome),
3334 .flags = FLAG_ADVANCED,
3337 .label = "domain logons",
3339 .p_class = P_GLOBAL,
3340 .offset = GLOBAL_VAR(bDomainLogons),
3343 .flags = FLAG_ADVANCED,
3347 .label = "init logon delayed hosts",
3349 .p_class = P_GLOBAL,
3350 .offset = GLOBAL_VAR(szInitLogonDelayedHosts),
3353 .flags = FLAG_ADVANCED,
3357 .label = "init logon delay",
3359 .p_class = P_GLOBAL,
3360 .offset = GLOBAL_VAR(InitLogonDelay),
3363 .flags = FLAG_ADVANCED,
3367 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3370 .label = "os level",
3372 .p_class = P_GLOBAL,
3373 .offset = GLOBAL_VAR(os_level),
3376 .flags = FLAG_BASIC | FLAG_ADVANCED,
3379 .label = "lm announce",
3381 .p_class = P_GLOBAL,
3382 .offset = GLOBAL_VAR(lm_announce),
3384 .enum_list = enum_bool_auto,
3385 .flags = FLAG_ADVANCED,
3388 .label = "lm interval",
3390 .p_class = P_GLOBAL,
3391 .offset = GLOBAL_VAR(lm_interval),
3394 .flags = FLAG_ADVANCED,
3397 .label = "preferred master",
3399 .p_class = P_GLOBAL,
3400 .offset = GLOBAL_VAR(iPreferredMaster),
3402 .enum_list = enum_bool_auto,
3403 .flags = FLAG_BASIC | FLAG_ADVANCED,
3406 .label = "prefered master",
3408 .p_class = P_GLOBAL,
3409 .offset = GLOBAL_VAR(iPreferredMaster),
3411 .enum_list = enum_bool_auto,
3415 .label = "local master",
3417 .p_class = P_GLOBAL,
3418 .offset = GLOBAL_VAR(bLocalMaster),
3421 .flags = FLAG_BASIC | FLAG_ADVANCED,
3424 .label = "domain master",
3426 .p_class = P_GLOBAL,
3427 .offset = GLOBAL_VAR(iDomainMaster),
3429 .enum_list = enum_bool_auto,
3430 .flags = FLAG_BASIC | FLAG_ADVANCED,
3433 .label = "browse list",
3435 .p_class = P_GLOBAL,
3436 .offset = GLOBAL_VAR(bBrowseList),
3439 .flags = FLAG_ADVANCED,
3442 .label = "browseable",
3445 .offset = LOCAL_VAR(bBrowseable),
3448 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3451 .label = "browsable",
3454 .offset = LOCAL_VAR(bBrowseable),
3460 .label = "access based share enum",
3463 .offset = LOCAL_VAR(bAccessBasedShareEnum),
3466 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3469 .label = "enhanced browsing",
3471 .p_class = P_GLOBAL,
3472 .offset = GLOBAL_VAR(enhanced_browsing),
3475 .flags = FLAG_ADVANCED,
3478 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3481 .label = "dns proxy",
3483 .p_class = P_GLOBAL,
3484 .offset = GLOBAL_VAR(bDNSproxy),
3487 .flags = FLAG_ADVANCED,
3490 .label = "wins proxy",
3492 .p_class = P_GLOBAL,
3493 .offset = GLOBAL_VAR(bWINSproxy),
3496 .flags = FLAG_ADVANCED,
3499 .label = "wins server",
3501 .p_class = P_GLOBAL,
3502 .offset = GLOBAL_VAR(szWINSservers),
3505 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3508 .label = "wins support",
3510 .p_class = P_GLOBAL,
3511 .offset = GLOBAL_VAR(bWINSsupport),
3514 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3517 .label = "wins hook",
3519 .p_class = P_GLOBAL,
3520 .offset = GLOBAL_VAR(szWINSHook),
3523 .flags = FLAG_ADVANCED,
3526 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3529 .label = "blocking locks",
3532 .offset = LOCAL_VAR(bBlockingLocks),
3535 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3538 .label = "csc policy",
3541 .offset = LOCAL_VAR(iCSCPolicy),
3543 .enum_list = enum_csc_policy,
3544 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3547 .label = "fake oplocks",
3550 .offset = LOCAL_VAR(bFakeOplocks),
3553 .flags = FLAG_ADVANCED | FLAG_SHARE,
3556 .label = "kernel oplocks",
3558 .p_class = P_GLOBAL,
3559 .offset = GLOBAL_VAR(bKernelOplocks),
3562 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3568 .offset = LOCAL_VAR(bLocking),
3571 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3574 .label = "lock spin time",
3576 .p_class = P_GLOBAL,
3577 .offset = GLOBAL_VAR(iLockSpinTime),
3580 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3586 .offset = LOCAL_VAR(bOpLocks),
3589 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3592 .label = "level2 oplocks",
3595 .offset = LOCAL_VAR(bLevel2OpLocks),
3598 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3601 .label = "oplock break wait time",
3603 .p_class = P_GLOBAL,
3604 .offset = GLOBAL_VAR(oplock_break_wait_time),
3607 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3610 .label = "oplock contention limit",
3613 .offset = LOCAL_VAR(iOplockContentionLimit),
3616 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3619 .label = "posix locking",
3622 .offset = LOCAL_VAR(bPosixLocking),
3625 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3628 .label = "strict locking",
3631 .offset = LOCAL_VAR(iStrictLocking),
3633 .enum_list = enum_bool_auto,
3634 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3637 .label = "share modes",
3640 .offset = LOCAL_VAR(bShareModes),
3643 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3646 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3649 .label = "ldap admin dn",
3651 .p_class = P_GLOBAL,
3652 .offset = GLOBAL_VAR(szLdapAdminDn),
3655 .flags = FLAG_ADVANCED,
3658 .label = "ldap delete dn",
3660 .p_class = P_GLOBAL,
3661 .offset = GLOBAL_VAR(ldap_delete_dn),
3664 .flags = FLAG_ADVANCED,
3667 .label = "ldap group suffix",
3669 .p_class = P_GLOBAL,
3670 .offset = GLOBAL_VAR(szLdapGroupSuffix),
3673 .flags = FLAG_ADVANCED,
3676 .label = "ldap idmap suffix",
3678 .p_class = P_GLOBAL,
3679 .offset = GLOBAL_VAR(szLdapIdmapSuffix),
3682 .flags = FLAG_ADVANCED,
3685 .label = "ldap machine suffix",
3687 .p_class = P_GLOBAL,
3688 .offset = GLOBAL_VAR(szLdapMachineSuffix),
3691 .flags = FLAG_ADVANCED,
3694 .label = "ldap passwd sync",
3696 .p_class = P_GLOBAL,
3697 .offset = GLOBAL_VAR(ldap_passwd_sync),
3699 .enum_list = enum_ldap_passwd_sync,
3700 .flags = FLAG_ADVANCED,
3703 .label = "ldap password sync",
3705 .p_class = P_GLOBAL,
3706 .offset = GLOBAL_VAR(ldap_passwd_sync),
3708 .enum_list = enum_ldap_passwd_sync,
3712 .label = "ldap replication sleep",
3714 .p_class = P_GLOBAL,
3715 .offset = GLOBAL_VAR(ldap_replication_sleep),
3718 .flags = FLAG_ADVANCED,
3721 .label = "ldap suffix",
3723 .p_class = P_GLOBAL,
3724 .offset = GLOBAL_VAR(szLdapSuffix),
3727 .flags = FLAG_ADVANCED,
3730 .label = "ldap ssl",
3732 .p_class = P_GLOBAL,
3733 .offset = GLOBAL_VAR(ldap_ssl),
3735 .enum_list = enum_ldap_ssl,
3736 .flags = FLAG_ADVANCED,
3739 .label = "ldap ssl ads",
3741 .p_class = P_GLOBAL,
3742 .offset = GLOBAL_VAR(ldap_ssl_ads),
3745 .flags = FLAG_ADVANCED,
3748 .label = "ldap deref",
3750 .p_class = P_GLOBAL,
3751 .offset = GLOBAL_VAR(ldap_deref),
3753 .enum_list = enum_ldap_deref,
3754 .flags = FLAG_ADVANCED,
3757 .label = "ldap follow referral",
3759 .p_class = P_GLOBAL,
3760 .offset = GLOBAL_VAR(ldap_follow_referral),
3762 .enum_list = enum_bool_auto,
3763 .flags = FLAG_ADVANCED,
3766 .label = "ldap timeout",
3768 .p_class = P_GLOBAL,
3769 .offset = GLOBAL_VAR(ldap_timeout),
3772 .flags = FLAG_ADVANCED,
3775 .label = "ldap connection timeout",
3777 .p_class = P_GLOBAL,
3778 .offset = GLOBAL_VAR(ldap_connection_timeout),
3781 .flags = FLAG_ADVANCED,
3784 .label = "ldap page size",
3786 .p_class = P_GLOBAL,
3787 .offset = GLOBAL_VAR(ldap_page_size),
3790 .flags = FLAG_ADVANCED,
3793 .label = "ldap user suffix",
3795 .p_class = P_GLOBAL,
3796 .offset = GLOBAL_VAR(szLdapUserSuffix),
3799 .flags = FLAG_ADVANCED,
3802 .label = "ldap debug level",
3804 .p_class = P_GLOBAL,
3805 .offset = GLOBAL_VAR(ldap_debug_level),
3806 .special = handle_ldap_debug_level,
3808 .flags = FLAG_ADVANCED,
3811 .label = "ldap debug threshold",
3813 .p_class = P_GLOBAL,
3814 .offset = GLOBAL_VAR(ldap_debug_threshold),
3817 .flags = FLAG_ADVANCED,
3820 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3823 .label = "eventlog list",
3825 .p_class = P_GLOBAL,
3826 .offset = GLOBAL_VAR(szEventLogs),
3829 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3832 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3835 .label = "add share command",
3837 .p_class = P_GLOBAL,
3838 .offset = GLOBAL_VAR(szAddShareCommand),
3841 .flags = FLAG_ADVANCED,
3844 .label = "change share command",
3846 .p_class = P_GLOBAL,
3847 .offset = GLOBAL_VAR(szChangeShareCommand),
3850 .flags = FLAG_ADVANCED,
3853 .label = "delete share command",
3855 .p_class = P_GLOBAL,
3856 .offset = GLOBAL_VAR(szDeleteShareCommand),
3859 .flags = FLAG_ADVANCED,
3862 .label = "config file",
3864 .p_class = P_GLOBAL,
3865 .offset = GLOBAL_VAR(szConfigFile),
3868 .flags = FLAG_HIDE|FLAG_META,
3873 .p_class = P_GLOBAL,
3874 .offset = GLOBAL_VAR(szAutoServices),
3877 .flags = FLAG_ADVANCED,
3880 .label = "auto services",
3882 .p_class = P_GLOBAL,
3883 .offset = GLOBAL_VAR(szAutoServices),
3886 .flags = FLAG_ADVANCED,
3889 .label = "lock directory",
3891 .p_class = P_GLOBAL,
3892 .offset = GLOBAL_VAR(szLockDir),
3895 .flags = FLAG_ADVANCED,
3898 .label = "lock dir",
3900 .p_class = P_GLOBAL,
3901 .offset = GLOBAL_VAR(szLockDir),
3907 .label = "state directory",
3909 .p_class = P_GLOBAL,
3910 .offset = GLOBAL_VAR(szStateDir),
3913 .flags = FLAG_ADVANCED,
3916 .label = "cache directory",
3918 .p_class = P_GLOBAL,
3919 .offset = GLOBAL_VAR(szCacheDir),
3922 .flags = FLAG_ADVANCED,
3925 .label = "pid directory",
3927 .p_class = P_GLOBAL,
3928 .offset = GLOBAL_VAR(szPidDir),
3931 .flags = FLAG_ADVANCED,
3935 .label = "utmp directory",
3937 .p_class = P_GLOBAL,
3938 .offset = GLOBAL_VAR(szUtmpDir),
3941 .flags = FLAG_ADVANCED,
3944 .label = "wtmp directory",
3946 .p_class = P_GLOBAL,
3947 .offset = GLOBAL_VAR(szWtmpDir),
3950 .flags = FLAG_ADVANCED,
3955 .p_class = P_GLOBAL,
3956 .offset = GLOBAL_VAR(bUtmp),
3959 .flags = FLAG_ADVANCED,
3963 .label = "default service",
3965 .p_class = P_GLOBAL,
3966 .offset = GLOBAL_VAR(szDefaultService),
3969 .flags = FLAG_ADVANCED,
3974 .p_class = P_GLOBAL,
3975 .offset = GLOBAL_VAR(szDefaultService),
3978 .flags = FLAG_ADVANCED,
3981 .label = "message command",
3983 .p_class = P_GLOBAL,
3984 .offset = GLOBAL_VAR(szMsgCommand),
3987 .flags = FLAG_ADVANCED,
3990 .label = "dfree cache time",
3993 .offset = LOCAL_VAR(iDfreeCacheTime),
3996 .flags = FLAG_ADVANCED,
3999 .label = "dfree command",
4002 .offset = LOCAL_VAR(szDfree),
4005 .flags = FLAG_ADVANCED,
4008 .label = "get quota command",
4010 .p_class = P_GLOBAL,
4011 .offset = GLOBAL_VAR(szGetQuota),
4014 .flags = FLAG_ADVANCED,
4017 .label = "set quota command",
4019 .p_class = P_GLOBAL,
4020 .offset = GLOBAL_VAR(szSetQuota),
4023 .flags = FLAG_ADVANCED,
4026 .label = "remote announce",
4028 .p_class = P_GLOBAL,
4029 .offset = GLOBAL_VAR(szRemoteAnnounce),
4032 .flags = FLAG_ADVANCED,
4035 .label = "remote browse sync",
4037 .p_class = P_GLOBAL,
4038 .offset = GLOBAL_VAR(szRemoteBrowseSync),
4041 .flags = FLAG_ADVANCED,
4044 .label = "socket address",
4046 .p_class = P_GLOBAL,
4047 .offset = GLOBAL_VAR(szSocketAddress),
4050 .flags = FLAG_ADVANCED,
4053 .label = "nmbd bind explicit broadcast",
4055 .p_class = P_GLOBAL,
4056 .offset = GLOBAL_VAR(bNmbdBindExplicitBroadcast),
4059 .flags = FLAG_ADVANCED,
4062 .label = "homedir map",
4064 .p_class = P_GLOBAL,
4065 .offset = GLOBAL_VAR(szNISHomeMapName),
4068 .flags = FLAG_ADVANCED,
4071 .label = "afs username map",
4073 .p_class = P_GLOBAL,
4074 .offset = GLOBAL_VAR(szAfsUsernameMap),
4077 .flags = FLAG_ADVANCED,
4080 .label = "afs token lifetime",
4082 .p_class = P_GLOBAL,
4083 .offset = GLOBAL_VAR(iAfsTokenLifetime),
4086 .flags = FLAG_ADVANCED,
4089 .label = "log nt token command",
4091 .p_class = P_GLOBAL,
4092 .offset = GLOBAL_VAR(szLogNtTokenCommand),
4095 .flags = FLAG_ADVANCED,
4098 .label = "NIS homedir",
4100 .p_class = P_GLOBAL,
4101 .offset = GLOBAL_VAR(bNISHomeMap),
4104 .flags = FLAG_ADVANCED,
4110 .offset = LOCAL_VAR(valid),
4119 .offset = LOCAL_VAR(szCopy),
4120 .special = handle_copy,
4128 .offset = LOCAL_VAR(szInclude),
4129 .special = handle_include,
4131 .flags = FLAG_HIDE|FLAG_META,
4137 .offset = LOCAL_VAR(szPreExec),
4140 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4146 .offset = LOCAL_VAR(szPreExec),
4149 .flags = FLAG_ADVANCED,
4152 .label = "preexec close",
4155 .offset = LOCAL_VAR(bPreexecClose),
4158 .flags = FLAG_ADVANCED | FLAG_SHARE,
4161 .label = "postexec",
4164 .offset = LOCAL_VAR(szPostExec),
4167 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4170 .label = "root preexec",
4173 .offset = LOCAL_VAR(szRootPreExec),
4176 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4179 .label = "root preexec close",
4182 .offset = LOCAL_VAR(bRootpreexecClose),
4185 .flags = FLAG_ADVANCED | FLAG_SHARE,
4188 .label = "root postexec",
4191 .offset = LOCAL_VAR(szRootPostExec),
4194 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4197 .label = "available",
4200 .offset = LOCAL_VAR(bAvailable),
4203 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4206 .label = "registry shares",
4208 .p_class = P_GLOBAL,
4209 .offset = GLOBAL_VAR(bRegistryShares),
4212 .flags = FLAG_ADVANCED,
4215 .label = "usershare allow guests",
4217 .p_class = P_GLOBAL,
4218 .offset = GLOBAL_VAR(bUsershareAllowGuests),
4221 .flags = FLAG_ADVANCED,
4224 .label = "usershare max shares",
4226 .p_class = P_GLOBAL,
4227 .offset = GLOBAL_VAR(iUsershareMaxShares),
4230 .flags = FLAG_ADVANCED,
4233 .label = "usershare owner only",
4235 .p_class = P_GLOBAL,
4236 .offset = GLOBAL_VAR(bUsershareOwnerOnly),
4239 .flags = FLAG_ADVANCED,
4242 .label = "usershare path",
4244 .p_class = P_GLOBAL,
4245 .offset = GLOBAL_VAR(szUsersharePath),
4248 .flags = FLAG_ADVANCED,
4251 .label = "usershare prefix allow list",
4253 .p_class = P_GLOBAL,
4254 .offset = GLOBAL_VAR(szUsersharePrefixAllowList),
4257 .flags = FLAG_ADVANCED,
4260 .label = "usershare prefix deny list",
4262 .p_class = P_GLOBAL,
4263 .offset = GLOBAL_VAR(szUsersharePrefixDenyList),
4266 .flags = FLAG_ADVANCED,
4269 .label = "usershare template share",
4271 .p_class = P_GLOBAL,
4272 .offset = GLOBAL_VAR(szUsershareTemplateShare),
4275 .flags = FLAG_ADVANCED,
4281 .offset = LOCAL_VAR(volume),
4284 .flags = FLAG_ADVANCED | FLAG_SHARE,
4290 .offset = LOCAL_VAR(fstype),
4293 .flags = FLAG_ADVANCED | FLAG_SHARE,
4296 .label = "set directory",
4299 .offset = LOCAL_VAR(bNo_set_dir),
4302 .flags = FLAG_ADVANCED | FLAG_SHARE,
4305 .label = "wide links",
4308 .offset = LOCAL_VAR(bWidelinks),
4311 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4314 .label = "follow symlinks",
4317 .offset = LOCAL_VAR(bSymlinks),
4320 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4323 .label = "dont descend",
4326 .offset = LOCAL_VAR(szDontdescend),
4329 .flags = FLAG_ADVANCED | FLAG_SHARE,
4332 .label = "magic script",
4335 .offset = LOCAL_VAR(szMagicScript),
4338 .flags = FLAG_ADVANCED | FLAG_SHARE,
4341 .label = "magic output",
4344 .offset = LOCAL_VAR(szMagicOutput),
4347 .flags = FLAG_ADVANCED | FLAG_SHARE,
4350 .label = "delete readonly",
4353 .offset = LOCAL_VAR(bDeleteReadonly),
4356 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4359 .label = "dos filemode",
4362 .offset = LOCAL_VAR(bDosFilemode),
4365 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4368 .label = "dos filetimes",
4371 .offset = LOCAL_VAR(bDosFiletimes),
4374 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4377 .label = "dos filetime resolution",
4380 .offset = LOCAL_VAR(bDosFiletimeResolution),
4383 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4386 .label = "fake directory create times",
4389 .offset = LOCAL_VAR(bFakeDirCreateTimes),
4392 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4395 .label = "async smb echo handler",
4397 .p_class = P_GLOBAL,
4398 .offset = GLOBAL_VAR(bAsyncSMBEchoHandler),
4401 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4404 .label = "multicast dns register",
4406 .p_class = P_GLOBAL,
4407 .offset = GLOBAL_VAR(bMulticastDnsRegister),
4410 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4413 .label = "panic action",
4415 .p_class = P_GLOBAL,
4416 .offset = GLOBAL_VAR(szPanicAction),
4419 .flags = FLAG_ADVANCED,
4422 .label = "perfcount module",
4424 .p_class = P_GLOBAL,
4425 .offset = GLOBAL_VAR(szSMBPerfcountModule),
4428 .flags = FLAG_ADVANCED,
4431 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4434 .label = "vfs objects",
4437 .offset = LOCAL_VAR(szVfsObjects),
4440 .flags = FLAG_ADVANCED | FLAG_SHARE,
4443 .label = "vfs object",
4446 .offset = LOCAL_VAR(szVfsObjects),
4453 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4456 .label = "msdfs root",
4459 .offset = LOCAL_VAR(bMSDfsRoot),
4462 .flags = FLAG_ADVANCED | FLAG_SHARE,
4465 .label = "msdfs proxy",
4468 .offset = LOCAL_VAR(szMSDfsProxy),
4471 .flags = FLAG_ADVANCED | FLAG_SHARE,
4474 .label = "host msdfs",
4476 .p_class = P_GLOBAL,
4477 .offset = GLOBAL_VAR(bHostMSDfs),
4480 .flags = FLAG_ADVANCED,
4483 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4486 .label = "passdb expand explicit",
4488 .p_class = P_GLOBAL,
4489 .offset = GLOBAL_VAR(bPassdbExpandExplicit),
4492 .flags = FLAG_ADVANCED,
4495 .label = "idmap backend",
4497 .p_class = P_GLOBAL,
4498 .offset = GLOBAL_VAR(szIdmapBackend),
4499 .special = handle_idmap_backend,
4501 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4504 .label = "idmap cache time",
4506 .p_class = P_GLOBAL,
4507 .offset = GLOBAL_VAR(iIdmapCacheTime),
4510 .flags = FLAG_ADVANCED,
4513 .label = "idmap negative cache time",
4515 .p_class = P_GLOBAL,
4516 .offset = GLOBAL_VAR(iIdmapNegativeCacheTime),
4519 .flags = FLAG_ADVANCED,
4522 .label = "idmap uid",
4524 .p_class = P_GLOBAL,
4525 .offset = GLOBAL_VAR(szIdmapUID),
4526 .special = handle_idmap_uid,
4528 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4531 .label = "winbind uid",
4533 .p_class = P_GLOBAL,
4534 .offset = GLOBAL_VAR(szIdmapUID),
4535 .special = handle_idmap_uid,
4540 .label = "idmap gid",
4542 .p_class = P_GLOBAL,
4543 .offset = GLOBAL_VAR(szIdmapGID),
4544 .special = handle_idmap_gid,
4546 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4549 .label = "winbind gid",
4551 .p_class = P_GLOBAL,
4552 .offset = GLOBAL_VAR(szIdmapGID),
4553 .special = handle_idmap_gid,
4558 .label = "template homedir",
4560 .p_class = P_GLOBAL,
4561 .offset = GLOBAL_VAR(szTemplateHomedir),
4564 .flags = FLAG_ADVANCED,
4567 .label = "template shell",
4569 .p_class = P_GLOBAL,
4570 .offset = GLOBAL_VAR(szTemplateShell),
4573 .flags = FLAG_ADVANCED,
4576 .label = "winbind separator",
4578 .p_class = P_GLOBAL,
4579 .offset = GLOBAL_VAR(szWinbindSeparator),
4582 .flags = FLAG_ADVANCED,
4585 .label = "winbind cache time",
4587 .p_class = P_GLOBAL,
4588 .offset = GLOBAL_VAR(winbind_cache_time),
4591 .flags = FLAG_ADVANCED,
4594 .label = "winbind reconnect delay",
4596 .p_class = P_GLOBAL,
4597 .offset = GLOBAL_VAR(winbind_reconnect_delay),
4600 .flags = FLAG_ADVANCED,
4603 .label = "winbind max clients",
4605 .p_class = P_GLOBAL,
4606 .offset = GLOBAL_VAR(winbind_max_clients),
4609 .flags = FLAG_ADVANCED,
4612 .label = "winbind enum users",
4614 .p_class = P_GLOBAL,
4615 .offset = GLOBAL_VAR(bWinbindEnumUsers),
4618 .flags = FLAG_ADVANCED,
4621 .label = "winbind enum groups",
4623 .p_class = P_GLOBAL,
4624 .offset = GLOBAL_VAR(bWinbindEnumGroups),
4627 .flags = FLAG_ADVANCED,
4630 .label = "winbind use default domain",
4632 .p_class = P_GLOBAL,
4633 .offset = GLOBAL_VAR(bWinbindUseDefaultDomain),
4636 .flags = FLAG_ADVANCED,
4639 .label = "winbind trusted domains only",
4641 .p_class = P_GLOBAL,
4642 .offset = GLOBAL_VAR(bWinbindTrustedDomainsOnly),
4645 .flags = FLAG_ADVANCED,
4648 .label = "winbind nested groups",
4650 .p_class = P_GLOBAL,
4651 .offset = GLOBAL_VAR(bWinbindNestedGroups),
4654 .flags = FLAG_ADVANCED,
4657 .label = "winbind expand groups",
4659 .p_class = P_GLOBAL,
4660 .offset = GLOBAL_VAR(winbind_expand_groups),
4663 .flags = FLAG_ADVANCED,
4666 .label = "winbind nss info",
4668 .p_class = P_GLOBAL,
4669 .offset = GLOBAL_VAR(szWinbindNssInfo),
4672 .flags = FLAG_ADVANCED,
4675 .label = "winbind refresh tickets",
4677 .p_class = P_GLOBAL,
4678 .offset = GLOBAL_VAR(bWinbindRefreshTickets),
4681 .flags = FLAG_ADVANCED,
4684 .label = "winbind offline logon",
4686 .p_class = P_GLOBAL,
4687 .offset = GLOBAL_VAR(bWinbindOfflineLogon),
4690 .flags = FLAG_ADVANCED,
4693 .label = "winbind normalize names",
4695 .p_class = P_GLOBAL,
4696 .offset = GLOBAL_VAR(bWinbindNormalizeNames),
4699 .flags = FLAG_ADVANCED,
4702 .label = "winbind rpc only",
4704 .p_class = P_GLOBAL,
4705 .offset = GLOBAL_VAR(bWinbindRpcOnly),
4708 .flags = FLAG_ADVANCED,
4711 .label = "create krb5 conf",
4713 .p_class = P_GLOBAL,
4714 .offset = GLOBAL_VAR(bCreateKrb5Conf),
4717 .flags = FLAG_ADVANCED,
4720 .label = "ncalrpc dir",
4722 .p_class = P_GLOBAL,
4723 .offset = GLOBAL_VAR(ncalrpc_dir),
4726 .flags = FLAG_ADVANCED,
4729 .label = "winbind max domain connections",
4731 .p_class = P_GLOBAL,
4732 .offset = GLOBAL_VAR(winbindMaxDomainConnections),
4735 .flags = FLAG_ADVANCED,
4738 {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0}
4741 /***************************************************************************
4742 Initialise the sDefault parameter structure for the printer values.
4743 ***************************************************************************/
4745 static void init_printer_values(struct loadparm_service *pService)
4747 /* choose defaults depending on the type of printing */
4748 switch (pService->iPrinting) {
4753 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4754 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4755 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4760 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4761 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4762 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4763 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4764 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4765 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4766 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4772 /* set the lpq command to contain the destination printer
4773 name only. This is used by cups_queue_get() */
4774 string_set(&pService->szLpqcommand, "%p");
4775 string_set(&pService->szLprmcommand, "");
4776 string_set(&pService->szPrintcommand, "");
4777 string_set(&pService->szLppausecommand, "");
4778 string_set(&pService->szLpresumecommand, "");
4779 string_set(&pService->szQueuepausecommand, "");
4780 string_set(&pService->szQueueresumecommand, "");
4782 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4783 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4784 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4785 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4786 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4787 string_set(&pService->szQueuepausecommand, "disable '%p'");
4788 string_set(&pService->szQueueresumecommand, "enable '%p'");
4789 #endif /* HAVE_CUPS */
4794 string_set(&pService->szLpqcommand, "lpstat -o%p");
4795 string_set(&pService->szLprmcommand, "cancel %p-%j");
4796 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4797 string_set(&pService->szQueuepausecommand, "disable %p");
4798 string_set(&pService->szQueueresumecommand, "enable %p");
4800 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4801 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4806 string_set(&pService->szLpqcommand, "lpq -P%p");
4807 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4808 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4811 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4815 const char *tdbfile;
4818 tdbfile = talloc_asprintf(
4819 talloc_tos(), "tdbfile=%s",
4820 lp_parm_const_string(-1, "vlp", "tdbfile",
4822 if (tdbfile == NULL) {
4823 tdbfile="tdbfile=/tmp/vlp.tdb";
4826 tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
4828 string_set(&pService->szPrintcommand,
4829 tmp ? tmp : "vlp print %p %s");
4832 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
4834 string_set(&pService->szLpqcommand,
4835 tmp ? tmp : "vlp lpq %p");
4838 tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
4840 string_set(&pService->szLprmcommand,
4841 tmp ? tmp : "vlp lprm %p %j");
4844 tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
4846 string_set(&pService->szLppausecommand,
4847 tmp ? tmp : "vlp lppause %p %j");
4850 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
4852 string_set(&pService->szLpresumecommand,
4853 tmp ? tmp : "vlp lpresume %p %j");
4856 tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
4858 string_set(&pService->szQueuepausecommand,
4859 tmp ? tmp : "vlp queuepause %p");
4862 tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
4864 string_set(&pService->szQueueresumecommand,
4865 tmp ? tmp : "vlp queueresume %p");
4870 #endif /* DEVELOPER */
4875 * Function to return the default value for the maximum number of open
4876 * file descriptors permitted. This function tries to consult the
4877 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4878 * the smaller of those.
4880 static int max_open_files(void)
4882 int sysctl_max = MAX_OPEN_FILES;
4883 int rlimit_max = MAX_OPEN_FILES;
4885 #ifdef HAVE_SYSCTLBYNAME
4887 size_t size = sizeof(sysctl_max);
4888 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4893 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4899 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4900 rlimit_max = rl.rlim_cur;
4902 #if defined(RLIM_INFINITY)
4903 if(rl.rlim_cur == RLIM_INFINITY)
4904 rlimit_max = MAX_OPEN_FILES;
4909 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4910 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4911 "minimum Windows limit (%d)\n",
4913 MIN_OPEN_FILES_WINDOWS));
4914 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4917 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4918 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4919 "minimum Windows limit (%d)\n",
4921 MIN_OPEN_FILES_WINDOWS));
4922 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4925 return MIN(sysctl_max, rlimit_max);
4929 * Common part of freeing allocated data for one parameter.
4931 static void free_one_parameter_common(void *parm_ptr,
4932 struct parm_struct parm)
4934 if ((parm.type == P_STRING) ||
4935 (parm.type == P_USTRING))
4937 string_free((char**)parm_ptr);
4938 } else if (parm.type == P_LIST) {
4939 TALLOC_FREE(*((char***)parm_ptr));
4944 * Free the allocated data for one parameter for a share
4945 * given as a service struct.
4947 static void free_one_parameter(struct loadparm_service *service,
4948 struct parm_struct parm)
4952 if (parm.p_class != P_LOCAL) {
4956 parm_ptr = lp_parm_ptr(service, &parm);
4958 free_one_parameter_common(parm_ptr, parm);
4962 * Free the allocated parameter data of a share given
4963 * as a service struct.
4965 static void free_parameters(struct loadparm_service *service)
4969 for (i=0; parm_table[i].label; i++) {
4970 free_one_parameter(service, parm_table[i]);
4975 * Free the allocated data for one parameter for a given share
4976 * specified by an snum.
4978 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4983 parm_ptr = lp_parm_ptr(NULL, &parm);
4984 } else if (parm.p_class != P_LOCAL) {
4987 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
4990 free_one_parameter_common(parm_ptr, parm);
4994 * Free the allocated parameter data for a share specified
4997 static void free_parameters_by_snum(int snum)
5001 for (i=0; parm_table[i].label; i++) {
5002 free_one_parameter_by_snum(snum, parm_table[i]);
5007 * Free the allocated global parameters.
5009 static void free_global_parameters(void)
5011 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
5014 static int map_parameter(const char *pszParmName);
5016 struct lp_stored_option {
5017 struct lp_stored_option *prev, *next;
5022 static struct lp_stored_option *stored_options;
5025 save options set by lp_set_cmdline() into a list. This list is
5026 re-applied when we do a globals reset, so that cmdline set options
5027 are sticky across reloads of smb.conf
5029 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
5031 struct lp_stored_option *entry, *entry_next;
5032 for (entry = stored_options; entry != NULL; entry = entry_next) {
5033 entry_next = entry->next;
5034 if (strcmp(pszParmName, entry->label) == 0) {
5035 DLIST_REMOVE(stored_options, entry);
5041 entry = talloc(NULL, struct lp_stored_option);
5046 entry->label = talloc_strdup(entry, pszParmName);
5047 if (!entry->label) {
5052 entry->value = talloc_strdup(entry, pszParmValue);
5053 if (!entry->value) {
5058 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
5063 static bool apply_lp_set_cmdline(void)
5065 struct lp_stored_option *entry = NULL;
5066 for (entry = stored_options; entry != NULL; entry = entry->next) {
5067 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
5068 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
5069 entry->label, entry->value));
5076 /***************************************************************************
5077 Initialise the global parameter structure.
5078 ***************************************************************************/
5080 static void init_globals(bool reinit_globals)
5082 static bool done_init = false;
5086 /* If requested to initialize only once and we've already done it... */
5087 if (!reinit_globals && done_init) {
5088 /* ... then we have nothing more to do */
5093 /* The logfile can be set before this is invoked. Free it if so. */
5094 if (Globals.szLogFile != NULL) {
5095 string_free(&Globals.szLogFile);
5096 Globals.szLogFile = NULL;
5100 free_global_parameters();
5103 /* This memset and the free_global_parameters() above will
5104 * wipe out smb.conf options set with lp_set_cmdline(). The
5105 * apply_lp_set_cmdline() call puts these values back in the
5106 * table once the defaults are set */
5107 memset((void *)&Globals, '\0', sizeof(Globals));
5109 for (i = 0; parm_table[i].label; i++) {
5110 if ((parm_table[i].type == P_STRING ||
5111 parm_table[i].type == P_USTRING))
5113 string_set(lp_parm_ptr(NULL, &parm_table[i]), "");
5118 string_set(&sDefault.fstype, FSTYPE_STRING);
5119 string_set(&sDefault.szPrintjobUsername, "%U");
5121 init_printer_values(&sDefault);
5124 DEBUG(3, ("Initialising global parameters\n"));
5126 /* Must manually force to upper case here, as this does not go via the handler */
5127 string_set(&Globals.szNetbiosName, myhostname_upper());
5129 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
5130 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
5132 /* use the new 'hash2' method by default, with a prefix of 1 */
5133 string_set(&Globals.szManglingMethod, "hash2");
5134 Globals.mangle_prefix = 1;
5136 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5138 /* using UTF8 by default allows us to support all chars */
5139 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5141 /* Use codepage 850 as a default for the dos character set */
5142 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5145 * Allow the default PASSWD_CHAT to be overridden in local.h.
5147 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5149 string_set(&Globals.szWorkgroup, DEFAULT_WORKGROUP);
5151 string_set(&Globals.szPasswdProgram, "");
5152 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5153 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5154 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5155 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5156 string_set(&Globals.szSocketAddress, "0.0.0.0");
5158 * By default support explicit binding to broadcast
5161 Globals.bNmbdBindExplicitBroadcast = true;
5163 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5164 smb_panic("init_globals: ENOMEM");
5166 string_set(&Globals.szServerString, s);
5169 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5172 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5174 string_set(&Globals.szLogonDrive, "");
5175 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5176 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5177 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5179 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5180 string_set(&Globals.szPasswordServer, "*");
5182 Globals.AlgorithmicRidBase = BASE_RID;
5184 Globals.bLoadPrinters = true;
5185 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
5187 Globals.ConfigBackend = config_backend;
5189 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5190 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5191 Globals.max_xmit = 0x4104;
5192 Globals.max_mux = 50; /* This is *needed* for profile support. */
5193 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
5194 Globals.bDisableSpoolss = false;
5195 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5196 Globals.pwordlevel = 0;
5197 Globals.unamelevel = 0;
5198 Globals.deadtime = 0;
5199 Globals.getwd_cache = true;
5200 Globals.bLargeReadwrite = true;
5201 Globals.max_log_size = 5000;
5202 Globals.max_open_files = max_open_files();
5203 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5204 Globals.maxprotocol = PROTOCOL_NT1;
5205 Globals.minprotocol = PROTOCOL_CORE;
5206 Globals.security = SEC_USER;
5207 Globals.paranoid_server_security = true;
5208 Globals.bEncryptPasswords = true;
5209 Globals.clientSchannel = Auto;
5210 Globals.serverSchannel = Auto;
5211 Globals.bReadRaw = true;
5212 Globals.bWriteRaw = true;
5213 Globals.bNullPasswords = false;
5214 Globals.bObeyPamRestrictions = false;
5216 Globals.bSyslogOnly = false;
5217 Globals.bTimestampLogs = true;
5218 string_set(&Globals.szLogLevel, "0");
5219 Globals.bDebugPrefixTimestamp = false;
5220 Globals.bDebugHiresTimestamp = true;
5221 Globals.bDebugPid = false;
5222 Globals.bDebugUid = false;
5223 Globals.bDebugClass = false;
5224 Globals.bEnableCoreFiles = true;
5225 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5226 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5227 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5228 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5229 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5230 Globals.lm_interval = 60;
5231 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5232 Globals.bNISHomeMap = false;
5233 #ifdef WITH_NISPLUS_HOME
5234 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5236 string_set(&Globals.szNISHomeMapName, "auto.home");
5239 Globals.bTimeServer = false;
5240 Globals.bBindInterfacesOnly = false;
5241 Globals.bUnixPasswdSync = false;
5242 Globals.bPamPasswordChange = false;
5243 Globals.bPasswdChatDebug = false;
5244 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5245 Globals.bNTPipeSupport = true; /* Do NT pipes by default. */
5246 Globals.bNTStatusSupport = true; /* Use NT status by default. */
5247 Globals.bStatCache = true; /* use stat cache by default */
5248 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5249 Globals.restrict_anonymous = 0;
5250 Globals.bClientLanManAuth = false; /* Do NOT use the LanMan hash if it is available */
5251 Globals.bClientPlaintextAuth = false; /* Do NOT use a plaintext password even if is requested by the server */
5252 Globals.bLanmanAuth = false; /* Do NOT use the LanMan hash, even if it is supplied */
5253 Globals.bNTLMAuth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5254 Globals.bClientNTLMv2Auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
5255 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
5257 Globals.map_to_guest = 0; /* By Default, "Never" */
5258 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5259 Globals.enhanced_browsing = true;
5260 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5261 #ifdef MMAP_BLACKLIST
5262 Globals.bUseMmap = false;
5264 Globals.bUseMmap = true;
5266 Globals.bUnixExtensions = true;
5267 Globals.bResetOnZeroVC = false;
5268 Globals.bLogWriteableFilesOnExit = false;
5269 Globals.bCreateKrb5Conf = true;
5270 Globals.winbindMaxDomainConnections = 1;
5272 /* hostname lookups can be very expensive and are broken on
5273 a large number of sites (tridge) */
5274 Globals.bHostnameLookups = false;
5276 string_set(&Globals.szPassdbBackend, "tdbsam");
5277 string_set(&Globals.szLdapSuffix, "");
5278 string_set(&Globals.szLdapMachineSuffix, "");
5279 string_set(&Globals.szLdapUserSuffix, "");
5280 string_set(&Globals.szLdapGroupSuffix, "");
5281 string_set(&Globals.szLdapIdmapSuffix, "");
5283 string_set(&Globals.szLdapAdminDn, "");
5284 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5285 Globals.ldap_ssl_ads = false;
5286 Globals.ldap_deref = -1;
5287 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5288 Globals.ldap_delete_dn = false;
5289 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5290 Globals.ldap_follow_referral = Auto;
5291 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5292 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5293 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5295 Globals.ldap_debug_level = 0;
5296 Globals.ldap_debug_threshold = 10;
5298 /* This is what we tell the afs client. in reality we set the token
5299 * to never expire, though, when this runs out the afs client will
5300 * forget the token. Set to 0 to get NEVERDATE.*/
5301 Globals.iAfsTokenLifetime = 604800;
5302 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5304 /* these parameters are set to defaults that are more appropriate
5305 for the increasing samba install base:
5307 as a member of the workgroup, that will possibly become a
5308 _local_ master browser (lm = true). this is opposed to a forced
5309 local master browser startup (pm = true).
5311 doesn't provide WINS server service by default (wsupp = false),
5312 and doesn't provide domain master browser services by default, either.
5316 Globals.bMsAddPrinterWizard = true;
5317 Globals.os_level = 20;
5318 Globals.bLocalMaster = true;
5319 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5320 Globals.bDomainLogons = false;
5321 Globals.bBrowseList = true;
5322 Globals.bWINSsupport = false;
5323 Globals.bWINSproxy = false;
5325 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5326 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5328 Globals.bDNSproxy = true;
5330 /* this just means to use them if they exist */
5331 Globals.bKernelOplocks = true;
5333 Globals.bAllowTrustedDomains = true;
5334 string_set(&Globals.szIdmapBackend, "tdb");
5336 string_set(&Globals.szTemplateShell, "/bin/false");
5337 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5338 string_set(&Globals.szWinbindSeparator, "\\");
5340 string_set(&Globals.szCupsServer, "");
5341 string_set(&Globals.szIPrintServer, "");
5343 string_set(&Globals.ctdbdSocket, "");
5344 Globals.szClusterAddresses = NULL;
5345 Globals.clustering = false;
5346 Globals.ctdb_timeout = 0;
5347 Globals.ctdb_locktime_warn_threshold = 0;
5349 Globals.winbind_cache_time = 300; /* 5 minutes */
5350 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5351 Globals.winbind_max_clients = 200;
5352 Globals.bWinbindEnumUsers = false;
5353 Globals.bWinbindEnumGroups = false;
5354 Globals.bWinbindUseDefaultDomain = false;
5355 Globals.bWinbindTrustedDomainsOnly = false;
5356 Globals.bWinbindNestedGroups = true;
5357 Globals.winbind_expand_groups = 1;
5358 Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
5359 Globals.bWinbindRefreshTickets = false;
5360 Globals.bWinbindOfflineLogon = false;
5362 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5363 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5365 Globals.bPassdbExpandExplicit = false;
5367 Globals.name_cache_timeout = 660; /* In seconds */
5369 Globals.bUseSpnego = true;
5370 Globals.bClientUseSpnego = true;
5372 Globals.client_signing = Auto;
5373 Globals.server_signing = false;
5375 Globals.bDeferSharingViolations = true;
5376 string_set(&Globals.smb_ports, SMB_PORTS);
5378 Globals.bEnablePrivileges = true;
5379 Globals.bHostMSDfs = true;
5380 Globals.bASUSupport = false;
5382 /* User defined shares. */
5383 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5384 smb_panic("init_globals: ENOMEM");
5386 string_set(&Globals.szUsersharePath, s);
5388 string_set(&Globals.szUsershareTemplateShare, "");
5389 Globals.iUsershareMaxShares = 0;
5390 /* By default disallow sharing of directories not owned by the sharer. */
5391 Globals.bUsershareOwnerOnly = true;
5392 /* By default disallow guest access to usershares. */
5393 Globals.bUsershareAllowGuests = false;
5395 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5397 /* By default no shares out of the registry */
5398 Globals.bRegistryShares = false;
5400 Globals.iminreceivefile = 0;
5402 Globals.bMapUntrustedToDomain = false;
5403 Globals.bMulticastDnsRegister = true;
5405 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
5406 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
5407 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
5408 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5410 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5412 /* Now put back the settings that were set with lp_set_cmdline() */
5413 apply_lp_set_cmdline();
5416 /*******************************************************************
5417 Convenience routine to grab string parameters into temporary memory
5418 and run standard_sub_basic on them. The buffers can be written to by
5419 callers without affecting the source string.
5420 ********************************************************************/
5422 static char *lp_string(const char *s)
5425 TALLOC_CTX *ctx = talloc_tos();
5427 /* The follow debug is useful for tracking down memory problems
5428 especially if you have an inner loop that is calling a lp_*()
5429 function that returns a string. Perhaps this debug should be
5430 present all the time? */
5433 DEBUG(10, ("lp_string(%s)\n", s));
5439 ret = talloc_sub_basic(ctx,
5440 get_current_username(),
5441 current_user_info.domain,
5443 if (trim_char(ret, '\"', '\"')) {
5444 if (strchr(ret,'\"') != NULL) {
5446 ret = talloc_sub_basic(ctx,
5447 get_current_username(),
5448 current_user_info.domain,
5456 In this section all the functions that are used to access the
5457 parameters from the rest of the program are defined
5460 #define FN_GLOBAL_STRING(fn_name,ptr) \
5461 char *fn_name(void) {return(lp_string(*(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5462 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5463 const char *fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5464 #define FN_GLOBAL_LIST(fn_name,ptr) \
5465 const char **fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5466 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5467 bool fn_name(void) {return(*(bool *)(&Globals.ptr));}
5468 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5469 char fn_name(void) {return(*(char *)(&Globals.ptr));}
5470 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5471 int fn_name(void) {return(*(int *)(&Globals.ptr));}
5473 #define FN_LOCAL_STRING(fn_name,val) \
5474 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5475 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5476 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5477 #define FN_LOCAL_LIST(fn_name,val) \
5478 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5479 #define FN_LOCAL_BOOL(fn_name,val) \
5480 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5481 #define FN_LOCAL_INTEGER(fn_name,val) \
5482 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5484 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5485 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5486 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5487 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5488 #define FN_LOCAL_CHAR(fn_name,val) \
5489 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5491 FN_GLOBAL_CONST_STRING(lp_smb_ports, smb_ports)
5492 FN_GLOBAL_CONST_STRING(lp_dos_charset, dos_charset)
5493 FN_GLOBAL_CONST_STRING(lp_unix_charset, unix_charset)
5494 FN_GLOBAL_STRING(lp_logfile, szLogFile)
5495 FN_GLOBAL_STRING(lp_configfile, szConfigFile)
5496 FN_GLOBAL_CONST_STRING(lp_smb_passwd_file, szSMBPasswdFile)
5497 FN_GLOBAL_CONST_STRING(lp_private_dir, szPrivateDir)
5498 FN_GLOBAL_STRING(lp_serverstring, szServerString)
5499 FN_GLOBAL_INTEGER(lp_printcap_cache_time, PrintcapCacheTime)
5500 FN_GLOBAL_STRING(lp_addport_cmd, szAddPortCommand)
5501 FN_GLOBAL_STRING(lp_enumports_cmd, szEnumPortsCommand)
5502 FN_GLOBAL_STRING(lp_addprinter_cmd, szAddPrinterCommand)
5503 FN_GLOBAL_STRING(lp_deleteprinter_cmd, szDeletePrinterCommand)
5504 FN_GLOBAL_STRING(lp_os2_driver_map, szOs2DriverMap)
5505 FN_GLOBAL_CONST_STRING(lp_lockdir, szLockDir)
5506 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5507 * build process or in smb.conf, we use that value. Otherwise they
5508 * default to the value of lp_lockdir(). */
5509 const char *lp_statedir(void) {
5510 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5511 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5512 return(*(char **)(&Globals.szStateDir) ?
5513 *(char **)(&Globals.szStateDir) : "");
5515 return(*(char **)(&Globals.szLockDir) ?
5516 *(char **)(&Globals.szLockDir) : "");
5518 const char *lp_cachedir(void) {
5519 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5520 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5521 return(*(char **)(&Globals.szCacheDir) ?
5522 *(char **)(&Globals.szCacheDir) : "");
5524 return(*(char **)(&Globals.szLockDir) ?
5525 *(char **)(&Globals.szLockDir) : "");
5527 FN_GLOBAL_CONST_STRING(lp_piddir, szPidDir)
5528 FN_GLOBAL_STRING(lp_mangling_method, szManglingMethod)
5529 FN_GLOBAL_INTEGER(lp_mangle_prefix, mangle_prefix)
5530 FN_GLOBAL_CONST_STRING(lp_utmpdir, szUtmpDir)
5531 FN_GLOBAL_CONST_STRING(lp_wtmpdir, szWtmpDir)
5532 FN_GLOBAL_BOOL(lp_utmp, bUtmp)
5533 FN_GLOBAL_STRING(lp_rootdir, szRootdir)
5534 FN_GLOBAL_STRING(lp_perfcount_module, szSMBPerfcountModule)
5535 FN_GLOBAL_STRING(lp_defaultservice, szDefaultService)
5536 FN_GLOBAL_STRING(lp_msg_command, szMsgCommand)
5537 FN_GLOBAL_STRING(lp_get_quota_command, szGetQuota)
5538 FN_GLOBAL_STRING(lp_set_quota_command, szSetQuota)
5539 FN_GLOBAL_STRING(lp_auto_services, szAutoServices)
5540 FN_GLOBAL_STRING(lp_passwd_program, szPasswdProgram)
5541 FN_GLOBAL_STRING(lp_passwd_chat, szPasswdChat)
5542 FN_GLOBAL_CONST_STRING(lp_passwordserver, szPasswordServer)
5543 FN_GLOBAL_CONST_STRING(lp_name_resolve_order, szNameResolveOrder)
5544 FN_GLOBAL_CONST_STRING(lp_workgroup, szWorkgroup)
5545 FN_GLOBAL_CONST_STRING(lp_netbios_name, szNetbiosName)
5546 FN_GLOBAL_CONST_STRING(lp_netbios_scope, szNetbiosScope)
5547 FN_GLOBAL_CONST_STRING(lp_realm, szRealmUpper)
5548 FN_GLOBAL_CONST_STRING(lp_dnsdomain, szDnsDomain)
5549 FN_GLOBAL_CONST_STRING(lp_afs_username_map, szAfsUsernameMap)
5550 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, iAfsTokenLifetime)
5551 FN_GLOBAL_STRING(lp_log_nt_token_command, szLogNtTokenCommand)
5552 FN_GLOBAL_STRING(lp_username_map, szUsernameMap)
5553 FN_GLOBAL_CONST_STRING(lp_logon_script, szLogonScript)
5554 FN_GLOBAL_CONST_STRING(lp_logon_path, szLogonPath)
5555 FN_GLOBAL_CONST_STRING(lp_logon_drive, szLogonDrive)
5556 FN_GLOBAL_CONST_STRING(lp_logon_home, szLogonHome)
5557 FN_GLOBAL_STRING(lp_remote_announce, szRemoteAnnounce)
5558 FN_GLOBAL_STRING(lp_remote_browse_sync, szRemoteBrowseSync)
5559 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, bNmbdBindExplicitBroadcast)
5560 FN_GLOBAL_LIST(lp_wins_server_list, szWINSservers)
5561 FN_GLOBAL_LIST(lp_interfaces, szInterfaces)
5562 FN_GLOBAL_STRING(lp_nis_home_map_name, szNISHomeMapName)
5563 FN_GLOBAL_LIST(lp_netbios_aliases, szNetbiosAliases)
5564 FN_GLOBAL_CONST_STRING(lp_passdb_backend, szPassdbBackend)
5565 FN_GLOBAL_LIST(lp_preload_modules, szPreloadModules)
5566 FN_GLOBAL_STRING(lp_panic_action, szPanicAction)
5567 FN_GLOBAL_STRING(lp_adduser_script, szAddUserScript)
5568 FN_GLOBAL_STRING(lp_renameuser_script, szRenameUserScript)
5569 FN_GLOBAL_STRING(lp_deluser_script, szDelUserScript)
5571 FN_GLOBAL_CONST_STRING(lp_guestaccount, szGuestaccount)
5572 FN_GLOBAL_STRING(lp_addgroup_script, szAddGroupScript)
5573 FN_GLOBAL_STRING(lp_delgroup_script, szDelGroupScript)
5574 FN_GLOBAL_STRING(lp_addusertogroup_script, szAddUserToGroupScript)
5575 FN_GLOBAL_STRING(lp_deluserfromgroup_script, szDelUserFromGroupScript)
5576 FN_GLOBAL_STRING(lp_setprimarygroup_script, szSetPrimaryGroupScript)
5578 FN_GLOBAL_STRING(lp_addmachine_script, szAddMachineScript)
5580 FN_GLOBAL_STRING(lp_shutdown_script, szShutdownScript)
5581 FN_GLOBAL_STRING(lp_abort_shutdown_script, szAbortShutdownScript)
5582 FN_GLOBAL_STRING(lp_username_map_script, szUsernameMapScript)
5583 FN_GLOBAL_INTEGER(lp_username_map_cache_time, iUsernameMapCacheTime)
5585 FN_GLOBAL_STRING(lp_check_password_script, szCheckPasswordScript)
5587 FN_GLOBAL_STRING(lp_wins_hook, szWINSHook)
5588 FN_GLOBAL_CONST_STRING(lp_template_homedir, szTemplateHomedir)
5589 FN_GLOBAL_CONST_STRING(lp_template_shell, szTemplateShell)
5590 FN_GLOBAL_CONST_STRING(lp_winbind_separator, szWinbindSeparator)
5591 FN_GLOBAL_INTEGER(lp_acl_compatibility, iAclCompat)
5592 FN_GLOBAL_BOOL(lp_winbind_enum_users, bWinbindEnumUsers)
5593 FN_GLOBAL_BOOL(lp_winbind_enum_groups, bWinbindEnumGroups)
5594 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, bWinbindUseDefaultDomain)
5595 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, bWinbindTrustedDomainsOnly)
5596 FN_GLOBAL_BOOL(lp_winbind_nested_groups, bWinbindNestedGroups)
5597 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, winbind_expand_groups)
5598 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, bWinbindRefreshTickets)
5599 FN_GLOBAL_BOOL(lp_winbind_offline_logon, bWinbindOfflineLogon)
5600 FN_GLOBAL_BOOL(lp_winbind_normalize_names, bWinbindNormalizeNames)
5601 FN_GLOBAL_BOOL(lp_winbind_rpc_only, bWinbindRpcOnly)
5602 FN_GLOBAL_BOOL(lp_create_krb5_conf, bCreateKrb5Conf)
5603 static FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections_int,
5604 winbindMaxDomainConnections)
5606 int lp_winbind_max_domain_connections(void)
5608 if (lp_winbind_offline_logon() &&
5609 lp_winbind_max_domain_connections_int() > 1) {
5610 DEBUG(1, ("offline logons active, restricting max domain "
5611 "connections to 1\n"));
5614 return MAX(1, lp_winbind_max_domain_connections_int());
5617 FN_GLOBAL_CONST_STRING(lp_idmap_backend, szIdmapBackend)
5618 FN_GLOBAL_INTEGER(lp_idmap_cache_time, iIdmapCacheTime)
5619 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, iIdmapNegativeCacheTime)
5620 FN_GLOBAL_INTEGER(lp_keepalive, iKeepalive)
5621 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, bPassdbExpandExplicit)
5623 FN_GLOBAL_STRING(lp_ldap_suffix, szLdapSuffix)
5624 FN_GLOBAL_STRING(lp_ldap_admin_dn, szLdapAdminDn)
5625 FN_GLOBAL_INTEGER(lp_ldap_ssl, ldap_ssl)
5626 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, ldap_ssl_ads)
5627 FN_GLOBAL_INTEGER(lp_ldap_deref, ldap_deref)
5628 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, ldap_follow_referral)
5629 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, ldap_passwd_sync)
5630 FN_GLOBAL_BOOL(lp_ldap_delete_dn, ldap_delete_dn)
5631 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, ldap_replication_sleep)
5632 FN_GLOBAL_INTEGER(lp_ldap_timeout, ldap_timeout)
5633 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, ldap_connection_timeout)
5634 FN_GLOBAL_INTEGER(lp_ldap_page_size, ldap_page_size)
5635 FN_GLOBAL_INTEGER(lp_ldap_debug_level, ldap_debug_level)
5636 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, ldap_debug_threshold)
5637 FN_GLOBAL_STRING(lp_add_share_cmd, szAddShareCommand)
5638 FN_GLOBAL_STRING(lp_change_share_cmd, szChangeShareCommand)
5639 FN_GLOBAL_STRING(lp_delete_share_cmd, szDeleteShareCommand)
5640 FN_GLOBAL_STRING(lp_usershare_path, szUsersharePath)
5641 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, szUsersharePrefixAllowList)
5642 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, szUsersharePrefixDenyList)
5644 FN_GLOBAL_LIST(lp_eventlog_list, szEventLogs)
5646 FN_GLOBAL_BOOL(lp_registry_shares, bRegistryShares)
5647 FN_GLOBAL_BOOL(lp_usershare_allow_guests, bUsershareAllowGuests)
5648 FN_GLOBAL_BOOL(lp_usershare_owner_only, bUsershareOwnerOnly)
5649 FN_GLOBAL_BOOL(lp_disable_netbios, bDisableNetbios)
5650 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, bResetOnZeroVC)
5651 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5652 bLogWriteableFilesOnExit)
5653 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, bMsAddPrinterWizard)
5654 FN_GLOBAL_BOOL(lp_dns_proxy, bDNSproxy)
5655 FN_GLOBAL_BOOL(lp_wins_support, bWINSsupport)
5656 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, bWINSsupport)
5657 FN_GLOBAL_BOOL(lp_wins_proxy, bWINSproxy)
5658 FN_GLOBAL_BOOL(lp_local_master, bLocalMaster)
5659 FN_GLOBAL_BOOL(lp_domain_logons, bDomainLogons)
5660 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, szInitLogonDelayedHosts)
5661 FN_GLOBAL_INTEGER(lp_init_logon_delay, InitLogonDelay)
5662 FN_GLOBAL_BOOL(lp_load_printers, bLoadPrinters)
5663 FN_GLOBAL_BOOL(_lp_readraw, bReadRaw)
5664 FN_GLOBAL_BOOL(lp_large_readwrite, bLargeReadwrite)
5665 FN_GLOBAL_BOOL(_lp_writeraw, bWriteRaw)
5666 FN_GLOBAL_BOOL(lp_null_passwords, bNullPasswords)
5667 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, bObeyPamRestrictions)
5668 FN_GLOBAL_BOOL(lp_encrypted_passwords, bEncryptPasswords)
5669 FN_GLOBAL_INTEGER(lp_client_schannel, clientSchannel)
5670 FN_GLOBAL_INTEGER(lp_server_schannel, serverSchannel)
5671 FN_GLOBAL_BOOL(lp_syslog_only, bSyslogOnly)
5672 FN_GLOBAL_BOOL(lp_timestamp_logs, bTimestampLogs)
5673 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, bDebugPrefixTimestamp)
5674 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, bDebugHiresTimestamp)
5675 FN_GLOBAL_BOOL(lp_debug_pid, bDebugPid)
5676 FN_GLOBAL_BOOL(lp_debug_uid, bDebugUid)
5677 FN_GLOBAL_BOOL(lp_debug_class, bDebugClass)
5678 FN_GLOBAL_BOOL(lp_enable_core_files, bEnableCoreFiles)
5679 FN_GLOBAL_BOOL(lp_browse_list, bBrowseList)
5680 FN_GLOBAL_BOOL(lp_nis_home_map, bNISHomeMap)
5681 static FN_GLOBAL_BOOL(lp_time_server, bTimeServer)
5682 FN_GLOBAL_BOOL(lp_bind_interfaces_only, bBindInterfacesOnly)
5683 FN_GLOBAL_BOOL(lp_pam_password_change, bPamPasswordChange)
5684 FN_GLOBAL_BOOL(lp_unix_password_sync, bUnixPasswdSync)
5685 FN_GLOBAL_BOOL(lp_passwd_chat_debug, bPasswdChatDebug)
5686 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, iPasswdChatTimeout)
5687 FN_GLOBAL_BOOL(lp_nt_pipe_support, bNTPipeSupport)
5688 FN_GLOBAL_BOOL(lp_nt_status_support, bNTStatusSupport)
5689 FN_GLOBAL_BOOL(lp_stat_cache, bStatCache)
5690 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, iMaxStatCacheSize)
5691 FN_GLOBAL_BOOL(lp_allow_trusted_domains, bAllowTrustedDomains)
5692 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, bMapUntrustedToDomain)
5693 FN_GLOBAL_INTEGER(lp_restrict_anonymous, restrict_anonymous)
5694 FN_GLOBAL_BOOL(lp_lanman_auth, bLanmanAuth)
5695 FN_GLOBAL_BOOL(lp_ntlm_auth, bNTLMAuth)
5696 FN_GLOBAL_BOOL(lp_client_plaintext_auth, bClientPlaintextAuth)
5697 FN_GLOBAL_BOOL(lp_client_lanman_auth, bClientLanManAuth)
5698 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, bClientNTLMv2Auth)
5699 FN_GLOBAL_BOOL(lp_host_msdfs, bHostMSDfs)
5700 FN_GLOBAL_BOOL(lp_kernel_oplocks, bKernelOplocks)
5701 FN_GLOBAL_BOOL(lp_enhanced_browsing, enhanced_browsing)
5702 FN_GLOBAL_BOOL(lp_use_mmap, bUseMmap)
5703 FN_GLOBAL_BOOL(lp_unix_extensions, bUnixExtensions)
5704 FN_GLOBAL_BOOL(lp_use_spnego, bUseSpnego)
5705 FN_GLOBAL_BOOL(lp_client_use_spnego, bClientUseSpnego)
5706 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, client_use_spnego_principal)
5707 FN_GLOBAL_BOOL(lp_send_spnego_principal, send_spnego_principal)
5708 FN_GLOBAL_BOOL(lp_hostname_lookups, bHostnameLookups)
5709 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5710 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5711 FN_GLOBAL_CONST_STRING(lp_dedicated_keytab_file, szDedicatedKeytabFile)
5712 FN_GLOBAL_INTEGER(lp_kerberos_method, iKerberosMethod)
5713 FN_GLOBAL_BOOL(lp_defer_sharing_violations, bDeferSharingViolations)
5714 FN_GLOBAL_BOOL(lp_enable_privileges, bEnablePrivileges)
5715 FN_GLOBAL_BOOL(lp_enable_asu_support, bASUSupport)
5716 FN_GLOBAL_INTEGER(lp_os_level, os_level)
5717 FN_GLOBAL_INTEGER(lp_max_ttl, max_ttl)
5718 FN_GLOBAL_INTEGER(lp_max_wins_ttl, max_wins_ttl)
5719 FN_GLOBAL_INTEGER(lp_min_wins_ttl, min_wins_ttl)
5720 FN_GLOBAL_INTEGER(lp_max_log_size, max_log_size)
5721 FN_GLOBAL_INTEGER(lp_max_open_files, max_open_files)
5722 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, open_files_db_hash_size)
5723 FN_GLOBAL_INTEGER(lp_maxxmit, max_xmit)
5724 FN_GLOBAL_INTEGER(lp_maxmux, max_mux)
5725 FN_GLOBAL_INTEGER(lp_passwordlevel, pwordlevel)
5726 FN_GLOBAL_INTEGER(lp_usernamelevel, unamelevel)
5727 FN_GLOBAL_INTEGER(lp_deadtime, deadtime)
5728 FN_GLOBAL_BOOL(lp_getwd_cache, getwd_cache)
5729 static FN_GLOBAL_INTEGER(_lp_maxprotocol, maxprotocol)
5730 int lp_maxprotocol(void)
5732 int ret = _lp_maxprotocol();
5733 if ((ret == PROTOCOL_SMB2) && (lp_security() == SEC_SHARE)) {
5734 DEBUG(2,("WARNING!!: \"security = share\" is incompatible "
5735 "with the SMB2 protocol. Resetting to SMB1.\n" ));
5736 lp_do_parameter(-1, "max protocol", "NT1");
5737 return PROTOCOL_NT1;
5741 FN_GLOBAL_INTEGER(lp_minprotocol, minprotocol)
5742 FN_GLOBAL_INTEGER(lp_security, security)
5743 FN_GLOBAL_LIST(lp_auth_methods, AuthMethods)
5744 FN_GLOBAL_BOOL(lp_paranoid_server_security, paranoid_server_security)
5745 FN_GLOBAL_INTEGER(lp_maxdisksize, maxdisksize)
5746 FN_GLOBAL_INTEGER(lp_lpqcachetime, lpqcachetime)
5747 FN_GLOBAL_INTEGER(lp_max_smbd_processes, iMaxSmbdProcesses)
5748 FN_GLOBAL_BOOL(_lp_disable_spoolss, bDisableSpoolss)
5749 FN_GLOBAL_INTEGER(lp_syslog, syslog)
5750 FN_GLOBAL_INTEGER(lp_lm_announce, lm_announce)
5751 FN_GLOBAL_INTEGER(lp_lm_interval, lm_interval)
5752 FN_GLOBAL_INTEGER(lp_machine_password_timeout, machine_password_timeout)
5753 FN_GLOBAL_INTEGER(lp_map_to_guest, map_to_guest)
5754 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, oplock_break_wait_time)
5755 FN_GLOBAL_INTEGER(lp_lock_spin_time, iLockSpinTime)
5756 FN_GLOBAL_INTEGER(lp_usershare_max_shares, iUsershareMaxShares)
5757 FN_GLOBAL_CONST_STRING(lp_socket_options, szSocketOptions)
5758 FN_GLOBAL_INTEGER(lp_config_backend, ConfigBackend)
5759 FN_GLOBAL_INTEGER(lp_smb2_max_read, ismb2_max_read)
5760 FN_GLOBAL_INTEGER(lp_smb2_max_write, ismb2_max_write)
5761 FN_GLOBAL_INTEGER(lp_smb2_max_trans, ismb2_max_trans)
5762 int lp_smb2_max_credits(void)
5764 if (Globals.ismb2_max_credits == 0) {
5765 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5767 return Globals.ismb2_max_credits;
5769 FN_LOCAL_STRING(lp_preexec, szPreExec)
5770 FN_LOCAL_STRING(lp_postexec, szPostExec)
5771 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5772 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5773 FN_LOCAL_STRING(lp_servicename, szService)
5774 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5775 FN_LOCAL_STRING(lp_pathname, szPath)
5776 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5777 FN_LOCAL_STRING(lp_username, szUsername)
5778 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5779 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5780 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5781 FN_GLOBAL_LIST(lp_svcctl_list, szServicesList)
5782 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5783 FN_GLOBAL_STRING(lp_cups_server, szCupsServer)
5784 int lp_cups_encrypt(void)
5787 #ifdef HAVE_HTTPCONNECTENCRYPT
5788 switch (Globals.CupsEncrypt) {
5790 result = HTTP_ENCRYPT_REQUIRED;
5793 result = HTTP_ENCRYPT_ALWAYS;
5796 result = HTTP_ENCRYPT_NEVER;
5802 FN_GLOBAL_STRING(lp_iprint_server, szIPrintServer)
5803 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, cups_connection_timeout)
5804 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, ctdbdSocket)
5805 FN_GLOBAL_LIST(lp_cluster_addresses, szClusterAddresses)
5806 FN_GLOBAL_BOOL(lp_clustering, clustering)
5807 FN_GLOBAL_INTEGER(lp_ctdb_timeout, ctdb_timeout)
5808 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, ctdb_locktime_warn_threshold)
5809 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5810 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5811 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5812 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5813 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5814 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5815 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5816 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5817 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5818 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5819 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5820 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5821 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5822 FN_LOCAL_STRING(lp_comment, comment)
5823 FN_LOCAL_STRING(lp_force_user, force_user)
5824 FN_LOCAL_STRING(lp_force_group, force_group)
5825 FN_LOCAL_LIST(lp_readlist, readlist)
5826 FN_LOCAL_LIST(lp_writelist, writelist)
5827 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5828 FN_LOCAL_STRING(lp_fstype, fstype)
5829 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5830 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5831 static FN_LOCAL_STRING(lp_volume, volume)
5832 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5833 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5834 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5835 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5836 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5837 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5838 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5839 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5840 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5841 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5842 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5843 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5844 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5845 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5846 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5847 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5848 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5849 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5850 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5851 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5852 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5853 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5854 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5855 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5856 FN_LOCAL_BOOL(lp_print_notify_backchannel, bPrintNotifyBackchannel)
5857 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5858 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5859 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5860 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5861 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5862 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5863 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5864 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5865 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5866 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5867 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5868 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5869 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5870 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5871 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5872 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5873 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5874 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5875 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5876 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5877 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5878 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5879 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5880 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5881 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, bAsyncSMBEchoHandler)
5882 FN_GLOBAL_BOOL(lp_multicast_dns_register, bMulticastDnsRegister)
5883 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5884 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5885 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5886 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5887 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5888 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5889 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5890 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5891 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5892 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5893 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5894 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5895 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5896 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5897 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5898 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5899 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5900 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5901 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5902 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5903 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5904 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5905 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5906 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5907 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5908 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5909 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5910 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5911 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5912 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5913 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5914 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5915 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5916 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5917 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5918 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5919 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5920 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5921 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5922 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5923 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5924 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5925 FN_GLOBAL_INTEGER(lp_winbind_cache_time, winbind_cache_time)
5926 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, winbind_reconnect_delay)
5927 FN_GLOBAL_INTEGER(lp_winbind_max_clients, winbind_max_clients)
5928 FN_GLOBAL_LIST(lp_winbind_nss_info, szWinbindNssInfo)
5929 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, AlgorithmicRidBase)
5930 FN_GLOBAL_INTEGER(lp_name_cache_timeout, name_cache_timeout)
5931 FN_GLOBAL_INTEGER(lp_client_signing, client_signing)
5932 FN_GLOBAL_INTEGER(lp_server_signing, server_signing)
5933 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, client_ldap_sasl_wrapping)
5935 FN_GLOBAL_CONST_STRING(lp_ncalrpc_dir, ncalrpc_dir)
5937 /* local prototypes */
5939 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5940 static const char *get_boolean(bool bool_value);
5941 static int getservicebyname(const char *pszServiceName,
5942 struct loadparm_service *pserviceDest);
5943 static void copy_service(struct loadparm_service *pserviceDest,
5944 struct loadparm_service *pserviceSource,
5945 struct bitmap *pcopymapDest);
5946 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5948 static bool do_section(const char *pszSectionName, void *userdata);
5949 static void init_copymap(struct loadparm_service *pservice);
5950 static bool hash_a_service(const char *name, int number);
5951 static void free_service_byindex(int iService);
5952 static void free_param_opts(struct param_opt_struct **popts);
5953 static void show_parameter(int parmIndex);
5954 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5957 * This is a helper function for parametrical options support. It returns a
5958 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5959 * parametrical functions are quite simple
5961 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5964 bool global_section = false;
5966 struct param_opt_struct *data;
5968 if (snum >= iNumServices) return NULL;
5971 data = Globals.param_opt;
5972 global_section = true;
5974 data = ServicePtrs[snum]->param_opt;
5977 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5978 DEBUG(0,("asprintf failed!\n"));
5983 if (strwicmp(data->key, param_key) == 0) {
5984 string_free(¶m_key);
5990 if (!global_section) {
5991 /* Try to fetch the same option but from globals */
5992 /* but only if we are not already working with Globals */
5993 data = Globals.param_opt;
5995 if (strwicmp(data->key, param_key) == 0) {
5996 string_free(¶m_key);
6003 string_free(¶m_key);
6009 #define MISSING_PARAMETER(name) \
6010 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
6012 /*******************************************************************
6013 convenience routine to return int parameters.
6014 ********************************************************************/
6015 static int lp_int(const char *s)
6019 MISSING_PARAMETER(lp_int);
6023 return (int)strtol(s, NULL, 0);
6026 /*******************************************************************
6027 convenience routine to return unsigned long parameters.
6028 ********************************************************************/
6029 static unsigned long lp_ulong(const char *s)
6033 MISSING_PARAMETER(lp_ulong);
6037 return strtoul(s, NULL, 0);
6040 /*******************************************************************
6041 convenience routine to return boolean parameters.
6042 ********************************************************************/
6043 static bool lp_bool(const char *s)
6048 MISSING_PARAMETER(lp_bool);
6052 if (!set_boolean(s, &ret)) {
6053 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
6060 /*******************************************************************
6061 convenience routine to return enum parameters.
6062 ********************************************************************/
6063 static int lp_enum(const char *s,const struct enum_list *_enum)
6067 if (!s || !*s || !_enum) {
6068 MISSING_PARAMETER(lp_enum);
6072 for (i=0; _enum[i].name; i++) {
6073 if (strequal(_enum[i].name,s))
6074 return _enum[i].value;
6077 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
6081 #undef MISSING_PARAMETER
6083 /* Return parametric option from a given service. Type is a part of option before ':' */
6084 /* Parametric option has following syntax: 'Type: option = value' */
6085 /* the returned value is talloced on the talloc_tos() */
6086 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
6088 struct param_opt_struct *data = get_parametrics(snum, type, option);
6090 if (data == NULL||data->value==NULL) {
6092 return lp_string(def);
6098 return lp_string(data->value);
6101 /* Return parametric option from a given service. Type is a part of option before ':' */
6102 /* Parametric option has following syntax: 'Type: option = value' */
6103 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6105 struct param_opt_struct *data = get_parametrics(snum, type, option);
6107 if (data == NULL||data->value==NULL)
6113 /* Return parametric option from a given service. Type is a part of option before ':' */
6114 /* Parametric option has following syntax: 'Type: option = value' */
6116 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6118 struct param_opt_struct *data = get_parametrics(snum, type, option);
6120 if (data == NULL||data->value==NULL)
6121 return (const char **)def;
6123 if (data->list==NULL) {
6124 data->list = str_list_make_v3(NULL, data->value, NULL);
6127 return (const char **)data->list;
6130 /* Return parametric option from a given service. Type is a part of option before ':' */
6131 /* Parametric option has following syntax: 'Type: option = value' */
6133 int lp_parm_int(int snum, const char *type, const char *option, int def)
6135 struct param_opt_struct *data = get_parametrics(snum, type, option);
6137 if (data && data->value && *data->value)
6138 return lp_int(data->value);
6143 /* Return parametric option from a given service. Type is a part of option before ':' */
6144 /* Parametric option has following syntax: 'Type: option = value' */
6146 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6148 struct param_opt_struct *data = get_parametrics(snum, type, option);
6150 if (data && data->value && *data->value)
6151 return lp_ulong(data->value);
6156 /* Return parametric option from a given service. Type is a part of option before ':' */
6157 /* Parametric option has following syntax: 'Type: option = value' */
6159 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6161 struct param_opt_struct *data = get_parametrics(snum, type, option);
6163 if (data && data->value && *data->value)
6164 return lp_bool(data->value);
6169 /* Return parametric option from a given service. Type is a part of option before ':' */
6170 /* Parametric option has following syntax: 'Type: option = value' */
6172 int lp_parm_enum(int snum, const char *type, const char *option,
6173 const struct enum_list *_enum, int def)
6175 struct param_opt_struct *data = get_parametrics(snum, type, option);
6177 if (data && data->value && *data->value && _enum)
6178 return lp_enum(data->value, _enum);
6184 /***************************************************************************
6185 Initialise a service to the defaults.
6186 ***************************************************************************/
6188 static void init_service(struct loadparm_service *pservice)
6190 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
6191 copy_service(pservice, &sDefault, NULL);
6196 * free a param_opts structure.
6197 * param_opts handling should be moved to talloc;
6198 * then this whole functions reduces to a TALLOC_FREE().
6201 static void free_param_opts(struct param_opt_struct **popts)
6203 struct param_opt_struct *opt, *next_opt;
6205 if (popts == NULL) {
6209 if (*popts != NULL) {
6210 DEBUG(5, ("Freeing parametrics:\n"));
6213 while (opt != NULL) {
6214 string_free(&opt->key);
6215 string_free(&opt->value);
6216 TALLOC_FREE(opt->list);
6217 next_opt = opt->next;
6224 /***************************************************************************
6225 Free the dynamically allocated parts of a service struct.
6226 ***************************************************************************/
6228 static void free_service(struct loadparm_service *pservice)
6233 if (pservice->szService)
6234 DEBUG(5, ("free_service: Freeing service %s\n",
6235 pservice->szService));
6237 free_parameters(pservice);
6239 string_free(&pservice->szService);
6240 TALLOC_FREE(pservice->copymap);
6242 free_param_opts(&pservice->param_opt);
6244 ZERO_STRUCTP(pservice);
6248 /***************************************************************************
6249 remove a service indexed in the ServicePtrs array from the ServiceHash
6250 and free the dynamically allocated parts
6251 ***************************************************************************/
6253 static void free_service_byindex(int idx)
6255 if ( !LP_SNUM_OK(idx) )
6258 ServicePtrs[idx]->valid = false;
6259 invalid_services[num_invalid_services++] = idx;
6261 /* we have to cleanup the hash record */
6263 if (ServicePtrs[idx]->szService) {
6264 char *canon_name = canonicalize_servicename(
6266 ServicePtrs[idx]->szService );
6268 dbwrap_delete_bystring(ServiceHash, canon_name );
6269 TALLOC_FREE(canon_name);
6272 free_service(ServicePtrs[idx]);
6275 /***************************************************************************
6276 Add a new service to the services array initialising it with the given
6278 ***************************************************************************/
6280 static int add_a_service(const struct loadparm_service *pservice, const char *name)
6283 struct loadparm_service tservice;
6284 int num_to_alloc = iNumServices + 1;
6286 tservice = *pservice;
6288 /* it might already exist */
6290 i = getservicebyname(name, NULL);
6296 /* find an invalid one */
6298 if (num_invalid_services > 0) {
6299 i = invalid_services[--num_invalid_services];
6302 /* if not, then create one */
6303 if (i == iNumServices) {
6304 struct loadparm_service **tsp;
6307 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
6309 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6313 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct loadparm_service);
6314 if (!ServicePtrs[iNumServices]) {
6315 DEBUG(0,("add_a_service: out of memory!\n"));
6320 /* enlarge invalid_services here for now... */
6321 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6323 if (tinvalid == NULL) {
6324 DEBUG(0,("add_a_service: failed to enlarge "
6325 "invalid_services!\n"));
6328 invalid_services = tinvalid;
6330 free_service_byindex(i);
6333 ServicePtrs[i]->valid = true;
6335 init_service(ServicePtrs[i]);
6336 copy_service(ServicePtrs[i], &tservice, NULL);
6338 string_set(&ServicePtrs[i]->szService, name);
6340 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6341 i, ServicePtrs[i]->szService));
6343 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6350 /***************************************************************************
6351 Convert a string to uppercase and remove whitespaces.
6352 ***************************************************************************/
6354 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6359 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6363 result = talloc_strdup(ctx, src);
6364 SMB_ASSERT(result != NULL);
6370 /***************************************************************************
6371 Add a name/index pair for the services array to the hash table.
6372 ***************************************************************************/
6374 static bool hash_a_service(const char *name, int idx)
6378 if ( !ServiceHash ) {
6379 DEBUG(10,("hash_a_service: creating servicehash\n"));
6380 ServiceHash = db_open_rbt(NULL);
6381 if ( !ServiceHash ) {
6382 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6387 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6390 canon_name = canonicalize_servicename(talloc_tos(), name );
6392 dbwrap_store_bystring(ServiceHash, canon_name,
6393 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6396 TALLOC_FREE(canon_name);
6401 /***************************************************************************
6402 Add a new home service, with the specified home directory, defaults coming
6404 ***************************************************************************/
6406 bool lp_add_home(const char *pszHomename, int iDefaultService,
6407 const char *user, const char *pszHomedir)
6411 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6412 pszHomedir[0] == '\0') {
6416 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6421 if (!(*(ServicePtrs[iDefaultService]->szPath))
6422 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6423 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6426 if (!(*(ServicePtrs[i]->comment))) {
6427 char *comment = NULL;
6428 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6431 string_set(&ServicePtrs[i]->comment, comment);
6435 /* set the browseable flag from the global default */
6437 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6438 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6440 ServicePtrs[i]->autoloaded = true;
6442 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6443 user, ServicePtrs[i]->szPath ));
6448 /***************************************************************************
6449 Add a new service, based on an old one.
6450 ***************************************************************************/
6452 int lp_add_service(const char *pszService, int iDefaultService)
6454 if (iDefaultService < 0) {
6455 return add_a_service(&sDefault, pszService);
6458 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6461 /***************************************************************************
6462 Add the IPC service.
6463 ***************************************************************************/
6465 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6467 char *comment = NULL;
6468 int i = add_a_service(&sDefault, ipc_name);
6473 if (asprintf(&comment, "IPC Service (%s)",
6474 Globals.szServerString) < 0) {
6478 string_set(&ServicePtrs[i]->szPath, tmpdir());
6479 string_set(&ServicePtrs[i]->szUsername, "");
6480 string_set(&ServicePtrs[i]->comment, comment);
6481 string_set(&ServicePtrs[i]->fstype, "IPC");
6482 ServicePtrs[i]->iMaxConnections = 0;
6483 ServicePtrs[i]->bAvailable = true;
6484 ServicePtrs[i]->bRead_only = true;
6485 ServicePtrs[i]->bGuest_only = false;
6486 ServicePtrs[i]->bAdministrative_share = true;
6487 ServicePtrs[i]->bGuest_ok = guest_ok;
6488 ServicePtrs[i]->bPrint_ok = false;
6489 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6491 DEBUG(3, ("adding IPC service\n"));
6497 /***************************************************************************
6498 Add a new printer service, with defaults coming from service iFrom.
6499 ***************************************************************************/
6501 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6503 const char *comment = "From Printcap";
6504 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6509 /* note that we do NOT default the availability flag to true - */
6510 /* we take it from the default service passed. This allows all */
6511 /* dynamic printers to be disabled by disabling the [printers] */
6512 /* entry (if/when the 'available' keyword is implemented!). */
6514 /* the printer name is set to the service name. */
6515 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6516 string_set(&ServicePtrs[i]->comment, comment);
6518 /* set the browseable flag from the gloabl default */
6519 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6521 /* Printers cannot be read_only. */
6522 ServicePtrs[i]->bRead_only = false;
6523 /* No share modes on printer services. */
6524 ServicePtrs[i]->bShareModes = false;
6525 /* No oplocks on printer services. */
6526 ServicePtrs[i]->bOpLocks = false;
6527 /* Printer services must be printable. */
6528 ServicePtrs[i]->bPrint_ok = true;
6530 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6536 /***************************************************************************
6537 Check whether the given parameter name is valid.
6538 Parametric options (names containing a colon) are considered valid.
6539 ***************************************************************************/
6541 bool lp_parameter_is_valid(const char *pszParmName)
6543 return ((map_parameter(pszParmName) != -1) ||
6544 (strchr(pszParmName, ':') != NULL));
6547 /***************************************************************************
6548 Check whether the given name is the name of a global parameter.
6549 Returns true for strings belonging to parameters of class
6550 P_GLOBAL, false for all other strings, also for parametric options
6551 and strings not belonging to any option.
6552 ***************************************************************************/
6554 bool lp_parameter_is_global(const char *pszParmName)
6556 int num = map_parameter(pszParmName);
6559 return (parm_table[num].p_class == P_GLOBAL);
6565 /**************************************************************************
6566 Check whether the given name is the canonical name of a parameter.
6567 Returns false if it is not a valid parameter Name.
6568 For parametric options, true is returned.
6569 **************************************************************************/
6571 bool lp_parameter_is_canonical(const char *parm_name)
6573 if (!lp_parameter_is_valid(parm_name)) {
6577 return (map_parameter(parm_name) ==
6578 map_parameter_canonical(parm_name, NULL));
6581 /**************************************************************************
6582 Determine the canonical name for a parameter.
6583 Indicate when it is an inverse (boolean) synonym instead of a
6585 **************************************************************************/
6587 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6592 if (!lp_parameter_is_valid(parm_name)) {
6597 num = map_parameter_canonical(parm_name, inverse);
6599 /* parametric option */
6600 *canon_parm = parm_name;
6602 *canon_parm = parm_table[num].label;
6609 /**************************************************************************
6610 Determine the canonical name for a parameter.
6611 Turn the value given into the inverse boolean expression when
6612 the synonym is an invers boolean synonym.
6614 Return true if parm_name is a valid parameter name and
6615 in case it is an invers boolean synonym, if the val string could
6616 successfully be converted to the reverse bool.
6617 Return false in all other cases.
6618 **************************************************************************/
6620 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6622 const char **canon_parm,
6623 const char **canon_val)
6628 if (!lp_parameter_is_valid(parm_name)) {
6634 num = map_parameter_canonical(parm_name, &inverse);
6636 /* parametric option */
6637 *canon_parm = parm_name;
6640 *canon_parm = parm_table[num].label;
6642 if (!lp_invert_boolean(val, canon_val)) {
6654 /***************************************************************************
6655 Map a parameter's string representation to something we can use.
6656 Returns false if the parameter string is not recognised, else TRUE.
6657 ***************************************************************************/
6659 static int map_parameter(const char *pszParmName)
6663 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6666 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6667 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6670 /* Warn only if it isn't parametric option */
6671 if (strchr(pszParmName, ':') == NULL)
6672 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6673 /* We do return 'fail' for parametric options as well because they are
6674 stored in different storage
6679 /***************************************************************************
6680 Map a parameter's string representation to the index of the canonical
6681 form of the parameter (it might be a synonym).
6682 Returns -1 if the parameter string is not recognised.
6683 ***************************************************************************/
6685 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6687 int parm_num, canon_num;
6688 bool loc_inverse = false;
6690 parm_num = map_parameter(pszParmName);
6691 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6692 /* invalid, parametric or no canidate for synonyms ... */
6696 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6697 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6698 parm_num = canon_num;
6704 if (inverse != NULL) {
6705 *inverse = loc_inverse;
6710 /***************************************************************************
6711 return true if parameter number parm1 is a synonym of parameter
6712 number parm2 (parm2 being the principal name).
6713 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
6715 ***************************************************************************/
6717 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6719 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
6720 (parm_table[parm1].flags & FLAG_HIDE) &&
6721 !(parm_table[parm2].flags & FLAG_HIDE))
6723 if (inverse != NULL) {
6724 if ((parm_table[parm1].type == P_BOOLREV) &&
6725 (parm_table[parm2].type == P_BOOL))
6737 /***************************************************************************
6738 Show one parameter's name, type, [values,] and flags.
6739 (helper functions for show_parameter_list)
6740 ***************************************************************************/
6742 static void show_parameter(int parmIndex)
6744 int enumIndex, flagIndex;
6749 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6750 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6752 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6753 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6755 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6756 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6757 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
6759 printf("%s=%s", parm_table[parmIndex].label,
6760 type[parm_table[parmIndex].type]);
6761 if (parm_table[parmIndex].type == P_ENUM) {
6764 parm_table[parmIndex].enum_list[enumIndex].name;
6768 enumIndex ? "|" : "",
6769 parm_table[parmIndex].enum_list[enumIndex].name);
6774 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6775 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6778 flag_names[flagIndex]);
6783 /* output synonyms */
6785 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6786 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6787 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6788 parm_table[parmIndex2].label);
6789 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6791 printf(" (synonyms: ");
6796 printf("%s%s", parm_table[parmIndex2].label,
6797 inverse ? "[i]" : "");
6807 /***************************************************************************
6808 Show all parameter's name, type, [values,] and flags.
6809 ***************************************************************************/
6811 void show_parameter_list(void)
6813 int classIndex, parmIndex;
6814 const char *section_names[] = { "local", "global", NULL};
6816 for (classIndex=0; section_names[classIndex]; classIndex++) {
6817 printf("[%s]\n", section_names[classIndex]);
6818 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6819 if (parm_table[parmIndex].p_class == classIndex) {
6820 show_parameter(parmIndex);
6826 /***************************************************************************
6827 Check if a given string correctly represents a boolean value.
6828 ***************************************************************************/
6830 bool lp_string_is_valid_boolean(const char *parm_value)
6832 return set_boolean(parm_value, NULL);
6835 /***************************************************************************
6836 Get the standard string representation of a boolean value ("yes" or "no")
6837 ***************************************************************************/
6839 static const char *get_boolean(bool bool_value)
6841 static const char *yes_str = "yes";
6842 static const char *no_str = "no";
6844 return (bool_value ? yes_str : no_str);
6847 /***************************************************************************
6848 Provide the string of the negated boolean value associated to the boolean
6849 given as a string. Returns false if the passed string does not correctly
6850 represent a boolean.
6851 ***************************************************************************/
6853 bool lp_invert_boolean(const char *str, const char **inverse_str)
6857 if (!set_boolean(str, &val)) {
6861 *inverse_str = get_boolean(!val);
6865 /***************************************************************************
6866 Provide the canonical string representation of a boolean value given
6867 as a string. Return true on success, false if the string given does
6868 not correctly represent a boolean.
6869 ***************************************************************************/
6871 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6875 if (!set_boolean(str, &val)) {
6879 *canon_str = get_boolean(val);
6883 /***************************************************************************
6884 Find a service by name. Otherwise works like get_service.
6885 ***************************************************************************/
6887 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
6893 if (ServiceHash == NULL) {
6897 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6899 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6901 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6902 iService = *(int *)data.dptr;
6905 TALLOC_FREE(canon_name);
6907 if ((iService != -1) && (LP_SNUM_OK(iService))
6908 && (pserviceDest != NULL)) {
6909 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6915 /***************************************************************************
6916 Copy a service structure to another.
6917 If pcopymapDest is NULL then copy all fields
6918 ***************************************************************************/
6921 * Add a parametric option to a param_opt_struct,
6922 * replacing old value, if already present.
6924 static void set_param_opt(struct param_opt_struct **opt_list,
6925 const char *opt_name,
6926 const char *opt_value,
6929 struct param_opt_struct *new_opt, *opt;
6932 if (opt_list == NULL) {
6939 /* Traverse destination */
6941 /* If we already have same option, override it */
6942 if (strwicmp(opt->key, opt_name) == 0) {
6943 if ((opt->flags & FLAG_CMDLINE) &&
6944 !(flags & FLAG_CMDLINE)) {
6945 /* it's been marked as not to be
6949 string_free(&opt->value);
6950 TALLOC_FREE(opt->list);
6951 opt->value = SMB_STRDUP(opt_value);
6959 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6960 new_opt->key = SMB_STRDUP(opt_name);
6961 new_opt->value = SMB_STRDUP(opt_value);
6962 new_opt->list = NULL;
6963 new_opt->flags = flags;
6964 DLIST_ADD(*opt_list, new_opt);
6968 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
6969 struct bitmap *pcopymapDest)
6972 bool bcopyall = (pcopymapDest == NULL);
6973 struct param_opt_struct *data;
6975 for (i = 0; parm_table[i].label; i++)
6976 if (parm_table[i].p_class == P_LOCAL &&
6977 (bcopyall || bitmap_query(pcopymapDest,i))) {
6978 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
6979 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
6981 switch (parm_table[i].type) {
6984 *(bool *)dest_ptr = *(bool *)src_ptr;
6990 *(int *)dest_ptr = *(int *)src_ptr;
6994 *(char *)dest_ptr = *(char *)src_ptr;
6998 string_set((char **)dest_ptr,
7004 char *upper_string = strupper_talloc(talloc_tos(),
7006 string_set((char **)dest_ptr,
7008 TALLOC_FREE(upper_string);
7012 TALLOC_FREE(*((char ***)dest_ptr));
7013 *((char ***)dest_ptr) = str_list_copy(NULL,
7014 *(const char ***)src_ptr);
7022 init_copymap(pserviceDest);
7023 if (pserviceSource->copymap)
7024 bitmap_copy(pserviceDest->copymap,
7025 pserviceSource->copymap);
7028 data = pserviceSource->param_opt;
7030 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->flags);
7035 /***************************************************************************
7036 Check a service for consistency. Return false if the service is in any way
7037 incomplete or faulty, else true.
7038 ***************************************************************************/
7040 bool service_ok(int iService)
7045 if (ServicePtrs[iService]->szService[0] == '\0') {
7046 DEBUG(0, ("The following message indicates an internal error:\n"));
7047 DEBUG(0, ("No service name in service entry.\n"));
7051 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
7052 /* I can't see why you'd want a non-printable printer service... */
7053 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
7054 if (!ServicePtrs[iService]->bPrint_ok) {
7055 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
7056 ServicePtrs[iService]->szService));
7057 ServicePtrs[iService]->bPrint_ok = true;
7059 /* [printers] service must also be non-browsable. */
7060 if (ServicePtrs[iService]->bBrowseable)
7061 ServicePtrs[iService]->bBrowseable = false;
7064 if (ServicePtrs[iService]->szPath[0] == '\0' &&
7065 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
7066 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
7068 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
7069 ServicePtrs[iService]->szService));
7070 ServicePtrs[iService]->bAvailable = false;
7073 /* If a service is flagged unavailable, log the fact at level 1. */
7074 if (!ServicePtrs[iService]->bAvailable)
7075 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
7076 ServicePtrs[iService]->szService));
7081 static struct smbconf_ctx *lp_smbconf_ctx(void)
7084 static struct smbconf_ctx *conf_ctx = NULL;
7086 if (conf_ctx == NULL) {
7087 err = smbconf_init(NULL, &conf_ctx, "registry:");
7088 if (!SBC_ERROR_IS_OK(err)) {
7089 DEBUG(1, ("error initializing registry configuration: "
7090 "%s\n", sbcErrorString(err)));
7098 static bool process_smbconf_service(struct smbconf_service *service)
7103 if (service == NULL) {
7107 ret = do_section(service->name, NULL);
7111 for (count = 0; count < service->num_params; count++) {
7112 ret = do_parameter(service->param_names[count],
7113 service->param_values[count],
7119 if (iServiceIndex >= 0) {
7120 return service_ok(iServiceIndex);
7126 * load a service from registry and activate it
7128 bool process_registry_service(const char *service_name)
7131 struct smbconf_service *service = NULL;
7132 TALLOC_CTX *mem_ctx = talloc_stackframe();
7133 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7136 if (conf_ctx == NULL) {
7140 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7142 if (!smbconf_share_exists(conf_ctx, service_name)) {
7144 * Registry does not contain data for this service (yet),
7145 * but make sure lp_load doesn't return false.
7151 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7152 if (!SBC_ERROR_IS_OK(err)) {
7156 ret = process_smbconf_service(service);
7162 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7165 TALLOC_FREE(mem_ctx);
7170 * process_registry_globals
7172 static bool process_registry_globals(void)
7176 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7178 ret = do_parameter("registry shares", "yes", NULL);
7183 return process_registry_service(GLOBAL_NAME);
7186 bool process_registry_shares(void)
7190 struct smbconf_service **service = NULL;
7191 uint32_t num_shares = 0;
7192 TALLOC_CTX *mem_ctx = talloc_stackframe();
7193 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7196 if (conf_ctx == NULL) {
7200 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7201 if (!SBC_ERROR_IS_OK(err)) {
7207 for (count = 0; count < num_shares; count++) {
7208 if (strequal(service[count]->name, GLOBAL_NAME)) {
7211 ret = process_smbconf_service(service[count]);
7218 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7221 TALLOC_FREE(mem_ctx);
7225 #define MAX_INCLUDE_DEPTH 100
7227 static uint8_t include_depth;
7229 static struct file_lists {
7230 struct file_lists *next;
7234 } *file_lists = NULL;
7236 /*******************************************************************
7237 Keep a linked list of all config files so we know when one has changed
7238 it's date and needs to be reloaded.
7239 ********************************************************************/
7241 static void add_to_file_list(const char *fname, const char *subfname)
7243 struct file_lists *f = file_lists;
7246 if (f->name && !strcmp(f->name, fname))
7252 f = SMB_MALLOC_P(struct file_lists);
7255 f->next = file_lists;
7256 f->name = SMB_STRDUP(fname);
7261 f->subfname = SMB_STRDUP(subfname);
7268 f->modtime = file_modtime(subfname);
7270 time_t t = file_modtime(subfname);
7278 * Free the file lists
7280 static void free_file_list(void)
7282 struct file_lists *f;
7283 struct file_lists *next;
7288 SAFE_FREE( f->name );
7289 SAFE_FREE( f->subfname );
7298 * Utility function for outsiders to check if we're running on registry.
7300 bool lp_config_backend_is_registry(void)
7302 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7306 * Utility function to check if the config backend is FILE.
7308 bool lp_config_backend_is_file(void)
7310 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7313 /*******************************************************************
7314 Check if a config file has changed date.
7315 ********************************************************************/
7317 bool lp_file_list_changed(void)
7319 struct file_lists *f = file_lists;
7321 DEBUG(6, ("lp_file_list_changed()\n"));
7326 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7327 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7329 if (conf_ctx == NULL) {
7332 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7335 DEBUGADD(6, ("registry config changed\n"));
7340 n2 = talloc_sub_basic(talloc_tos(),
7341 get_current_username(),
7342 current_user_info.domain,
7347 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7348 f->name, n2, ctime(&f->modtime)));
7350 mod_time = file_modtime(n2);
7353 ((f->modtime != mod_time) ||
7354 (f->subfname == NULL) ||
7355 (strcmp(n2, f->subfname) != 0)))
7358 ("file %s modified: %s\n", n2,
7360 f->modtime = mod_time;
7361 SAFE_FREE(f->subfname);
7362 f->subfname = SMB_STRDUP(n2);
7375 * Initialize iconv conversion descriptors.
7377 * This is called the first time it is needed, and also called again
7378 * every time the configuration is reloaded, because the charset or
7379 * codepage might have changed.
7381 static void init_iconv(void)
7383 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
7385 true, global_iconv_handle);
7388 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7390 if (strcmp(*ptr, pszParmValue) != 0) {
7391 string_set(ptr, pszParmValue);
7397 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7399 bool is_utf8 = false;
7400 size_t len = strlen(pszParmValue);
7402 if (len == 4 || len == 5) {
7403 /* Don't use StrCaseCmp here as we don't want to
7404 initialize iconv. */
7405 if ((toupper_ascii(pszParmValue[0]) == 'U') &&
7406 (toupper_ascii(pszParmValue[1]) == 'T') &&
7407 (toupper_ascii(pszParmValue[2]) == 'F')) {
7409 if (pszParmValue[3] == '8') {
7413 if (pszParmValue[3] == '-' &&
7414 pszParmValue[4] == '8') {
7421 if (strcmp(*ptr, pszParmValue) != 0) {
7423 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
7424 "be UTF8, using (default value) %s instead.\n",
7425 DEFAULT_DOS_CHARSET));
7426 pszParmValue = DEFAULT_DOS_CHARSET;
7428 string_set(ptr, pszParmValue);
7434 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7437 char *realm = strupper_talloc(talloc_tos(), pszParmValue);
7438 char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
7440 ret &= string_set(&Globals.szRealm, pszParmValue);
7441 ret &= string_set(&Globals.szRealmUpper, realm);
7442 ret &= string_set(&Globals.szDnsDomain, dnsdomain);
7444 TALLOC_FREE(dnsdomain);
7449 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7451 TALLOC_FREE(Globals.szNetbiosAliases);
7452 Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
7453 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7456 /***************************************************************************
7457 Handle the include operation.
7458 ***************************************************************************/
7459 static bool bAllowIncludeRegistry = true;
7461 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7465 if (include_depth >= MAX_INCLUDE_DEPTH) {
7466 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7471 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7472 if (!bAllowIncludeRegistry) {
7475 if (bInGlobalSection) {
7478 ret = process_registry_globals();
7482 DEBUG(1, ("\"include = registry\" only effective "
7483 "in %s section\n", GLOBAL_NAME));
7488 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7489 current_user_info.domain,
7492 add_to_file_list(pszParmValue, fname);
7494 string_set(ptr, fname);
7496 if (file_exist(fname)) {
7499 ret = pm_process(fname, do_section, do_parameter, NULL);
7505 DEBUG(2, ("Can't find include file %s\n", fname));
7510 /***************************************************************************
7511 Handle the interpretation of the copy parameter.
7512 ***************************************************************************/
7514 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7518 struct loadparm_service serviceTemp;
7520 string_set(ptr, pszParmValue);
7522 init_service(&serviceTemp);
7526 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7528 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7529 if (iTemp == iServiceIndex) {
7530 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7532 copy_service(ServicePtrs[iServiceIndex],
7534 ServicePtrs[iServiceIndex]->copymap);
7538 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7542 free_service(&serviceTemp);
7546 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7548 Globals.ldap_debug_level = lp_int(pszParmValue);
7549 init_ldap_debugging();
7553 /***************************************************************************
7554 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7559 idmap uid = 1000-1999
7562 We only do simple parsing checks here. The strings are parsed into useful
7563 structures in the idmap daemon code.
7565 ***************************************************************************/
7567 /* Some lp_ routines to return idmap [ug]id information */
7569 static uid_t idmap_uid_low, idmap_uid_high;
7570 static gid_t idmap_gid_low, idmap_gid_high;
7572 bool lp_idmap_uid(uid_t *low, uid_t *high)
7574 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7578 *low = idmap_uid_low;
7581 *high = idmap_uid_high;
7586 bool lp_idmap_gid(gid_t *low, gid_t *high)
7588 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7592 *low = idmap_gid_low;
7595 *high = idmap_gid_high;
7600 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7602 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7607 /* Do some simple checks on "idmap [ug]id" parameter values */
7609 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7611 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7616 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7618 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7623 /***************************************************************************
7624 Handle the DEBUG level list.
7625 ***************************************************************************/
7627 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
7629 string_set(ptr, pszParmValueIn);
7630 return debug_parse_levels(pszParmValueIn);
7633 /***************************************************************************
7634 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7635 ***************************************************************************/
7637 static const char *append_ldap_suffix( const char *str )
7639 const char *suffix_string;
7642 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7643 Globals.szLdapSuffix );
7644 if ( !suffix_string ) {
7645 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7649 return suffix_string;
7652 const char *lp_ldap_machine_suffix(void)
7654 if (Globals.szLdapMachineSuffix[0])
7655 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7657 return lp_string(Globals.szLdapSuffix);
7660 const char *lp_ldap_user_suffix(void)
7662 if (Globals.szLdapUserSuffix[0])
7663 return append_ldap_suffix(Globals.szLdapUserSuffix);
7665 return lp_string(Globals.szLdapSuffix);
7668 const char *lp_ldap_group_suffix(void)
7670 if (Globals.szLdapGroupSuffix[0])
7671 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7673 return lp_string(Globals.szLdapSuffix);
7676 const char *lp_ldap_idmap_suffix(void)
7678 if (Globals.szLdapIdmapSuffix[0])
7679 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7681 return lp_string(Globals.szLdapSuffix);
7684 /****************************************************************************
7685 set the value for a P_ENUM
7686 ***************************************************************************/
7688 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7693 for (i = 0; parm->enum_list[i].name; i++) {
7694 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7695 *ptr = parm->enum_list[i].value;
7699 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7700 pszParmValue, parm->label));
7703 /***************************************************************************
7704 ***************************************************************************/
7706 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7708 static int parm_num = -1;
7709 struct loadparm_service *s;
7711 if ( parm_num == -1 )
7712 parm_num = map_parameter( "printing" );
7714 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7719 s = ServicePtrs[snum];
7721 init_printer_values( s );
7727 /***************************************************************************
7728 Initialise a copymap.
7729 ***************************************************************************/
7731 static void init_copymap(struct loadparm_service *pservice)
7735 TALLOC_FREE(pservice->copymap);
7737 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7738 if (!pservice->copymap)
7740 ("Couldn't allocate copymap!! (size %d)\n",
7741 (int)NUMPARAMETERS));
7743 for (i = 0; i < NUMPARAMETERS; i++)
7744 bitmap_set(pservice->copymap, i);
7748 return the parameter pointer for a parameter
7750 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
7752 if (service == NULL) {
7753 if (parm->p_class == P_LOCAL)
7754 return (void *)(((char *)&sDefault)+parm->offset);
7755 else if (parm->p_class == P_GLOBAL)
7756 return (void *)(((char *)&Globals)+parm->offset);
7759 return (void *)(((char *)service) + parm->offset);
7763 /***************************************************************************
7764 Return the local pointer to a parameter given the service number and parameter
7765 ***************************************************************************/
7767 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
7769 return lp_parm_ptr(ServicePtrs[snum], parm);
7772 /***************************************************************************
7773 Process a parameter for a particular service number. If snum < 0
7774 then assume we are in the globals.
7775 ***************************************************************************/
7777 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7780 void *parm_ptr = NULL; /* where we are going to store the result */
7781 struct param_opt_struct **opt_list;
7783 parmnum = map_parameter(pszParmName);
7786 if (strchr(pszParmName, ':') == NULL) {
7787 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7793 * We've got a parametric option
7796 opt_list = (snum < 0)
7797 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7798 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7803 /* if it's already been set by the command line, then we don't
7805 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7809 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7810 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7814 /* we might point at a service, the default service or a global */
7816 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
7818 if (parm_table[parmnum].p_class == P_GLOBAL) {
7820 ("Global parameter %s found in service section!\n",
7824 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
7828 if (!ServicePtrs[snum]->copymap)
7829 init_copymap(ServicePtrs[snum]);
7831 /* this handles the aliases - set the copymap for other entries with
7832 the same data pointer */
7833 for (i = 0; parm_table[i].label; i++)
7834 if (parm_table[i].offset == parm_table[parmnum].offset)
7835 bitmap_clear(ServicePtrs[snum]->copymap, i);
7838 /* if it is a special case then go ahead */
7839 if (parm_table[parmnum].special) {
7840 return parm_table[parmnum].special(NULL, snum, pszParmValue,
7844 /* now switch on the type of variable it is */
7845 switch (parm_table[parmnum].type)
7848 *(bool *)parm_ptr = lp_bool(pszParmValue);
7852 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7856 *(int *)parm_ptr = lp_int(pszParmValue);
7860 *(char *)parm_ptr = *pszParmValue;
7864 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7866 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7871 TALLOC_FREE(*((char ***)parm_ptr));
7872 *(char ***)parm_ptr = str_list_make_v3(
7873 NULL, pszParmValue, NULL);
7877 string_set((char **)parm_ptr, pszParmValue);
7882 char *upper_string = strupper_talloc(talloc_tos(),
7884 string_set((char **)parm_ptr, upper_string);
7885 TALLOC_FREE(upper_string);
7889 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7898 /***************************************************************************
7899 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7900 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7901 ***************************************************************************/
7903 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7906 parmnum = map_parameter(pszParmName);
7908 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7909 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7912 parm_table[parmnum].flags |= FLAG_CMDLINE;
7914 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7915 * be grouped in the table, so we don't have to search the
7917 for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) {
7918 parm_table[i].flags |= FLAG_CMDLINE;
7920 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset;i++) {
7921 parm_table[i].flags |= FLAG_CMDLINE;
7925 store_lp_set_cmdline(pszParmName, pszParmValue);
7930 /* it might be parametric */
7931 if (strchr(pszParmName, ':') != NULL) {
7932 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7934 store_lp_set_cmdline(pszParmName, pszParmValue);
7939 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7943 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7945 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7948 /***************************************************************************
7949 Process a parameter.
7950 ***************************************************************************/
7952 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7955 if (!bInGlobalSection && bGlobalOnly)
7958 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7960 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7961 pszParmName, pszParmValue));
7965 set a option from the commandline in 'a=b' format. Use to support --option
7967 bool lp_set_option(const char *option)
7972 s = talloc_strdup(NULL, option);
7985 /* skip white spaces after the = sign */
7988 } while (*p == ' ');
7990 ret = lp_set_cmdline(s, p);
7995 /**************************************************************************
7996 Print a parameter of the specified type.
7997 ***************************************************************************/
7999 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
8005 for (i = 0; p->enum_list[i].name; i++) {
8006 if (*(int *)ptr == p->enum_list[i].value) {
8008 p->enum_list[i].name);
8015 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
8019 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
8023 fprintf(f, "%d", *(int *)ptr);
8027 fprintf(f, "%c", *(char *)ptr);
8031 char *o = octal_string(*(int *)ptr);
8032 fprintf(f, "%s", o);
8038 if ((char ***)ptr && *(char ***)ptr) {
8039 char **list = *(char ***)ptr;
8040 for (; *list; list++) {
8041 /* surround strings with whitespace in double quotes */
8042 if ( strchr_m( *list, ' ' ) )
8043 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
8045 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
8052 if (*(char **)ptr) {
8053 fprintf(f, "%s", *(char **)ptr);
8061 /***************************************************************************
8062 Check if two parameters are equal.
8063 ***************************************************************************/
8065 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8070 return (*((bool *)ptr1) == *((bool *)ptr2));
8075 return (*((int *)ptr1) == *((int *)ptr2));
8078 return (*((char *)ptr1) == *((char *)ptr2));
8081 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8086 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8091 return (p1 == p2 || strequal(p1, p2));
8099 /***************************************************************************
8100 Initialize any local varients in the sDefault table.
8101 ***************************************************************************/
8103 void init_locals(void)
8108 /***************************************************************************
8109 Process a new section (service). At this stage all sections are services.
8110 Later we'll have special sections that permit server parameters to be set.
8111 Returns true on success, false on failure.
8112 ***************************************************************************/
8114 static bool do_section(const char *pszSectionName, void *userdata)
8117 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8118 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8121 /* if we were in a global section then do the local inits */
8122 if (bInGlobalSection && !isglobal)
8125 /* if we've just struck a global section, note the fact. */
8126 bInGlobalSection = isglobal;
8128 /* check for multiple global sections */
8129 if (bInGlobalSection) {
8130 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8134 if (!bInGlobalSection && bGlobalOnly)
8137 /* if we have a current service, tidy it up before moving on */
8140 if (iServiceIndex >= 0)
8141 bRetval = service_ok(iServiceIndex);
8143 /* if all is still well, move to the next record in the services array */
8145 /* We put this here to avoid an odd message order if messages are */
8146 /* issued by the post-processing of a previous section. */
8147 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8149 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8151 DEBUG(0, ("Failed to add a new service\n"));
8154 /* Clean all parametric options for service */
8155 /* They will be added during parsing again */
8156 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
8163 /***************************************************************************
8164 Determine if a partcular base parameter is currentl set to the default value.
8165 ***************************************************************************/
8167 static bool is_default(int i)
8169 if (!defaults_saved)
8171 switch (parm_table[i].type) {
8173 return str_list_equal((const char **)parm_table[i].def.lvalue,
8174 *(const char ***)lp_parm_ptr(NULL,
8178 return strequal(parm_table[i].def.svalue,
8179 *(char **)lp_parm_ptr(NULL,
8183 return parm_table[i].def.bvalue ==
8184 *(bool *)lp_parm_ptr(NULL,
8187 return parm_table[i].def.cvalue ==
8188 *(char *)lp_parm_ptr(NULL,
8193 return parm_table[i].def.ivalue ==
8194 *(int *)lp_parm_ptr(NULL,
8202 /***************************************************************************
8203 Display the contents of the global structure.
8204 ***************************************************************************/
8206 static void dump_globals(FILE *f)
8209 struct param_opt_struct *data;
8211 fprintf(f, "[global]\n");
8213 for (i = 0; parm_table[i].label; i++)
8214 if (parm_table[i].p_class == P_GLOBAL &&
8215 !(parm_table[i].flags & FLAG_META) &&
8216 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
8217 if (defaults_saved && is_default(i))
8219 fprintf(f, "\t%s = ", parm_table[i].label);
8220 print_parameter(&parm_table[i], lp_parm_ptr(NULL,
8225 if (Globals.param_opt != NULL) {
8226 data = Globals.param_opt;
8228 fprintf(f, "\t%s = %s\n", data->key, data->value);
8235 /***************************************************************************
8236 Return true if a local parameter is currently set to the global default.
8237 ***************************************************************************/
8239 bool lp_is_default(int snum, struct parm_struct *parm)
8241 return equal_parameter(parm->type,
8242 lp_parm_ptr(ServicePtrs[snum], parm),
8243 lp_parm_ptr(NULL, parm));
8246 /***************************************************************************
8247 Display the contents of a single services record.
8248 ***************************************************************************/
8250 static void dump_a_service(struct loadparm_service *pService, FILE * f)
8253 struct param_opt_struct *data;
8255 if (pService != &sDefault)
8256 fprintf(f, "[%s]\n", pService->szService);
8258 for (i = 0; parm_table[i].label; i++) {
8260 if (parm_table[i].p_class == P_LOCAL &&
8261 !(parm_table[i].flags & FLAG_META) &&
8262 (*parm_table[i].label != '-') &&
8263 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
8265 if (pService == &sDefault) {
8266 if (defaults_saved && is_default(i))
8269 if (equal_parameter(parm_table[i].type,
8270 lp_parm_ptr(pService, &parm_table[i]),
8271 lp_parm_ptr(NULL, &parm_table[i])))
8275 fprintf(f, "\t%s = ", parm_table[i].label);
8276 print_parameter(&parm_table[i],
8277 lp_parm_ptr(pService, &parm_table[i]),
8283 if (pService->param_opt != NULL) {
8284 data = pService->param_opt;
8286 fprintf(f, "\t%s = %s\n", data->key, data->value);
8292 /***************************************************************************
8293 Display the contents of a parameter of a single services record.
8294 ***************************************************************************/
8296 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8299 bool result = false;
8302 fstring local_parm_name;
8304 const char *parm_opt_value;
8306 /* check for parametrical option */
8307 fstrcpy( local_parm_name, parm_name);
8308 parm_opt = strchr( local_parm_name, ':');
8313 if (strlen(parm_opt)) {
8314 parm_opt_value = lp_parm_const_string( snum,
8315 local_parm_name, parm_opt, NULL);
8316 if (parm_opt_value) {
8317 printf( "%s\n", parm_opt_value);
8324 /* check for a key and print the value */
8331 for (i = 0; parm_table[i].label; i++) {
8332 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8333 !(parm_table[i].flags & FLAG_META) &&
8334 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8335 (*parm_table[i].label != '-') &&
8336 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
8341 ptr = lp_parm_ptr(NULL,
8344 ptr = lp_parm_ptr(ServicePtrs[snum],
8348 print_parameter(&parm_table[i],
8359 /***************************************************************************
8360 Return info about the requested parameter (given as a string).
8361 Return NULL when the string is not a valid parameter name.
8362 ***************************************************************************/
8364 struct parm_struct *lp_get_parameter(const char *param_name)
8366 int num = map_parameter(param_name);
8372 return &parm_table[num];
8375 /***************************************************************************
8376 Return info about the next parameter in a service.
8377 snum==GLOBAL_SECTION_SNUM gives the globals.
8378 Return NULL when out of parameters.
8379 ***************************************************************************/
8381 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8384 /* do the globals */
8385 for (; parm_table[*i].label; (*i)++) {
8386 if (parm_table[*i].p_class == P_SEPARATOR)
8387 return &parm_table[(*i)++];
8389 if ((*parm_table[*i].label == '-'))
8393 && (parm_table[*i].offset ==
8394 parm_table[(*i) - 1].offset))
8397 if (is_default(*i) && !allparameters)
8400 return &parm_table[(*i)++];
8403 struct loadparm_service *pService = ServicePtrs[snum];
8405 for (; parm_table[*i].label; (*i)++) {
8406 if (parm_table[*i].p_class == P_SEPARATOR)
8407 return &parm_table[(*i)++];
8409 if (parm_table[*i].p_class == P_LOCAL &&
8410 (*parm_table[*i].label != '-') &&
8412 (parm_table[*i].offset !=
8413 parm_table[(*i) - 1].offset)))
8415 if (allparameters ||
8416 !equal_parameter(parm_table[*i].type,
8417 lp_parm_ptr(pService,
8422 return &parm_table[(*i)++];
8433 /***************************************************************************
8434 Display the contents of a single copy structure.
8435 ***************************************************************************/
8436 static void dump_copy_map(bool *pcopymap)
8442 printf("\n\tNon-Copied parameters:\n");
8444 for (i = 0; parm_table[i].label; i++)
8445 if (parm_table[i].p_class == P_LOCAL &&
8446 parm_table[i].ptr && !pcopymap[i] &&
8447 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8449 printf("\t\t%s\n", parm_table[i].label);
8454 /***************************************************************************
8455 Return TRUE if the passed service number is within range.
8456 ***************************************************************************/
8458 bool lp_snum_ok(int iService)
8460 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8463 /***************************************************************************
8464 Auto-load some home services.
8465 ***************************************************************************/
8467 static void lp_add_auto_services(char *str)
8477 s = SMB_STRDUP(str);
8481 homes = lp_servicenumber(HOMES_NAME);
8483 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8484 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8487 if (lp_servicenumber(p) >= 0)
8490 home = get_user_home_dir(talloc_tos(), p);
8492 if (home && home[0] && homes >= 0)
8493 lp_add_home(p, homes, p, home);
8500 /***************************************************************************
8501 Auto-load one printer.
8502 ***************************************************************************/
8504 void lp_add_one_printer(const char *name, const char *comment,
8505 const char *location, void *pdata)
8507 int printers = lp_servicenumber(PRINTERS_NAME);
8510 if (lp_servicenumber(name) < 0) {
8511 lp_add_printer(name, printers);
8512 if ((i = lp_servicenumber(name)) >= 0) {
8513 string_set(&ServicePtrs[i]->comment, comment);
8514 ServicePtrs[i]->autoloaded = true;
8519 /***************************************************************************
8520 Have we loaded a services file yet?
8521 ***************************************************************************/
8523 bool lp_loaded(void)
8528 /***************************************************************************
8529 Unload unused services.
8530 ***************************************************************************/
8532 void lp_killunused(struct smbd_server_connection *sconn,
8533 bool (*snumused) (struct smbd_server_connection *, int))
8536 for (i = 0; i < iNumServices; i++) {
8540 /* don't kill autoloaded or usershare services */
8541 if ( ServicePtrs[i]->autoloaded ||
8542 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8546 if (!snumused || !snumused(sconn, i)) {
8547 free_service_byindex(i);
8553 * Kill all except autoloaded and usershare services - convenience wrapper
8555 void lp_kill_all_services(void)
8557 lp_killunused(NULL, NULL);
8560 /***************************************************************************
8562 ***************************************************************************/
8564 void lp_killservice(int iServiceIn)
8566 if (VALID(iServiceIn)) {
8567 free_service_byindex(iServiceIn);
8571 /***************************************************************************
8572 Save the curent values of all global and sDefault parameters into the
8573 defaults union. This allows swat and testparm to show only the
8574 changed (ie. non-default) parameters.
8575 ***************************************************************************/
8577 static void lp_save_defaults(void)
8580 for (i = 0; parm_table[i].label; i++) {
8581 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset)
8583 switch (parm_table[i].type) {
8585 parm_table[i].def.lvalue = str_list_copy(
8586 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
8590 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
8594 parm_table[i].def.bvalue =
8595 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
8598 parm_table[i].def.cvalue =
8599 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
8604 parm_table[i].def.ivalue =
8605 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
8611 defaults_saved = true;
8614 /***********************************************************
8615 If we should send plaintext/LANMAN passwords in the clinet
8616 ************************************************************/
8618 static void set_allowed_client_auth(void)
8620 if (Globals.bClientNTLMv2Auth) {
8621 Globals.bClientLanManAuth = false;
8623 if (!Globals.bClientLanManAuth) {
8624 Globals.bClientPlaintextAuth = false;
8628 /***************************************************************************
8630 The following code allows smbd to read a user defined share file.
8631 Yes, this is my intent. Yes, I'm comfortable with that...
8633 THE FOLLOWING IS SECURITY CRITICAL CODE.
8635 It washes your clothes, it cleans your house, it guards you while you sleep...
8636 Do not f%^k with it....
8637 ***************************************************************************/
8639 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8641 /***************************************************************************
8642 Check allowed stat state of a usershare file.
8643 Ensure we print out who is dicking with us so the admin can
8644 get their sorry ass fired.
8645 ***************************************************************************/
8647 static bool check_usershare_stat(const char *fname,
8648 const SMB_STRUCT_STAT *psbuf)
8650 if (!S_ISREG(psbuf->st_ex_mode)) {
8651 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8652 "not a regular file\n",
8653 fname, (unsigned int)psbuf->st_ex_uid ));
8657 /* Ensure this doesn't have the other write bit set. */
8658 if (psbuf->st_ex_mode & S_IWOTH) {
8659 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8660 "public write. Refusing to allow as a usershare file.\n",
8661 fname, (unsigned int)psbuf->st_ex_uid ));
8665 /* Should be 10k or less. */
8666 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8667 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8668 "too large (%u) to be a user share file.\n",
8669 fname, (unsigned int)psbuf->st_ex_uid,
8670 (unsigned int)psbuf->st_ex_size ));
8677 /***************************************************************************
8678 Parse the contents of a usershare file.
8679 ***************************************************************************/
8681 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8682 SMB_STRUCT_STAT *psbuf,
8683 const char *servicename,
8687 char **pp_sharepath,
8689 char **pp_cp_servicename,
8690 struct security_descriptor **ppsd,
8693 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8694 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8697 SMB_STRUCT_STAT sbuf;
8698 char *sharepath = NULL;
8699 char *comment = NULL;
8701 *pp_sharepath = NULL;
8704 *pallow_guest = false;
8707 return USERSHARE_MALFORMED_FILE;
8710 if (strcmp(lines[0], "#VERSION 1") == 0) {
8712 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8715 return USERSHARE_MALFORMED_FILE;
8718 return USERSHARE_BAD_VERSION;
8721 if (strncmp(lines[1], "path=", 5) != 0) {
8722 return USERSHARE_MALFORMED_PATH;
8725 sharepath = talloc_strdup(ctx, &lines[1][5]);
8727 return USERSHARE_POSIX_ERR;
8729 trim_string(sharepath, " ", " ");
8731 if (strncmp(lines[2], "comment=", 8) != 0) {
8732 return USERSHARE_MALFORMED_COMMENT_DEF;
8735 comment = talloc_strdup(ctx, &lines[2][8]);
8737 return USERSHARE_POSIX_ERR;
8739 trim_string(comment, " ", " ");
8740 trim_char(comment, '"', '"');
8742 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8743 return USERSHARE_MALFORMED_ACL_DEF;
8746 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8747 return USERSHARE_ACL_ERR;
8751 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8752 return USERSHARE_MALFORMED_ACL_DEF;
8754 if (lines[4][9] == 'y') {
8755 *pallow_guest = true;
8758 /* Backwards compatible extension to file version #2. */
8760 if (strncmp(lines[5], "sharename=", 10) != 0) {
8761 return USERSHARE_MALFORMED_SHARENAME_DEF;
8763 if (!strequal(&lines[5][10], servicename)) {
8764 return USERSHARE_BAD_SHARENAME;
8766 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8767 if (!*pp_cp_servicename) {
8768 return USERSHARE_POSIX_ERR;
8773 if (*pp_cp_servicename == NULL) {
8774 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8775 if (!*pp_cp_servicename) {
8776 return USERSHARE_POSIX_ERR;
8780 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8781 /* Path didn't change, no checks needed. */
8782 *pp_sharepath = sharepath;
8783 *pp_comment = comment;
8784 return USERSHARE_OK;
8787 /* The path *must* be absolute. */
8788 if (sharepath[0] != '/') {
8789 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8790 servicename, sharepath));
8791 return USERSHARE_PATH_NOT_ABSOLUTE;
8794 /* If there is a usershare prefix deny list ensure one of these paths
8795 doesn't match the start of the user given path. */
8796 if (prefixdenylist) {
8798 for ( i=0; prefixdenylist[i]; i++ ) {
8799 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8800 servicename, i, prefixdenylist[i], sharepath ));
8801 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8802 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8803 "usershare prefix deny list entries.\n",
8804 servicename, sharepath));
8805 return USERSHARE_PATH_IS_DENIED;
8810 /* If there is a usershare prefix allow list ensure one of these paths
8811 does match the start of the user given path. */
8813 if (prefixallowlist) {
8815 for ( i=0; prefixallowlist[i]; i++ ) {
8816 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8817 servicename, i, prefixallowlist[i], sharepath ));
8818 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8822 if (prefixallowlist[i] == NULL) {
8823 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8824 "usershare prefix allow list entries.\n",
8825 servicename, sharepath));
8826 return USERSHARE_PATH_NOT_ALLOWED;
8830 /* Ensure this is pointing to a directory. */
8831 dp = sys_opendir(sharepath);
8834 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8835 servicename, sharepath));
8836 return USERSHARE_PATH_NOT_DIRECTORY;
8839 /* Ensure the owner of the usershare file has permission to share
8842 if (sys_stat(sharepath, &sbuf, false) == -1) {
8843 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8844 servicename, sharepath, strerror(errno) ));
8846 return USERSHARE_POSIX_ERR;
8851 if (!S_ISDIR(sbuf.st_ex_mode)) {
8852 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8853 servicename, sharepath ));
8854 return USERSHARE_PATH_NOT_DIRECTORY;
8857 /* Check if sharing is restricted to owner-only. */
8858 /* psbuf is the stat of the usershare definition file,
8859 sbuf is the stat of the target directory to be shared. */
8861 if (lp_usershare_owner_only()) {
8862 /* root can share anything. */
8863 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8864 return USERSHARE_PATH_NOT_ALLOWED;
8868 *pp_sharepath = sharepath;
8869 *pp_comment = comment;
8870 return USERSHARE_OK;
8873 /***************************************************************************
8874 Deal with a usershare file.
8877 -1 - Bad name, invalid contents.
8878 - service name already existed and not a usershare, problem
8879 with permissions to share directory etc.
8880 ***************************************************************************/
8882 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8884 SMB_STRUCT_STAT sbuf;
8885 SMB_STRUCT_STAT lsbuf;
8887 char *sharepath = NULL;
8888 char *comment = NULL;
8889 char *cp_service_name = NULL;
8890 char **lines = NULL;
8894 TALLOC_CTX *ctx = talloc_stackframe();
8895 struct security_descriptor *psd = NULL;
8896 bool guest_ok = false;
8897 char *canon_name = NULL;
8898 bool added_service = false;
8901 /* Ensure share name doesn't contain invalid characters. */
8902 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8903 DEBUG(0,("process_usershare_file: share name %s contains "
8904 "invalid characters (any of %s)\n",
8905 file_name, INVALID_SHARENAME_CHARS ));
8909 canon_name = canonicalize_servicename(ctx, file_name);
8914 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8919 /* Minimize the race condition by doing an lstat before we
8920 open and fstat. Ensure this isn't a symlink link. */
8922 if (sys_lstat(fname, &lsbuf, false) != 0) {
8923 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8924 fname, strerror(errno) ));
8928 /* This must be a regular file, not a symlink, directory or
8929 other strange filetype. */
8930 if (!check_usershare_stat(fname, &lsbuf)) {
8935 TDB_DATA data = dbwrap_fetch_bystring(
8936 ServiceHash, canon_name, canon_name);
8940 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8941 iService = *(int *)data.dptr;
8945 if (iService != -1 &&
8946 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8947 &lsbuf.st_ex_mtime) == 0) {
8948 /* Nothing changed - Mark valid and return. */
8949 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8951 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8956 /* Try and open the file read only - no symlinks allowed. */
8958 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8960 fd = sys_open(fname, O_RDONLY, 0);
8964 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8965 fname, strerror(errno) ));
8969 /* Now fstat to be *SURE* it's a regular file. */
8970 if (sys_fstat(fd, &sbuf, false) != 0) {
8972 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8973 fname, strerror(errno) ));
8977 /* Is it the same dev/inode as was lstated ? */
8978 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8980 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8981 "Symlink spoofing going on ?\n", fname ));
8985 /* This must be a regular file, not a symlink, directory or
8986 other strange filetype. */
8987 if (!check_usershare_stat(fname, &sbuf)) {
8991 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8994 if (lines == NULL) {
8995 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8996 fname, (unsigned int)sbuf.st_ex_uid ));
9000 if (parse_usershare_file(ctx, &sbuf, file_name,
9001 iService, lines, numlines, &sharepath,
9002 &comment, &cp_service_name,
9003 &psd, &guest_ok) != USERSHARE_OK) {
9007 /* Everything ok - add the service possibly using a template. */
9009 const struct loadparm_service *sp = &sDefault;
9010 if (snum_template != -1) {
9011 sp = ServicePtrs[snum_template];
9014 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
9015 DEBUG(0, ("process_usershare_file: Failed to add "
9016 "new service %s\n", cp_service_name));
9020 added_service = true;
9022 /* Read only is controlled by usershare ACL below. */
9023 ServicePtrs[iService]->bRead_only = false;
9026 /* Write the ACL of the new/modified share. */
9027 if (!set_share_security(canon_name, psd)) {
9028 DEBUG(0, ("process_usershare_file: Failed to set share "
9029 "security for user share %s\n",
9034 /* If from a template it may be marked invalid. */
9035 ServicePtrs[iService]->valid = true;
9037 /* Set the service as a valid usershare. */
9038 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9040 /* Set guest access. */
9041 if (lp_usershare_allow_guests()) {
9042 ServicePtrs[iService]->bGuest_ok = guest_ok;
9045 /* And note when it was loaded. */
9046 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
9047 string_set(&ServicePtrs[iService]->szPath, sharepath);
9048 string_set(&ServicePtrs[iService]->comment, comment);
9054 if (ret == -1 && iService != -1 && added_service) {
9055 lp_remove_service(iService);
9063 /***************************************************************************
9064 Checks if a usershare entry has been modified since last load.
9065 ***************************************************************************/
9067 static bool usershare_exists(int iService, struct timespec *last_mod)
9069 SMB_STRUCT_STAT lsbuf;
9070 const char *usersharepath = Globals.szUsersharePath;
9073 if (asprintf(&fname, "%s/%s",
9075 ServicePtrs[iService]->szService) < 0) {
9079 if (sys_lstat(fname, &lsbuf, false) != 0) {
9084 if (!S_ISREG(lsbuf.st_ex_mode)) {
9090 *last_mod = lsbuf.st_ex_mtime;
9094 /***************************************************************************
9095 Load a usershare service by name. Returns a valid servicenumber or -1.
9096 ***************************************************************************/
9098 int load_usershare_service(const char *servicename)
9100 SMB_STRUCT_STAT sbuf;
9101 const char *usersharepath = Globals.szUsersharePath;
9102 int max_user_shares = Globals.iUsershareMaxShares;
9103 int snum_template = -1;
9105 if (*usersharepath == 0 || max_user_shares == 0) {
9109 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9110 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9111 usersharepath, strerror(errno) ));
9115 if (!S_ISDIR(sbuf.st_ex_mode)) {
9116 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9122 * This directory must be owned by root, and have the 't' bit set.
9123 * It also must not be writable by "other".
9127 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9129 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9131 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9132 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9137 /* Ensure the template share exists if it's set. */
9138 if (Globals.szUsershareTemplateShare[0]) {
9139 /* We can't use lp_servicenumber here as we are recommending that
9140 template shares have -valid=false set. */
9141 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9142 if (ServicePtrs[snum_template]->szService &&
9143 strequal(ServicePtrs[snum_template]->szService,
9144 Globals.szUsershareTemplateShare)) {
9149 if (snum_template == -1) {
9150 DEBUG(0,("load_usershare_service: usershare template share %s "
9151 "does not exist.\n",
9152 Globals.szUsershareTemplateShare ));
9157 return process_usershare_file(usersharepath, servicename, snum_template);
9160 /***************************************************************************
9161 Load all user defined shares from the user share directory.
9162 We only do this if we're enumerating the share list.
9163 This is the function that can delete usershares that have
9165 ***************************************************************************/
9167 int load_usershare_shares(struct smbd_server_connection *sconn)
9170 SMB_STRUCT_STAT sbuf;
9171 SMB_STRUCT_DIRENT *de;
9172 int num_usershares = 0;
9173 int max_user_shares = Globals.iUsershareMaxShares;
9174 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9175 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9176 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9178 int snum_template = -1;
9179 const char *usersharepath = Globals.szUsersharePath;
9180 int ret = lp_numservices();
9182 if (max_user_shares == 0 || *usersharepath == '\0') {
9183 return lp_numservices();
9186 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9187 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9188 usersharepath, strerror(errno) ));
9193 * This directory must be owned by root, and have the 't' bit set.
9194 * It also must not be writable by "other".
9198 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9200 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9202 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9203 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9208 /* Ensure the template share exists if it's set. */
9209 if (Globals.szUsershareTemplateShare[0]) {
9210 /* We can't use lp_servicenumber here as we are recommending that
9211 template shares have -valid=false set. */
9212 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9213 if (ServicePtrs[snum_template]->szService &&
9214 strequal(ServicePtrs[snum_template]->szService,
9215 Globals.szUsershareTemplateShare)) {
9220 if (snum_template == -1) {
9221 DEBUG(0,("load_usershare_shares: usershare template share %s "
9222 "does not exist.\n",
9223 Globals.szUsershareTemplateShare ));
9228 /* Mark all existing usershares as pending delete. */
9229 for (iService = iNumServices - 1; iService >= 0; iService--) {
9230 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9231 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9235 dp = sys_opendir(usersharepath);
9237 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9238 usersharepath, strerror(errno) ));
9242 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9243 (de = sys_readdir(dp));
9244 num_dir_entries++ ) {
9246 const char *n = de->d_name;
9248 /* Ignore . and .. */
9250 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9256 /* Temporary file used when creating a share. */
9257 num_tmp_dir_entries++;
9260 /* Allow 20% tmp entries. */
9261 if (num_tmp_dir_entries > allowed_tmp_entries) {
9262 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9263 "in directory %s\n",
9264 num_tmp_dir_entries, usersharepath));
9268 r = process_usershare_file(usersharepath, n, snum_template);
9270 /* Update the services count. */
9272 if (num_usershares >= max_user_shares) {
9273 DEBUG(0,("load_usershare_shares: max user shares reached "
9274 "on file %s in directory %s\n",
9275 n, usersharepath ));
9278 } else if (r == -1) {
9279 num_bad_dir_entries++;
9282 /* Allow 20% bad entries. */
9283 if (num_bad_dir_entries > allowed_bad_entries) {
9284 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9285 "in directory %s\n",
9286 num_bad_dir_entries, usersharepath));
9290 /* Allow 20% bad entries. */
9291 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9292 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9293 "in directory %s\n",
9294 num_dir_entries, usersharepath));
9301 /* Sweep through and delete any non-refreshed usershares that are
9302 not currently in use. */
9303 for (iService = iNumServices - 1; iService >= 0; iService--) {
9304 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9305 if (conn_snum_used(sconn, iService)) {
9308 /* Remove from the share ACL db. */
9309 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9310 lp_servicename(iService) ));
9311 delete_share_security(lp_servicename(iService));
9312 free_service_byindex(iService);
9316 return lp_numservices();
9319 /********************************************************
9320 Destroy global resources allocated in this file
9321 ********************************************************/
9323 void gfree_loadparm(void)
9329 /* Free resources allocated to services */
9331 for ( i = 0; i < iNumServices; i++ ) {
9333 free_service_byindex(i);
9337 SAFE_FREE( ServicePtrs );
9340 /* Now release all resources allocated to global
9341 parameters and the default service */
9343 free_global_parameters();
9347 /***************************************************************************
9348 Allow client apps to specify that they are a client
9349 ***************************************************************************/
9350 void lp_set_in_client(bool b)
9356 /***************************************************************************
9357 Determine if we're running in a client app
9358 ***************************************************************************/
9359 bool lp_is_in_client(void)
9364 /***************************************************************************
9365 Load the services array from the services file. Return true on success,
9367 ***************************************************************************/
9369 static bool lp_load_ex(const char *pszFname,
9373 bool initialize_globals,
9374 bool allow_include_registry,
9375 bool allow_registry_shares)
9382 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9384 bInGlobalSection = true;
9385 bGlobalOnly = global_only;
9386 bAllowIncludeRegistry = allow_include_registry;
9388 init_globals(initialize_globals);
9392 if (save_defaults) {
9397 free_param_opts(&Globals.param_opt);
9399 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
9401 /* We get sections first, so have to start 'behind' to make up */
9404 if (lp_config_backend_is_file()) {
9405 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9406 current_user_info.domain,
9409 smb_panic("lp_load_ex: out of memory");
9412 add_to_file_list(pszFname, n2);
9414 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9417 /* finish up the last section */
9418 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9420 if (iServiceIndex >= 0) {
9421 bRetval = service_ok(iServiceIndex);
9425 if (lp_config_backend_is_registry()) {
9426 /* config backend changed to registry in config file */
9428 * We need to use this extra global variable here to
9429 * survive restart: init_globals uses this as a default
9430 * for ConfigBackend. Otherwise, init_globals would
9431 * send us into an endless loop here.
9433 config_backend = CONFIG_BACKEND_REGISTRY;
9435 DEBUG(1, ("lp_load_ex: changing to config backend "
9438 lp_kill_all_services();
9439 return lp_load_ex(pszFname, global_only, save_defaults,
9440 add_ipc, initialize_globals,
9441 allow_include_registry,
9442 allow_registry_shares);
9444 } else if (lp_config_backend_is_registry()) {
9445 bRetval = process_registry_globals();
9447 DEBUG(0, ("Illegal config backend given: %d\n",
9448 lp_config_backend()));
9452 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9453 bRetval = process_registry_shares();
9456 lp_add_auto_services(lp_auto_services());
9459 /* When 'restrict anonymous = 2' guest connections to ipc$
9461 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9462 if ( lp_enable_asu_support() ) {
9463 lp_add_ipc("ADMIN$", false);
9468 set_default_server_announce_type();
9469 set_allowed_client_auth();
9471 if (lp_security() == SEC_SHARE) {
9472 DEBUG(1, ("WARNING: The security=share option is deprecated\n"));
9473 } else if (lp_security() == SEC_SERVER) {
9474 DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
9477 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
9478 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
9479 lp_passwordserver()));
9484 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9485 /* if bWINSsupport is true and we are in the client */
9486 if (lp_is_in_client() && Globals.bWINSsupport) {
9487 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9492 fault_configure(smb_panic_s3);
9494 bAllowIncludeRegistry = true;
9499 bool lp_load(const char *pszFname,
9503 bool initialize_globals)
9505 return lp_load_ex(pszFname,
9510 true, /* allow_include_registry */
9511 false); /* allow_registry_shares*/
9514 bool lp_load_initial_only(const char *pszFname)
9516 return lp_load_ex(pszFname,
9517 true, /* global only */
9518 false, /* save_defaults */
9519 false, /* add_ipc */
9520 true, /* initialize_globals */
9521 false, /* allow_include_registry */
9522 false); /* allow_registry_shares*/
9525 bool lp_load_with_registry_shares(const char *pszFname,
9529 bool initialize_globals)
9531 return lp_load_ex(pszFname,
9536 true, /* allow_include_registry */
9537 true); /* allow_registry_shares*/
9540 /***************************************************************************
9541 Return the max number of services.
9542 ***************************************************************************/
9544 int lp_numservices(void)
9546 return (iNumServices);
9549 /***************************************************************************
9550 Display the contents of the services array in human-readable form.
9551 ***************************************************************************/
9553 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9558 defaults_saved = false;
9562 dump_a_service(&sDefault, f);
9564 for (iService = 0; iService < maxtoprint; iService++) {
9566 lp_dump_one(f, show_defaults, iService);
9570 /***************************************************************************
9571 Display the contents of one service in human-readable form.
9572 ***************************************************************************/
9574 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9577 if (ServicePtrs[snum]->szService[0] == '\0')
9579 dump_a_service(ServicePtrs[snum], f);
9583 /***************************************************************************
9584 Return the number of the service with the given name, or -1 if it doesn't
9585 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9586 getservicebyname()! This works ONLY if all services have been loaded, and
9587 does not copy the found service.
9588 ***************************************************************************/
9590 int lp_servicenumber(const char *pszServiceName)
9593 fstring serviceName;
9595 if (!pszServiceName) {
9596 return GLOBAL_SECTION_SNUM;
9599 for (iService = iNumServices - 1; iService >= 0; iService--) {
9600 if (VALID(iService) && ServicePtrs[iService]->szService) {
9602 * The substitution here is used to support %U is
9605 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9606 standard_sub_basic(get_current_username(),
9607 current_user_info.domain,
9608 serviceName,sizeof(serviceName));
9609 if (strequal(serviceName, pszServiceName)) {
9615 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9616 struct timespec last_mod;
9618 if (!usershare_exists(iService, &last_mod)) {
9619 /* Remove the share security tdb entry for it. */
9620 delete_share_security(lp_servicename(iService));
9621 /* Remove it from the array. */
9622 free_service_byindex(iService);
9623 /* Doesn't exist anymore. */
9624 return GLOBAL_SECTION_SNUM;
9627 /* Has it been modified ? If so delete and reload. */
9628 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9630 /* Remove it from the array. */
9631 free_service_byindex(iService);
9632 /* and now reload it. */
9633 iService = load_usershare_service(pszServiceName);
9638 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9639 return GLOBAL_SECTION_SNUM;
9645 bool share_defined(const char *service_name)
9647 return (lp_servicenumber(service_name) != -1);
9650 /*******************************************************************
9651 A useful volume label function.
9652 ********************************************************************/
9654 const char *volume_label(int snum)
9657 const char *label = lp_volume(snum);
9659 label = lp_servicename(snum);
9662 /* This returns a 33 byte guarenteed null terminated string. */
9663 ret = talloc_strndup(talloc_tos(), label, 32);
9670 /*******************************************************************
9671 Set the server type we will announce as via nmbd.
9672 ********************************************************************/
9674 static void set_default_server_announce_type(void)
9676 default_server_announce = 0;
9677 default_server_announce |= SV_TYPE_WORKSTATION;
9678 default_server_announce |= SV_TYPE_SERVER;
9679 default_server_announce |= SV_TYPE_SERVER_UNIX;
9681 /* note that the flag should be set only if we have a
9682 printer service but nmbd doesn't actually load the
9683 services so we can't tell --jerry */
9685 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9687 default_server_announce |= SV_TYPE_SERVER_NT;
9688 default_server_announce |= SV_TYPE_NT;
9690 switch (lp_server_role()) {
9691 case ROLE_DOMAIN_MEMBER:
9692 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9694 case ROLE_DOMAIN_PDC:
9695 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9697 case ROLE_DOMAIN_BDC:
9698 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9700 case ROLE_STANDALONE:
9704 if (lp_time_server())
9705 default_server_announce |= SV_TYPE_TIME_SOURCE;
9707 if (lp_host_msdfs())
9708 default_server_announce |= SV_TYPE_DFS_SERVER;
9711 /***********************************************************
9712 If we are PDC then prefer us as DMB
9713 ************************************************************/
9715 bool lp_domain_master(void)
9717 if (Globals.iDomainMaster == Auto)
9718 return (lp_server_role() == ROLE_DOMAIN_PDC);
9720 return (bool)Globals.iDomainMaster;
9723 /***********************************************************
9724 If we are PDC then prefer us as DMB
9725 ************************************************************/
9727 bool lp_domain_master_true_or_auto(void)
9729 if (Globals.iDomainMaster) /* auto or yes */
9735 /***********************************************************
9736 If we are DMB then prefer us as LMB
9737 ************************************************************/
9739 bool lp_preferred_master(void)
9741 if (Globals.iPreferredMaster == Auto)
9742 return (lp_local_master() && lp_domain_master());
9744 return (bool)Globals.iPreferredMaster;
9747 /*******************************************************************
9749 ********************************************************************/
9751 void lp_remove_service(int snum)
9753 ServicePtrs[snum]->valid = false;
9754 invalid_services[num_invalid_services++] = snum;
9757 /*******************************************************************
9759 ********************************************************************/
9761 void lp_copy_service(int snum, const char *new_name)
9763 do_section(new_name, NULL);
9765 snum = lp_servicenumber(new_name);
9767 lp_do_parameter(snum, "copy", lp_servicename(snum));
9772 /*******************************************************************
9773 Get the default server type we will announce as via nmbd.
9774 ********************************************************************/
9776 int lp_default_server_announce(void)
9778 return default_server_announce;
9781 /***********************************************************
9782 Set the global name resolution order (used in smbclient).
9783 ************************************************************/
9785 void lp_set_name_resolve_order(const char *new_order)
9787 string_set(&Globals.szNameResolveOrder, new_order);
9790 const char *lp_printername(int snum)
9792 const char *ret = _lp_printername(snum);
9793 if (ret == NULL || (ret != NULL && *ret == '\0'))
9794 ret = lp_const_servicename(snum);
9800 /***********************************************************
9801 Allow daemons such as winbindd to fix their logfile name.
9802 ************************************************************/
9804 void lp_set_logfile(const char *name)
9806 string_set(&Globals.szLogFile, name);
9807 debug_set_logfile(name);
9810 /*******************************************************************
9811 Return the max print jobs per queue.
9812 ********************************************************************/
9814 int lp_maxprintjobs(int snum)
9816 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9817 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9818 maxjobs = PRINT_MAX_JOBID - 1;
9823 const char *lp_printcapname(void)
9825 if ((Globals.szPrintcapname != NULL) &&
9826 (Globals.szPrintcapname[0] != '\0'))
9827 return Globals.szPrintcapname;
9829 if (sDefault.iPrinting == PRINT_CUPS) {
9837 if (sDefault.iPrinting == PRINT_BSD)
9838 return "/etc/printcap";
9840 return PRINTCAP_NAME;
9843 static uint32 spoolss_state;
9845 bool lp_disable_spoolss( void )
9847 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9848 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9850 return spoolss_state == SVCCTL_STOPPED ? true : false;
9853 void lp_set_spoolss_state( uint32 state )
9855 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9857 spoolss_state = state;
9860 uint32 lp_get_spoolss_state( void )
9862 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9865 /*******************************************************************
9866 Ensure we don't use sendfile if server smb signing is active.
9867 ********************************************************************/
9869 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9871 bool sign_active = false;
9873 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9874 if (get_Protocol() < PROTOCOL_NT1) {
9877 if (signing_state) {
9878 sign_active = smb_signing_is_active(signing_state);
9880 return (_lp_use_sendfile(snum) &&
9881 (get_remote_arch() != RA_WIN95) &&
9885 /*******************************************************************
9886 Turn off sendfile if we find the underlying OS doesn't support it.
9887 ********************************************************************/
9889 void set_use_sendfile(int snum, bool val)
9891 if (LP_SNUM_OK(snum))
9892 ServicePtrs[snum]->bUseSendfile = val;
9894 sDefault.bUseSendfile = val;
9897 /*******************************************************************
9898 Turn off storing DOS attributes if this share doesn't support it.
9899 ********************************************************************/
9901 void set_store_dos_attributes(int snum, bool val)
9903 if (!LP_SNUM_OK(snum))
9905 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9908 void lp_set_mangling_method(const char *new_method)
9910 string_set(&Globals.szManglingMethod, new_method);
9913 /*******************************************************************
9914 Global state for POSIX pathname processing.
9915 ********************************************************************/
9917 static bool posix_pathnames;
9919 bool lp_posix_pathnames(void)
9921 return posix_pathnames;
9924 /*******************************************************************
9925 Change everything needed to ensure POSIX pathname processing (currently
9927 ********************************************************************/
9929 void lp_set_posix_pathnames(void)
9931 posix_pathnames = true;
9934 /*******************************************************************
9935 Global state for POSIX lock processing - CIFS unix extensions.
9936 ********************************************************************/
9938 bool posix_default_lock_was_set;
9939 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9941 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9943 if (posix_default_lock_was_set) {
9944 return posix_cifsx_locktype;
9946 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9950 /*******************************************************************
9951 ********************************************************************/
9953 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9955 posix_default_lock_was_set = true;
9956 posix_cifsx_locktype = val;
9959 int lp_min_receive_file_size(void)
9961 if (Globals.iminreceivefile < 0) {
9964 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9967 /*******************************************************************
9968 If socket address is an empty character string, it is necessary to
9969 define it as "0.0.0.0".
9970 ********************************************************************/
9972 const char *lp_socket_address(void)
9974 char *sock_addr = Globals.szSocketAddress;
9976 if (sock_addr[0] == '\0'){
9977 string_set(&Globals.szSocketAddress, "0.0.0.0");
9979 return Globals.szSocketAddress;
9982 void lp_set_passdb_backend(const char *backend)
9984 string_set(&Globals.szPassdbBackend, backend);
9987 /*******************************************************************
9988 Safe wide links checks.
9989 This helper function always verify the validity of wide links,
9990 even after a configuration file reload.
9991 ********************************************************************/
9993 static bool lp_widelinks_internal(int snum)
9995 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9996 sDefault.bWidelinks);
9999 void widelinks_warning(int snum)
10001 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10002 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10003 "These parameters are incompatible. "
10004 "Wide links will be disabled for this share.\n",
10005 lp_servicename(snum) ));
10009 bool lp_widelinks(int snum)
10011 /* wide links is always incompatible with unix extensions */
10012 if (lp_unix_extensions()) {
10016 return lp_widelinks_internal(snum);
10019 bool lp_writeraw(void)
10021 if (lp_async_smb_echo_handler()) {
10024 return _lp_writeraw();
10027 bool lp_readraw(void)
10029 if (lp_async_smb_echo_handler()) {
10032 return _lp_readraw();