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"
64 #include "../librpc/gen_ndr/svcctl.h"
66 #include "smb_signing.h"
70 #ifdef HAVE_SYS_SYSCTL_H
71 #include <sys/sysctl.h>
74 #ifdef HAVE_HTTPCONNECTENCRYPT
75 #include <cups/http.h>
80 extern userdom_struct current_user_info;
83 #define GLOBAL_NAME "global"
87 #define PRINTERS_NAME "printers"
91 #define HOMES_NAME "homes"
94 /* the special value for the include parameter
95 * to be interpreted not as a file name but to
96 * trigger loading of the global smb.conf options
98 #ifndef INCLUDE_REGISTRY_NAME
99 #define INCLUDE_REGISTRY_NAME "registry"
102 static bool in_client = False; /* Not in the client by default */
103 static struct smbconf_csn conf_last_csn;
105 #define CONFIG_BACKEND_FILE 0
106 #define CONFIG_BACKEND_REGISTRY 1
108 static int config_backend = CONFIG_BACKEND_FILE;
110 /* some helpful bits */
111 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
112 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
114 #define USERSHARE_VALID 1
115 #define USERSHARE_PENDING_DELETE 2
117 static bool defaults_saved = False;
119 struct param_opt_struct {
120 struct param_opt_struct *prev, *next;
128 * This structure describes global (ie., server-wide) parameters.
130 struct loadparm_global {
135 char *szPrintcapname;
136 char *szAddPortCommand;
137 char *szEnumPortsCommand;
138 char *szAddPrinterCommand;
139 char *szDeletePrinterCommand;
140 char *szOs2DriverMap;
146 char *szDefaultService;
150 char *szServerString;
151 char *szAutoServices;
152 char *szPasswdProgram;
156 char *szSMBPasswdFile;
158 char *szPassdbBackend;
159 char **szPreloadModules;
160 char *szPasswordServer;
161 char *szSocketOptions;
165 char *szAfsUsernameMap;
166 int iAfsTokenLifetime;
167 char *szLogNtTokenCommand;
173 char **szWINSservers;
175 char *szRemoteAnnounce;
176 char *szRemoteBrowseSync;
177 char *szSocketAddress;
178 bool bNmbdBindExplicitBroadcast;
179 char *szNISHomeMapName;
182 char **szNetbiosAliases;
183 char *szNetbiosScope;
184 char *szNameResolveOrder;
186 char *szAddUserScript;
187 char *szRenameUserScript;
188 char *szDelUserScript;
189 char *szAddGroupScript;
190 char *szDelGroupScript;
191 char *szAddUserToGroupScript;
192 char *szDelUserFromGroupScript;
193 char *szSetPrimaryGroupScript;
194 char *szAddMachineScript;
195 char *szShutdownScript;
196 char *szAbortShutdownScript;
197 char *szUsernameMapScript;
198 int iUsernameMapCacheTime;
199 char *szCheckPasswordScript;
206 bool bPassdbExpandExplicit;
207 int AlgorithmicRidBase;
208 char *szTemplateHomedir;
209 char *szTemplateShell;
210 char *szWinbindSeparator;
211 bool bWinbindEnumUsers;
212 bool bWinbindEnumGroups;
213 bool bWinbindUseDefaultDomain;
214 bool bWinbindTrustedDomainsOnly;
215 bool bWinbindNestedGroups;
216 int winbind_expand_groups;
217 bool bWinbindRefreshTickets;
218 bool bWinbindOfflineLogon;
219 bool bWinbindNormalizeNames;
220 bool bWinbindRpcOnly;
221 bool bCreateKrb5Conf;
222 int winbindMaxDomainConnections;
223 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;
314 bool bObeyPamRestrictions;
316 int PrintcapCacheTime;
317 bool bLargeReadwrite;
324 bool bBindInterfacesOnly;
325 bool bPamPasswordChange;
326 bool bUnixPasswdSync;
327 bool bPasswdChatDebug;
328 int iPasswdChatTimeout;
332 bool bNTStatusSupport;
334 int iMaxStatCacheSize;
336 bool bAllowTrustedDomains;
340 bool bClientLanManAuth;
341 bool bClientNTLMv2Auth;
342 bool bClientPlaintextAuth;
343 bool bClientUseSpnego;
344 bool client_use_spnego_principal;
345 bool send_spnego_principal;
346 bool bDebugPrefixTimestamp;
347 bool bDebugHiresTimestamp;
351 bool bEnableCoreFiles;
354 bool bHostnameLookups;
355 bool bUnixExtensions;
356 bool bDisableNetbios;
357 char * szDedicatedKeytabFile;
359 bool bDeferSharingViolations;
360 bool bEnablePrivileges;
362 bool bUsershareOwnerOnly;
363 bool bUsershareAllowGuests;
364 bool bRegistryShares;
365 int restrict_anonymous;
366 int name_cache_timeout;
369 int client_ldap_sasl_wrapping;
370 int iUsershareMaxShares;
372 int iIdmapNegativeCacheTime;
374 bool bLogWriteableFilesOnExit;
377 struct param_opt_struct *param_opt;
378 int cups_connection_timeout;
379 char *szSMBPerfcountModule;
380 bool bMapUntrustedToDomain;
381 bool bAsyncSMBEchoHandler;
382 bool bMulticastDnsRegister;
386 int ismb2_max_credits;
390 static struct loadparm_global Globals;
393 * This structure describes a single service.
395 struct loadparm_service {
399 struct timespec usershare_last_mod;
403 char **szInvalidUsers;
411 char *szRootPostExec;
413 char *szPrintcommand;
416 char *szLppausecommand;
417 char *szLpresumecommand;
418 char *szQueuepausecommand;
419 char *szQueueresumecommand;
421 char *szPrintjobUsername;
429 char *szVetoOplockFiles;
435 char **printer_admin;
440 char *szAioWriteBehind;
444 int iMaxReportedPrintJobs;
447 int iCreate_force_mode;
449 int iSecurity_force_mode;
452 int iDir_Security_mask;
453 int iDir_Security_force_mode;
457 int iOplockContentionLimit;
462 bool bRootpreexecClose;
465 bool bShortCasePreserve;
467 bool bHideSpecialFiles;
468 bool bHideUnReadable;
469 bool bHideUnWriteableFiles;
471 bool bAccessBasedShareEnum;
476 bool bAdministrative_share;
479 bool bPrintNotifyBackchannel;
483 bool bStoreDosAttributes;
496 bool bStrictAllocate;
499 struct bitmap *copymap;
500 bool bDeleteReadonly;
502 bool bDeleteVetoFiles;
505 bool bDosFiletimeResolution;
506 bool bFakeDirCreateTimes;
512 bool bUseClientDriver;
513 bool bDefaultDevmode;
514 bool bForcePrintername;
516 bool bForceUnknownAclUser;
519 bool bMap_acl_inherit;
522 bool bAclCheckPermissions;
523 bool bAclMapFullControl;
524 bool bAclGroupControl;
526 bool bKernelChangeNotify;
527 int iallocation_roundup_size;
531 int iDirectoryNameCacheSize;
533 struct param_opt_struct *param_opt;
535 char dummy[3]; /* for alignment */
539 /* This is a default service used to prime a services structure */
540 static struct loadparm_service sDefault = {
542 False, /* not autoloaded */
543 0, /* not a usershare */
544 {0, }, /* No last mod time */
545 NULL, /* szService */
547 NULL, /* szUsername */
548 NULL, /* szInvalidUsers */
549 NULL, /* szValidUsers */
550 NULL, /* szAdminUsers */
552 NULL, /* szInclude */
553 NULL, /* szPreExec */
554 NULL, /* szPostExec */
555 NULL, /* szRootPreExec */
556 NULL, /* szRootPostExec */
557 NULL, /* szCupsOptions */
558 NULL, /* szPrintcommand */
559 NULL, /* szLpqcommand */
560 NULL, /* szLprmcommand */
561 NULL, /* szLppausecommand */
562 NULL, /* szLpresumecommand */
563 NULL, /* szQueuepausecommand */
564 NULL, /* szQueueresumecommand */
565 NULL, /* szPrintername */
566 NULL, /* szPrintjobUsername */
567 NULL, /* szDontdescend */
568 NULL, /* szHostsallow */
569 NULL, /* szHostsdeny */
570 NULL, /* szMagicScript */
571 NULL, /* szMagicOutput */
572 NULL, /* szVetoFiles */
573 NULL, /* szHideFiles */
574 NULL, /* szVetoOplockFiles */
576 NULL, /* force user */
577 NULL, /* force group */
579 NULL, /* writelist */
580 NULL, /* printer admin */
583 NULL, /* vfs objects */
584 NULL, /* szMSDfsProxy */
585 NULL, /* szAioWriteBehind */
587 0, /* iMinPrintSpace */
588 1000, /* iMaxPrintJobs */
589 0, /* iMaxReportedPrintJobs */
590 0, /* iWriteCacheSize */
591 0744, /* iCreate_mask */
592 0000, /* iCreate_force_mode */
593 0777, /* iSecurity_mask */
594 0, /* iSecurity_force_mode */
595 0755, /* iDir_mask */
596 0000, /* iDir_force_mode */
597 0777, /* iDir_Security_mask */
598 0, /* iDir_Security_force_mode */
599 0, /* iMaxConnections */
600 CASE_LOWER, /* iDefaultCase */
601 DEFAULT_PRINTING, /* iPrinting */
602 2, /* iOplockContentionLimit */
604 1024, /* iBlock_size */
605 0, /* iDfreeCacheTime */
606 False, /* bPreexecClose */
607 False, /* bRootpreexecClose */
608 Auto, /* case sensitive */
609 True, /* case preserve */
610 True, /* short case preserve */
611 True, /* bHideDotFiles */
612 False, /* bHideSpecialFiles */
613 False, /* bHideUnReadable */
614 False, /* bHideUnWriteableFiles */
615 True, /* bBrowseable */
616 False, /* bAccessBasedShareEnum */
617 True, /* bAvailable */
618 True, /* bRead_only */
619 True, /* bNo_set_dir */
620 False, /* bGuest_only */
621 False, /* bAdministrative_share */
622 False, /* bGuest_ok */
623 False, /* bPrint_ok */
624 True, /* bPrintNotifyBackchannel */
625 False, /* bMap_system */
626 False, /* bMap_hidden */
627 True, /* bMap_archive */
628 False, /* bStoreDosAttributes */
629 False, /* bDmapiSupport */
631 Auto, /* iStrictLocking */
632 True, /* bPosixLocking */
633 True, /* bShareModes */
635 True, /* bLevel2OpLocks */
636 False, /* bOnlyUser */
637 True, /* bMangledNames */
638 false, /* bWidelinks */
639 True, /* bSymlinks */
640 False, /* bSyncAlways */
641 False, /* bStrictAllocate */
642 False, /* bStrictSync */
643 '~', /* magic char */
645 False, /* bDeleteReadonly */
646 False, /* bFakeOplocks */
647 False, /* bDeleteVetoFiles */
648 False, /* bDosFilemode */
649 True, /* bDosFiletimes */
650 False, /* bDosFiletimeResolution */
651 False, /* bFakeDirCreateTimes */
652 True, /* bBlockingLocks */
653 False, /* bInheritPerms */
654 False, /* bInheritACLS */
655 False, /* bInheritOwner */
656 False, /* bMSDfsRoot */
657 False, /* bUseClientDriver */
658 True, /* bDefaultDevmode */
659 False, /* bForcePrintername */
660 True, /* bNTAclSupport */
661 False, /* bForceUnknownAclUser */
662 False, /* bUseSendfile */
663 False, /* bProfileAcls */
664 False, /* bMap_acl_inherit */
665 False, /* bAfs_Share */
666 False, /* bEASupport */
667 True, /* bAclCheckPermissions */
668 True, /* bAclMapFullControl */
669 False, /* bAclGroupControl */
670 True, /* bChangeNotify */
671 True, /* bKernelChangeNotify */
672 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
673 0, /* iAioReadSize */
674 0, /* iAioWriteSize */
675 MAP_READONLY_YES, /* iMap_readonly */
676 #ifdef BROKEN_DIRECTORY_HANDLING
677 0, /* iDirectoryNameCacheSize */
679 100, /* iDirectoryNameCacheSize */
681 Auto, /* ismb_encrypt */
682 NULL, /* Parametric options */
687 /* local variables */
688 static struct loadparm_service **ServicePtrs = NULL;
689 static int iNumServices = 0;
690 static int iServiceIndex = 0;
691 static struct db_context *ServiceHash;
692 static int *invalid_services = NULL;
693 static int num_invalid_services = 0;
694 static bool bInGlobalSection = True;
695 static bool bGlobalOnly = False;
696 static int default_server_announce;
698 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
700 /* prototypes for the special type handlers */
701 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
702 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
703 static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr);
704 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
705 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
706 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
707 static bool handle_realm( int snum, const char *pszParmValue, char **ptr );
708 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
709 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
710 static bool handle_dos_charset( int snum, const char *pszParmValue, char **ptr );
711 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
712 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
714 static void set_default_server_announce_type(void);
715 static void set_allowed_client_auth(void);
717 static void add_to_file_list(const char *fname, const char *subfname);
718 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
720 static const struct enum_list enum_protocol[] = {
721 {PROTOCOL_SMB2, "SMB2"},
722 {PROTOCOL_NT1, "NT1"},
723 {PROTOCOL_LANMAN2, "LANMAN2"},
724 {PROTOCOL_LANMAN1, "LANMAN1"},
725 {PROTOCOL_CORE, "CORE"},
726 {PROTOCOL_COREPLUS, "COREPLUS"},
727 {PROTOCOL_COREPLUS, "CORE+"},
731 static const struct enum_list enum_security[] = {
732 {SEC_SHARE, "SHARE"},
734 {SEC_SERVER, "SERVER"},
735 {SEC_DOMAIN, "DOMAIN"},
742 static const struct enum_list enum_printing[] = {
743 {PRINT_SYSV, "sysv"},
745 {PRINT_HPUX, "hpux"},
749 {PRINT_LPRNG, "lprng"},
750 {PRINT_CUPS, "cups"},
751 {PRINT_IPRINT, "iprint"},
753 {PRINT_LPROS2, "os2"},
754 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
755 {PRINT_TEST, "test"},
757 #endif /* DEVELOPER */
761 static const struct enum_list enum_ldap_sasl_wrapping[] = {
763 {ADS_AUTH_SASL_SIGN, "sign"},
764 {ADS_AUTH_SASL_SEAL, "seal"},
768 static const struct enum_list enum_ldap_ssl[] = {
769 {LDAP_SSL_OFF, "no"},
770 {LDAP_SSL_OFF, "off"},
771 {LDAP_SSL_START_TLS, "start tls"},
772 {LDAP_SSL_START_TLS, "start_tls"},
776 /* LDAP Dereferencing Alias types */
777 #define SAMBA_LDAP_DEREF_NEVER 0
778 #define SAMBA_LDAP_DEREF_SEARCHING 1
779 #define SAMBA_LDAP_DEREF_FINDING 2
780 #define SAMBA_LDAP_DEREF_ALWAYS 3
782 static const struct enum_list enum_ldap_deref[] = {
783 {SAMBA_LDAP_DEREF_NEVER, "never"},
784 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
785 {SAMBA_LDAP_DEREF_FINDING, "finding"},
786 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
790 static const struct enum_list enum_ldap_passwd_sync[] = {
791 {LDAP_PASSWD_SYNC_OFF, "no"},
792 {LDAP_PASSWD_SYNC_OFF, "off"},
793 {LDAP_PASSWD_SYNC_ON, "yes"},
794 {LDAP_PASSWD_SYNC_ON, "on"},
795 {LDAP_PASSWD_SYNC_ONLY, "only"},
799 static const struct enum_list enum_map_readonly[] = {
800 {MAP_READONLY_NO, "no"},
801 {MAP_READONLY_NO, "false"},
802 {MAP_READONLY_NO, "0"},
803 {MAP_READONLY_YES, "yes"},
804 {MAP_READONLY_YES, "true"},
805 {MAP_READONLY_YES, "1"},
806 {MAP_READONLY_PERMISSIONS, "permissions"},
807 {MAP_READONLY_PERMISSIONS, "perms"},
811 static const struct enum_list enum_case[] = {
812 {CASE_LOWER, "lower"},
813 {CASE_UPPER, "upper"},
819 static const struct enum_list enum_bool_auto[] = {
830 static const struct enum_list enum_csc_policy[] = {
831 {CSC_POLICY_MANUAL, "manual"},
832 {CSC_POLICY_DOCUMENTS, "documents"},
833 {CSC_POLICY_PROGRAMS, "programs"},
834 {CSC_POLICY_DISABLE, "disable"},
838 /* SMB signing types. */
839 static const struct enum_list enum_smb_signing_vals[] = {
851 {Required, "required"},
852 {Required, "mandatory"},
854 {Required, "forced"},
855 {Required, "enforced"},
859 /* ACL compatibility options. */
860 static const struct enum_list enum_acl_compat_vals[] = {
861 { ACL_COMPAT_AUTO, "auto" },
862 { ACL_COMPAT_WINNT, "winnt" },
863 { ACL_COMPAT_WIN2K, "win2k" },
868 Do you want session setups at user level security with a invalid
869 password to be rejected or allowed in as guest? WinNT rejects them
870 but it can be a pain as it means "net view" needs to use a password
872 You have 3 choices in the setting of map_to_guest:
874 "Never" means session setups with an invalid password
875 are rejected. This is the default.
877 "Bad User" means session setups with an invalid password
878 are rejected, unless the username does not exist, in which case it
879 is treated as a guest login
881 "Bad Password" means session setups with an invalid password
882 are treated as a guest login
884 Note that map_to_guest only has an effect in user or server
888 static const struct enum_list enum_map_to_guest[] = {
889 {NEVER_MAP_TO_GUEST, "Never"},
890 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
891 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
892 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
896 /* Config backend options */
898 static const struct enum_list enum_config_backend[] = {
899 {CONFIG_BACKEND_FILE, "file"},
900 {CONFIG_BACKEND_REGISTRY, "registry"},
904 /* ADS kerberos ticket verification options */
906 static const struct enum_list enum_kerberos_method[] = {
907 {KERBEROS_VERIFY_SECRETS, "default"},
908 {KERBEROS_VERIFY_SECRETS, "secrets only"},
909 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
910 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
911 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
915 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
917 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
918 * screen in SWAT. This is used to exclude parameters as well as to squash all
919 * parameters that have been duplicated by pseudonyms.
921 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
922 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
923 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
926 * NOTE2: Handling of duplicated (synonym) parameters:
927 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
928 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
929 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
930 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
933 static struct parm_struct parm_table[] = {
934 {N_("Base Options"), P_SEP, P_SEPARATOR},
937 .label = "dos charset",
940 .ptr = &Globals.dos_charset,
941 .special = handle_dos_charset,
943 .flags = FLAG_ADVANCED
946 .label = "unix charset",
949 .ptr = &Globals.unix_charset,
950 .special = handle_charset,
952 .flags = FLAG_ADVANCED
958 .ptr = &sDefault.comment,
961 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
967 .ptr = &sDefault.szPath,
970 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
973 .label = "directory",
976 .ptr = &sDefault.szPath,
982 .label = "workgroup",
985 .ptr = &Globals.szWorkgroup,
988 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
994 .ptr = &Globals.szRealm,
995 .special = handle_realm,
997 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1000 .label = "netbios name",
1002 .p_class = P_GLOBAL,
1003 .ptr = &Globals.szNetbiosName,
1006 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1009 .label = "netbios aliases",
1011 .p_class = P_GLOBAL,
1012 .ptr = &Globals.szNetbiosAliases,
1013 .special = handle_netbios_aliases,
1015 .flags = FLAG_ADVANCED,
1018 .label = "netbios scope",
1020 .p_class = P_GLOBAL,
1021 .ptr = &Globals.szNetbiosScope,
1024 .flags = FLAG_ADVANCED,
1027 .label = "server string",
1029 .p_class = P_GLOBAL,
1030 .ptr = &Globals.szServerString,
1033 .flags = FLAG_BASIC | FLAG_ADVANCED,
1036 .label = "interfaces",
1038 .p_class = P_GLOBAL,
1039 .ptr = &Globals.szInterfaces,
1042 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1045 .label = "bind interfaces only",
1047 .p_class = P_GLOBAL,
1048 .ptr = &Globals.bBindInterfacesOnly,
1051 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1054 .label = "config backend",
1056 .p_class = P_GLOBAL,
1057 .ptr = &Globals.ConfigBackend,
1059 .enum_list = enum_config_backend,
1060 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1063 {N_("Security Options"), P_SEP, P_SEPARATOR},
1066 .label = "security",
1068 .p_class = P_GLOBAL,
1069 .ptr = &Globals.security,
1071 .enum_list = enum_security,
1072 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1075 .label = "auth methods",
1077 .p_class = P_GLOBAL,
1078 .ptr = &Globals.AuthMethods,
1081 .flags = FLAG_ADVANCED,
1084 .label = "encrypt passwords",
1086 .p_class = P_GLOBAL,
1087 .ptr = &Globals.bEncryptPasswords,
1090 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1093 .label = "client schannel",
1095 .p_class = P_GLOBAL,
1096 .ptr = &Globals.clientSchannel,
1098 .enum_list = enum_bool_auto,
1099 .flags = FLAG_BASIC | FLAG_ADVANCED,
1102 .label = "server schannel",
1104 .p_class = P_GLOBAL,
1105 .ptr = &Globals.serverSchannel,
1107 .enum_list = enum_bool_auto,
1108 .flags = FLAG_BASIC | FLAG_ADVANCED,
1111 .label = "allow trusted domains",
1113 .p_class = P_GLOBAL,
1114 .ptr = &Globals.bAllowTrustedDomains,
1117 .flags = FLAG_ADVANCED,
1120 .label = "map to guest",
1122 .p_class = P_GLOBAL,
1123 .ptr = &Globals.map_to_guest,
1125 .enum_list = enum_map_to_guest,
1126 .flags = FLAG_ADVANCED,
1129 .label = "null passwords",
1131 .p_class = P_GLOBAL,
1132 .ptr = &Globals.bNullPasswords,
1135 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1138 .label = "obey pam restrictions",
1140 .p_class = P_GLOBAL,
1141 .ptr = &Globals.bObeyPamRestrictions,
1144 .flags = FLAG_ADVANCED,
1147 .label = "password server",
1149 .p_class = P_GLOBAL,
1150 .ptr = &Globals.szPasswordServer,
1153 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1156 .label = "smb passwd file",
1158 .p_class = P_GLOBAL,
1159 .ptr = &Globals.szSMBPasswdFile,
1162 .flags = FLAG_ADVANCED,
1165 .label = "private dir",
1167 .p_class = P_GLOBAL,
1168 .ptr = &Globals.szPrivateDir,
1171 .flags = FLAG_ADVANCED,
1174 .label = "passdb backend",
1176 .p_class = P_GLOBAL,
1177 .ptr = &Globals.szPassdbBackend,
1180 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1183 .label = "algorithmic rid base",
1185 .p_class = P_GLOBAL,
1186 .ptr = &Globals.AlgorithmicRidBase,
1189 .flags = FLAG_ADVANCED,
1192 .label = "root directory",
1194 .p_class = P_GLOBAL,
1195 .ptr = &Globals.szRootdir,
1198 .flags = FLAG_ADVANCED,
1201 .label = "root dir",
1203 .p_class = P_GLOBAL,
1204 .ptr = &Globals.szRootdir,
1212 .p_class = P_GLOBAL,
1213 .ptr = &Globals.szRootdir,
1219 .label = "guest account",
1221 .p_class = P_GLOBAL,
1222 .ptr = &Globals.szGuestaccount,
1225 .flags = FLAG_BASIC | FLAG_ADVANCED,
1228 .label = "enable privileges",
1230 .p_class = P_GLOBAL,
1231 .ptr = &Globals.bEnablePrivileges,
1234 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1238 .label = "pam password change",
1240 .p_class = P_GLOBAL,
1241 .ptr = &Globals.bPamPasswordChange,
1244 .flags = FLAG_ADVANCED,
1247 .label = "passwd program",
1249 .p_class = P_GLOBAL,
1250 .ptr = &Globals.szPasswdProgram,
1253 .flags = FLAG_ADVANCED,
1256 .label = "passwd chat",
1258 .p_class = P_GLOBAL,
1259 .ptr = &Globals.szPasswdChat,
1262 .flags = FLAG_ADVANCED,
1265 .label = "passwd chat debug",
1267 .p_class = P_GLOBAL,
1268 .ptr = &Globals.bPasswdChatDebug,
1271 .flags = FLAG_ADVANCED,
1274 .label = "passwd chat timeout",
1276 .p_class = P_GLOBAL,
1277 .ptr = &Globals.iPasswdChatTimeout,
1280 .flags = FLAG_ADVANCED,
1283 .label = "check password script",
1285 .p_class = P_GLOBAL,
1286 .ptr = &Globals.szCheckPasswordScript,
1289 .flags = FLAG_ADVANCED,
1292 .label = "username map",
1294 .p_class = P_GLOBAL,
1295 .ptr = &Globals.szUsernameMap,
1298 .flags = FLAG_ADVANCED,
1301 .label = "password level",
1303 .p_class = P_GLOBAL,
1304 .ptr = &Globals.pwordlevel,
1307 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1310 .label = "username level",
1312 .p_class = P_GLOBAL,
1313 .ptr = &Globals.unamelevel,
1316 .flags = FLAG_ADVANCED,
1319 .label = "unix password sync",
1321 .p_class = P_GLOBAL,
1322 .ptr = &Globals.bUnixPasswdSync,
1325 .flags = FLAG_ADVANCED,
1328 .label = "restrict anonymous",
1330 .p_class = P_GLOBAL,
1331 .ptr = &Globals.restrict_anonymous,
1334 .flags = FLAG_ADVANCED,
1337 .label = "lanman auth",
1339 .p_class = P_GLOBAL,
1340 .ptr = &Globals.bLanmanAuth,
1343 .flags = FLAG_ADVANCED,
1346 .label = "ntlm auth",
1348 .p_class = P_GLOBAL,
1349 .ptr = &Globals.bNTLMAuth,
1352 .flags = FLAG_ADVANCED,
1355 .label = "client NTLMv2 auth",
1357 .p_class = P_GLOBAL,
1358 .ptr = &Globals.bClientNTLMv2Auth,
1361 .flags = FLAG_ADVANCED,
1364 .label = "client lanman auth",
1366 .p_class = P_GLOBAL,
1367 .ptr = &Globals.bClientLanManAuth,
1370 .flags = FLAG_ADVANCED,
1373 .label = "client plaintext auth",
1375 .p_class = P_GLOBAL,
1376 .ptr = &Globals.bClientPlaintextAuth,
1379 .flags = FLAG_ADVANCED,
1382 .label = "client use spnego principal",
1384 .p_class = P_GLOBAL,
1385 .ptr = &Globals.client_use_spnego_principal,
1388 .flags = FLAG_ADVANCED,
1391 .label = "send spnego principal",
1393 .p_class = P_GLOBAL,
1394 .ptr = &Globals.send_spnego_principal,
1397 .flags = FLAG_ADVANCED,
1400 .label = "username",
1403 .ptr = &sDefault.szUsername,
1406 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1412 .ptr = &sDefault.szUsername,
1421 .ptr = &sDefault.szUsername,
1427 .label = "invalid users",
1430 .ptr = &sDefault.szInvalidUsers,
1433 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1436 .label = "valid users",
1439 .ptr = &sDefault.szValidUsers,
1442 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1445 .label = "admin users",
1448 .ptr = &sDefault.szAdminUsers,
1451 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1454 .label = "read list",
1457 .ptr = &sDefault.readlist,
1460 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1463 .label = "write list",
1466 .ptr = &sDefault.writelist,
1469 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1472 .label = "printer admin",
1475 .ptr = &sDefault.printer_admin,
1478 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1481 .label = "force user",
1484 .ptr = &sDefault.force_user,
1487 .flags = FLAG_ADVANCED | FLAG_SHARE,
1490 .label = "force group",
1493 .ptr = &sDefault.force_group,
1496 .flags = FLAG_ADVANCED | FLAG_SHARE,
1502 .ptr = &sDefault.force_group,
1505 .flags = FLAG_ADVANCED,
1508 .label = "read only",
1511 .ptr = &sDefault.bRead_only,
1514 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1517 .label = "write ok",
1520 .ptr = &sDefault.bRead_only,
1526 .label = "writeable",
1529 .ptr = &sDefault.bRead_only,
1535 .label = "writable",
1538 .ptr = &sDefault.bRead_only,
1544 .label = "acl check permissions",
1547 .ptr = &sDefault.bAclCheckPermissions,
1550 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1553 .label = "acl group control",
1556 .ptr = &sDefault.bAclGroupControl,
1559 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1562 .label = "acl map full control",
1565 .ptr = &sDefault.bAclMapFullControl,
1568 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1571 .label = "create mask",
1574 .ptr = &sDefault.iCreate_mask,
1577 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1580 .label = "create mode",
1583 .ptr = &sDefault.iCreate_mask,
1589 .label = "force create mode",
1592 .ptr = &sDefault.iCreate_force_mode,
1595 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1598 .label = "security mask",
1601 .ptr = &sDefault.iSecurity_mask,
1604 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1607 .label = "force security mode",
1610 .ptr = &sDefault.iSecurity_force_mode,
1613 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1616 .label = "directory mask",
1619 .ptr = &sDefault.iDir_mask,
1622 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1625 .label = "directory mode",
1628 .ptr = &sDefault.iDir_mask,
1631 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1634 .label = "force directory mode",
1637 .ptr = &sDefault.iDir_force_mode,
1640 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1643 .label = "directory security mask",
1646 .ptr = &sDefault.iDir_Security_mask,
1649 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1652 .label = "force directory security mode",
1655 .ptr = &sDefault.iDir_Security_force_mode,
1658 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1661 .label = "force unknown acl user",
1664 .ptr = &sDefault.bForceUnknownAclUser,
1667 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1670 .label = "inherit permissions",
1673 .ptr = &sDefault.bInheritPerms,
1676 .flags = FLAG_ADVANCED | FLAG_SHARE,
1679 .label = "inherit acls",
1682 .ptr = &sDefault.bInheritACLS,
1685 .flags = FLAG_ADVANCED | FLAG_SHARE,
1688 .label = "inherit owner",
1691 .ptr = &sDefault.bInheritOwner,
1694 .flags = FLAG_ADVANCED | FLAG_SHARE,
1697 .label = "guest only",
1700 .ptr = &sDefault.bGuest_only,
1703 .flags = FLAG_ADVANCED | FLAG_SHARE,
1706 .label = "only guest",
1709 .ptr = &sDefault.bGuest_only,
1715 .label = "administrative share",
1718 .ptr = &sDefault.bAdministrative_share,
1721 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1725 .label = "guest ok",
1728 .ptr = &sDefault.bGuest_ok,
1731 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1737 .ptr = &sDefault.bGuest_ok,
1743 .label = "only user",
1746 .ptr = &sDefault.bOnlyUser,
1749 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1752 .label = "hosts allow",
1755 .ptr = &sDefault.szHostsallow,
1758 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1761 .label = "allow hosts",
1764 .ptr = &sDefault.szHostsallow,
1770 .label = "hosts deny",
1773 .ptr = &sDefault.szHostsdeny,
1776 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1779 .label = "deny hosts",
1782 .ptr = &sDefault.szHostsdeny,
1788 .label = "preload modules",
1790 .p_class = P_GLOBAL,
1791 .ptr = &Globals.szPreloadModules,
1794 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1797 .label = "dedicated keytab file",
1799 .p_class = P_GLOBAL,
1800 .ptr = &Globals.szDedicatedKeytabFile,
1803 .flags = FLAG_ADVANCED,
1806 .label = "kerberos method",
1808 .p_class = P_GLOBAL,
1809 .ptr = &Globals.iKerberosMethod,
1811 .enum_list = enum_kerberos_method,
1812 .flags = FLAG_ADVANCED,
1815 .label = "map untrusted to domain",
1817 .p_class = P_GLOBAL,
1818 .ptr = &Globals.bMapUntrustedToDomain,
1821 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1825 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1828 .label = "log level",
1830 .p_class = P_GLOBAL,
1831 .ptr = &Globals.szLogLevel,
1832 .special = handle_debug_list,
1834 .flags = FLAG_ADVANCED,
1837 .label = "debuglevel",
1839 .p_class = P_GLOBAL,
1840 .ptr = &Globals.szLogLevel,
1841 .special = handle_debug_list,
1848 .p_class = P_GLOBAL,
1849 .ptr = &Globals.syslog,
1852 .flags = FLAG_ADVANCED,
1855 .label = "syslog only",
1857 .p_class = P_GLOBAL,
1858 .ptr = &Globals.bSyslogOnly,
1861 .flags = FLAG_ADVANCED,
1864 .label = "log file",
1866 .p_class = P_GLOBAL,
1867 .ptr = &Globals.szLogFile,
1870 .flags = FLAG_ADVANCED,
1873 .label = "max log size",
1875 .p_class = P_GLOBAL,
1876 .ptr = &Globals.max_log_size,
1879 .flags = FLAG_ADVANCED,
1882 .label = "debug timestamp",
1884 .p_class = P_GLOBAL,
1885 .ptr = &Globals.bTimestampLogs,
1888 .flags = FLAG_ADVANCED,
1891 .label = "timestamp logs",
1893 .p_class = P_GLOBAL,
1894 .ptr = &Globals.bTimestampLogs,
1897 .flags = FLAG_ADVANCED,
1900 .label = "debug prefix timestamp",
1902 .p_class = P_GLOBAL,
1903 .ptr = &Globals.bDebugPrefixTimestamp,
1906 .flags = FLAG_ADVANCED,
1909 .label = "debug hires timestamp",
1911 .p_class = P_GLOBAL,
1912 .ptr = &Globals.bDebugHiresTimestamp,
1915 .flags = FLAG_ADVANCED,
1918 .label = "debug pid",
1920 .p_class = P_GLOBAL,
1921 .ptr = &Globals.bDebugPid,
1924 .flags = FLAG_ADVANCED,
1927 .label = "debug uid",
1929 .p_class = P_GLOBAL,
1930 .ptr = &Globals.bDebugUid,
1933 .flags = FLAG_ADVANCED,
1936 .label = "debug class",
1938 .p_class = P_GLOBAL,
1939 .ptr = &Globals.bDebugClass,
1942 .flags = FLAG_ADVANCED,
1945 .label = "enable core files",
1947 .p_class = P_GLOBAL,
1948 .ptr = &Globals.bEnableCoreFiles,
1951 .flags = FLAG_ADVANCED,
1954 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1957 .label = "allocation roundup size",
1960 .ptr = &sDefault.iallocation_roundup_size,
1963 .flags = FLAG_ADVANCED,
1966 .label = "aio read size",
1969 .ptr = &sDefault.iAioReadSize,
1972 .flags = FLAG_ADVANCED,
1975 .label = "aio write size",
1978 .ptr = &sDefault.iAioWriteSize,
1981 .flags = FLAG_ADVANCED,
1984 .label = "aio write behind",
1987 .ptr = &sDefault.szAioWriteBehind,
1990 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1993 .label = "smb ports",
1995 .p_class = P_GLOBAL,
1996 .ptr = &Globals.smb_ports,
1999 .flags = FLAG_ADVANCED,
2002 .label = "large readwrite",
2004 .p_class = P_GLOBAL,
2005 .ptr = &Globals.bLargeReadwrite,
2008 .flags = FLAG_ADVANCED,
2011 .label = "max protocol",
2013 .p_class = P_GLOBAL,
2014 .ptr = &Globals.maxprotocol,
2016 .enum_list = enum_protocol,
2017 .flags = FLAG_ADVANCED,
2020 .label = "protocol",
2022 .p_class = P_GLOBAL,
2023 .ptr = &Globals.maxprotocol,
2025 .enum_list = enum_protocol,
2026 .flags = FLAG_ADVANCED,
2029 .label = "min protocol",
2031 .p_class = P_GLOBAL,
2032 .ptr = &Globals.minprotocol,
2034 .enum_list = enum_protocol,
2035 .flags = FLAG_ADVANCED,
2038 .label = "min receivefile size",
2040 .p_class = P_GLOBAL,
2041 .ptr = &Globals.iminreceivefile,
2044 .flags = FLAG_ADVANCED,
2047 .label = "read raw",
2049 .p_class = P_GLOBAL,
2050 .ptr = &Globals.bReadRaw,
2053 .flags = FLAG_ADVANCED,
2056 .label = "write raw",
2058 .p_class = P_GLOBAL,
2059 .ptr = &Globals.bWriteRaw,
2062 .flags = FLAG_ADVANCED,
2065 .label = "disable netbios",
2067 .p_class = P_GLOBAL,
2068 .ptr = &Globals.bDisableNetbios,
2071 .flags = FLAG_ADVANCED,
2074 .label = "reset on zero vc",
2076 .p_class = P_GLOBAL,
2077 .ptr = &Globals.bResetOnZeroVC,
2080 .flags = FLAG_ADVANCED,
2083 .label = "log writeable files on exit",
2085 .p_class = P_GLOBAL,
2086 .ptr = &Globals.bLogWriteableFilesOnExit,
2089 .flags = FLAG_ADVANCED,
2092 .label = "acl compatibility",
2094 .p_class = P_GLOBAL,
2095 .ptr = &Globals.iAclCompat,
2097 .enum_list = enum_acl_compat_vals,
2098 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2101 .label = "defer sharing violations",
2103 .p_class = P_GLOBAL,
2104 .ptr = &Globals.bDeferSharingViolations,
2107 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2110 .label = "ea support",
2113 .ptr = &sDefault.bEASupport,
2116 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2119 .label = "nt acl support",
2122 .ptr = &sDefault.bNTAclSupport,
2125 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2128 .label = "nt pipe support",
2130 .p_class = P_GLOBAL,
2131 .ptr = &Globals.bNTPipeSupport,
2134 .flags = FLAG_ADVANCED,
2137 .label = "nt status support",
2139 .p_class = P_GLOBAL,
2140 .ptr = &Globals.bNTStatusSupport,
2143 .flags = FLAG_ADVANCED,
2146 .label = "profile acls",
2149 .ptr = &sDefault.bProfileAcls,
2152 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2155 .label = "map acl inherit",
2158 .ptr = &sDefault.bMap_acl_inherit,
2161 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2164 .label = "afs share",
2167 .ptr = &sDefault.bAfs_Share,
2170 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2175 .p_class = P_GLOBAL,
2176 .ptr = &Globals.max_mux,
2179 .flags = FLAG_ADVANCED,
2182 .label = "max xmit",
2184 .p_class = P_GLOBAL,
2185 .ptr = &Globals.max_xmit,
2188 .flags = FLAG_ADVANCED,
2191 .label = "name resolve order",
2193 .p_class = P_GLOBAL,
2194 .ptr = &Globals.szNameResolveOrder,
2197 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2202 .p_class = P_GLOBAL,
2203 .ptr = &Globals.max_ttl,
2206 .flags = FLAG_ADVANCED,
2209 .label = "max wins ttl",
2211 .p_class = P_GLOBAL,
2212 .ptr = &Globals.max_wins_ttl,
2215 .flags = FLAG_ADVANCED,
2218 .label = "min wins ttl",
2220 .p_class = P_GLOBAL,
2221 .ptr = &Globals.min_wins_ttl,
2224 .flags = FLAG_ADVANCED,
2227 .label = "time server",
2229 .p_class = P_GLOBAL,
2230 .ptr = &Globals.bTimeServer,
2233 .flags = FLAG_ADVANCED,
2236 .label = "unix extensions",
2238 .p_class = P_GLOBAL,
2239 .ptr = &Globals.bUnixExtensions,
2242 .flags = FLAG_ADVANCED,
2245 .label = "use spnego",
2247 .p_class = P_GLOBAL,
2248 .ptr = &Globals.bUseSpnego,
2251 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
2254 .label = "client signing",
2256 .p_class = P_GLOBAL,
2257 .ptr = &Globals.client_signing,
2259 .enum_list = enum_smb_signing_vals,
2260 .flags = FLAG_ADVANCED,
2263 .label = "server signing",
2265 .p_class = P_GLOBAL,
2266 .ptr = &Globals.server_signing,
2268 .enum_list = enum_smb_signing_vals,
2269 .flags = FLAG_ADVANCED,
2272 .label = "smb encrypt",
2275 .ptr = &sDefault.ismb_encrypt,
2277 .enum_list = enum_smb_signing_vals,
2278 .flags = FLAG_ADVANCED,
2281 .label = "client use spnego",
2283 .p_class = P_GLOBAL,
2284 .ptr = &Globals.bClientUseSpnego,
2287 .flags = FLAG_ADVANCED,
2290 .label = "client ldap sasl wrapping",
2292 .p_class = P_GLOBAL,
2293 .ptr = &Globals.client_ldap_sasl_wrapping,
2295 .enum_list = enum_ldap_sasl_wrapping,
2296 .flags = FLAG_ADVANCED,
2299 .label = "enable asu support",
2301 .p_class = P_GLOBAL,
2302 .ptr = &Globals.bASUSupport,
2305 .flags = FLAG_ADVANCED,
2308 .label = "svcctl list",
2310 .p_class = P_GLOBAL,
2311 .ptr = &Globals.szServicesList,
2314 .flags = FLAG_ADVANCED,
2317 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2320 .label = "block size",
2323 .ptr = &sDefault.iBlock_size,
2326 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2329 .label = "deadtime",
2331 .p_class = P_GLOBAL,
2332 .ptr = &Globals.deadtime,
2335 .flags = FLAG_ADVANCED,
2338 .label = "getwd cache",
2340 .p_class = P_GLOBAL,
2341 .ptr = &Globals.getwd_cache,
2344 .flags = FLAG_ADVANCED,
2347 .label = "keepalive",
2349 .p_class = P_GLOBAL,
2350 .ptr = &Globals.iKeepalive,
2353 .flags = FLAG_ADVANCED,
2356 .label = "change notify",
2359 .ptr = &sDefault.bChangeNotify,
2362 .flags = FLAG_ADVANCED | FLAG_SHARE,
2365 .label = "directory name cache size",
2368 .ptr = &sDefault.iDirectoryNameCacheSize,
2371 .flags = FLAG_ADVANCED | FLAG_SHARE,
2374 .label = "kernel change notify",
2377 .ptr = &sDefault.bKernelChangeNotify,
2380 .flags = FLAG_ADVANCED | FLAG_SHARE,
2383 .label = "lpq cache time",
2385 .p_class = P_GLOBAL,
2386 .ptr = &Globals.lpqcachetime,
2389 .flags = FLAG_ADVANCED,
2392 .label = "max smbd processes",
2394 .p_class = P_GLOBAL,
2395 .ptr = &Globals.iMaxSmbdProcesses,
2398 .flags = FLAG_ADVANCED,
2401 .label = "max connections",
2404 .ptr = &sDefault.iMaxConnections,
2407 .flags = FLAG_ADVANCED | FLAG_SHARE,
2410 .label = "paranoid server security",
2412 .p_class = P_GLOBAL,
2413 .ptr = &Globals.paranoid_server_security,
2416 .flags = FLAG_ADVANCED,
2419 .label = "max disk size",
2421 .p_class = P_GLOBAL,
2422 .ptr = &Globals.maxdisksize,
2425 .flags = FLAG_ADVANCED,
2428 .label = "max open files",
2430 .p_class = P_GLOBAL,
2431 .ptr = &Globals.max_open_files,
2434 .flags = FLAG_ADVANCED,
2437 .label = "min print space",
2440 .ptr = &sDefault.iMinPrintSpace,
2443 .flags = FLAG_ADVANCED | FLAG_PRINT,
2446 .label = "socket options",
2448 .p_class = P_GLOBAL,
2449 .ptr = &Globals.szSocketOptions,
2452 .flags = FLAG_ADVANCED,
2455 .label = "strict allocate",
2458 .ptr = &sDefault.bStrictAllocate,
2461 .flags = FLAG_ADVANCED | FLAG_SHARE,
2464 .label = "strict sync",
2467 .ptr = &sDefault.bStrictSync,
2470 .flags = FLAG_ADVANCED | FLAG_SHARE,
2473 .label = "sync always",
2476 .ptr = &sDefault.bSyncAlways,
2479 .flags = FLAG_ADVANCED | FLAG_SHARE,
2482 .label = "use mmap",
2484 .p_class = P_GLOBAL,
2485 .ptr = &Globals.bUseMmap,
2488 .flags = FLAG_ADVANCED,
2491 .label = "use sendfile",
2494 .ptr = &sDefault.bUseSendfile,
2497 .flags = FLAG_ADVANCED | FLAG_SHARE,
2500 .label = "hostname lookups",
2502 .p_class = P_GLOBAL,
2503 .ptr = &Globals.bHostnameLookups,
2506 .flags = FLAG_ADVANCED,
2509 .label = "write cache size",
2512 .ptr = &sDefault.iWriteCacheSize,
2515 .flags = FLAG_ADVANCED | FLAG_SHARE,
2518 .label = "name cache timeout",
2520 .p_class = P_GLOBAL,
2521 .ptr = &Globals.name_cache_timeout,
2524 .flags = FLAG_ADVANCED,
2527 .label = "ctdbd socket",
2529 .p_class = P_GLOBAL,
2530 .ptr = &Globals.ctdbdSocket,
2533 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2536 .label = "cluster addresses",
2538 .p_class = P_GLOBAL,
2539 .ptr = &Globals.szClusterAddresses,
2542 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2545 .label = "clustering",
2547 .p_class = P_GLOBAL,
2548 .ptr = &Globals.clustering,
2551 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2554 .label = "ctdb timeout",
2556 .p_class = P_GLOBAL,
2557 .ptr = &Globals.ctdb_timeout,
2560 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2563 .label = "ctdb locktime warn threshold",
2565 .p_class = P_GLOBAL,
2566 .ptr = &Globals.ctdb_locktime_warn_threshold,
2569 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2572 .label = "smb2 max read",
2574 .p_class = P_GLOBAL,
2575 .ptr = &Globals.ismb2_max_read,
2578 .flags = FLAG_ADVANCED,
2581 .label = "smb2 max write",
2583 .p_class = P_GLOBAL,
2584 .ptr = &Globals.ismb2_max_write,
2587 .flags = FLAG_ADVANCED,
2590 .label = "smb2 max trans",
2592 .p_class = P_GLOBAL,
2593 .ptr = &Globals.ismb2_max_trans,
2596 .flags = FLAG_ADVANCED,
2599 .label = "smb2 max credits",
2601 .p_class = P_GLOBAL,
2602 .ptr = &Globals.ismb2_max_credits,
2605 .flags = FLAG_ADVANCED,
2608 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2611 .label = "max reported print jobs",
2614 .ptr = &sDefault.iMaxReportedPrintJobs,
2617 .flags = FLAG_ADVANCED | FLAG_PRINT,
2620 .label = "max print jobs",
2623 .ptr = &sDefault.iMaxPrintJobs,
2626 .flags = FLAG_ADVANCED | FLAG_PRINT,
2629 .label = "load printers",
2631 .p_class = P_GLOBAL,
2632 .ptr = &Globals.bLoadPrinters,
2635 .flags = FLAG_ADVANCED | FLAG_PRINT,
2638 .label = "printcap cache time",
2640 .p_class = P_GLOBAL,
2641 .ptr = &Globals.PrintcapCacheTime,
2644 .flags = FLAG_ADVANCED | FLAG_PRINT,
2647 .label = "printcap name",
2649 .p_class = P_GLOBAL,
2650 .ptr = &Globals.szPrintcapname,
2653 .flags = FLAG_ADVANCED | FLAG_PRINT,
2656 .label = "printcap",
2658 .p_class = P_GLOBAL,
2659 .ptr = &Globals.szPrintcapname,
2665 .label = "printable",
2668 .ptr = &sDefault.bPrint_ok,
2671 .flags = FLAG_ADVANCED | FLAG_PRINT,
2674 .label = "print notify backchannel",
2677 .ptr = &sDefault.bPrintNotifyBackchannel,
2680 .flags = FLAG_ADVANCED,
2683 .label = "print ok",
2686 .ptr = &sDefault.bPrint_ok,
2692 .label = "printing",
2695 .ptr = &sDefault.iPrinting,
2696 .special = handle_printing,
2697 .enum_list = enum_printing,
2698 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2701 .label = "cups options",
2704 .ptr = &sDefault.szCupsOptions,
2707 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2710 .label = "cups server",
2712 .p_class = P_GLOBAL,
2713 .ptr = &Globals.szCupsServer,
2716 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2719 .label = "cups encrypt",
2721 .p_class = P_GLOBAL,
2722 .ptr = &Globals.CupsEncrypt,
2724 .enum_list = enum_bool_auto,
2725 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2729 .label = "cups connection timeout",
2731 .p_class = P_GLOBAL,
2732 .ptr = &Globals.cups_connection_timeout,
2735 .flags = FLAG_ADVANCED,
2738 .label = "iprint server",
2740 .p_class = P_GLOBAL,
2741 .ptr = &Globals.szIPrintServer,
2744 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2747 .label = "print command",
2750 .ptr = &sDefault.szPrintcommand,
2753 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2756 .label = "disable spoolss",
2758 .p_class = P_GLOBAL,
2759 .ptr = &Globals.bDisableSpoolss,
2762 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2765 .label = "enable spoolss",
2767 .p_class = P_GLOBAL,
2768 .ptr = &Globals.bDisableSpoolss,
2774 .label = "lpq command",
2777 .ptr = &sDefault.szLpqcommand,
2780 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2783 .label = "lprm command",
2786 .ptr = &sDefault.szLprmcommand,
2789 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2792 .label = "lppause command",
2795 .ptr = &sDefault.szLppausecommand,
2798 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2801 .label = "lpresume command",
2804 .ptr = &sDefault.szLpresumecommand,
2807 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2810 .label = "queuepause command",
2813 .ptr = &sDefault.szQueuepausecommand,
2816 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2819 .label = "queueresume command",
2822 .ptr = &sDefault.szQueueresumecommand,
2825 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2828 .label = "addport command",
2830 .p_class = P_GLOBAL,
2831 .ptr = &Globals.szAddPortCommand,
2834 .flags = FLAG_ADVANCED,
2837 .label = "enumports command",
2839 .p_class = P_GLOBAL,
2840 .ptr = &Globals.szEnumPortsCommand,
2843 .flags = FLAG_ADVANCED,
2846 .label = "addprinter command",
2848 .p_class = P_GLOBAL,
2849 .ptr = &Globals.szAddPrinterCommand,
2852 .flags = FLAG_ADVANCED,
2855 .label = "deleteprinter command",
2857 .p_class = P_GLOBAL,
2858 .ptr = &Globals.szDeletePrinterCommand,
2861 .flags = FLAG_ADVANCED,
2864 .label = "show add printer wizard",
2866 .p_class = P_GLOBAL,
2867 .ptr = &Globals.bMsAddPrinterWizard,
2870 .flags = FLAG_ADVANCED,
2873 .label = "os2 driver map",
2875 .p_class = P_GLOBAL,
2876 .ptr = &Globals.szOs2DriverMap,
2879 .flags = FLAG_ADVANCED,
2883 .label = "printer name",
2886 .ptr = &sDefault.szPrintername,
2889 .flags = FLAG_ADVANCED | FLAG_PRINT,
2895 .ptr = &sDefault.szPrintername,
2901 .label = "use client driver",
2904 .ptr = &sDefault.bUseClientDriver,
2907 .flags = FLAG_ADVANCED | FLAG_PRINT,
2910 .label = "default devmode",
2913 .ptr = &sDefault.bDefaultDevmode,
2916 .flags = FLAG_ADVANCED | FLAG_PRINT,
2919 .label = "force printername",
2922 .ptr = &sDefault.bForcePrintername,
2925 .flags = FLAG_ADVANCED | FLAG_PRINT,
2928 .label = "printjob username",
2931 .ptr = &sDefault.szPrintjobUsername,
2934 .flags = FLAG_ADVANCED | FLAG_PRINT,
2937 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2940 .label = "mangling method",
2942 .p_class = P_GLOBAL,
2943 .ptr = &Globals.szManglingMethod,
2946 .flags = FLAG_ADVANCED,
2949 .label = "mangle prefix",
2951 .p_class = P_GLOBAL,
2952 .ptr = &Globals.mangle_prefix,
2955 .flags = FLAG_ADVANCED,
2959 .label = "default case",
2962 .ptr = &sDefault.iDefaultCase,
2964 .enum_list = enum_case,
2965 .flags = FLAG_ADVANCED | FLAG_SHARE,
2968 .label = "case sensitive",
2971 .ptr = &sDefault.iCaseSensitive,
2973 .enum_list = enum_bool_auto,
2974 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2977 .label = "casesignames",
2980 .ptr = &sDefault.iCaseSensitive,
2982 .enum_list = enum_bool_auto,
2983 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2986 .label = "preserve case",
2989 .ptr = &sDefault.bCasePreserve,
2992 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2995 .label = "short preserve case",
2998 .ptr = &sDefault.bShortCasePreserve,
3001 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3004 .label = "mangling char",
3007 .ptr = &sDefault.magic_char,
3010 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3013 .label = "hide dot files",
3016 .ptr = &sDefault.bHideDotFiles,
3019 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3022 .label = "hide special files",
3025 .ptr = &sDefault.bHideSpecialFiles,
3028 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3031 .label = "hide unreadable",
3034 .ptr = &sDefault.bHideUnReadable,
3037 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3040 .label = "hide unwriteable files",
3043 .ptr = &sDefault.bHideUnWriteableFiles,
3046 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3049 .label = "delete veto files",
3052 .ptr = &sDefault.bDeleteVetoFiles,
3055 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3058 .label = "veto files",
3061 .ptr = &sDefault.szVetoFiles,
3064 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3067 .label = "hide files",
3070 .ptr = &sDefault.szHideFiles,
3073 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3076 .label = "veto oplock files",
3079 .ptr = &sDefault.szVetoOplockFiles,
3082 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3085 .label = "map archive",
3088 .ptr = &sDefault.bMap_archive,
3091 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3094 .label = "map hidden",
3097 .ptr = &sDefault.bMap_hidden,
3100 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3103 .label = "map system",
3106 .ptr = &sDefault.bMap_system,
3109 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3112 .label = "map readonly",
3115 .ptr = &sDefault.iMap_readonly,
3117 .enum_list = enum_map_readonly,
3118 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3121 .label = "mangled names",
3124 .ptr = &sDefault.bMangledNames,
3127 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3130 .label = "max stat cache size",
3132 .p_class = P_GLOBAL,
3133 .ptr = &Globals.iMaxStatCacheSize,
3136 .flags = FLAG_ADVANCED,
3139 .label = "stat cache",
3141 .p_class = P_GLOBAL,
3142 .ptr = &Globals.bStatCache,
3145 .flags = FLAG_ADVANCED,
3148 .label = "store dos attributes",
3151 .ptr = &sDefault.bStoreDosAttributes,
3154 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3157 .label = "dmapi support",
3160 .ptr = &sDefault.bDmapiSupport,
3163 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3167 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3170 .label = "machine password timeout",
3172 .p_class = P_GLOBAL,
3173 .ptr = &Globals.machine_password_timeout,
3176 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3179 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3182 .label = "add user script",
3184 .p_class = P_GLOBAL,
3185 .ptr = &Globals.szAddUserScript,
3188 .flags = FLAG_ADVANCED,
3191 .label = "rename user script",
3193 .p_class = P_GLOBAL,
3194 .ptr = &Globals.szRenameUserScript,
3197 .flags = FLAG_ADVANCED,
3200 .label = "delete user script",
3202 .p_class = P_GLOBAL,
3203 .ptr = &Globals.szDelUserScript,
3206 .flags = FLAG_ADVANCED,
3209 .label = "add group script",
3211 .p_class = P_GLOBAL,
3212 .ptr = &Globals.szAddGroupScript,
3215 .flags = FLAG_ADVANCED,
3218 .label = "delete group script",
3220 .p_class = P_GLOBAL,
3221 .ptr = &Globals.szDelGroupScript,
3224 .flags = FLAG_ADVANCED,
3227 .label = "add user to group script",
3229 .p_class = P_GLOBAL,
3230 .ptr = &Globals.szAddUserToGroupScript,
3233 .flags = FLAG_ADVANCED,
3236 .label = "delete user from group script",
3238 .p_class = P_GLOBAL,
3239 .ptr = &Globals.szDelUserFromGroupScript,
3242 .flags = FLAG_ADVANCED,
3245 .label = "set primary group script",
3247 .p_class = P_GLOBAL,
3248 .ptr = &Globals.szSetPrimaryGroupScript,
3251 .flags = FLAG_ADVANCED,
3254 .label = "add machine script",
3256 .p_class = P_GLOBAL,
3257 .ptr = &Globals.szAddMachineScript,
3260 .flags = FLAG_ADVANCED,
3263 .label = "shutdown script",
3265 .p_class = P_GLOBAL,
3266 .ptr = &Globals.szShutdownScript,
3269 .flags = FLAG_ADVANCED,
3272 .label = "abort shutdown script",
3274 .p_class = P_GLOBAL,
3275 .ptr = &Globals.szAbortShutdownScript,
3278 .flags = FLAG_ADVANCED,
3281 .label = "username map script",
3283 .p_class = P_GLOBAL,
3284 .ptr = &Globals.szUsernameMapScript,
3287 .flags = FLAG_ADVANCED,
3290 .label = "username map cache time",
3292 .p_class = P_GLOBAL,
3293 .ptr = &Globals.iUsernameMapCacheTime,
3296 .flags = FLAG_ADVANCED,
3299 .label = "logon script",
3301 .p_class = P_GLOBAL,
3302 .ptr = &Globals.szLogonScript,
3305 .flags = FLAG_ADVANCED,
3308 .label = "logon path",
3310 .p_class = P_GLOBAL,
3311 .ptr = &Globals.szLogonPath,
3314 .flags = FLAG_ADVANCED,
3317 .label = "logon drive",
3319 .p_class = P_GLOBAL,
3320 .ptr = &Globals.szLogonDrive,
3323 .flags = FLAG_ADVANCED,
3326 .label = "logon home",
3328 .p_class = P_GLOBAL,
3329 .ptr = &Globals.szLogonHome,
3332 .flags = FLAG_ADVANCED,
3335 .label = "domain logons",
3337 .p_class = P_GLOBAL,
3338 .ptr = &Globals.bDomainLogons,
3341 .flags = FLAG_ADVANCED,
3345 .label = "init logon delayed hosts",
3347 .p_class = P_GLOBAL,
3348 .ptr = &Globals.szInitLogonDelayedHosts,
3351 .flags = FLAG_ADVANCED,
3355 .label = "init logon delay",
3357 .p_class = P_GLOBAL,
3358 .ptr = &Globals.InitLogonDelay,
3361 .flags = FLAG_ADVANCED,
3365 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3368 .label = "os level",
3370 .p_class = P_GLOBAL,
3371 .ptr = &Globals.os_level,
3374 .flags = FLAG_BASIC | FLAG_ADVANCED,
3377 .label = "lm announce",
3379 .p_class = P_GLOBAL,
3380 .ptr = &Globals.lm_announce,
3382 .enum_list = enum_bool_auto,
3383 .flags = FLAG_ADVANCED,
3386 .label = "lm interval",
3388 .p_class = P_GLOBAL,
3389 .ptr = &Globals.lm_interval,
3392 .flags = FLAG_ADVANCED,
3395 .label = "preferred master",
3397 .p_class = P_GLOBAL,
3398 .ptr = &Globals.iPreferredMaster,
3400 .enum_list = enum_bool_auto,
3401 .flags = FLAG_BASIC | FLAG_ADVANCED,
3404 .label = "prefered master",
3406 .p_class = P_GLOBAL,
3407 .ptr = &Globals.iPreferredMaster,
3409 .enum_list = enum_bool_auto,
3413 .label = "local master",
3415 .p_class = P_GLOBAL,
3416 .ptr = &Globals.bLocalMaster,
3419 .flags = FLAG_BASIC | FLAG_ADVANCED,
3422 .label = "domain master",
3424 .p_class = P_GLOBAL,
3425 .ptr = &Globals.iDomainMaster,
3427 .enum_list = enum_bool_auto,
3428 .flags = FLAG_BASIC | FLAG_ADVANCED,
3431 .label = "browse list",
3433 .p_class = P_GLOBAL,
3434 .ptr = &Globals.bBrowseList,
3437 .flags = FLAG_ADVANCED,
3440 .label = "browseable",
3443 .ptr = &sDefault.bBrowseable,
3446 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3449 .label = "browsable",
3452 .ptr = &sDefault.bBrowseable,
3458 .label = "access based share enum",
3461 .ptr = &sDefault.bAccessBasedShareEnum,
3464 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3467 .label = "enhanced browsing",
3469 .p_class = P_GLOBAL,
3470 .ptr = &Globals.enhanced_browsing,
3473 .flags = FLAG_ADVANCED,
3476 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3479 .label = "dns proxy",
3481 .p_class = P_GLOBAL,
3482 .ptr = &Globals.bDNSproxy,
3485 .flags = FLAG_ADVANCED,
3488 .label = "wins proxy",
3490 .p_class = P_GLOBAL,
3491 .ptr = &Globals.bWINSproxy,
3494 .flags = FLAG_ADVANCED,
3497 .label = "wins server",
3499 .p_class = P_GLOBAL,
3500 .ptr = &Globals.szWINSservers,
3503 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3506 .label = "wins support",
3508 .p_class = P_GLOBAL,
3509 .ptr = &Globals.bWINSsupport,
3512 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3515 .label = "wins hook",
3517 .p_class = P_GLOBAL,
3518 .ptr = &Globals.szWINSHook,
3521 .flags = FLAG_ADVANCED,
3524 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3527 .label = "blocking locks",
3530 .ptr = &sDefault.bBlockingLocks,
3533 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3536 .label = "csc policy",
3539 .ptr = &sDefault.iCSCPolicy,
3541 .enum_list = enum_csc_policy,
3542 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3545 .label = "fake oplocks",
3548 .ptr = &sDefault.bFakeOplocks,
3551 .flags = FLAG_ADVANCED | FLAG_SHARE,
3554 .label = "kernel oplocks",
3556 .p_class = P_GLOBAL,
3557 .ptr = &Globals.bKernelOplocks,
3560 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3566 .ptr = &sDefault.bLocking,
3569 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3572 .label = "lock spin time",
3574 .p_class = P_GLOBAL,
3575 .ptr = &Globals.iLockSpinTime,
3578 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3584 .ptr = &sDefault.bOpLocks,
3587 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3590 .label = "level2 oplocks",
3593 .ptr = &sDefault.bLevel2OpLocks,
3596 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3599 .label = "oplock break wait time",
3601 .p_class = P_GLOBAL,
3602 .ptr = &Globals.oplock_break_wait_time,
3605 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3608 .label = "oplock contention limit",
3611 .ptr = &sDefault.iOplockContentionLimit,
3614 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3617 .label = "posix locking",
3620 .ptr = &sDefault.bPosixLocking,
3623 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3626 .label = "strict locking",
3629 .ptr = &sDefault.iStrictLocking,
3631 .enum_list = enum_bool_auto,
3632 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3635 .label = "share modes",
3638 .ptr = &sDefault.bShareModes,
3641 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3644 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3647 .label = "ldap admin dn",
3649 .p_class = P_GLOBAL,
3650 .ptr = &Globals.szLdapAdminDn,
3653 .flags = FLAG_ADVANCED,
3656 .label = "ldap delete dn",
3658 .p_class = P_GLOBAL,
3659 .ptr = &Globals.ldap_delete_dn,
3662 .flags = FLAG_ADVANCED,
3665 .label = "ldap group suffix",
3667 .p_class = P_GLOBAL,
3668 .ptr = &Globals.szLdapGroupSuffix,
3671 .flags = FLAG_ADVANCED,
3674 .label = "ldap idmap suffix",
3676 .p_class = P_GLOBAL,
3677 .ptr = &Globals.szLdapIdmapSuffix,
3680 .flags = FLAG_ADVANCED,
3683 .label = "ldap machine suffix",
3685 .p_class = P_GLOBAL,
3686 .ptr = &Globals.szLdapMachineSuffix,
3689 .flags = FLAG_ADVANCED,
3692 .label = "ldap passwd sync",
3694 .p_class = P_GLOBAL,
3695 .ptr = &Globals.ldap_passwd_sync,
3697 .enum_list = enum_ldap_passwd_sync,
3698 .flags = FLAG_ADVANCED,
3701 .label = "ldap password sync",
3703 .p_class = P_GLOBAL,
3704 .ptr = &Globals.ldap_passwd_sync,
3706 .enum_list = enum_ldap_passwd_sync,
3710 .label = "ldap replication sleep",
3712 .p_class = P_GLOBAL,
3713 .ptr = &Globals.ldap_replication_sleep,
3716 .flags = FLAG_ADVANCED,
3719 .label = "ldap suffix",
3721 .p_class = P_GLOBAL,
3722 .ptr = &Globals.szLdapSuffix,
3725 .flags = FLAG_ADVANCED,
3728 .label = "ldap ssl",
3730 .p_class = P_GLOBAL,
3731 .ptr = &Globals.ldap_ssl,
3733 .enum_list = enum_ldap_ssl,
3734 .flags = FLAG_ADVANCED,
3737 .label = "ldap ssl ads",
3739 .p_class = P_GLOBAL,
3740 .ptr = &Globals.ldap_ssl_ads,
3743 .flags = FLAG_ADVANCED,
3746 .label = "ldap deref",
3748 .p_class = P_GLOBAL,
3749 .ptr = &Globals.ldap_deref,
3751 .enum_list = enum_ldap_deref,
3752 .flags = FLAG_ADVANCED,
3755 .label = "ldap follow referral",
3757 .p_class = P_GLOBAL,
3758 .ptr = &Globals.ldap_follow_referral,
3760 .enum_list = enum_bool_auto,
3761 .flags = FLAG_ADVANCED,
3764 .label = "ldap timeout",
3766 .p_class = P_GLOBAL,
3767 .ptr = &Globals.ldap_timeout,
3770 .flags = FLAG_ADVANCED,
3773 .label = "ldap connection timeout",
3775 .p_class = P_GLOBAL,
3776 .ptr = &Globals.ldap_connection_timeout,
3779 .flags = FLAG_ADVANCED,
3782 .label = "ldap page size",
3784 .p_class = P_GLOBAL,
3785 .ptr = &Globals.ldap_page_size,
3788 .flags = FLAG_ADVANCED,
3791 .label = "ldap user suffix",
3793 .p_class = P_GLOBAL,
3794 .ptr = &Globals.szLdapUserSuffix,
3797 .flags = FLAG_ADVANCED,
3800 .label = "ldap debug level",
3802 .p_class = P_GLOBAL,
3803 .ptr = &Globals.ldap_debug_level,
3804 .special = handle_ldap_debug_level,
3806 .flags = FLAG_ADVANCED,
3809 .label = "ldap debug threshold",
3811 .p_class = P_GLOBAL,
3812 .ptr = &Globals.ldap_debug_threshold,
3815 .flags = FLAG_ADVANCED,
3818 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3821 .label = "eventlog list",
3823 .p_class = P_GLOBAL,
3824 .ptr = &Globals.szEventLogs,
3827 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3830 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3833 .label = "add share command",
3835 .p_class = P_GLOBAL,
3836 .ptr = &Globals.szAddShareCommand,
3839 .flags = FLAG_ADVANCED,
3842 .label = "change share command",
3844 .p_class = P_GLOBAL,
3845 .ptr = &Globals.szChangeShareCommand,
3848 .flags = FLAG_ADVANCED,
3851 .label = "delete share command",
3853 .p_class = P_GLOBAL,
3854 .ptr = &Globals.szDeleteShareCommand,
3857 .flags = FLAG_ADVANCED,
3860 .label = "config file",
3862 .p_class = P_GLOBAL,
3863 .ptr = &Globals.szConfigFile,
3866 .flags = FLAG_HIDE|FLAG_META,
3871 .p_class = P_GLOBAL,
3872 .ptr = &Globals.szAutoServices,
3875 .flags = FLAG_ADVANCED,
3878 .label = "auto services",
3880 .p_class = P_GLOBAL,
3881 .ptr = &Globals.szAutoServices,
3884 .flags = FLAG_ADVANCED,
3887 .label = "lock directory",
3889 .p_class = P_GLOBAL,
3890 .ptr = &Globals.szLockDir,
3893 .flags = FLAG_ADVANCED,
3896 .label = "lock dir",
3898 .p_class = P_GLOBAL,
3899 .ptr = &Globals.szLockDir,
3905 .label = "state directory",
3907 .p_class = P_GLOBAL,
3908 .ptr = &Globals.szStateDir,
3911 .flags = FLAG_ADVANCED,
3914 .label = "cache directory",
3916 .p_class = P_GLOBAL,
3917 .ptr = &Globals.szCacheDir,
3920 .flags = FLAG_ADVANCED,
3923 .label = "pid directory",
3925 .p_class = P_GLOBAL,
3926 .ptr = &Globals.szPidDir,
3929 .flags = FLAG_ADVANCED,
3933 .label = "utmp directory",
3935 .p_class = P_GLOBAL,
3936 .ptr = &Globals.szUtmpDir,
3939 .flags = FLAG_ADVANCED,
3942 .label = "wtmp directory",
3944 .p_class = P_GLOBAL,
3945 .ptr = &Globals.szWtmpDir,
3948 .flags = FLAG_ADVANCED,
3953 .p_class = P_GLOBAL,
3954 .ptr = &Globals.bUtmp,
3957 .flags = FLAG_ADVANCED,
3961 .label = "default service",
3963 .p_class = P_GLOBAL,
3964 .ptr = &Globals.szDefaultService,
3967 .flags = FLAG_ADVANCED,
3972 .p_class = P_GLOBAL,
3973 .ptr = &Globals.szDefaultService,
3976 .flags = FLAG_ADVANCED,
3979 .label = "message command",
3981 .p_class = P_GLOBAL,
3982 .ptr = &Globals.szMsgCommand,
3985 .flags = FLAG_ADVANCED,
3988 .label = "dfree cache time",
3991 .ptr = &sDefault.iDfreeCacheTime,
3994 .flags = FLAG_ADVANCED,
3997 .label = "dfree command",
4000 .ptr = &sDefault.szDfree,
4003 .flags = FLAG_ADVANCED,
4006 .label = "get quota command",
4008 .p_class = P_GLOBAL,
4009 .ptr = &Globals.szGetQuota,
4012 .flags = FLAG_ADVANCED,
4015 .label = "set quota command",
4017 .p_class = P_GLOBAL,
4018 .ptr = &Globals.szSetQuota,
4021 .flags = FLAG_ADVANCED,
4024 .label = "remote announce",
4026 .p_class = P_GLOBAL,
4027 .ptr = &Globals.szRemoteAnnounce,
4030 .flags = FLAG_ADVANCED,
4033 .label = "remote browse sync",
4035 .p_class = P_GLOBAL,
4036 .ptr = &Globals.szRemoteBrowseSync,
4039 .flags = FLAG_ADVANCED,
4042 .label = "socket address",
4044 .p_class = P_GLOBAL,
4045 .ptr = &Globals.szSocketAddress,
4048 .flags = FLAG_ADVANCED,
4051 .label = "nmbd bind explicit broadcast",
4053 .p_class = P_GLOBAL,
4054 .ptr = &Globals.bNmbdBindExplicitBroadcast,
4057 .flags = FLAG_ADVANCED,
4060 .label = "homedir map",
4062 .p_class = P_GLOBAL,
4063 .ptr = &Globals.szNISHomeMapName,
4066 .flags = FLAG_ADVANCED,
4069 .label = "afs username map",
4071 .p_class = P_GLOBAL,
4072 .ptr = &Globals.szAfsUsernameMap,
4075 .flags = FLAG_ADVANCED,
4078 .label = "afs token lifetime",
4080 .p_class = P_GLOBAL,
4081 .ptr = &Globals.iAfsTokenLifetime,
4084 .flags = FLAG_ADVANCED,
4087 .label = "log nt token command",
4089 .p_class = P_GLOBAL,
4090 .ptr = &Globals.szLogNtTokenCommand,
4093 .flags = FLAG_ADVANCED,
4096 .label = "NIS homedir",
4098 .p_class = P_GLOBAL,
4099 .ptr = &Globals.bNISHomeMap,
4102 .flags = FLAG_ADVANCED,
4108 .ptr = &sDefault.valid,
4117 .ptr = &sDefault.szCopy,
4118 .special = handle_copy,
4126 .ptr = &sDefault.szInclude,
4127 .special = handle_include,
4129 .flags = FLAG_HIDE|FLAG_META,
4135 .ptr = &sDefault.szPreExec,
4138 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4144 .ptr = &sDefault.szPreExec,
4147 .flags = FLAG_ADVANCED,
4150 .label = "preexec close",
4153 .ptr = &sDefault.bPreexecClose,
4156 .flags = FLAG_ADVANCED | FLAG_SHARE,
4159 .label = "postexec",
4162 .ptr = &sDefault.szPostExec,
4165 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4168 .label = "root preexec",
4171 .ptr = &sDefault.szRootPreExec,
4174 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4177 .label = "root preexec close",
4180 .ptr = &sDefault.bRootpreexecClose,
4183 .flags = FLAG_ADVANCED | FLAG_SHARE,
4186 .label = "root postexec",
4189 .ptr = &sDefault.szRootPostExec,
4192 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4195 .label = "available",
4198 .ptr = &sDefault.bAvailable,
4201 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4204 .label = "registry shares",
4206 .p_class = P_GLOBAL,
4207 .ptr = &Globals.bRegistryShares,
4210 .flags = FLAG_ADVANCED,
4213 .label = "usershare allow guests",
4215 .p_class = P_GLOBAL,
4216 .ptr = &Globals.bUsershareAllowGuests,
4219 .flags = FLAG_ADVANCED,
4222 .label = "usershare max shares",
4224 .p_class = P_GLOBAL,
4225 .ptr = &Globals.iUsershareMaxShares,
4228 .flags = FLAG_ADVANCED,
4231 .label = "usershare owner only",
4233 .p_class = P_GLOBAL,
4234 .ptr = &Globals.bUsershareOwnerOnly,
4237 .flags = FLAG_ADVANCED,
4240 .label = "usershare path",
4242 .p_class = P_GLOBAL,
4243 .ptr = &Globals.szUsersharePath,
4246 .flags = FLAG_ADVANCED,
4249 .label = "usershare prefix allow list",
4251 .p_class = P_GLOBAL,
4252 .ptr = &Globals.szUsersharePrefixAllowList,
4255 .flags = FLAG_ADVANCED,
4258 .label = "usershare prefix deny list",
4260 .p_class = P_GLOBAL,
4261 .ptr = &Globals.szUsersharePrefixDenyList,
4264 .flags = FLAG_ADVANCED,
4267 .label = "usershare template share",
4269 .p_class = P_GLOBAL,
4270 .ptr = &Globals.szUsershareTemplateShare,
4273 .flags = FLAG_ADVANCED,
4279 .ptr = &sDefault.volume,
4282 .flags = FLAG_ADVANCED | FLAG_SHARE,
4288 .ptr = &sDefault.fstype,
4291 .flags = FLAG_ADVANCED | FLAG_SHARE,
4294 .label = "set directory",
4297 .ptr = &sDefault.bNo_set_dir,
4300 .flags = FLAG_ADVANCED | FLAG_SHARE,
4303 .label = "wide links",
4306 .ptr = &sDefault.bWidelinks,
4309 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4312 .label = "follow symlinks",
4315 .ptr = &sDefault.bSymlinks,
4318 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4321 .label = "dont descend",
4324 .ptr = &sDefault.szDontdescend,
4327 .flags = FLAG_ADVANCED | FLAG_SHARE,
4330 .label = "magic script",
4333 .ptr = &sDefault.szMagicScript,
4336 .flags = FLAG_ADVANCED | FLAG_SHARE,
4339 .label = "magic output",
4342 .ptr = &sDefault.szMagicOutput,
4345 .flags = FLAG_ADVANCED | FLAG_SHARE,
4348 .label = "delete readonly",
4351 .ptr = &sDefault.bDeleteReadonly,
4354 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4357 .label = "dos filemode",
4360 .ptr = &sDefault.bDosFilemode,
4363 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4366 .label = "dos filetimes",
4369 .ptr = &sDefault.bDosFiletimes,
4372 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4375 .label = "dos filetime resolution",
4378 .ptr = &sDefault.bDosFiletimeResolution,
4381 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4384 .label = "fake directory create times",
4387 .ptr = &sDefault.bFakeDirCreateTimes,
4390 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4393 .label = "async smb echo handler",
4395 .p_class = P_GLOBAL,
4396 .ptr = &Globals.bAsyncSMBEchoHandler,
4399 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4402 .label = "multicast dns register",
4404 .p_class = P_GLOBAL,
4405 .ptr = &Globals.bMulticastDnsRegister,
4408 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4411 .label = "panic action",
4413 .p_class = P_GLOBAL,
4414 .ptr = &Globals.szPanicAction,
4417 .flags = FLAG_ADVANCED,
4420 .label = "perfcount module",
4422 .p_class = P_GLOBAL,
4423 .ptr = &Globals.szSMBPerfcountModule,
4426 .flags = FLAG_ADVANCED,
4429 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4432 .label = "vfs objects",
4435 .ptr = &sDefault.szVfsObjects,
4438 .flags = FLAG_ADVANCED | FLAG_SHARE,
4441 .label = "vfs object",
4444 .ptr = &sDefault.szVfsObjects,
4451 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4454 .label = "msdfs root",
4457 .ptr = &sDefault.bMSDfsRoot,
4460 .flags = FLAG_ADVANCED | FLAG_SHARE,
4463 .label = "msdfs proxy",
4466 .ptr = &sDefault.szMSDfsProxy,
4469 .flags = FLAG_ADVANCED | FLAG_SHARE,
4472 .label = "host msdfs",
4474 .p_class = P_GLOBAL,
4475 .ptr = &Globals.bHostMSDfs,
4478 .flags = FLAG_ADVANCED,
4481 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4484 .label = "passdb expand explicit",
4486 .p_class = P_GLOBAL,
4487 .ptr = &Globals.bPassdbExpandExplicit,
4490 .flags = FLAG_ADVANCED,
4493 .label = "idmap backend",
4495 .p_class = P_GLOBAL,
4496 .ptr = &Globals.szIdmapBackend,
4497 .special = handle_idmap_backend,
4499 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4502 .label = "idmap cache time",
4504 .p_class = P_GLOBAL,
4505 .ptr = &Globals.iIdmapCacheTime,
4508 .flags = FLAG_ADVANCED,
4511 .label = "idmap negative cache time",
4513 .p_class = P_GLOBAL,
4514 .ptr = &Globals.iIdmapNegativeCacheTime,
4517 .flags = FLAG_ADVANCED,
4520 .label = "idmap uid",
4522 .p_class = P_GLOBAL,
4523 .ptr = &Globals.szIdmapUID,
4524 .special = handle_idmap_uid,
4526 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4529 .label = "winbind uid",
4531 .p_class = P_GLOBAL,
4532 .ptr = &Globals.szIdmapUID,
4533 .special = handle_idmap_uid,
4538 .label = "idmap gid",
4540 .p_class = P_GLOBAL,
4541 .ptr = &Globals.szIdmapGID,
4542 .special = handle_idmap_gid,
4544 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4547 .label = "winbind gid",
4549 .p_class = P_GLOBAL,
4550 .ptr = &Globals.szIdmapGID,
4551 .special = handle_idmap_gid,
4556 .label = "template homedir",
4558 .p_class = P_GLOBAL,
4559 .ptr = &Globals.szTemplateHomedir,
4562 .flags = FLAG_ADVANCED,
4565 .label = "template shell",
4567 .p_class = P_GLOBAL,
4568 .ptr = &Globals.szTemplateShell,
4571 .flags = FLAG_ADVANCED,
4574 .label = "winbind separator",
4576 .p_class = P_GLOBAL,
4577 .ptr = &Globals.szWinbindSeparator,
4580 .flags = FLAG_ADVANCED,
4583 .label = "winbind cache time",
4585 .p_class = P_GLOBAL,
4586 .ptr = &Globals.winbind_cache_time,
4589 .flags = FLAG_ADVANCED,
4592 .label = "winbind reconnect delay",
4594 .p_class = P_GLOBAL,
4595 .ptr = &Globals.winbind_reconnect_delay,
4598 .flags = FLAG_ADVANCED,
4601 .label = "winbind max clients",
4603 .p_class = P_GLOBAL,
4604 .ptr = &Globals.winbind_max_clients,
4607 .flags = FLAG_ADVANCED,
4610 .label = "winbind enum users",
4612 .p_class = P_GLOBAL,
4613 .ptr = &Globals.bWinbindEnumUsers,
4616 .flags = FLAG_ADVANCED,
4619 .label = "winbind enum groups",
4621 .p_class = P_GLOBAL,
4622 .ptr = &Globals.bWinbindEnumGroups,
4625 .flags = FLAG_ADVANCED,
4628 .label = "winbind use default domain",
4630 .p_class = P_GLOBAL,
4631 .ptr = &Globals.bWinbindUseDefaultDomain,
4634 .flags = FLAG_ADVANCED,
4637 .label = "winbind trusted domains only",
4639 .p_class = P_GLOBAL,
4640 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4643 .flags = FLAG_ADVANCED,
4646 .label = "winbind nested groups",
4648 .p_class = P_GLOBAL,
4649 .ptr = &Globals.bWinbindNestedGroups,
4652 .flags = FLAG_ADVANCED,
4655 .label = "winbind expand groups",
4657 .p_class = P_GLOBAL,
4658 .ptr = &Globals.winbind_expand_groups,
4661 .flags = FLAG_ADVANCED,
4664 .label = "winbind nss info",
4666 .p_class = P_GLOBAL,
4667 .ptr = &Globals.szWinbindNssInfo,
4670 .flags = FLAG_ADVANCED,
4673 .label = "winbind refresh tickets",
4675 .p_class = P_GLOBAL,
4676 .ptr = &Globals.bWinbindRefreshTickets,
4679 .flags = FLAG_ADVANCED,
4682 .label = "winbind offline logon",
4684 .p_class = P_GLOBAL,
4685 .ptr = &Globals.bWinbindOfflineLogon,
4688 .flags = FLAG_ADVANCED,
4691 .label = "winbind normalize names",
4693 .p_class = P_GLOBAL,
4694 .ptr = &Globals.bWinbindNormalizeNames,
4697 .flags = FLAG_ADVANCED,
4700 .label = "winbind rpc only",
4702 .p_class = P_GLOBAL,
4703 .ptr = &Globals.bWinbindRpcOnly,
4706 .flags = FLAG_ADVANCED,
4709 .label = "create krb5 conf",
4711 .p_class = P_GLOBAL,
4712 .ptr = &Globals.bCreateKrb5Conf,
4715 .flags = FLAG_ADVANCED,
4718 .label = "ncalrpc dir",
4720 .p_class = P_GLOBAL,
4721 .ptr = &Globals.ncalrpc_dir,
4724 .flags = FLAG_ADVANCED,
4727 .label = "winbind max domain connections",
4729 .p_class = P_GLOBAL,
4730 .ptr = &Globals.winbindMaxDomainConnections,
4733 .flags = FLAG_ADVANCED,
4736 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4739 /***************************************************************************
4740 Initialise the sDefault parameter structure for the printer values.
4741 ***************************************************************************/
4743 static void init_printer_values(struct loadparm_service *pService)
4745 /* choose defaults depending on the type of printing */
4746 switch (pService->iPrinting) {
4751 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4752 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4753 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4758 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4759 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4760 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4761 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4762 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4763 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4764 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4770 /* set the lpq command to contain the destination printer
4771 name only. This is used by cups_queue_get() */
4772 string_set(&pService->szLpqcommand, "%p");
4773 string_set(&pService->szLprmcommand, "");
4774 string_set(&pService->szPrintcommand, "");
4775 string_set(&pService->szLppausecommand, "");
4776 string_set(&pService->szLpresumecommand, "");
4777 string_set(&pService->szQueuepausecommand, "");
4778 string_set(&pService->szQueueresumecommand, "");
4780 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4781 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4782 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4783 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4784 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4785 string_set(&pService->szQueuepausecommand, "disable '%p'");
4786 string_set(&pService->szQueueresumecommand, "enable '%p'");
4787 #endif /* HAVE_CUPS */
4792 string_set(&pService->szLpqcommand, "lpstat -o%p");
4793 string_set(&pService->szLprmcommand, "cancel %p-%j");
4794 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4795 string_set(&pService->szQueuepausecommand, "disable %p");
4796 string_set(&pService->szQueueresumecommand, "enable %p");
4798 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4799 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4804 string_set(&pService->szLpqcommand, "lpq -P%p");
4805 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4806 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4809 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4813 const char *tdbfile;
4816 tdbfile = talloc_asprintf(
4817 talloc_tos(), "tdbfile=%s",
4818 lp_parm_const_string(-1, "vlp", "tdbfile",
4820 if (tdbfile == NULL) {
4821 tdbfile="tdbfile=/tmp/vlp.tdb";
4824 tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
4826 string_set(&pService->szPrintcommand,
4827 tmp ? tmp : "vlp print %p %s");
4830 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
4832 string_set(&pService->szLpqcommand,
4833 tmp ? tmp : "vlp lpq %p");
4836 tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
4838 string_set(&pService->szLprmcommand,
4839 tmp ? tmp : "vlp lprm %p %j");
4842 tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
4844 string_set(&pService->szLppausecommand,
4845 tmp ? tmp : "vlp lppause %p %j");
4848 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
4850 string_set(&pService->szLpresumecommand,
4851 tmp ? tmp : "vlp lpresume %p %j");
4854 tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
4856 string_set(&pService->szQueuepausecommand,
4857 tmp ? tmp : "vlp queuepause %p");
4860 tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
4862 string_set(&pService->szQueueresumecommand,
4863 tmp ? tmp : "vlp queueresume %p");
4868 #endif /* DEVELOPER */
4873 * Function to return the default value for the maximum number of open
4874 * file descriptors permitted. This function tries to consult the
4875 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4876 * the smaller of those.
4878 static int max_open_files(void)
4880 int sysctl_max = MAX_OPEN_FILES;
4881 int rlimit_max = MAX_OPEN_FILES;
4883 #ifdef HAVE_SYSCTLBYNAME
4885 size_t size = sizeof(sysctl_max);
4886 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4891 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4897 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4898 rlimit_max = rl.rlim_cur;
4900 #if defined(RLIM_INFINITY)
4901 if(rl.rlim_cur == RLIM_INFINITY)
4902 rlimit_max = MAX_OPEN_FILES;
4907 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4908 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4909 "minimum Windows limit (%d)\n",
4911 MIN_OPEN_FILES_WINDOWS));
4912 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4915 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4916 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4917 "minimum Windows limit (%d)\n",
4919 MIN_OPEN_FILES_WINDOWS));
4920 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4923 return MIN(sysctl_max, rlimit_max);
4927 * Common part of freeing allocated data for one parameter.
4929 static void free_one_parameter_common(void *parm_ptr,
4930 struct parm_struct parm)
4932 if ((parm.type == P_STRING) ||
4933 (parm.type == P_USTRING))
4935 string_free((char**)parm_ptr);
4936 } else if (parm.type == P_LIST) {
4937 TALLOC_FREE(*((char***)parm_ptr));
4942 * Free the allocated data for one parameter for a share
4943 * given as a service struct.
4945 static void free_one_parameter(struct loadparm_service *service,
4946 struct parm_struct parm)
4950 if (parm.p_class != P_LOCAL) {
4954 parm_ptr = lp_parm_ptr(service, &parm);
4956 free_one_parameter_common(parm_ptr, parm);
4960 * Free the allocated parameter data of a share given
4961 * as a service struct.
4963 static void free_parameters(struct loadparm_service *service)
4967 for (i=0; parm_table[i].label; i++) {
4968 free_one_parameter(service, parm_table[i]);
4973 * Free the allocated data for one parameter for a given share
4974 * specified by an snum.
4976 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4980 if (parm.ptr == NULL) {
4985 parm_ptr = lp_parm_ptr(NULL, &parm);
4986 } else if (parm.p_class != P_LOCAL) {
4989 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
4992 free_one_parameter_common(parm_ptr, parm);
4996 * Free the allocated parameter data for a share specified
4999 static void free_parameters_by_snum(int snum)
5003 for (i=0; parm_table[i].label; i++) {
5004 free_one_parameter_by_snum(snum, parm_table[i]);
5009 * Free the allocated global parameters.
5011 static void free_global_parameters(void)
5013 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
5016 static int map_parameter(const char *pszParmName);
5018 struct lp_stored_option {
5019 struct lp_stored_option *prev, *next;
5024 static struct lp_stored_option *stored_options;
5027 save options set by lp_set_cmdline() into a list. This list is
5028 re-applied when we do a globals reset, so that cmdline set options
5029 are sticky across reloads of smb.conf
5031 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
5033 struct lp_stored_option *entry, *entry_next;
5034 for (entry = stored_options; entry != NULL; entry = entry_next) {
5035 entry_next = entry->next;
5036 if (strcmp(pszParmName, entry->label) == 0) {
5037 DLIST_REMOVE(stored_options, entry);
5043 entry = talloc(NULL, struct lp_stored_option);
5048 entry->label = talloc_strdup(entry, pszParmName);
5049 if (!entry->label) {
5054 entry->value = talloc_strdup(entry, pszParmValue);
5055 if (!entry->value) {
5060 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
5065 static bool apply_lp_set_cmdline(void)
5067 struct lp_stored_option *entry = NULL;
5068 for (entry = stored_options; entry != NULL; entry = entry->next) {
5069 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
5070 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
5071 entry->label, entry->value));
5078 /***************************************************************************
5079 Initialise the global parameter structure.
5080 ***************************************************************************/
5082 static void init_globals(bool reinit_globals)
5084 static bool done_init = False;
5088 /* If requested to initialize only once and we've already done it... */
5089 if (!reinit_globals && done_init) {
5090 /* ... then we have nothing more to do */
5095 /* The logfile can be set before this is invoked. Free it if so. */
5096 if (Globals.szLogFile != NULL) {
5097 string_free(&Globals.szLogFile);
5098 Globals.szLogFile = NULL;
5102 free_global_parameters();
5105 /* This memset and the free_global_parameters() above will
5106 * wipe out smb.conf options set with lp_set_cmdline(). The
5107 * apply_lp_set_cmdline() call puts these values back in the
5108 * table once the defaults are set */
5109 memset((void *)&Globals, '\0', sizeof(Globals));
5111 for (i = 0; parm_table[i].label; i++) {
5112 if ((parm_table[i].type == P_STRING ||
5113 parm_table[i].type == P_USTRING) &&
5116 string_set(lp_parm_ptr(NULL, &parm_table[i]), "");
5121 string_set(&sDefault.fstype, FSTYPE_STRING);
5122 string_set(&sDefault.szPrintjobUsername, "%U");
5124 init_printer_values(&sDefault);
5127 DEBUG(3, ("Initialising global parameters\n"));
5129 /* Must manually force to upper case here, as this does not go via the handler */
5130 string_set(&Globals.szNetbiosName, myhostname_upper());
5132 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
5133 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
5135 /* use the new 'hash2' method by default, with a prefix of 1 */
5136 string_set(&Globals.szManglingMethod, "hash2");
5137 Globals.mangle_prefix = 1;
5139 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5141 /* using UTF8 by default allows us to support all chars */
5142 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5144 /* Use codepage 850 as a default for the dos character set */
5145 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5148 * Allow the default PASSWD_CHAT to be overridden in local.h.
5150 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5152 string_set(&Globals.szWorkgroup, WORKGROUP);
5154 string_set(&Globals.szPasswdProgram, "");
5155 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5156 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5157 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5158 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5159 string_set(&Globals.szSocketAddress, "0.0.0.0");
5161 * By default support explicit binding to broadcast
5164 Globals.bNmbdBindExplicitBroadcast = true;
5166 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5167 smb_panic("init_globals: ENOMEM");
5169 string_set(&Globals.szServerString, s);
5172 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5175 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5177 string_set(&Globals.szLogonDrive, "");
5178 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5179 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5180 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5182 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5183 string_set(&Globals.szPasswordServer, "*");
5185 Globals.AlgorithmicRidBase = BASE_RID;
5187 Globals.bLoadPrinters = True;
5188 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
5190 Globals.ConfigBackend = config_backend;
5192 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5193 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5194 Globals.max_xmit = 0x4104;
5195 Globals.max_mux = 50; /* This is *needed* for profile support. */
5196 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
5197 Globals.bDisableSpoolss = False;
5198 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5199 Globals.pwordlevel = 0;
5200 Globals.unamelevel = 0;
5201 Globals.deadtime = 0;
5202 Globals.getwd_cache = true;
5203 Globals.bLargeReadwrite = True;
5204 Globals.max_log_size = 5000;
5205 Globals.max_open_files = max_open_files();
5206 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5207 Globals.maxprotocol = PROTOCOL_NT1;
5208 Globals.minprotocol = PROTOCOL_CORE;
5209 Globals.security = SEC_USER;
5210 Globals.paranoid_server_security = True;
5211 Globals.bEncryptPasswords = True;
5212 Globals.bUpdateEncrypt = False;
5213 Globals.clientSchannel = Auto;
5214 Globals.serverSchannel = Auto;
5215 Globals.bReadRaw = True;
5216 Globals.bWriteRaw = True;
5217 Globals.bNullPasswords = False;
5218 Globals.bObeyPamRestrictions = False;
5220 Globals.bSyslogOnly = False;
5221 Globals.bTimestampLogs = True;
5222 string_set(&Globals.szLogLevel, "0");
5223 Globals.bDebugPrefixTimestamp = False;
5224 Globals.bDebugHiresTimestamp = true;
5225 Globals.bDebugPid = False;
5226 Globals.bDebugUid = False;
5227 Globals.bDebugClass = False;
5228 Globals.bEnableCoreFiles = True;
5229 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5230 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5231 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5232 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5233 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5234 Globals.lm_interval = 60;
5235 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5236 Globals.bNISHomeMap = False;
5237 #ifdef WITH_NISPLUS_HOME
5238 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5240 string_set(&Globals.szNISHomeMapName, "auto.home");
5243 Globals.bTimeServer = False;
5244 Globals.bBindInterfacesOnly = False;
5245 Globals.bUnixPasswdSync = False;
5246 Globals.bPamPasswordChange = False;
5247 Globals.bPasswdChatDebug = False;
5248 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5249 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5250 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5251 Globals.bStatCache = True; /* use stat cache by default */
5252 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5253 Globals.restrict_anonymous = 0;
5254 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5255 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5256 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5257 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5258 Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
5259 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
5261 Globals.map_to_guest = 0; /* By Default, "Never" */
5262 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5263 Globals.enhanced_browsing = true;
5264 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5265 #ifdef MMAP_BLACKLIST
5266 Globals.bUseMmap = False;
5268 Globals.bUseMmap = True;
5270 Globals.bUnixExtensions = True;
5271 Globals.bResetOnZeroVC = False;
5272 Globals.bLogWriteableFilesOnExit = False;
5273 Globals.bCreateKrb5Conf = true;
5274 Globals.winbindMaxDomainConnections = 1;
5276 /* hostname lookups can be very expensive and are broken on
5277 a large number of sites (tridge) */
5278 Globals.bHostnameLookups = False;
5280 string_set(&Globals.szPassdbBackend, "tdbsam");
5281 string_set(&Globals.szLdapSuffix, "");
5282 string_set(&Globals.szLdapMachineSuffix, "");
5283 string_set(&Globals.szLdapUserSuffix, "");
5284 string_set(&Globals.szLdapGroupSuffix, "");
5285 string_set(&Globals.szLdapIdmapSuffix, "");
5287 string_set(&Globals.szLdapAdminDn, "");
5288 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5289 Globals.ldap_ssl_ads = False;
5290 Globals.ldap_deref = -1;
5291 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5292 Globals.ldap_delete_dn = False;
5293 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5294 Globals.ldap_follow_referral = Auto;
5295 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5296 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5297 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5299 Globals.ldap_debug_level = 0;
5300 Globals.ldap_debug_threshold = 10;
5302 /* This is what we tell the afs client. in reality we set the token
5303 * to never expire, though, when this runs out the afs client will
5304 * forget the token. Set to 0 to get NEVERDATE.*/
5305 Globals.iAfsTokenLifetime = 604800;
5306 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5308 /* these parameters are set to defaults that are more appropriate
5309 for the increasing samba install base:
5311 as a member of the workgroup, that will possibly become a
5312 _local_ master browser (lm = True). this is opposed to a forced
5313 local master browser startup (pm = True).
5315 doesn't provide WINS server service by default (wsupp = False),
5316 and doesn't provide domain master browser services by default, either.
5320 Globals.bMsAddPrinterWizard = True;
5321 Globals.os_level = 20;
5322 Globals.bLocalMaster = True;
5323 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5324 Globals.bDomainLogons = False;
5325 Globals.bBrowseList = True;
5326 Globals.bWINSsupport = False;
5327 Globals.bWINSproxy = False;
5329 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5330 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5332 Globals.bDNSproxy = True;
5334 /* this just means to use them if they exist */
5335 Globals.bKernelOplocks = True;
5337 Globals.bAllowTrustedDomains = True;
5338 string_set(&Globals.szIdmapBackend, "tdb");
5339 Globals.bIdmapReadOnly = false;
5341 string_set(&Globals.szTemplateShell, "/bin/false");
5342 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5343 string_set(&Globals.szWinbindSeparator, "\\");
5345 string_set(&Globals.szCupsServer, "");
5346 string_set(&Globals.szIPrintServer, "");
5348 string_set(&Globals.ctdbdSocket, "");
5349 Globals.szClusterAddresses = NULL;
5350 Globals.clustering = False;
5351 Globals.ctdb_timeout = 0;
5352 Globals.ctdb_locktime_warn_threshold = 0;
5354 Globals.winbind_cache_time = 300; /* 5 minutes */
5355 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5356 Globals.winbind_max_clients = 200;
5357 Globals.bWinbindEnumUsers = False;
5358 Globals.bWinbindEnumGroups = False;
5359 Globals.bWinbindUseDefaultDomain = False;
5360 Globals.bWinbindTrustedDomainsOnly = False;
5361 Globals.bWinbindNestedGroups = True;
5362 Globals.winbind_expand_groups = 1;
5363 Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
5364 Globals.bWinbindRefreshTickets = False;
5365 Globals.bWinbindOfflineLogon = False;
5367 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5368 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5370 Globals.bPassdbExpandExplicit = False;
5372 Globals.name_cache_timeout = 660; /* In seconds */
5374 Globals.bUseSpnego = True;
5375 Globals.bClientUseSpnego = True;
5377 Globals.client_signing = Auto;
5378 Globals.server_signing = False;
5380 Globals.bDeferSharingViolations = True;
5381 string_set(&Globals.smb_ports, SMB_PORTS);
5383 Globals.bEnablePrivileges = True;
5384 Globals.bHostMSDfs = True;
5385 Globals.bASUSupport = False;
5387 /* User defined shares. */
5388 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5389 smb_panic("init_globals: ENOMEM");
5391 string_set(&Globals.szUsersharePath, s);
5393 string_set(&Globals.szUsershareTemplateShare, "");
5394 Globals.iUsershareMaxShares = 0;
5395 /* By default disallow sharing of directories not owned by the sharer. */
5396 Globals.bUsershareOwnerOnly = True;
5397 /* By default disallow guest access to usershares. */
5398 Globals.bUsershareAllowGuests = False;
5400 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5402 /* By default no shares out of the registry */
5403 Globals.bRegistryShares = False;
5405 Globals.iminreceivefile = 0;
5407 Globals.bMapUntrustedToDomain = false;
5408 Globals.bMulticastDnsRegister = true;
5410 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
5411 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
5412 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
5413 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5415 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5417 /* Now put back the settings that were set with lp_set_cmdline() */
5418 apply_lp_set_cmdline();
5421 /*******************************************************************
5422 Convenience routine to grab string parameters into temporary memory
5423 and run standard_sub_basic on them. The buffers can be written to by
5424 callers without affecting the source string.
5425 ********************************************************************/
5427 static char *lp_string(const char *s)
5430 TALLOC_CTX *ctx = talloc_tos();
5432 /* The follow debug is useful for tracking down memory problems
5433 especially if you have an inner loop that is calling a lp_*()
5434 function that returns a string. Perhaps this debug should be
5435 present all the time? */
5438 DEBUG(10, ("lp_string(%s)\n", s));
5444 ret = talloc_sub_basic(ctx,
5445 get_current_username(),
5446 current_user_info.domain,
5448 if (trim_char(ret, '\"', '\"')) {
5449 if (strchr(ret,'\"') != NULL) {
5451 ret = talloc_sub_basic(ctx,
5452 get_current_username(),
5453 current_user_info.domain,
5461 In this section all the functions that are used to access the
5462 parameters from the rest of the program are defined
5465 #define FN_GLOBAL_STRING(fn_name,ptr) \
5466 char *fn_name(void) {return(lp_string(*(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5467 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5468 const char *fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5469 #define FN_GLOBAL_LIST(fn_name,ptr) \
5470 const char **fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5471 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5472 bool fn_name(void) {return(*(bool *)(&Globals.ptr));}
5473 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5474 char fn_name(void) {return(*(char *)(&Globals.ptr));}
5475 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5476 int fn_name(void) {return(*(int *)(&Globals.ptr));}
5478 #define FN_LOCAL_STRING(fn_name,val) \
5479 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5480 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5481 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5482 #define FN_LOCAL_LIST(fn_name,val) \
5483 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5484 #define FN_LOCAL_BOOL(fn_name,val) \
5485 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5486 #define FN_LOCAL_INTEGER(fn_name,val) \
5487 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5489 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5490 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5491 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5492 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5493 #define FN_LOCAL_CHAR(fn_name,val) \
5494 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5496 FN_GLOBAL_CONST_STRING(lp_smb_ports, smb_ports)
5497 FN_GLOBAL_CONST_STRING(lp_dos_charset, dos_charset)
5498 FN_GLOBAL_CONST_STRING(lp_unix_charset, unix_charset)
5499 FN_GLOBAL_STRING(lp_logfile, szLogFile)
5500 FN_GLOBAL_STRING(lp_configfile, szConfigFile)
5501 FN_GLOBAL_CONST_STRING(lp_smb_passwd_file, szSMBPasswdFile)
5502 FN_GLOBAL_CONST_STRING(lp_private_dir, szPrivateDir)
5503 FN_GLOBAL_STRING(lp_serverstring, szServerString)
5504 FN_GLOBAL_INTEGER(lp_printcap_cache_time, PrintcapCacheTime)
5505 FN_GLOBAL_STRING(lp_addport_cmd, szAddPortCommand)
5506 FN_GLOBAL_STRING(lp_enumports_cmd, szEnumPortsCommand)
5507 FN_GLOBAL_STRING(lp_addprinter_cmd, szAddPrinterCommand)
5508 FN_GLOBAL_STRING(lp_deleteprinter_cmd, szDeletePrinterCommand)
5509 FN_GLOBAL_STRING(lp_os2_driver_map, szOs2DriverMap)
5510 FN_GLOBAL_CONST_STRING(lp_lockdir, szLockDir)
5511 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5512 * build process or in smb.conf, we use that value. Otherwise they
5513 * default to the value of lp_lockdir(). */
5514 const char *lp_statedir(void) {
5515 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5516 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5517 return(*(char **)(&Globals.szStateDir) ?
5518 *(char **)(&Globals.szStateDir) : "");
5520 return(*(char **)(&Globals.szLockDir) ?
5521 *(char **)(&Globals.szLockDir) : "");
5523 const char *lp_cachedir(void) {
5524 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5525 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5526 return(*(char **)(&Globals.szCacheDir) ?
5527 *(char **)(&Globals.szCacheDir) : "");
5529 return(*(char **)(&Globals.szLockDir) ?
5530 *(char **)(&Globals.szLockDir) : "");
5532 FN_GLOBAL_CONST_STRING(lp_piddir, szPidDir)
5533 FN_GLOBAL_STRING(lp_mangling_method, szManglingMethod)
5534 FN_GLOBAL_INTEGER(lp_mangle_prefix, mangle_prefix)
5535 FN_GLOBAL_CONST_STRING(lp_utmpdir, szUtmpDir)
5536 FN_GLOBAL_CONST_STRING(lp_wtmpdir, szWtmpDir)
5537 FN_GLOBAL_BOOL(lp_utmp, bUtmp)
5538 FN_GLOBAL_STRING(lp_rootdir, szRootdir)
5539 FN_GLOBAL_STRING(lp_perfcount_module, szSMBPerfcountModule)
5540 FN_GLOBAL_STRING(lp_defaultservice, szDefaultService)
5541 FN_GLOBAL_STRING(lp_msg_command, szMsgCommand)
5542 FN_GLOBAL_STRING(lp_get_quota_command, szGetQuota)
5543 FN_GLOBAL_STRING(lp_set_quota_command, szSetQuota)
5544 FN_GLOBAL_STRING(lp_auto_services, szAutoServices)
5545 FN_GLOBAL_STRING(lp_passwd_program, szPasswdProgram)
5546 FN_GLOBAL_STRING(lp_passwd_chat, szPasswdChat)
5547 FN_GLOBAL_CONST_STRING(lp_passwordserver, szPasswordServer)
5548 FN_GLOBAL_CONST_STRING(lp_name_resolve_order, szNameResolveOrder)
5549 FN_GLOBAL_CONST_STRING(lp_workgroup, szWorkgroup)
5550 FN_GLOBAL_CONST_STRING(lp_netbios_name, szNetbiosName)
5551 FN_GLOBAL_CONST_STRING(lp_netbios_scope, szNetbiosScope)
5552 FN_GLOBAL_CONST_STRING(lp_realm, szRealmUpper)
5553 FN_GLOBAL_CONST_STRING(lp_dnsdomain, szDnsDomain)
5554 FN_GLOBAL_CONST_STRING(lp_afs_username_map, szAfsUsernameMap)
5555 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, iAfsTokenLifetime)
5556 FN_GLOBAL_STRING(lp_log_nt_token_command, szLogNtTokenCommand)
5557 FN_GLOBAL_STRING(lp_username_map, szUsernameMap)
5558 FN_GLOBAL_CONST_STRING(lp_logon_script, szLogonScript)
5559 FN_GLOBAL_CONST_STRING(lp_logon_path, szLogonPath)
5560 FN_GLOBAL_CONST_STRING(lp_logon_drive, szLogonDrive)
5561 FN_GLOBAL_CONST_STRING(lp_logon_home, szLogonHome)
5562 FN_GLOBAL_STRING(lp_remote_announce, szRemoteAnnounce)
5563 FN_GLOBAL_STRING(lp_remote_browse_sync, szRemoteBrowseSync)
5564 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, bNmbdBindExplicitBroadcast)
5565 FN_GLOBAL_LIST(lp_wins_server_list, szWINSservers)
5566 FN_GLOBAL_LIST(lp_interfaces, szInterfaces)
5567 FN_GLOBAL_STRING(lp_nis_home_map_name, szNISHomeMapName)
5568 FN_GLOBAL_LIST(lp_netbios_aliases, szNetbiosAliases)
5569 FN_GLOBAL_CONST_STRING(lp_passdb_backend, szPassdbBackend)
5570 FN_GLOBAL_LIST(lp_preload_modules, szPreloadModules)
5571 FN_GLOBAL_STRING(lp_panic_action, szPanicAction)
5572 FN_GLOBAL_STRING(lp_adduser_script, szAddUserScript)
5573 FN_GLOBAL_STRING(lp_renameuser_script, szRenameUserScript)
5574 FN_GLOBAL_STRING(lp_deluser_script, szDelUserScript)
5576 FN_GLOBAL_CONST_STRING(lp_guestaccount, szGuestaccount)
5577 FN_GLOBAL_STRING(lp_addgroup_script, szAddGroupScript)
5578 FN_GLOBAL_STRING(lp_delgroup_script, szDelGroupScript)
5579 FN_GLOBAL_STRING(lp_addusertogroup_script, szAddUserToGroupScript)
5580 FN_GLOBAL_STRING(lp_deluserfromgroup_script, szDelUserFromGroupScript)
5581 FN_GLOBAL_STRING(lp_setprimarygroup_script, szSetPrimaryGroupScript)
5583 FN_GLOBAL_STRING(lp_addmachine_script, szAddMachineScript)
5585 FN_GLOBAL_STRING(lp_shutdown_script, szShutdownScript)
5586 FN_GLOBAL_STRING(lp_abort_shutdown_script, szAbortShutdownScript)
5587 FN_GLOBAL_STRING(lp_username_map_script, szUsernameMapScript)
5588 FN_GLOBAL_INTEGER(lp_username_map_cache_time, iUsernameMapCacheTime)
5590 FN_GLOBAL_STRING(lp_check_password_script, szCheckPasswordScript)
5592 FN_GLOBAL_STRING(lp_wins_hook, szWINSHook)
5593 FN_GLOBAL_CONST_STRING(lp_template_homedir, szTemplateHomedir)
5594 FN_GLOBAL_CONST_STRING(lp_template_shell, szTemplateShell)
5595 FN_GLOBAL_CONST_STRING(lp_winbind_separator, szWinbindSeparator)
5596 FN_GLOBAL_INTEGER(lp_acl_compatibility, iAclCompat)
5597 FN_GLOBAL_BOOL(lp_winbind_enum_users, bWinbindEnumUsers)
5598 FN_GLOBAL_BOOL(lp_winbind_enum_groups, bWinbindEnumGroups)
5599 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, bWinbindUseDefaultDomain)
5600 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, bWinbindTrustedDomainsOnly)
5601 FN_GLOBAL_BOOL(lp_winbind_nested_groups, bWinbindNestedGroups)
5602 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, winbind_expand_groups)
5603 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, bWinbindRefreshTickets)
5604 FN_GLOBAL_BOOL(lp_winbind_offline_logon, bWinbindOfflineLogon)
5605 FN_GLOBAL_BOOL(lp_winbind_normalize_names, bWinbindNormalizeNames)
5606 FN_GLOBAL_BOOL(lp_winbind_rpc_only, bWinbindRpcOnly)
5607 FN_GLOBAL_BOOL(lp_create_krb5_conf, bCreateKrb5Conf)
5608 static FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections_int,
5609 winbindMaxDomainConnections)
5611 int lp_winbind_max_domain_connections(void)
5613 if (lp_winbind_offline_logon() &&
5614 lp_winbind_max_domain_connections_int() > 1) {
5615 DEBUG(1, ("offline logons active, restricting max domain "
5616 "connections to 1\n"));
5619 return MAX(1, lp_winbind_max_domain_connections_int());
5622 FN_GLOBAL_CONST_STRING(lp_idmap_backend, szIdmapBackend)
5623 FN_GLOBAL_INTEGER(lp_idmap_cache_time, iIdmapCacheTime)
5624 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, iIdmapNegativeCacheTime)
5625 FN_GLOBAL_INTEGER(lp_keepalive, iKeepalive)
5626 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, bPassdbExpandExplicit)
5628 FN_GLOBAL_STRING(lp_ldap_suffix, szLdapSuffix)
5629 FN_GLOBAL_STRING(lp_ldap_admin_dn, szLdapAdminDn)
5630 FN_GLOBAL_INTEGER(lp_ldap_ssl, ldap_ssl)
5631 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, ldap_ssl_ads)
5632 FN_GLOBAL_INTEGER(lp_ldap_deref, ldap_deref)
5633 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, ldap_follow_referral)
5634 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, ldap_passwd_sync)
5635 FN_GLOBAL_BOOL(lp_ldap_delete_dn, ldap_delete_dn)
5636 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, ldap_replication_sleep)
5637 FN_GLOBAL_INTEGER(lp_ldap_timeout, ldap_timeout)
5638 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, ldap_connection_timeout)
5639 FN_GLOBAL_INTEGER(lp_ldap_page_size, ldap_page_size)
5640 FN_GLOBAL_INTEGER(lp_ldap_debug_level, ldap_debug_level)
5641 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, ldap_debug_threshold)
5642 FN_GLOBAL_STRING(lp_add_share_cmd, szAddShareCommand)
5643 FN_GLOBAL_STRING(lp_change_share_cmd, szChangeShareCommand)
5644 FN_GLOBAL_STRING(lp_delete_share_cmd, szDeleteShareCommand)
5645 FN_GLOBAL_STRING(lp_usershare_path, szUsersharePath)
5646 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, szUsersharePrefixAllowList)
5647 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, szUsersharePrefixDenyList)
5649 FN_GLOBAL_LIST(lp_eventlog_list, szEventLogs)
5651 FN_GLOBAL_BOOL(lp_registry_shares, bRegistryShares)
5652 FN_GLOBAL_BOOL(lp_usershare_allow_guests, bUsershareAllowGuests)
5653 FN_GLOBAL_BOOL(lp_usershare_owner_only, bUsershareOwnerOnly)
5654 FN_GLOBAL_BOOL(lp_disable_netbios, bDisableNetbios)
5655 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, bResetOnZeroVC)
5656 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5657 bLogWriteableFilesOnExit)
5658 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, bMsAddPrinterWizard)
5659 FN_GLOBAL_BOOL(lp_dns_proxy, bDNSproxy)
5660 FN_GLOBAL_BOOL(lp_wins_support, bWINSsupport)
5661 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, bWINSsupport)
5662 FN_GLOBAL_BOOL(lp_wins_proxy, bWINSproxy)
5663 FN_GLOBAL_BOOL(lp_local_master, bLocalMaster)
5664 FN_GLOBAL_BOOL(lp_domain_logons, bDomainLogons)
5665 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, szInitLogonDelayedHosts)
5666 FN_GLOBAL_INTEGER(lp_init_logon_delay, InitLogonDelay)
5667 FN_GLOBAL_BOOL(lp_load_printers, bLoadPrinters)
5668 FN_GLOBAL_BOOL(_lp_readraw, bReadRaw)
5669 FN_GLOBAL_BOOL(lp_large_readwrite, bLargeReadwrite)
5670 FN_GLOBAL_BOOL(_lp_writeraw, bWriteRaw)
5671 FN_GLOBAL_BOOL(lp_null_passwords, bNullPasswords)
5672 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, bObeyPamRestrictions)
5673 FN_GLOBAL_BOOL(lp_encrypted_passwords, bEncryptPasswords)
5674 FN_GLOBAL_INTEGER(lp_client_schannel, clientSchannel)
5675 FN_GLOBAL_INTEGER(lp_server_schannel, serverSchannel)
5676 FN_GLOBAL_BOOL(lp_syslog_only, bSyslogOnly)
5677 FN_GLOBAL_BOOL(lp_timestamp_logs, bTimestampLogs)
5678 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, bDebugPrefixTimestamp)
5679 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, bDebugHiresTimestamp)
5680 FN_GLOBAL_BOOL(lp_debug_pid, bDebugPid)
5681 FN_GLOBAL_BOOL(lp_debug_uid, bDebugUid)
5682 FN_GLOBAL_BOOL(lp_debug_class, bDebugClass)
5683 FN_GLOBAL_BOOL(lp_enable_core_files, bEnableCoreFiles)
5684 FN_GLOBAL_BOOL(lp_browse_list, bBrowseList)
5685 FN_GLOBAL_BOOL(lp_nis_home_map, bNISHomeMap)
5686 static FN_GLOBAL_BOOL(lp_time_server, bTimeServer)
5687 FN_GLOBAL_BOOL(lp_bind_interfaces_only, bBindInterfacesOnly)
5688 FN_GLOBAL_BOOL(lp_pam_password_change, bPamPasswordChange)
5689 FN_GLOBAL_BOOL(lp_unix_password_sync, bUnixPasswdSync)
5690 FN_GLOBAL_BOOL(lp_passwd_chat_debug, bPasswdChatDebug)
5691 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, iPasswdChatTimeout)
5692 FN_GLOBAL_BOOL(lp_nt_pipe_support, bNTPipeSupport)
5693 FN_GLOBAL_BOOL(lp_nt_status_support, bNTStatusSupport)
5694 FN_GLOBAL_BOOL(lp_stat_cache, bStatCache)
5695 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, iMaxStatCacheSize)
5696 FN_GLOBAL_BOOL(lp_allow_trusted_domains, bAllowTrustedDomains)
5697 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, bMapUntrustedToDomain)
5698 FN_GLOBAL_INTEGER(lp_restrict_anonymous, restrict_anonymous)
5699 FN_GLOBAL_BOOL(lp_lanman_auth, bLanmanAuth)
5700 FN_GLOBAL_BOOL(lp_ntlm_auth, bNTLMAuth)
5701 FN_GLOBAL_BOOL(lp_client_plaintext_auth, bClientPlaintextAuth)
5702 FN_GLOBAL_BOOL(lp_client_lanman_auth, bClientLanManAuth)
5703 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, bClientNTLMv2Auth)
5704 FN_GLOBAL_BOOL(lp_host_msdfs, bHostMSDfs)
5705 FN_GLOBAL_BOOL(lp_kernel_oplocks, bKernelOplocks)
5706 FN_GLOBAL_BOOL(lp_enhanced_browsing, enhanced_browsing)
5707 FN_GLOBAL_BOOL(lp_use_mmap, bUseMmap)
5708 FN_GLOBAL_BOOL(lp_unix_extensions, bUnixExtensions)
5709 FN_GLOBAL_BOOL(lp_use_spnego, bUseSpnego)
5710 FN_GLOBAL_BOOL(lp_client_use_spnego, bClientUseSpnego)
5711 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, client_use_spnego_principal)
5712 FN_GLOBAL_BOOL(lp_send_spnego_principal, send_spnego_principal)
5713 FN_GLOBAL_BOOL(lp_hostname_lookups, bHostnameLookups)
5714 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5715 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5716 FN_GLOBAL_CONST_STRING(lp_dedicated_keytab_file, szDedicatedKeytabFile)
5717 FN_GLOBAL_INTEGER(lp_kerberos_method, iKerberosMethod)
5718 FN_GLOBAL_BOOL(lp_defer_sharing_violations, bDeferSharingViolations)
5719 FN_GLOBAL_BOOL(lp_enable_privileges, bEnablePrivileges)
5720 FN_GLOBAL_BOOL(lp_enable_asu_support, bASUSupport)
5721 FN_GLOBAL_INTEGER(lp_os_level, os_level)
5722 FN_GLOBAL_INTEGER(lp_max_ttl, max_ttl)
5723 FN_GLOBAL_INTEGER(lp_max_wins_ttl, max_wins_ttl)
5724 FN_GLOBAL_INTEGER(lp_min_wins_ttl, min_wins_ttl)
5725 FN_GLOBAL_INTEGER(lp_max_log_size, max_log_size)
5726 FN_GLOBAL_INTEGER(lp_max_open_files, max_open_files)
5727 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, open_files_db_hash_size)
5728 FN_GLOBAL_INTEGER(lp_maxxmit, max_xmit)
5729 FN_GLOBAL_INTEGER(lp_maxmux, max_mux)
5730 FN_GLOBAL_INTEGER(lp_passwordlevel, pwordlevel)
5731 FN_GLOBAL_INTEGER(lp_usernamelevel, unamelevel)
5732 FN_GLOBAL_INTEGER(lp_deadtime, deadtime)
5733 FN_GLOBAL_BOOL(lp_getwd_cache, getwd_cache)
5734 static FN_GLOBAL_INTEGER(_lp_maxprotocol, maxprotocol)
5735 int lp_maxprotocol(void)
5737 int ret = _lp_maxprotocol();
5738 if ((ret == PROTOCOL_SMB2) && (lp_security() == SEC_SHARE)) {
5739 DEBUG(2,("WARNING!!: \"security = share\" is incompatible "
5740 "with the SMB2 protocol. Resetting to SMB1.\n" ));
5741 lp_do_parameter(-1, "max protocol", "NT1");
5742 return PROTOCOL_NT1;
5746 FN_GLOBAL_INTEGER(lp_minprotocol, minprotocol)
5747 FN_GLOBAL_INTEGER(lp_security, security)
5748 FN_GLOBAL_LIST(lp_auth_methods, AuthMethods)
5749 FN_GLOBAL_BOOL(lp_paranoid_server_security, paranoid_server_security)
5750 FN_GLOBAL_INTEGER(lp_maxdisksize, maxdisksize)
5751 FN_GLOBAL_INTEGER(lp_lpqcachetime, lpqcachetime)
5752 FN_GLOBAL_INTEGER(lp_max_smbd_processes, iMaxSmbdProcesses)
5753 FN_GLOBAL_BOOL(_lp_disable_spoolss, bDisableSpoolss)
5754 FN_GLOBAL_INTEGER(lp_syslog, syslog)
5755 FN_GLOBAL_INTEGER(lp_lm_announce, lm_announce)
5756 FN_GLOBAL_INTEGER(lp_lm_interval, lm_interval)
5757 FN_GLOBAL_INTEGER(lp_machine_password_timeout, machine_password_timeout)
5758 FN_GLOBAL_INTEGER(lp_map_to_guest, map_to_guest)
5759 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, oplock_break_wait_time)
5760 FN_GLOBAL_INTEGER(lp_lock_spin_time, iLockSpinTime)
5761 FN_GLOBAL_INTEGER(lp_usershare_max_shares, iUsershareMaxShares)
5762 FN_GLOBAL_CONST_STRING(lp_socket_options, szSocketOptions)
5763 FN_GLOBAL_INTEGER(lp_config_backend, ConfigBackend)
5764 FN_GLOBAL_INTEGER(lp_smb2_max_read, ismb2_max_read)
5765 FN_GLOBAL_INTEGER(lp_smb2_max_write, ismb2_max_write)
5766 FN_GLOBAL_INTEGER(lp_smb2_max_trans, ismb2_max_trans)
5767 int lp_smb2_max_credits(void)
5769 if (Globals.ismb2_max_credits == 0) {
5770 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5772 return Globals.ismb2_max_credits;
5774 FN_LOCAL_STRING(lp_preexec, szPreExec)
5775 FN_LOCAL_STRING(lp_postexec, szPostExec)
5776 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5777 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5778 FN_LOCAL_STRING(lp_servicename, szService)
5779 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5780 FN_LOCAL_STRING(lp_pathname, szPath)
5781 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5782 FN_LOCAL_STRING(lp_username, szUsername)
5783 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5784 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5785 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5786 FN_GLOBAL_LIST(lp_svcctl_list, szServicesList)
5787 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5788 FN_GLOBAL_STRING(lp_cups_server, szCupsServer)
5789 int lp_cups_encrypt(void)
5792 #ifdef HAVE_HTTPCONNECTENCRYPT
5793 switch (Globals.CupsEncrypt) {
5795 result = HTTP_ENCRYPT_REQUIRED;
5798 result = HTTP_ENCRYPT_ALWAYS;
5801 result = HTTP_ENCRYPT_NEVER;
5807 FN_GLOBAL_STRING(lp_iprint_server, szIPrintServer)
5808 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, cups_connection_timeout)
5809 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, ctdbdSocket)
5810 FN_GLOBAL_LIST(lp_cluster_addresses, szClusterAddresses)
5811 FN_GLOBAL_BOOL(lp_clustering, clustering)
5812 FN_GLOBAL_INTEGER(lp_ctdb_timeout, ctdb_timeout)
5813 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, ctdb_locktime_warn_threshold)
5814 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5815 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5816 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5817 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5818 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5819 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5820 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5821 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5822 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5823 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5824 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5825 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5826 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5827 FN_LOCAL_STRING(lp_comment, comment)
5828 FN_LOCAL_STRING(lp_force_user, force_user)
5829 FN_LOCAL_STRING(lp_force_group, force_group)
5830 FN_LOCAL_LIST(lp_readlist, readlist)
5831 FN_LOCAL_LIST(lp_writelist, writelist)
5832 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5833 FN_LOCAL_STRING(lp_fstype, fstype)
5834 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5835 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5836 static FN_LOCAL_STRING(lp_volume, volume)
5837 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5838 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5839 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5840 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5841 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5842 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5843 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5844 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5845 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5846 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5847 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5848 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5849 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5850 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5851 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5852 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5853 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5854 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5855 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5856 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5857 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5858 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5859 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5860 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5861 FN_LOCAL_BOOL(lp_print_notify_backchannel, bPrintNotifyBackchannel)
5862 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5863 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5864 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5865 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5866 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5867 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5868 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5869 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5870 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5871 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5872 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5873 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5874 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5875 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5876 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5877 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5878 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5879 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5880 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5881 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5882 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5883 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5884 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5885 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5886 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, bAsyncSMBEchoHandler)
5887 FN_GLOBAL_BOOL(lp_multicast_dns_register, bMulticastDnsRegister)
5888 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5889 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5890 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5891 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5892 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5893 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5894 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5895 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5896 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5897 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5898 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5899 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5900 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5901 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5902 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5903 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5904 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5905 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5906 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5907 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5908 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5909 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5910 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5911 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5912 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5913 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5914 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5915 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5916 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5917 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5918 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5919 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5920 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5921 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5922 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5923 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5924 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5925 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5926 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5927 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5928 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5929 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5930 FN_GLOBAL_INTEGER(lp_winbind_cache_time, winbind_cache_time)
5931 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, winbind_reconnect_delay)
5932 FN_GLOBAL_INTEGER(lp_winbind_max_clients, winbind_max_clients)
5933 FN_GLOBAL_LIST(lp_winbind_nss_info, szWinbindNssInfo)
5934 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, AlgorithmicRidBase)
5935 FN_GLOBAL_INTEGER(lp_name_cache_timeout, name_cache_timeout)
5936 FN_GLOBAL_INTEGER(lp_client_signing, client_signing)
5937 FN_GLOBAL_INTEGER(lp_server_signing, server_signing)
5938 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, client_ldap_sasl_wrapping)
5940 FN_GLOBAL_CONST_STRING(lp_ncalrpc_dir, ncalrpc_dir)
5942 /* local prototypes */
5944 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5945 static const char *get_boolean(bool bool_value);
5946 static int getservicebyname(const char *pszServiceName,
5947 struct loadparm_service *pserviceDest);
5948 static void copy_service(struct loadparm_service *pserviceDest,
5949 struct loadparm_service *pserviceSource,
5950 struct bitmap *pcopymapDest);
5951 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5953 static bool do_section(const char *pszSectionName, void *userdata);
5954 static void init_copymap(struct loadparm_service *pservice);
5955 static bool hash_a_service(const char *name, int number);
5956 static void free_service_byindex(int iService);
5957 static void free_param_opts(struct param_opt_struct **popts);
5958 static void show_parameter(int parmIndex);
5959 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5962 * This is a helper function for parametrical options support. It returns a
5963 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5964 * parametrical functions are quite simple
5966 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5969 bool global_section = False;
5971 struct param_opt_struct *data;
5973 if (snum >= iNumServices) return NULL;
5976 data = Globals.param_opt;
5977 global_section = True;
5979 data = ServicePtrs[snum]->param_opt;
5982 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5983 DEBUG(0,("asprintf failed!\n"));
5988 if (strwicmp(data->key, param_key) == 0) {
5989 string_free(¶m_key);
5995 if (!global_section) {
5996 /* Try to fetch the same option but from globals */
5997 /* but only if we are not already working with Globals */
5998 data = Globals.param_opt;
6000 if (strwicmp(data->key, param_key) == 0) {
6001 string_free(¶m_key);
6008 string_free(¶m_key);
6014 #define MISSING_PARAMETER(name) \
6015 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
6017 /*******************************************************************
6018 convenience routine to return int parameters.
6019 ********************************************************************/
6020 static int lp_int(const char *s)
6024 MISSING_PARAMETER(lp_int);
6028 return (int)strtol(s, NULL, 0);
6031 /*******************************************************************
6032 convenience routine to return unsigned long parameters.
6033 ********************************************************************/
6034 static unsigned long lp_ulong(const char *s)
6038 MISSING_PARAMETER(lp_ulong);
6042 return strtoul(s, NULL, 0);
6045 /*******************************************************************
6046 convenience routine to return boolean parameters.
6047 ********************************************************************/
6048 static bool lp_bool(const char *s)
6053 MISSING_PARAMETER(lp_bool);
6057 if (!set_boolean(s, &ret)) {
6058 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
6065 /*******************************************************************
6066 convenience routine to return enum parameters.
6067 ********************************************************************/
6068 static int lp_enum(const char *s,const struct enum_list *_enum)
6072 if (!s || !*s || !_enum) {
6073 MISSING_PARAMETER(lp_enum);
6077 for (i=0; _enum[i].name; i++) {
6078 if (strequal(_enum[i].name,s))
6079 return _enum[i].value;
6082 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
6086 #undef MISSING_PARAMETER
6088 /* Return parametric option from a given service. Type is a part of option before ':' */
6089 /* Parametric option has following syntax: 'Type: option = value' */
6090 /* the returned value is talloced on the talloc_tos() */
6091 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
6093 struct param_opt_struct *data = get_parametrics(snum, type, option);
6095 if (data == NULL||data->value==NULL) {
6097 return lp_string(def);
6103 return lp_string(data->value);
6106 /* Return parametric option from a given service. Type is a part of option before ':' */
6107 /* Parametric option has following syntax: 'Type: option = value' */
6108 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6110 struct param_opt_struct *data = get_parametrics(snum, type, option);
6112 if (data == NULL||data->value==NULL)
6118 /* Return parametric option from a given service. Type is a part of option before ':' */
6119 /* Parametric option has following syntax: 'Type: option = value' */
6121 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6123 struct param_opt_struct *data = get_parametrics(snum, type, option);
6125 if (data == NULL||data->value==NULL)
6126 return (const char **)def;
6128 if (data->list==NULL) {
6129 data->list = str_list_make_v3(NULL, data->value, NULL);
6132 return (const char **)data->list;
6135 /* Return parametric option from a given service. Type is a part of option before ':' */
6136 /* Parametric option has following syntax: 'Type: option = value' */
6138 int lp_parm_int(int snum, const char *type, const char *option, int def)
6140 struct param_opt_struct *data = get_parametrics(snum, type, option);
6142 if (data && data->value && *data->value)
6143 return lp_int(data->value);
6148 /* Return parametric option from a given service. Type is a part of option before ':' */
6149 /* Parametric option has following syntax: 'Type: option = value' */
6151 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6153 struct param_opt_struct *data = get_parametrics(snum, type, option);
6155 if (data && data->value && *data->value)
6156 return lp_ulong(data->value);
6161 /* Return parametric option from a given service. Type is a part of option before ':' */
6162 /* Parametric option has following syntax: 'Type: option = value' */
6164 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6166 struct param_opt_struct *data = get_parametrics(snum, type, option);
6168 if (data && data->value && *data->value)
6169 return lp_bool(data->value);
6174 /* Return parametric option from a given service. Type is a part of option before ':' */
6175 /* Parametric option has following syntax: 'Type: option = value' */
6177 int lp_parm_enum(int snum, const char *type, const char *option,
6178 const struct enum_list *_enum, int def)
6180 struct param_opt_struct *data = get_parametrics(snum, type, option);
6182 if (data && data->value && *data->value && _enum)
6183 return lp_enum(data->value, _enum);
6189 /***************************************************************************
6190 Initialise a service to the defaults.
6191 ***************************************************************************/
6193 static void init_service(struct loadparm_service *pservice)
6195 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
6196 copy_service(pservice, &sDefault, NULL);
6201 * free a param_opts structure.
6202 * param_opts handling should be moved to talloc;
6203 * then this whole functions reduces to a TALLOC_FREE().
6206 static void free_param_opts(struct param_opt_struct **popts)
6208 struct param_opt_struct *opt, *next_opt;
6210 if (popts == NULL) {
6214 if (*popts != NULL) {
6215 DEBUG(5, ("Freeing parametrics:\n"));
6218 while (opt != NULL) {
6219 string_free(&opt->key);
6220 string_free(&opt->value);
6221 TALLOC_FREE(opt->list);
6222 next_opt = opt->next;
6229 /***************************************************************************
6230 Free the dynamically allocated parts of a service struct.
6231 ***************************************************************************/
6233 static void free_service(struct loadparm_service *pservice)
6238 if (pservice->szService)
6239 DEBUG(5, ("free_service: Freeing service %s\n",
6240 pservice->szService));
6242 free_parameters(pservice);
6244 string_free(&pservice->szService);
6245 TALLOC_FREE(pservice->copymap);
6247 free_param_opts(&pservice->param_opt);
6249 ZERO_STRUCTP(pservice);
6253 /***************************************************************************
6254 remove a service indexed in the ServicePtrs array from the ServiceHash
6255 and free the dynamically allocated parts
6256 ***************************************************************************/
6258 static void free_service_byindex(int idx)
6260 if ( !LP_SNUM_OK(idx) )
6263 ServicePtrs[idx]->valid = False;
6264 invalid_services[num_invalid_services++] = idx;
6266 /* we have to cleanup the hash record */
6268 if (ServicePtrs[idx]->szService) {
6269 char *canon_name = canonicalize_servicename(
6271 ServicePtrs[idx]->szService );
6273 dbwrap_delete_bystring(ServiceHash, canon_name );
6274 TALLOC_FREE(canon_name);
6277 free_service(ServicePtrs[idx]);
6280 /***************************************************************************
6281 Add a new service to the services array initialising it with the given
6283 ***************************************************************************/
6285 static int add_a_service(const struct loadparm_service *pservice, const char *name)
6288 struct loadparm_service tservice;
6289 int num_to_alloc = iNumServices + 1;
6291 tservice = *pservice;
6293 /* it might already exist */
6295 i = getservicebyname(name, NULL);
6301 /* find an invalid one */
6303 if (num_invalid_services > 0) {
6304 i = invalid_services[--num_invalid_services];
6307 /* if not, then create one */
6308 if (i == iNumServices) {
6309 struct loadparm_service **tsp;
6312 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
6314 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6318 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct loadparm_service);
6319 if (!ServicePtrs[iNumServices]) {
6320 DEBUG(0,("add_a_service: out of memory!\n"));
6325 /* enlarge invalid_services here for now... */
6326 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6328 if (tinvalid == NULL) {
6329 DEBUG(0,("add_a_service: failed to enlarge "
6330 "invalid_services!\n"));
6333 invalid_services = tinvalid;
6335 free_service_byindex(i);
6338 ServicePtrs[i]->valid = True;
6340 init_service(ServicePtrs[i]);
6341 copy_service(ServicePtrs[i], &tservice, NULL);
6343 string_set(&ServicePtrs[i]->szService, name);
6345 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6346 i, ServicePtrs[i]->szService));
6348 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6355 /***************************************************************************
6356 Convert a string to uppercase and remove whitespaces.
6357 ***************************************************************************/
6359 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6364 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6368 result = talloc_strdup(ctx, src);
6369 SMB_ASSERT(result != NULL);
6375 /***************************************************************************
6376 Add a name/index pair for the services array to the hash table.
6377 ***************************************************************************/
6379 static bool hash_a_service(const char *name, int idx)
6383 if ( !ServiceHash ) {
6384 DEBUG(10,("hash_a_service: creating servicehash\n"));
6385 ServiceHash = db_open_rbt(NULL);
6386 if ( !ServiceHash ) {
6387 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6392 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6395 canon_name = canonicalize_servicename(talloc_tos(), name );
6397 dbwrap_store_bystring(ServiceHash, canon_name,
6398 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6401 TALLOC_FREE(canon_name);
6406 /***************************************************************************
6407 Add a new home service, with the specified home directory, defaults coming
6409 ***************************************************************************/
6411 bool lp_add_home(const char *pszHomename, int iDefaultService,
6412 const char *user, const char *pszHomedir)
6416 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6417 pszHomedir[0] == '\0') {
6421 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6426 if (!(*(ServicePtrs[iDefaultService]->szPath))
6427 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6428 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6431 if (!(*(ServicePtrs[i]->comment))) {
6432 char *comment = NULL;
6433 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6436 string_set(&ServicePtrs[i]->comment, comment);
6440 /* set the browseable flag from the global default */
6442 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6443 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6445 ServicePtrs[i]->autoloaded = True;
6447 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6448 user, ServicePtrs[i]->szPath ));
6453 /***************************************************************************
6454 Add a new service, based on an old one.
6455 ***************************************************************************/
6457 int lp_add_service(const char *pszService, int iDefaultService)
6459 if (iDefaultService < 0) {
6460 return add_a_service(&sDefault, pszService);
6463 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6466 /***************************************************************************
6467 Add the IPC service.
6468 ***************************************************************************/
6470 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6472 char *comment = NULL;
6473 int i = add_a_service(&sDefault, ipc_name);
6478 if (asprintf(&comment, "IPC Service (%s)",
6479 Globals.szServerString) < 0) {
6483 string_set(&ServicePtrs[i]->szPath, tmpdir());
6484 string_set(&ServicePtrs[i]->szUsername, "");
6485 string_set(&ServicePtrs[i]->comment, comment);
6486 string_set(&ServicePtrs[i]->fstype, "IPC");
6487 ServicePtrs[i]->iMaxConnections = 0;
6488 ServicePtrs[i]->bAvailable = True;
6489 ServicePtrs[i]->bRead_only = True;
6490 ServicePtrs[i]->bGuest_only = False;
6491 ServicePtrs[i]->bAdministrative_share = True;
6492 ServicePtrs[i]->bGuest_ok = guest_ok;
6493 ServicePtrs[i]->bPrint_ok = False;
6494 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6496 DEBUG(3, ("adding IPC service\n"));
6502 /***************************************************************************
6503 Add a new printer service, with defaults coming from service iFrom.
6504 ***************************************************************************/
6506 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6508 const char *comment = "From Printcap";
6509 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6514 /* note that we do NOT default the availability flag to True - */
6515 /* we take it from the default service passed. This allows all */
6516 /* dynamic printers to be disabled by disabling the [printers] */
6517 /* entry (if/when the 'available' keyword is implemented!). */
6519 /* the printer name is set to the service name. */
6520 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6521 string_set(&ServicePtrs[i]->comment, comment);
6523 /* set the browseable flag from the gloabl default */
6524 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6526 /* Printers cannot be read_only. */
6527 ServicePtrs[i]->bRead_only = False;
6528 /* No share modes on printer services. */
6529 ServicePtrs[i]->bShareModes = False;
6530 /* No oplocks on printer services. */
6531 ServicePtrs[i]->bOpLocks = False;
6532 /* Printer services must be printable. */
6533 ServicePtrs[i]->bPrint_ok = True;
6535 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6541 /***************************************************************************
6542 Check whether the given parameter name is valid.
6543 Parametric options (names containing a colon) are considered valid.
6544 ***************************************************************************/
6546 bool lp_parameter_is_valid(const char *pszParmName)
6548 return ((map_parameter(pszParmName) != -1) ||
6549 (strchr(pszParmName, ':') != NULL));
6552 /***************************************************************************
6553 Check whether the given name is the name of a global parameter.
6554 Returns True for strings belonging to parameters of class
6555 P_GLOBAL, False for all other strings, also for parametric options
6556 and strings not belonging to any option.
6557 ***************************************************************************/
6559 bool lp_parameter_is_global(const char *pszParmName)
6561 int num = map_parameter(pszParmName);
6564 return (parm_table[num].p_class == P_GLOBAL);
6570 /**************************************************************************
6571 Check whether the given name is the canonical name of a parameter.
6572 Returns False if it is not a valid parameter Name.
6573 For parametric options, True is returned.
6574 **************************************************************************/
6576 bool lp_parameter_is_canonical(const char *parm_name)
6578 if (!lp_parameter_is_valid(parm_name)) {
6582 return (map_parameter(parm_name) ==
6583 map_parameter_canonical(parm_name, NULL));
6586 /**************************************************************************
6587 Determine the canonical name for a parameter.
6588 Indicate when it is an inverse (boolean) synonym instead of a
6590 **************************************************************************/
6592 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6597 if (!lp_parameter_is_valid(parm_name)) {
6602 num = map_parameter_canonical(parm_name, inverse);
6604 /* parametric option */
6605 *canon_parm = parm_name;
6607 *canon_parm = parm_table[num].label;
6614 /**************************************************************************
6615 Determine the canonical name for a parameter.
6616 Turn the value given into the inverse boolean expression when
6617 the synonym is an invers boolean synonym.
6619 Return True if parm_name is a valid parameter name and
6620 in case it is an invers boolean synonym, if the val string could
6621 successfully be converted to the reverse bool.
6622 Return false in all other cases.
6623 **************************************************************************/
6625 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6627 const char **canon_parm,
6628 const char **canon_val)
6633 if (!lp_parameter_is_valid(parm_name)) {
6639 num = map_parameter_canonical(parm_name, &inverse);
6641 /* parametric option */
6642 *canon_parm = parm_name;
6645 *canon_parm = parm_table[num].label;
6647 if (!lp_invert_boolean(val, canon_val)) {
6659 /***************************************************************************
6660 Map a parameter's string representation to something we can use.
6661 Returns False if the parameter string is not recognised, else TRUE.
6662 ***************************************************************************/
6664 static int map_parameter(const char *pszParmName)
6668 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6671 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6672 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6675 /* Warn only if it isn't parametric option */
6676 if (strchr(pszParmName, ':') == NULL)
6677 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6678 /* We do return 'fail' for parametric options as well because they are
6679 stored in different storage
6684 /***************************************************************************
6685 Map a parameter's string representation to the index of the canonical
6686 form of the parameter (it might be a synonym).
6687 Returns -1 if the parameter string is not recognised.
6688 ***************************************************************************/
6690 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6692 int parm_num, canon_num;
6693 bool loc_inverse = False;
6695 parm_num = map_parameter(pszParmName);
6696 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6697 /* invalid, parametric or no canidate for synonyms ... */
6701 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6702 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6703 parm_num = canon_num;
6709 if (inverse != NULL) {
6710 *inverse = loc_inverse;
6715 /***************************************************************************
6716 return true if parameter number parm1 is a synonym of parameter
6717 number parm2 (parm2 being the principal name).
6718 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6720 ***************************************************************************/
6722 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6724 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6725 (parm_table[parm1].flags & FLAG_HIDE) &&
6726 !(parm_table[parm2].flags & FLAG_HIDE))
6728 if (inverse != NULL) {
6729 if ((parm_table[parm1].type == P_BOOLREV) &&
6730 (parm_table[parm2].type == P_BOOL))
6742 /***************************************************************************
6743 Show one parameter's name, type, [values,] and flags.
6744 (helper functions for show_parameter_list)
6745 ***************************************************************************/
6747 static void show_parameter(int parmIndex)
6749 int enumIndex, flagIndex;
6754 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6755 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6757 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6758 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6759 FLAG_HIDE, FLAG_DOS_STRING};
6760 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6761 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6762 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6764 printf("%s=%s", parm_table[parmIndex].label,
6765 type[parm_table[parmIndex].type]);
6766 if (parm_table[parmIndex].type == P_ENUM) {
6769 parm_table[parmIndex].enum_list[enumIndex].name;
6773 enumIndex ? "|" : "",
6774 parm_table[parmIndex].enum_list[enumIndex].name);
6779 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6780 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6783 flag_names[flagIndex]);
6788 /* output synonyms */
6790 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6791 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6792 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6793 parm_table[parmIndex2].label);
6794 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6796 printf(" (synonyms: ");
6801 printf("%s%s", parm_table[parmIndex2].label,
6802 inverse ? "[i]" : "");
6812 /***************************************************************************
6813 Show all parameter's name, type, [values,] and flags.
6814 ***************************************************************************/
6816 void show_parameter_list(void)
6818 int classIndex, parmIndex;
6819 const char *section_names[] = { "local", "global", NULL};
6821 for (classIndex=0; section_names[classIndex]; classIndex++) {
6822 printf("[%s]\n", section_names[classIndex]);
6823 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6824 if (parm_table[parmIndex].p_class == classIndex) {
6825 show_parameter(parmIndex);
6831 /***************************************************************************
6832 Check if a given string correctly represents a boolean value.
6833 ***************************************************************************/
6835 bool lp_string_is_valid_boolean(const char *parm_value)
6837 return set_boolean(parm_value, NULL);
6840 /***************************************************************************
6841 Get the standard string representation of a boolean value ("yes" or "no")
6842 ***************************************************************************/
6844 static const char *get_boolean(bool bool_value)
6846 static const char *yes_str = "yes";
6847 static const char *no_str = "no";
6849 return (bool_value ? yes_str : no_str);
6852 /***************************************************************************
6853 Provide the string of the negated boolean value associated to the boolean
6854 given as a string. Returns False if the passed string does not correctly
6855 represent a boolean.
6856 ***************************************************************************/
6858 bool lp_invert_boolean(const char *str, const char **inverse_str)
6862 if (!set_boolean(str, &val)) {
6866 *inverse_str = get_boolean(!val);
6870 /***************************************************************************
6871 Provide the canonical string representation of a boolean value given
6872 as a string. Return True on success, False if the string given does
6873 not correctly represent a boolean.
6874 ***************************************************************************/
6876 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6880 if (!set_boolean(str, &val)) {
6884 *canon_str = get_boolean(val);
6888 /***************************************************************************
6889 Find a service by name. Otherwise works like get_service.
6890 ***************************************************************************/
6892 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
6898 if (ServiceHash == NULL) {
6902 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6904 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6906 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6907 iService = *(int *)data.dptr;
6910 TALLOC_FREE(canon_name);
6912 if ((iService != -1) && (LP_SNUM_OK(iService))
6913 && (pserviceDest != NULL)) {
6914 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6920 /***************************************************************************
6921 Copy a service structure to another.
6922 If pcopymapDest is NULL then copy all fields
6923 ***************************************************************************/
6926 * Add a parametric option to a param_opt_struct,
6927 * replacing old value, if already present.
6929 static void set_param_opt(struct param_opt_struct **opt_list,
6930 const char *opt_name,
6931 const char *opt_value,
6934 struct param_opt_struct *new_opt, *opt;
6937 if (opt_list == NULL) {
6944 /* Traverse destination */
6946 /* If we already have same option, override it */
6947 if (strwicmp(opt->key, opt_name) == 0) {
6948 if ((opt->flags & FLAG_CMDLINE) &&
6949 !(flags & FLAG_CMDLINE)) {
6950 /* it's been marked as not to be
6954 string_free(&opt->value);
6955 TALLOC_FREE(opt->list);
6956 opt->value = SMB_STRDUP(opt_value);
6964 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6965 new_opt->key = SMB_STRDUP(opt_name);
6966 new_opt->value = SMB_STRDUP(opt_value);
6967 new_opt->list = NULL;
6968 new_opt->flags = flags;
6969 DLIST_ADD(*opt_list, new_opt);
6973 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
6974 struct bitmap *pcopymapDest)
6977 bool bcopyall = (pcopymapDest == NULL);
6978 struct param_opt_struct *data;
6980 for (i = 0; parm_table[i].label; i++)
6981 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6982 (bcopyall || bitmap_query(pcopymapDest,i))) {
6983 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
6984 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
6986 switch (parm_table[i].type) {
6989 *(bool *)dest_ptr = *(bool *)src_ptr;
6995 *(int *)dest_ptr = *(int *)src_ptr;
6999 *(char *)dest_ptr = *(char *)src_ptr;
7003 string_set((char **)dest_ptr,
7009 char *upper_string = strupper_talloc(talloc_tos(),
7011 string_set((char **)dest_ptr,
7013 TALLOC_FREE(upper_string);
7017 TALLOC_FREE(*((char ***)dest_ptr));
7018 *((char ***)dest_ptr) = str_list_copy(NULL,
7019 *(const char ***)src_ptr);
7027 init_copymap(pserviceDest);
7028 if (pserviceSource->copymap)
7029 bitmap_copy(pserviceDest->copymap,
7030 pserviceSource->copymap);
7033 data = pserviceSource->param_opt;
7035 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->flags);
7040 /***************************************************************************
7041 Check a service for consistency. Return False if the service is in any way
7042 incomplete or faulty, else True.
7043 ***************************************************************************/
7045 bool service_ok(int iService)
7050 if (ServicePtrs[iService]->szService[0] == '\0') {
7051 DEBUG(0, ("The following message indicates an internal error:\n"));
7052 DEBUG(0, ("No service name in service entry.\n"));
7056 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
7057 /* I can't see why you'd want a non-printable printer service... */
7058 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
7059 if (!ServicePtrs[iService]->bPrint_ok) {
7060 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
7061 ServicePtrs[iService]->szService));
7062 ServicePtrs[iService]->bPrint_ok = True;
7064 /* [printers] service must also be non-browsable. */
7065 if (ServicePtrs[iService]->bBrowseable)
7066 ServicePtrs[iService]->bBrowseable = False;
7069 if (ServicePtrs[iService]->szPath[0] == '\0' &&
7070 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
7071 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
7073 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
7074 ServicePtrs[iService]->szService));
7075 ServicePtrs[iService]->bAvailable = False;
7078 /* If a service is flagged unavailable, log the fact at level 1. */
7079 if (!ServicePtrs[iService]->bAvailable)
7080 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
7081 ServicePtrs[iService]->szService));
7086 static struct smbconf_ctx *lp_smbconf_ctx(void)
7089 static struct smbconf_ctx *conf_ctx = NULL;
7091 if (conf_ctx == NULL) {
7092 err = smbconf_init(NULL, &conf_ctx, "registry:");
7093 if (!SBC_ERROR_IS_OK(err)) {
7094 DEBUG(1, ("error initializing registry configuration: "
7095 "%s\n", sbcErrorString(err)));
7103 static bool process_smbconf_service(struct smbconf_service *service)
7108 if (service == NULL) {
7112 ret = do_section(service->name, NULL);
7116 for (count = 0; count < service->num_params; count++) {
7117 ret = do_parameter(service->param_names[count],
7118 service->param_values[count],
7124 if (iServiceIndex >= 0) {
7125 return service_ok(iServiceIndex);
7131 * load a service from registry and activate it
7133 bool process_registry_service(const char *service_name)
7136 struct smbconf_service *service = NULL;
7137 TALLOC_CTX *mem_ctx = talloc_stackframe();
7138 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7141 if (conf_ctx == NULL) {
7145 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7147 if (!smbconf_share_exists(conf_ctx, service_name)) {
7149 * Registry does not contain data for this service (yet),
7150 * but make sure lp_load doesn't return false.
7156 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7157 if (!SBC_ERROR_IS_OK(err)) {
7161 ret = process_smbconf_service(service);
7167 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7170 TALLOC_FREE(mem_ctx);
7175 * process_registry_globals
7177 static bool process_registry_globals(void)
7181 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7183 ret = do_parameter("registry shares", "yes", NULL);
7188 return process_registry_service(GLOBAL_NAME);
7191 bool process_registry_shares(void)
7195 struct smbconf_service **service = NULL;
7196 uint32_t num_shares = 0;
7197 TALLOC_CTX *mem_ctx = talloc_stackframe();
7198 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7201 if (conf_ctx == NULL) {
7205 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7206 if (!SBC_ERROR_IS_OK(err)) {
7212 for (count = 0; count < num_shares; count++) {
7213 if (strequal(service[count]->name, GLOBAL_NAME)) {
7216 ret = process_smbconf_service(service[count]);
7223 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7226 TALLOC_FREE(mem_ctx);
7230 #define MAX_INCLUDE_DEPTH 100
7232 static uint8_t include_depth;
7234 static struct file_lists {
7235 struct file_lists *next;
7239 } *file_lists = NULL;
7241 /*******************************************************************
7242 Keep a linked list of all config files so we know when one has changed
7243 it's date and needs to be reloaded.
7244 ********************************************************************/
7246 static void add_to_file_list(const char *fname, const char *subfname)
7248 struct file_lists *f = file_lists;
7251 if (f->name && !strcmp(f->name, fname))
7257 f = SMB_MALLOC_P(struct file_lists);
7260 f->next = file_lists;
7261 f->name = SMB_STRDUP(fname);
7266 f->subfname = SMB_STRDUP(subfname);
7273 f->modtime = file_modtime(subfname);
7275 time_t t = file_modtime(subfname);
7283 * Free the file lists
7285 static void free_file_list(void)
7287 struct file_lists *f;
7288 struct file_lists *next;
7293 SAFE_FREE( f->name );
7294 SAFE_FREE( f->subfname );
7303 * Utility function for outsiders to check if we're running on registry.
7305 bool lp_config_backend_is_registry(void)
7307 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7311 * Utility function to check if the config backend is FILE.
7313 bool lp_config_backend_is_file(void)
7315 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7318 /*******************************************************************
7319 Check if a config file has changed date.
7320 ********************************************************************/
7322 bool lp_file_list_changed(void)
7324 struct file_lists *f = file_lists;
7326 DEBUG(6, ("lp_file_list_changed()\n"));
7331 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7332 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7334 if (conf_ctx == NULL) {
7337 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7340 DEBUGADD(6, ("registry config changed\n"));
7345 n2 = talloc_sub_basic(talloc_tos(),
7346 get_current_username(),
7347 current_user_info.domain,
7352 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7353 f->name, n2, ctime(&f->modtime)));
7355 mod_time = file_modtime(n2);
7358 ((f->modtime != mod_time) ||
7359 (f->subfname == NULL) ||
7360 (strcmp(n2, f->subfname) != 0)))
7363 ("file %s modified: %s\n", n2,
7365 f->modtime = mod_time;
7366 SAFE_FREE(f->subfname);
7367 f->subfname = SMB_STRDUP(n2);
7380 * Initialize iconv conversion descriptors.
7382 * This is called the first time it is needed, and also called again
7383 * every time the configuration is reloaded, because the charset or
7384 * codepage might have changed.
7386 static void init_iconv(void)
7388 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
7390 true, global_iconv_handle);
7393 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7395 if (strcmp(*ptr, pszParmValue) != 0) {
7396 string_set(ptr, pszParmValue);
7402 static bool handle_dos_charset(int snum, const char *pszParmValue, char **ptr)
7404 bool is_utf8 = false;
7405 size_t len = strlen(pszParmValue);
7407 if (len == 4 || len == 5) {
7408 /* Don't use StrCaseCmp here as we don't want to
7409 initialize iconv. */
7410 if ((toupper_ascii(pszParmValue[0]) == 'U') &&
7411 (toupper_ascii(pszParmValue[1]) == 'T') &&
7412 (toupper_ascii(pszParmValue[2]) == 'F')) {
7414 if (pszParmValue[3] == '8') {
7418 if (pszParmValue[3] == '-' &&
7419 pszParmValue[4] == '8') {
7426 if (strcmp(*ptr, pszParmValue) != 0) {
7428 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
7429 "be UTF8, using (default value) %s instead.\n",
7430 DEFAULT_DOS_CHARSET));
7431 pszParmValue = DEFAULT_DOS_CHARSET;
7433 string_set(ptr, pszParmValue);
7439 static bool handle_realm(int snum, const char *pszParmValue, char **ptr)
7442 char *realm = strupper_talloc(talloc_tos(), pszParmValue);
7443 char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
7445 ret &= string_set(&Globals.szRealm, pszParmValue);
7446 ret &= string_set(&Globals.szRealmUpper, realm);
7447 ret &= string_set(&Globals.szDnsDomain, dnsdomain);
7449 TALLOC_FREE(dnsdomain);
7454 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7456 TALLOC_FREE(Globals.szNetbiosAliases);
7457 Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
7458 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7461 /***************************************************************************
7462 Handle the include operation.
7463 ***************************************************************************/
7464 static bool bAllowIncludeRegistry = true;
7466 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7470 if (include_depth >= MAX_INCLUDE_DEPTH) {
7471 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7476 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7477 if (!bAllowIncludeRegistry) {
7480 if (bInGlobalSection) {
7483 ret = process_registry_globals();
7487 DEBUG(1, ("\"include = registry\" only effective "
7488 "in %s section\n", GLOBAL_NAME));
7493 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7494 current_user_info.domain,
7497 add_to_file_list(pszParmValue, fname);
7499 string_set(ptr, fname);
7501 if (file_exist(fname)) {
7504 ret = pm_process(fname, do_section, do_parameter, NULL);
7510 DEBUG(2, ("Can't find include file %s\n", fname));
7515 /***************************************************************************
7516 Handle the interpretation of the copy parameter.
7517 ***************************************************************************/
7519 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7523 struct loadparm_service serviceTemp;
7525 string_set(ptr, pszParmValue);
7527 init_service(&serviceTemp);
7531 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7533 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7534 if (iTemp == iServiceIndex) {
7535 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7537 copy_service(ServicePtrs[iServiceIndex],
7539 ServicePtrs[iServiceIndex]->copymap);
7543 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7547 free_service(&serviceTemp);
7551 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7553 Globals.ldap_debug_level = lp_int(pszParmValue);
7554 init_ldap_debugging();
7558 /***************************************************************************
7559 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7564 idmap uid = 1000-1999
7567 We only do simple parsing checks here. The strings are parsed into useful
7568 structures in the idmap daemon code.
7570 ***************************************************************************/
7572 /* Some lp_ routines to return idmap [ug]id information */
7574 static uid_t idmap_uid_low, idmap_uid_high;
7575 static gid_t idmap_gid_low, idmap_gid_high;
7577 bool lp_idmap_uid(uid_t *low, uid_t *high)
7579 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7583 *low = idmap_uid_low;
7586 *high = idmap_uid_high;
7591 bool lp_idmap_gid(gid_t *low, gid_t *high)
7593 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7597 *low = idmap_gid_low;
7600 *high = idmap_gid_high;
7605 static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr)
7607 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7612 /* Do some simple checks on "idmap [ug]id" parameter values */
7614 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7616 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7621 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7623 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7628 /***************************************************************************
7629 Handle the DEBUG level list.
7630 ***************************************************************************/
7632 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7634 string_set(ptr, pszParmValueIn);
7635 return debug_parse_levels(pszParmValueIn);
7638 /***************************************************************************
7639 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7640 ***************************************************************************/
7642 static const char *append_ldap_suffix( const char *str )
7644 const char *suffix_string;
7647 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7648 Globals.szLdapSuffix );
7649 if ( !suffix_string ) {
7650 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7654 return suffix_string;
7657 const char *lp_ldap_machine_suffix(void)
7659 if (Globals.szLdapMachineSuffix[0])
7660 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7662 return lp_string(Globals.szLdapSuffix);
7665 const char *lp_ldap_user_suffix(void)
7667 if (Globals.szLdapUserSuffix[0])
7668 return append_ldap_suffix(Globals.szLdapUserSuffix);
7670 return lp_string(Globals.szLdapSuffix);
7673 const char *lp_ldap_group_suffix(void)
7675 if (Globals.szLdapGroupSuffix[0])
7676 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7678 return lp_string(Globals.szLdapSuffix);
7681 const char *lp_ldap_idmap_suffix(void)
7683 if (Globals.szLdapIdmapSuffix[0])
7684 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7686 return lp_string(Globals.szLdapSuffix);
7689 /****************************************************************************
7690 set the value for a P_ENUM
7691 ***************************************************************************/
7693 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7698 for (i = 0; parm->enum_list[i].name; i++) {
7699 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7700 *ptr = parm->enum_list[i].value;
7704 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7705 pszParmValue, parm->label));
7708 /***************************************************************************
7709 ***************************************************************************/
7711 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7713 static int parm_num = -1;
7714 struct loadparm_service *s;
7716 if ( parm_num == -1 )
7717 parm_num = map_parameter( "printing" );
7719 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7724 s = ServicePtrs[snum];
7726 init_printer_values( s );
7732 /***************************************************************************
7733 Initialise a copymap.
7734 ***************************************************************************/
7736 static void init_copymap(struct loadparm_service *pservice)
7740 TALLOC_FREE(pservice->copymap);
7742 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7743 if (!pservice->copymap)
7745 ("Couldn't allocate copymap!! (size %d)\n",
7746 (int)NUMPARAMETERS));
7748 for (i = 0; i < NUMPARAMETERS; i++)
7749 bitmap_set(pservice->copymap, i);
7753 return the parameter pointer for a parameter
7755 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
7757 if (service == NULL) {
7758 if (parm->p_class == P_LOCAL)
7760 else if (parm->p_class == P_GLOBAL)
7764 return (void *)(((char *)service) + PTR_DIFF(parm->ptr, &sDefault));
7768 /***************************************************************************
7769 Return the local pointer to a parameter given the service number and parameter
7770 ***************************************************************************/
7772 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
7774 return lp_parm_ptr(ServicePtrs[snum], parm);
7777 /***************************************************************************
7778 Process a parameter for a particular service number. If snum < 0
7779 then assume we are in the globals.
7780 ***************************************************************************/
7782 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7785 void *parm_ptr = NULL; /* where we are going to store the result */
7786 struct param_opt_struct **opt_list;
7788 parmnum = map_parameter(pszParmName);
7791 if (strchr(pszParmName, ':') == NULL) {
7792 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7798 * We've got a parametric option
7801 opt_list = (snum < 0)
7802 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7803 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7808 /* if it's already been set by the command line, then we don't
7810 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7814 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7815 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7819 /* we might point at a service, the default service or a global */
7821 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
7823 if (parm_table[parmnum].p_class == P_GLOBAL) {
7825 ("Global parameter %s found in service section!\n",
7829 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
7833 if (!ServicePtrs[snum]->copymap)
7834 init_copymap(ServicePtrs[snum]);
7836 /* this handles the aliases - set the copymap for other entries with
7837 the same data pointer */
7838 for (i = 0; parm_table[i].label; i++)
7839 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7840 bitmap_clear(ServicePtrs[snum]->copymap, i);
7843 /* if it is a special case then go ahead */
7844 if (parm_table[parmnum].special) {
7845 return parm_table[parmnum].special(snum, pszParmValue,
7849 /* now switch on the type of variable it is */
7850 switch (parm_table[parmnum].type)
7853 *(bool *)parm_ptr = lp_bool(pszParmValue);
7857 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7861 *(int *)parm_ptr = lp_int(pszParmValue);
7865 *(char *)parm_ptr = *pszParmValue;
7869 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7871 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7876 TALLOC_FREE(*((char ***)parm_ptr));
7877 *(char ***)parm_ptr = str_list_make_v3(
7878 NULL, pszParmValue, NULL);
7882 string_set((char **)parm_ptr, pszParmValue);
7887 char *upper_string = strupper_talloc(talloc_tos(),
7889 string_set((char **)parm_ptr, upper_string);
7890 TALLOC_FREE(upper_string);
7894 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7903 /***************************************************************************
7904 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7905 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7906 ***************************************************************************/
7908 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7911 parmnum = map_parameter(pszParmName);
7913 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7914 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7917 parm_table[parmnum].flags |= FLAG_CMDLINE;
7919 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7920 * be grouped in the table, so we don't have to search the
7922 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
7923 parm_table[i].flags |= FLAG_CMDLINE;
7925 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
7926 parm_table[i].flags |= FLAG_CMDLINE;
7930 store_lp_set_cmdline(pszParmName, pszParmValue);
7935 /* it might be parametric */
7936 if (strchr(pszParmName, ':') != NULL) {
7937 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7939 store_lp_set_cmdline(pszParmName, pszParmValue);
7944 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7948 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7950 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7953 /***************************************************************************
7954 Process a parameter.
7955 ***************************************************************************/
7957 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7960 if (!bInGlobalSection && bGlobalOnly)
7963 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7965 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7966 pszParmName, pszParmValue));
7970 set a option from the commandline in 'a=b' format. Use to support --option
7972 bool lp_set_option(const char *option)
7977 s = talloc_strdup(NULL, option);
7990 /* skip white spaces after the = sign */
7993 } while (*p == ' ');
7995 ret = lp_set_cmdline(s, p);
8000 /**************************************************************************
8001 Print a parameter of the specified type.
8002 ***************************************************************************/
8004 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
8010 for (i = 0; p->enum_list[i].name; i++) {
8011 if (*(int *)ptr == p->enum_list[i].value) {
8013 p->enum_list[i].name);
8020 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
8024 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
8028 fprintf(f, "%d", *(int *)ptr);
8032 fprintf(f, "%c", *(char *)ptr);
8036 char *o = octal_string(*(int *)ptr);
8037 fprintf(f, "%s", o);
8043 if ((char ***)ptr && *(char ***)ptr) {
8044 char **list = *(char ***)ptr;
8045 for (; *list; list++) {
8046 /* surround strings with whitespace in double quotes */
8047 if ( strchr_m( *list, ' ' ) )
8048 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
8050 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
8057 if (*(char **)ptr) {
8058 fprintf(f, "%s", *(char **)ptr);
8066 /***************************************************************************
8067 Check if two parameters are equal.
8068 ***************************************************************************/
8070 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8075 return (*((bool *)ptr1) == *((bool *)ptr2));
8080 return (*((int *)ptr1) == *((int *)ptr2));
8083 return (*((char *)ptr1) == *((char *)ptr2));
8086 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8091 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8096 return (p1 == p2 || strequal(p1, p2));
8104 /***************************************************************************
8105 Initialize any local varients in the sDefault table.
8106 ***************************************************************************/
8108 void init_locals(void)
8113 /***************************************************************************
8114 Process a new section (service). At this stage all sections are services.
8115 Later we'll have special sections that permit server parameters to be set.
8116 Returns True on success, False on failure.
8117 ***************************************************************************/
8119 static bool do_section(const char *pszSectionName, void *userdata)
8122 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8123 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8126 /* if we were in a global section then do the local inits */
8127 if (bInGlobalSection && !isglobal)
8130 /* if we've just struck a global section, note the fact. */
8131 bInGlobalSection = isglobal;
8133 /* check for multiple global sections */
8134 if (bInGlobalSection) {
8135 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8139 if (!bInGlobalSection && bGlobalOnly)
8142 /* if we have a current service, tidy it up before moving on */
8145 if (iServiceIndex >= 0)
8146 bRetval = service_ok(iServiceIndex);
8148 /* if all is still well, move to the next record in the services array */
8150 /* We put this here to avoid an odd message order if messages are */
8151 /* issued by the post-processing of a previous section. */
8152 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8154 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8156 DEBUG(0, ("Failed to add a new service\n"));
8159 /* Clean all parametric options for service */
8160 /* They will be added during parsing again */
8161 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
8168 /***************************************************************************
8169 Determine if a partcular base parameter is currentl set to the default value.
8170 ***************************************************************************/
8172 static bool is_default(int i)
8174 if (!defaults_saved)
8176 switch (parm_table[i].type) {
8178 return str_list_equal((const char **)parm_table[i].def.lvalue,
8179 *(const char ***)lp_parm_ptr(NULL,
8183 return strequal(parm_table[i].def.svalue,
8184 *(char **)lp_parm_ptr(NULL,
8188 return parm_table[i].def.bvalue ==
8189 *(bool *)lp_parm_ptr(NULL,
8192 return parm_table[i].def.cvalue ==
8193 *(char *)lp_parm_ptr(NULL,
8198 return parm_table[i].def.ivalue ==
8199 *(int *)lp_parm_ptr(NULL,
8207 /***************************************************************************
8208 Display the contents of the global structure.
8209 ***************************************************************************/
8211 static void dump_globals(FILE *f)
8214 struct param_opt_struct *data;
8216 fprintf(f, "[global]\n");
8218 for (i = 0; parm_table[i].label; i++)
8219 if (parm_table[i].p_class == P_GLOBAL &&
8220 !(parm_table[i].flags & FLAG_META) &&
8221 parm_table[i].ptr &&
8222 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8223 if (defaults_saved && is_default(i))
8225 fprintf(f, "\t%s = ", parm_table[i].label);
8226 print_parameter(&parm_table[i], lp_parm_ptr(NULL,
8231 if (Globals.param_opt != NULL) {
8232 data = Globals.param_opt;
8234 fprintf(f, "\t%s = %s\n", data->key, data->value);
8241 /***************************************************************************
8242 Return True if a local parameter is currently set to the global default.
8243 ***************************************************************************/
8245 bool lp_is_default(int snum, struct parm_struct *parm)
8247 return equal_parameter(parm->type,
8248 lp_parm_ptr(ServicePtrs[snum], parm),
8249 lp_parm_ptr(NULL, parm));
8252 /***************************************************************************
8253 Display the contents of a single services record.
8254 ***************************************************************************/
8256 static void dump_a_service(struct loadparm_service *pService, FILE * f)
8259 struct param_opt_struct *data;
8261 if (pService != &sDefault)
8262 fprintf(f, "[%s]\n", pService->szService);
8264 for (i = 0; parm_table[i].label; i++) {
8266 if (parm_table[i].p_class == P_LOCAL &&
8267 !(parm_table[i].flags & FLAG_META) &&
8268 parm_table[i].ptr &&
8269 (*parm_table[i].label != '-') &&
8270 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8272 if (pService == &sDefault) {
8273 if (defaults_saved && is_default(i))
8276 if (equal_parameter(parm_table[i].type,
8277 lp_parm_ptr(pService, &parm_table[i]),
8278 lp_parm_ptr(NULL, &parm_table[i])))
8282 fprintf(f, "\t%s = ", parm_table[i].label);
8283 print_parameter(&parm_table[i],
8284 lp_parm_ptr(pService, &parm_table[i]),
8290 if (pService->param_opt != NULL) {
8291 data = pService->param_opt;
8293 fprintf(f, "\t%s = %s\n", data->key, data->value);
8299 /***************************************************************************
8300 Display the contents of a parameter of a single services record.
8301 ***************************************************************************/
8303 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8306 bool result = False;
8309 fstring local_parm_name;
8311 const char *parm_opt_value;
8313 /* check for parametrical option */
8314 fstrcpy( local_parm_name, parm_name);
8315 parm_opt = strchr( local_parm_name, ':');
8320 if (strlen(parm_opt)) {
8321 parm_opt_value = lp_parm_const_string( snum,
8322 local_parm_name, parm_opt, NULL);
8323 if (parm_opt_value) {
8324 printf( "%s\n", parm_opt_value);
8331 /* check for a key and print the value */
8338 for (i = 0; parm_table[i].label; i++) {
8339 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8340 !(parm_table[i].flags & FLAG_META) &&
8341 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8342 parm_table[i].ptr &&
8343 (*parm_table[i].label != '-') &&
8344 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8349 ptr = lp_parm_ptr(NULL,
8352 ptr = lp_parm_ptr(ServicePtrs[snum],
8356 print_parameter(&parm_table[i],
8367 /***************************************************************************
8368 Return info about the requested parameter (given as a string).
8369 Return NULL when the string is not a valid parameter name.
8370 ***************************************************************************/
8372 struct parm_struct *lp_get_parameter(const char *param_name)
8374 int num = map_parameter(param_name);
8380 return &parm_table[num];
8383 /***************************************************************************
8384 Return info about the next parameter in a service.
8385 snum==GLOBAL_SECTION_SNUM gives the globals.
8386 Return NULL when out of parameters.
8387 ***************************************************************************/
8389 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8392 /* do the globals */
8393 for (; parm_table[*i].label; (*i)++) {
8394 if (parm_table[*i].p_class == P_SEPARATOR)
8395 return &parm_table[(*i)++];
8397 if (!parm_table[*i].ptr
8398 || (*parm_table[*i].label == '-'))
8402 && (parm_table[*i].ptr ==
8403 parm_table[(*i) - 1].ptr))
8406 if (is_default(*i) && !allparameters)
8409 return &parm_table[(*i)++];
8412 struct loadparm_service *pService = ServicePtrs[snum];
8414 for (; parm_table[*i].label; (*i)++) {
8415 if (parm_table[*i].p_class == P_SEPARATOR)
8416 return &parm_table[(*i)++];
8418 if (parm_table[*i].p_class == P_LOCAL &&
8419 parm_table[*i].ptr &&
8420 (*parm_table[*i].label != '-') &&
8422 (parm_table[*i].ptr !=
8423 parm_table[(*i) - 1].ptr)))
8425 if (allparameters ||
8426 !equal_parameter(parm_table[*i].type,
8427 lp_parm_ptr(pService,
8432 return &parm_table[(*i)++];
8443 /***************************************************************************
8444 Display the contents of a single copy structure.
8445 ***************************************************************************/
8446 static void dump_copy_map(bool *pcopymap)
8452 printf("\n\tNon-Copied parameters:\n");
8454 for (i = 0; parm_table[i].label; i++)
8455 if (parm_table[i].p_class == P_LOCAL &&
8456 parm_table[i].ptr && !pcopymap[i] &&
8457 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8459 printf("\t\t%s\n", parm_table[i].label);
8464 /***************************************************************************
8465 Return TRUE if the passed service number is within range.
8466 ***************************************************************************/
8468 bool lp_snum_ok(int iService)
8470 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8473 /***************************************************************************
8474 Auto-load some home services.
8475 ***************************************************************************/
8477 static void lp_add_auto_services(char *str)
8487 s = SMB_STRDUP(str);
8491 homes = lp_servicenumber(HOMES_NAME);
8493 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8494 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8497 if (lp_servicenumber(p) >= 0)
8500 home = get_user_home_dir(talloc_tos(), p);
8502 if (home && home[0] && homes >= 0)
8503 lp_add_home(p, homes, p, home);
8510 /***************************************************************************
8511 Auto-load one printer.
8512 ***************************************************************************/
8514 void lp_add_one_printer(const char *name, const char *comment,
8515 const char *location, void *pdata)
8517 int printers = lp_servicenumber(PRINTERS_NAME);
8520 if (lp_servicenumber(name) < 0) {
8521 lp_add_printer(name, printers);
8522 if ((i = lp_servicenumber(name)) >= 0) {
8523 string_set(&ServicePtrs[i]->comment, comment);
8524 ServicePtrs[i]->autoloaded = True;
8529 /***************************************************************************
8530 Have we loaded a services file yet?
8531 ***************************************************************************/
8533 bool lp_loaded(void)
8538 /***************************************************************************
8539 Unload unused services.
8540 ***************************************************************************/
8542 void lp_killunused(struct smbd_server_connection *sconn,
8543 bool (*snumused) (struct smbd_server_connection *, int))
8546 for (i = 0; i < iNumServices; i++) {
8550 /* don't kill autoloaded or usershare services */
8551 if ( ServicePtrs[i]->autoloaded ||
8552 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8556 if (!snumused || !snumused(sconn, i)) {
8557 free_service_byindex(i);
8563 * Kill all except autoloaded and usershare services - convenience wrapper
8565 void lp_kill_all_services(void)
8567 lp_killunused(NULL, NULL);
8570 /***************************************************************************
8572 ***************************************************************************/
8574 void lp_killservice(int iServiceIn)
8576 if (VALID(iServiceIn)) {
8577 free_service_byindex(iServiceIn);
8581 /***************************************************************************
8582 Save the curent values of all global and sDefault parameters into the
8583 defaults union. This allows swat and testparm to show only the
8584 changed (ie. non-default) parameters.
8585 ***************************************************************************/
8587 static void lp_save_defaults(void)
8590 for (i = 0; parm_table[i].label; i++) {
8591 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8593 switch (parm_table[i].type) {
8595 parm_table[i].def.lvalue = str_list_copy(
8596 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
8600 if (parm_table[i].ptr) {
8601 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
8603 parm_table[i].def.svalue = NULL;
8608 parm_table[i].def.bvalue =
8609 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
8612 parm_table[i].def.cvalue =
8613 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
8618 parm_table[i].def.ivalue =
8619 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
8625 defaults_saved = True;
8628 /***********************************************************
8629 If we should send plaintext/LANMAN passwords in the clinet
8630 ************************************************************/
8632 static void set_allowed_client_auth(void)
8634 if (Globals.bClientNTLMv2Auth) {
8635 Globals.bClientLanManAuth = False;
8637 if (!Globals.bClientLanManAuth) {
8638 Globals.bClientPlaintextAuth = False;
8642 /***************************************************************************
8644 The following code allows smbd to read a user defined share file.
8645 Yes, this is my intent. Yes, I'm comfortable with that...
8647 THE FOLLOWING IS SECURITY CRITICAL CODE.
8649 It washes your clothes, it cleans your house, it guards you while you sleep...
8650 Do not f%^k with it....
8651 ***************************************************************************/
8653 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8655 /***************************************************************************
8656 Check allowed stat state of a usershare file.
8657 Ensure we print out who is dicking with us so the admin can
8658 get their sorry ass fired.
8659 ***************************************************************************/
8661 static bool check_usershare_stat(const char *fname,
8662 const SMB_STRUCT_STAT *psbuf)
8664 if (!S_ISREG(psbuf->st_ex_mode)) {
8665 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8666 "not a regular file\n",
8667 fname, (unsigned int)psbuf->st_ex_uid ));
8671 /* Ensure this doesn't have the other write bit set. */
8672 if (psbuf->st_ex_mode & S_IWOTH) {
8673 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8674 "public write. Refusing to allow as a usershare file.\n",
8675 fname, (unsigned int)psbuf->st_ex_uid ));
8679 /* Should be 10k or less. */
8680 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8681 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8682 "too large (%u) to be a user share file.\n",
8683 fname, (unsigned int)psbuf->st_ex_uid,
8684 (unsigned int)psbuf->st_ex_size ));
8691 /***************************************************************************
8692 Parse the contents of a usershare file.
8693 ***************************************************************************/
8695 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8696 SMB_STRUCT_STAT *psbuf,
8697 const char *servicename,
8701 char **pp_sharepath,
8703 char **pp_cp_servicename,
8704 struct security_descriptor **ppsd,
8707 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8708 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8711 SMB_STRUCT_STAT sbuf;
8712 char *sharepath = NULL;
8713 char *comment = NULL;
8715 *pp_sharepath = NULL;
8718 *pallow_guest = False;
8721 return USERSHARE_MALFORMED_FILE;
8724 if (strcmp(lines[0], "#VERSION 1") == 0) {
8726 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8729 return USERSHARE_MALFORMED_FILE;
8732 return USERSHARE_BAD_VERSION;
8735 if (strncmp(lines[1], "path=", 5) != 0) {
8736 return USERSHARE_MALFORMED_PATH;
8739 sharepath = talloc_strdup(ctx, &lines[1][5]);
8741 return USERSHARE_POSIX_ERR;
8743 trim_string(sharepath, " ", " ");
8745 if (strncmp(lines[2], "comment=", 8) != 0) {
8746 return USERSHARE_MALFORMED_COMMENT_DEF;
8749 comment = talloc_strdup(ctx, &lines[2][8]);
8751 return USERSHARE_POSIX_ERR;
8753 trim_string(comment, " ", " ");
8754 trim_char(comment, '"', '"');
8756 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8757 return USERSHARE_MALFORMED_ACL_DEF;
8760 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8761 return USERSHARE_ACL_ERR;
8765 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8766 return USERSHARE_MALFORMED_ACL_DEF;
8768 if (lines[4][9] == 'y') {
8769 *pallow_guest = True;
8772 /* Backwards compatible extension to file version #2. */
8774 if (strncmp(lines[5], "sharename=", 10) != 0) {
8775 return USERSHARE_MALFORMED_SHARENAME_DEF;
8777 if (!strequal(&lines[5][10], servicename)) {
8778 return USERSHARE_BAD_SHARENAME;
8780 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8781 if (!*pp_cp_servicename) {
8782 return USERSHARE_POSIX_ERR;
8787 if (*pp_cp_servicename == NULL) {
8788 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8789 if (!*pp_cp_servicename) {
8790 return USERSHARE_POSIX_ERR;
8794 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8795 /* Path didn't change, no checks needed. */
8796 *pp_sharepath = sharepath;
8797 *pp_comment = comment;
8798 return USERSHARE_OK;
8801 /* The path *must* be absolute. */
8802 if (sharepath[0] != '/') {
8803 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8804 servicename, sharepath));
8805 return USERSHARE_PATH_NOT_ABSOLUTE;
8808 /* If there is a usershare prefix deny list ensure one of these paths
8809 doesn't match the start of the user given path. */
8810 if (prefixdenylist) {
8812 for ( i=0; prefixdenylist[i]; i++ ) {
8813 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8814 servicename, i, prefixdenylist[i], sharepath ));
8815 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8816 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8817 "usershare prefix deny list entries.\n",
8818 servicename, sharepath));
8819 return USERSHARE_PATH_IS_DENIED;
8824 /* If there is a usershare prefix allow list ensure one of these paths
8825 does match the start of the user given path. */
8827 if (prefixallowlist) {
8829 for ( i=0; prefixallowlist[i]; i++ ) {
8830 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8831 servicename, i, prefixallowlist[i], sharepath ));
8832 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8836 if (prefixallowlist[i] == NULL) {
8837 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8838 "usershare prefix allow list entries.\n",
8839 servicename, sharepath));
8840 return USERSHARE_PATH_NOT_ALLOWED;
8844 /* Ensure this is pointing to a directory. */
8845 dp = sys_opendir(sharepath);
8848 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8849 servicename, sharepath));
8850 return USERSHARE_PATH_NOT_DIRECTORY;
8853 /* Ensure the owner of the usershare file has permission to share
8856 if (sys_stat(sharepath, &sbuf, false) == -1) {
8857 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8858 servicename, sharepath, strerror(errno) ));
8860 return USERSHARE_POSIX_ERR;
8865 if (!S_ISDIR(sbuf.st_ex_mode)) {
8866 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8867 servicename, sharepath ));
8868 return USERSHARE_PATH_NOT_DIRECTORY;
8871 /* Check if sharing is restricted to owner-only. */
8872 /* psbuf is the stat of the usershare definition file,
8873 sbuf is the stat of the target directory to be shared. */
8875 if (lp_usershare_owner_only()) {
8876 /* root can share anything. */
8877 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8878 return USERSHARE_PATH_NOT_ALLOWED;
8882 *pp_sharepath = sharepath;
8883 *pp_comment = comment;
8884 return USERSHARE_OK;
8887 /***************************************************************************
8888 Deal with a usershare file.
8891 -1 - Bad name, invalid contents.
8892 - service name already existed and not a usershare, problem
8893 with permissions to share directory etc.
8894 ***************************************************************************/
8896 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8898 SMB_STRUCT_STAT sbuf;
8899 SMB_STRUCT_STAT lsbuf;
8901 char *sharepath = NULL;
8902 char *comment = NULL;
8903 char *cp_service_name = NULL;
8904 char **lines = NULL;
8908 TALLOC_CTX *ctx = talloc_stackframe();
8909 struct security_descriptor *psd = NULL;
8910 bool guest_ok = False;
8911 char *canon_name = NULL;
8912 bool added_service = false;
8915 /* Ensure share name doesn't contain invalid characters. */
8916 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8917 DEBUG(0,("process_usershare_file: share name %s contains "
8918 "invalid characters (any of %s)\n",
8919 file_name, INVALID_SHARENAME_CHARS ));
8923 canon_name = canonicalize_servicename(ctx, file_name);
8928 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8933 /* Minimize the race condition by doing an lstat before we
8934 open and fstat. Ensure this isn't a symlink link. */
8936 if (sys_lstat(fname, &lsbuf, false) != 0) {
8937 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8938 fname, strerror(errno) ));
8942 /* This must be a regular file, not a symlink, directory or
8943 other strange filetype. */
8944 if (!check_usershare_stat(fname, &lsbuf)) {
8949 TDB_DATA data = dbwrap_fetch_bystring(
8950 ServiceHash, canon_name, canon_name);
8954 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8955 iService = *(int *)data.dptr;
8959 if (iService != -1 &&
8960 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8961 &lsbuf.st_ex_mtime) == 0) {
8962 /* Nothing changed - Mark valid and return. */
8963 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8965 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8970 /* Try and open the file read only - no symlinks allowed. */
8972 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8974 fd = sys_open(fname, O_RDONLY, 0);
8978 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8979 fname, strerror(errno) ));
8983 /* Now fstat to be *SURE* it's a regular file. */
8984 if (sys_fstat(fd, &sbuf, false) != 0) {
8986 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8987 fname, strerror(errno) ));
8991 /* Is it the same dev/inode as was lstated ? */
8992 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8994 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8995 "Symlink spoofing going on ?\n", fname ));
8999 /* This must be a regular file, not a symlink, directory or
9000 other strange filetype. */
9001 if (!check_usershare_stat(fname, &sbuf)) {
9005 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
9008 if (lines == NULL) {
9009 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
9010 fname, (unsigned int)sbuf.st_ex_uid ));
9014 if (parse_usershare_file(ctx, &sbuf, file_name,
9015 iService, lines, numlines, &sharepath,
9016 &comment, &cp_service_name,
9017 &psd, &guest_ok) != USERSHARE_OK) {
9021 /* Everything ok - add the service possibly using a template. */
9023 const struct loadparm_service *sp = &sDefault;
9024 if (snum_template != -1) {
9025 sp = ServicePtrs[snum_template];
9028 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
9029 DEBUG(0, ("process_usershare_file: Failed to add "
9030 "new service %s\n", cp_service_name));
9034 added_service = true;
9036 /* Read only is controlled by usershare ACL below. */
9037 ServicePtrs[iService]->bRead_only = False;
9040 /* Write the ACL of the new/modified share. */
9041 if (!set_share_security(canon_name, psd)) {
9042 DEBUG(0, ("process_usershare_file: Failed to set share "
9043 "security for user share %s\n",
9048 /* If from a template it may be marked invalid. */
9049 ServicePtrs[iService]->valid = True;
9051 /* Set the service as a valid usershare. */
9052 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9054 /* Set guest access. */
9055 if (lp_usershare_allow_guests()) {
9056 ServicePtrs[iService]->bGuest_ok = guest_ok;
9059 /* And note when it was loaded. */
9060 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
9061 string_set(&ServicePtrs[iService]->szPath, sharepath);
9062 string_set(&ServicePtrs[iService]->comment, comment);
9068 if (ret == -1 && iService != -1 && added_service) {
9069 lp_remove_service(iService);
9077 /***************************************************************************
9078 Checks if a usershare entry has been modified since last load.
9079 ***************************************************************************/
9081 static bool usershare_exists(int iService, struct timespec *last_mod)
9083 SMB_STRUCT_STAT lsbuf;
9084 const char *usersharepath = Globals.szUsersharePath;
9087 if (asprintf(&fname, "%s/%s",
9089 ServicePtrs[iService]->szService) < 0) {
9093 if (sys_lstat(fname, &lsbuf, false) != 0) {
9098 if (!S_ISREG(lsbuf.st_ex_mode)) {
9104 *last_mod = lsbuf.st_ex_mtime;
9108 /***************************************************************************
9109 Load a usershare service by name. Returns a valid servicenumber or -1.
9110 ***************************************************************************/
9112 int load_usershare_service(const char *servicename)
9114 SMB_STRUCT_STAT sbuf;
9115 const char *usersharepath = Globals.szUsersharePath;
9116 int max_user_shares = Globals.iUsershareMaxShares;
9117 int snum_template = -1;
9119 if (*usersharepath == 0 || max_user_shares == 0) {
9123 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9124 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9125 usersharepath, strerror(errno) ));
9129 if (!S_ISDIR(sbuf.st_ex_mode)) {
9130 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9136 * This directory must be owned by root, and have the 't' bit set.
9137 * It also must not be writable by "other".
9141 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9143 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9145 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9146 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9151 /* Ensure the template share exists if it's set. */
9152 if (Globals.szUsershareTemplateShare[0]) {
9153 /* We can't use lp_servicenumber here as we are recommending that
9154 template shares have -valid=False set. */
9155 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9156 if (ServicePtrs[snum_template]->szService &&
9157 strequal(ServicePtrs[snum_template]->szService,
9158 Globals.szUsershareTemplateShare)) {
9163 if (snum_template == -1) {
9164 DEBUG(0,("load_usershare_service: usershare template share %s "
9165 "does not exist.\n",
9166 Globals.szUsershareTemplateShare ));
9171 return process_usershare_file(usersharepath, servicename, snum_template);
9174 /***************************************************************************
9175 Load all user defined shares from the user share directory.
9176 We only do this if we're enumerating the share list.
9177 This is the function that can delete usershares that have
9179 ***************************************************************************/
9181 int load_usershare_shares(struct smbd_server_connection *sconn)
9184 SMB_STRUCT_STAT sbuf;
9185 SMB_STRUCT_DIRENT *de;
9186 int num_usershares = 0;
9187 int max_user_shares = Globals.iUsershareMaxShares;
9188 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9189 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9190 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9192 int snum_template = -1;
9193 const char *usersharepath = Globals.szUsersharePath;
9194 int ret = lp_numservices();
9196 if (max_user_shares == 0 || *usersharepath == '\0') {
9197 return lp_numservices();
9200 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9201 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9202 usersharepath, strerror(errno) ));
9207 * This directory must be owned by root, and have the 't' bit set.
9208 * It also must not be writable by "other".
9212 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9214 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9216 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9217 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9222 /* Ensure the template share exists if it's set. */
9223 if (Globals.szUsershareTemplateShare[0]) {
9224 /* We can't use lp_servicenumber here as we are recommending that
9225 template shares have -valid=False set. */
9226 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9227 if (ServicePtrs[snum_template]->szService &&
9228 strequal(ServicePtrs[snum_template]->szService,
9229 Globals.szUsershareTemplateShare)) {
9234 if (snum_template == -1) {
9235 DEBUG(0,("load_usershare_shares: usershare template share %s "
9236 "does not exist.\n",
9237 Globals.szUsershareTemplateShare ));
9242 /* Mark all existing usershares as pending delete. */
9243 for (iService = iNumServices - 1; iService >= 0; iService--) {
9244 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9245 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9249 dp = sys_opendir(usersharepath);
9251 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9252 usersharepath, strerror(errno) ));
9256 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9257 (de = sys_readdir(dp));
9258 num_dir_entries++ ) {
9260 const char *n = de->d_name;
9262 /* Ignore . and .. */
9264 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9270 /* Temporary file used when creating a share. */
9271 num_tmp_dir_entries++;
9274 /* Allow 20% tmp entries. */
9275 if (num_tmp_dir_entries > allowed_tmp_entries) {
9276 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9277 "in directory %s\n",
9278 num_tmp_dir_entries, usersharepath));
9282 r = process_usershare_file(usersharepath, n, snum_template);
9284 /* Update the services count. */
9286 if (num_usershares >= max_user_shares) {
9287 DEBUG(0,("load_usershare_shares: max user shares reached "
9288 "on file %s in directory %s\n",
9289 n, usersharepath ));
9292 } else if (r == -1) {
9293 num_bad_dir_entries++;
9296 /* Allow 20% bad entries. */
9297 if (num_bad_dir_entries > allowed_bad_entries) {
9298 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9299 "in directory %s\n",
9300 num_bad_dir_entries, usersharepath));
9304 /* Allow 20% bad entries. */
9305 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9306 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9307 "in directory %s\n",
9308 num_dir_entries, usersharepath));
9315 /* Sweep through and delete any non-refreshed usershares that are
9316 not currently in use. */
9317 for (iService = iNumServices - 1; iService >= 0; iService--) {
9318 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9319 if (conn_snum_used(sconn, iService)) {
9322 /* Remove from the share ACL db. */
9323 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9324 lp_servicename(iService) ));
9325 delete_share_security(lp_servicename(iService));
9326 free_service_byindex(iService);
9330 return lp_numservices();
9333 /********************************************************
9334 Destroy global resources allocated in this file
9335 ********************************************************/
9337 void gfree_loadparm(void)
9343 /* Free resources allocated to services */
9345 for ( i = 0; i < iNumServices; i++ ) {
9347 free_service_byindex(i);
9351 SAFE_FREE( ServicePtrs );
9354 /* Now release all resources allocated to global
9355 parameters and the default service */
9357 free_global_parameters();
9361 /***************************************************************************
9362 Allow client apps to specify that they are a client
9363 ***************************************************************************/
9364 void lp_set_in_client(bool b)
9370 /***************************************************************************
9371 Determine if we're running in a client app
9372 ***************************************************************************/
9373 bool lp_is_in_client(void)
9378 /***************************************************************************
9379 Load the services array from the services file. Return True on success,
9381 ***************************************************************************/
9383 static bool lp_load_ex(const char *pszFname,
9387 bool initialize_globals,
9388 bool allow_include_registry,
9389 bool allow_registry_shares)
9396 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9398 bInGlobalSection = True;
9399 bGlobalOnly = global_only;
9400 bAllowIncludeRegistry = allow_include_registry;
9402 init_globals(initialize_globals);
9406 if (save_defaults) {
9411 free_param_opts(&Globals.param_opt);
9413 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
9415 /* We get sections first, so have to start 'behind' to make up */
9418 if (lp_config_backend_is_file()) {
9419 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9420 current_user_info.domain,
9423 smb_panic("lp_load_ex: out of memory");
9426 add_to_file_list(pszFname, n2);
9428 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9431 /* finish up the last section */
9432 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9434 if (iServiceIndex >= 0) {
9435 bRetval = service_ok(iServiceIndex);
9439 if (lp_config_backend_is_registry()) {
9440 /* config backend changed to registry in config file */
9442 * We need to use this extra global variable here to
9443 * survive restart: init_globals uses this as a default
9444 * for ConfigBackend. Otherwise, init_globals would
9445 * send us into an endless loop here.
9447 config_backend = CONFIG_BACKEND_REGISTRY;
9449 DEBUG(1, ("lp_load_ex: changing to config backend "
9452 lp_kill_all_services();
9453 return lp_load_ex(pszFname, global_only, save_defaults,
9454 add_ipc, initialize_globals,
9455 allow_include_registry,
9456 allow_registry_shares);
9458 } else if (lp_config_backend_is_registry()) {
9459 bRetval = process_registry_globals();
9461 DEBUG(0, ("Illegal config backend given: %d\n",
9462 lp_config_backend()));
9466 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9467 bRetval = process_registry_shares();
9470 lp_add_auto_services(lp_auto_services());
9473 /* When 'restrict anonymous = 2' guest connections to ipc$
9475 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9476 if ( lp_enable_asu_support() ) {
9477 lp_add_ipc("ADMIN$", false);
9482 set_default_server_announce_type();
9483 set_allowed_client_auth();
9485 if (lp_security() == SEC_SHARE) {
9486 DEBUG(1, ("WARNING: The security=share option is deprecated\n"));
9487 } else if (lp_security() == SEC_SERVER) {
9488 DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
9491 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
9492 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
9493 lp_passwordserver()));
9498 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9499 /* if bWINSsupport is true and we are in the client */
9500 if (lp_is_in_client() && Globals.bWINSsupport) {
9501 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9506 fault_configure(smb_panic_s3);
9508 bAllowIncludeRegistry = true;
9513 bool lp_load(const char *pszFname,
9517 bool initialize_globals)
9519 return lp_load_ex(pszFname,
9524 true, /* allow_include_registry */
9525 false); /* allow_registry_shares*/
9528 bool lp_load_initial_only(const char *pszFname)
9530 return lp_load_ex(pszFname,
9531 true, /* global only */
9532 false, /* save_defaults */
9533 false, /* add_ipc */
9534 true, /* initialize_globals */
9535 false, /* allow_include_registry */
9536 false); /* allow_registry_shares*/
9539 bool lp_load_with_registry_shares(const char *pszFname,
9543 bool initialize_globals)
9545 return lp_load_ex(pszFname,
9550 true, /* allow_include_registry */
9551 true); /* allow_registry_shares*/
9554 /***************************************************************************
9555 Return the max number of services.
9556 ***************************************************************************/
9558 int lp_numservices(void)
9560 return (iNumServices);
9563 /***************************************************************************
9564 Display the contents of the services array in human-readable form.
9565 ***************************************************************************/
9567 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9572 defaults_saved = False;
9576 dump_a_service(&sDefault, f);
9578 for (iService = 0; iService < maxtoprint; iService++) {
9580 lp_dump_one(f, show_defaults, iService);
9584 /***************************************************************************
9585 Display the contents of one service in human-readable form.
9586 ***************************************************************************/
9588 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9591 if (ServicePtrs[snum]->szService[0] == '\0')
9593 dump_a_service(ServicePtrs[snum], f);
9597 /***************************************************************************
9598 Return the number of the service with the given name, or -1 if it doesn't
9599 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9600 getservicebyname()! This works ONLY if all services have been loaded, and
9601 does not copy the found service.
9602 ***************************************************************************/
9604 int lp_servicenumber(const char *pszServiceName)
9607 fstring serviceName;
9609 if (!pszServiceName) {
9610 return GLOBAL_SECTION_SNUM;
9613 for (iService = iNumServices - 1; iService >= 0; iService--) {
9614 if (VALID(iService) && ServicePtrs[iService]->szService) {
9616 * The substitution here is used to support %U is
9619 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9620 standard_sub_basic(get_current_username(),
9621 current_user_info.domain,
9622 serviceName,sizeof(serviceName));
9623 if (strequal(serviceName, pszServiceName)) {
9629 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9630 struct timespec last_mod;
9632 if (!usershare_exists(iService, &last_mod)) {
9633 /* Remove the share security tdb entry for it. */
9634 delete_share_security(lp_servicename(iService));
9635 /* Remove it from the array. */
9636 free_service_byindex(iService);
9637 /* Doesn't exist anymore. */
9638 return GLOBAL_SECTION_SNUM;
9641 /* Has it been modified ? If so delete and reload. */
9642 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9644 /* Remove it from the array. */
9645 free_service_byindex(iService);
9646 /* and now reload it. */
9647 iService = load_usershare_service(pszServiceName);
9652 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9653 return GLOBAL_SECTION_SNUM;
9659 bool share_defined(const char *service_name)
9661 return (lp_servicenumber(service_name) != -1);
9664 /*******************************************************************
9665 A useful volume label function.
9666 ********************************************************************/
9668 const char *volume_label(int snum)
9671 const char *label = lp_volume(snum);
9673 label = lp_servicename(snum);
9676 /* This returns a 33 byte guarenteed null terminated string. */
9677 ret = talloc_strndup(talloc_tos(), label, 32);
9684 /*******************************************************************
9685 Set the server type we will announce as via nmbd.
9686 ********************************************************************/
9688 static void set_default_server_announce_type(void)
9690 default_server_announce = 0;
9691 default_server_announce |= SV_TYPE_WORKSTATION;
9692 default_server_announce |= SV_TYPE_SERVER;
9693 default_server_announce |= SV_TYPE_SERVER_UNIX;
9695 /* note that the flag should be set only if we have a
9696 printer service but nmbd doesn't actually load the
9697 services so we can't tell --jerry */
9699 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9701 default_server_announce |= SV_TYPE_SERVER_NT;
9702 default_server_announce |= SV_TYPE_NT;
9704 switch (lp_server_role()) {
9705 case ROLE_DOMAIN_MEMBER:
9706 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9708 case ROLE_DOMAIN_PDC:
9709 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9711 case ROLE_DOMAIN_BDC:
9712 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9714 case ROLE_STANDALONE:
9718 if (lp_time_server())
9719 default_server_announce |= SV_TYPE_TIME_SOURCE;
9721 if (lp_host_msdfs())
9722 default_server_announce |= SV_TYPE_DFS_SERVER;
9725 /***********************************************************
9726 If we are PDC then prefer us as DMB
9727 ************************************************************/
9729 bool lp_domain_master(void)
9731 if (Globals.iDomainMaster == Auto)
9732 return (lp_server_role() == ROLE_DOMAIN_PDC);
9734 return (bool)Globals.iDomainMaster;
9737 /***********************************************************
9738 If we are PDC then prefer us as DMB
9739 ************************************************************/
9741 bool lp_domain_master_true_or_auto(void)
9743 if (Globals.iDomainMaster) /* auto or yes */
9749 /***********************************************************
9750 If we are DMB then prefer us as LMB
9751 ************************************************************/
9753 bool lp_preferred_master(void)
9755 if (Globals.iPreferredMaster == Auto)
9756 return (lp_local_master() && lp_domain_master());
9758 return (bool)Globals.iPreferredMaster;
9761 /*******************************************************************
9763 ********************************************************************/
9765 void lp_remove_service(int snum)
9767 ServicePtrs[snum]->valid = False;
9768 invalid_services[num_invalid_services++] = snum;
9771 /*******************************************************************
9773 ********************************************************************/
9775 void lp_copy_service(int snum, const char *new_name)
9777 do_section(new_name, NULL);
9779 snum = lp_servicenumber(new_name);
9781 lp_do_parameter(snum, "copy", lp_servicename(snum));
9786 /*******************************************************************
9787 Get the default server type we will announce as via nmbd.
9788 ********************************************************************/
9790 int lp_default_server_announce(void)
9792 return default_server_announce;
9795 /***********************************************************
9796 Set the global name resolution order (used in smbclient).
9797 ************************************************************/
9799 void lp_set_name_resolve_order(const char *new_order)
9801 string_set(&Globals.szNameResolveOrder, new_order);
9804 const char *lp_printername(int snum)
9806 const char *ret = _lp_printername(snum);
9807 if (ret == NULL || (ret != NULL && *ret == '\0'))
9808 ret = lp_const_servicename(snum);
9814 /***********************************************************
9815 Allow daemons such as winbindd to fix their logfile name.
9816 ************************************************************/
9818 void lp_set_logfile(const char *name)
9820 string_set(&Globals.szLogFile, name);
9821 debug_set_logfile(name);
9824 /*******************************************************************
9825 Return the max print jobs per queue.
9826 ********************************************************************/
9828 int lp_maxprintjobs(int snum)
9830 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9831 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9832 maxjobs = PRINT_MAX_JOBID - 1;
9837 const char *lp_printcapname(void)
9839 if ((Globals.szPrintcapname != NULL) &&
9840 (Globals.szPrintcapname[0] != '\0'))
9841 return Globals.szPrintcapname;
9843 if (sDefault.iPrinting == PRINT_CUPS) {
9851 if (sDefault.iPrinting == PRINT_BSD)
9852 return "/etc/printcap";
9854 return PRINTCAP_NAME;
9857 static uint32 spoolss_state;
9859 bool lp_disable_spoolss( void )
9861 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9862 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9864 return spoolss_state == SVCCTL_STOPPED ? True : False;
9867 void lp_set_spoolss_state( uint32 state )
9869 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9871 spoolss_state = state;
9874 uint32 lp_get_spoolss_state( void )
9876 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9879 /*******************************************************************
9880 Ensure we don't use sendfile if server smb signing is active.
9881 ********************************************************************/
9883 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9885 bool sign_active = false;
9887 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9888 if (get_Protocol() < PROTOCOL_NT1) {
9891 if (signing_state) {
9892 sign_active = smb_signing_is_active(signing_state);
9894 return (_lp_use_sendfile(snum) &&
9895 (get_remote_arch() != RA_WIN95) &&
9899 /*******************************************************************
9900 Turn off sendfile if we find the underlying OS doesn't support it.
9901 ********************************************************************/
9903 void set_use_sendfile(int snum, bool val)
9905 if (LP_SNUM_OK(snum))
9906 ServicePtrs[snum]->bUseSendfile = val;
9908 sDefault.bUseSendfile = val;
9911 /*******************************************************************
9912 Turn off storing DOS attributes if this share doesn't support it.
9913 ********************************************************************/
9915 void set_store_dos_attributes(int snum, bool val)
9917 if (!LP_SNUM_OK(snum))
9919 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9922 void lp_set_mangling_method(const char *new_method)
9924 string_set(&Globals.szManglingMethod, new_method);
9927 /*******************************************************************
9928 Global state for POSIX pathname processing.
9929 ********************************************************************/
9931 static bool posix_pathnames;
9933 bool lp_posix_pathnames(void)
9935 return posix_pathnames;
9938 /*******************************************************************
9939 Change everything needed to ensure POSIX pathname processing (currently
9941 ********************************************************************/
9943 void lp_set_posix_pathnames(void)
9945 posix_pathnames = True;
9948 /*******************************************************************
9949 Global state for POSIX lock processing - CIFS unix extensions.
9950 ********************************************************************/
9952 bool posix_default_lock_was_set;
9953 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9955 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9957 if (posix_default_lock_was_set) {
9958 return posix_cifsx_locktype;
9960 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9964 /*******************************************************************
9965 ********************************************************************/
9967 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9969 posix_default_lock_was_set = True;
9970 posix_cifsx_locktype = val;
9973 int lp_min_receive_file_size(void)
9975 if (Globals.iminreceivefile < 0) {
9978 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9981 /*******************************************************************
9982 If socket address is an empty character string, it is necessary to
9983 define it as "0.0.0.0".
9984 ********************************************************************/
9986 const char *lp_socket_address(void)
9988 char *sock_addr = Globals.szSocketAddress;
9990 if (sock_addr[0] == '\0'){
9991 string_set(&Globals.szSocketAddress, "0.0.0.0");
9993 return Globals.szSocketAddress;
9996 void lp_set_passdb_backend(const char *backend)
9998 string_set(&Globals.szPassdbBackend, backend);
10001 /*******************************************************************
10002 Safe wide links checks.
10003 This helper function always verify the validity of wide links,
10004 even after a configuration file reload.
10005 ********************************************************************/
10007 static bool lp_widelinks_internal(int snum)
10009 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
10010 sDefault.bWidelinks);
10013 void widelinks_warning(int snum)
10015 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10016 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10017 "These parameters are incompatible. "
10018 "Wide links will be disabled for this share.\n",
10019 lp_servicename(snum) ));
10023 bool lp_widelinks(int snum)
10025 /* wide links is always incompatible with unix extensions */
10026 if (lp_unix_extensions()) {
10030 return lp_widelinks_internal(snum);
10033 bool lp_writeraw(void)
10035 if (lp_async_smb_echo_handler()) {
10038 return _lp_writeraw();
10041 bool lp_readraw(void)
10043 if (lp_async_smb_echo_handler()) {
10046 return _lp_readraw();