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
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 3 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
31 * This module provides suitable callback functions for the params
32 * module. It builds the internal table of service details which is
33 * then used by the rest of the server.
37 * 1) add it to the global or service structure definition
38 * 2) add it to the parm_table
39 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40 * 4) If it's a global then initialise it in init_globals. If a local
41 * (ie. service) parameter then initialise it in the sDefault structure
45 * The configuration file is processed sequentially for speed. It is NOT
46 * accessed randomly as happens in 'real' Windows. For this reason, there
47 * is a fair bit of sequence-dependent code here - ie., code which assumes
48 * that certain things happen before others. In particular, the code which
49 * happens at the boundary between sections is delicately poised, so be
57 #ifdef HAVE_SYS_SYSCTL_H
58 #include <sys/sysctl.h>
61 #ifdef HAVE_HTTPCONNECTENCRYPT
62 #include <cups/http.h>
67 extern userdom_struct current_user_info;
70 #define GLOBAL_NAME "global"
74 #define PRINTERS_NAME "printers"
78 #define HOMES_NAME "homes"
81 /* the special value for the include parameter
82 * to be interpreted not as a file name but to
83 * trigger loading of the global smb.conf options
85 #ifndef INCLUDE_REGISTRY_NAME
86 #define INCLUDE_REGISTRY_NAME "registry"
89 static bool in_client = False; /* Not in the client by default */
90 static struct smbconf_csn conf_last_csn;
92 #define CONFIG_BACKEND_FILE 0
93 #define CONFIG_BACKEND_REGISTRY 1
95 static int config_backend = CONFIG_BACKEND_FILE;
97 /* some helpful bits */
98 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
99 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
101 #define USERSHARE_VALID 1
102 #define USERSHARE_PENDING_DELETE 2
104 static bool defaults_saved = False;
106 struct param_opt_struct {
107 struct param_opt_struct *prev, *next;
114 * This structure describes global (ie., server-wide) parameters.
121 char *display_charset;
122 char *szPrintcapname;
123 char *szAddPortCommand;
124 char *szEnumPortsCommand;
125 char *szAddPrinterCommand;
126 char *szDeletePrinterCommand;
127 char *szOs2DriverMap;
133 char *szDefaultService;
137 char *szServerString;
138 char *szAutoServices;
139 char *szPasswdProgram;
143 char *szSMBPasswdFile;
145 char *szPassdbBackend;
146 char **szPreloadModules;
147 char *szPasswordServer;
148 char *szSocketOptions;
150 char *szAfsUsernameMap;
151 int iAfsTokenLifetime;
152 char *szLogNtTokenCommand;
158 char **szWINSservers;
160 char *szRemoteAnnounce;
161 char *szRemoteBrowseSync;
162 char *szSocketAddress;
163 char *szNISHomeMapName;
164 char *szAnnounceVersion; /* This is initialised in init_globals */
167 char **szNetbiosAliases;
168 char *szNetbiosScope;
169 char *szNameResolveOrder;
171 char *szAddUserScript;
172 char *szRenameUserScript;
173 char *szDelUserScript;
174 char *szAddGroupScript;
175 char *szDelGroupScript;
176 char *szAddUserToGroupScript;
177 char *szDelUserFromGroupScript;
178 char *szSetPrimaryGroupScript;
179 char *szAddMachineScript;
180 char *szShutdownScript;
181 char *szAbortShutdownScript;
182 char *szUsernameMapScript;
183 char *szCheckPasswordScript;
190 bool bPassdbExpandExplicit;
191 int AlgorithmicRidBase;
192 char *szTemplateHomedir;
193 char *szTemplateShell;
194 char *szWinbindSeparator;
195 bool bWinbindEnumUsers;
196 bool bWinbindEnumGroups;
197 bool bWinbindUseDefaultDomain;
198 bool bWinbindTrustedDomainsOnly;
199 bool bWinbindNestedGroups;
200 int winbind_expand_groups;
201 bool bWinbindRefreshTickets;
202 bool bWinbindOfflineLogon;
203 bool bWinbindNormalizeNames;
204 bool bWinbindRpcOnly;
205 bool bCreateKrb5Conf;
206 char *szIdmapBackend;
207 char *szIdmapAllocBackend;
208 char *szAddShareCommand;
209 char *szChangeShareCommand;
210 char *szDeleteShareCommand;
212 char *szGuestaccount;
213 char *szManglingMethod;
214 char **szServicesList;
215 char *szUsersharePath;
216 char *szUsershareTemplateShare;
217 char **szUsersharePrefixAllowList;
218 char **szUsersharePrefixDenyList;
225 int open_files_db_hash_size;
234 bool paranoid_server_security;
237 int iMaxSmbdProcesses;
238 bool bDisableSpoolss;
241 bool enhanced_browsing;
247 int announce_as; /* This is initialised in init_globals */
248 int machine_password_timeout;
250 int oplock_break_wait_time;
251 int winbind_cache_time;
252 int winbind_reconnect_delay;
253 int winbind_max_idle_children;
254 char **szWinbindNssInfo;
256 char *szLdapMachineSuffix;
257 char *szLdapUserSuffix;
258 char *szLdapIdmapSuffix;
259 char *szLdapGroupSuffix;
263 int ldap_follow_referral;
266 int ldap_debug_level;
267 int ldap_debug_threshold;
271 char *szIPrintServer;
273 char **szClusterAddresses;
276 int ldap_passwd_sync;
277 int ldap_replication_sleep;
278 int ldap_timeout; /* This is initialised in init_globals */
279 int ldap_connection_timeout;
282 bool bMsAddPrinterWizard;
287 int iPreferredMaster;
290 char **szInitLogonDelayedHosts;
292 bool bEncryptPasswords;
297 bool bObeyPamRestrictions;
299 int PrintcapCacheTime;
300 bool bLargeReadwrite;
307 bool bBindInterfacesOnly;
308 bool bPamPasswordChange;
309 bool bUnixPasswdSync;
310 bool bPasswdChatDebug;
311 int iPasswdChatTimeout;
315 bool bNTStatusSupport;
317 int iMaxStatCacheSize;
319 bool bAllowTrustedDomains;
323 bool bClientLanManAuth;
324 bool bClientNTLMv2Auth;
325 bool bClientPlaintextAuth;
326 bool bClientUseSpnego;
327 bool bDebugPrefixTimestamp;
328 bool bDebugHiresTimestamp;
332 bool bEnableCoreFiles;
335 bool bHostnameLookups;
336 bool bUnixExtensions;
337 bool bDisableNetbios;
338 char * szDedicatedKeytabFile;
340 bool bDeferSharingViolations;
341 bool bEnablePrivileges;
343 bool bUsershareOwnerOnly;
344 bool bUsershareAllowGuests;
345 bool bRegistryShares;
346 int restrict_anonymous;
347 int name_cache_timeout;
350 int client_ldap_sasl_wrapping;
351 int iUsershareMaxShares;
353 int iIdmapNegativeCacheTime;
357 struct param_opt_struct *param_opt;
358 int cups_connection_timeout;
359 char *szSMBPerfcountModule;
360 bool bMapUntrustedToDomain;
363 static struct global Globals;
366 * This structure describes a single service.
372 struct timespec usershare_last_mod;
376 char **szInvalidUsers;
384 char *szRootPostExec;
386 char *szPrintcommand;
389 char *szLppausecommand;
390 char *szLpresumecommand;
391 char *szQueuepausecommand;
392 char *szQueueresumecommand;
394 char *szPrintjobUsername;
402 char *szVetoOplockFiles;
408 char **printer_admin;
413 char *szAioWriteBehind;
417 int iMaxReportedPrintJobs;
420 int iCreate_force_mode;
422 int iSecurity_force_mode;
425 int iDir_Security_mask;
426 int iDir_Security_force_mode;
430 int iOplockContentionLimit;
435 bool bRootpreexecClose;
438 bool bShortCasePreserve;
440 bool bHideSpecialFiles;
441 bool bHideUnReadable;
442 bool bHideUnWriteableFiles;
444 bool bAccessBasedShareEnum;
449 bool bAdministrative_share;
455 bool bStoreDosAttributes;
468 bool bStrictAllocate;
471 struct bitmap *copymap;
472 bool bDeleteReadonly;
474 bool bDeleteVetoFiles;
477 bool bDosFiletimeResolution;
478 bool bFakeDirCreateTimes;
484 bool bUseClientDriver;
485 bool bDefaultDevmode;
486 bool bForcePrintername;
488 bool bForceUnknownAclUser;
491 bool bMap_acl_inherit;
494 bool bAclCheckPermissions;
495 bool bAclMapFullControl;
496 bool bAclGroupControl;
498 bool bKernelChangeNotify;
499 int iallocation_roundup_size;
503 int iDirectoryNameCacheSize;
505 struct param_opt_struct *param_opt;
507 char dummy[3]; /* for alignment */
511 /* This is a default service used to prime a services structure */
512 static struct service sDefault = {
514 False, /* not autoloaded */
515 0, /* not a usershare */
516 {0, }, /* No last mod time */
517 NULL, /* szService */
519 NULL, /* szUsername */
520 NULL, /* szInvalidUsers */
521 NULL, /* szValidUsers */
522 NULL, /* szAdminUsers */
524 NULL, /* szInclude */
525 NULL, /* szPreExec */
526 NULL, /* szPostExec */
527 NULL, /* szRootPreExec */
528 NULL, /* szRootPostExec */
529 NULL, /* szCupsOptions */
530 NULL, /* szPrintcommand */
531 NULL, /* szLpqcommand */
532 NULL, /* szLprmcommand */
533 NULL, /* szLppausecommand */
534 NULL, /* szLpresumecommand */
535 NULL, /* szQueuepausecommand */
536 NULL, /* szQueueresumecommand */
537 NULL, /* szPrintername */
538 NULL, /* szPrintjobUsername */
539 NULL, /* szDontdescend */
540 NULL, /* szHostsallow */
541 NULL, /* szHostsdeny */
542 NULL, /* szMagicScript */
543 NULL, /* szMagicOutput */
544 NULL, /* szVetoFiles */
545 NULL, /* szHideFiles */
546 NULL, /* szVetoOplockFiles */
548 NULL, /* force user */
549 NULL, /* force group */
551 NULL, /* writelist */
552 NULL, /* printer admin */
555 NULL, /* vfs objects */
556 NULL, /* szMSDfsProxy */
557 NULL, /* szAioWriteBehind */
559 0, /* iMinPrintSpace */
560 1000, /* iMaxPrintJobs */
561 0, /* iMaxReportedPrintJobs */
562 0, /* iWriteCacheSize */
563 0744, /* iCreate_mask */
564 0000, /* iCreate_force_mode */
565 0777, /* iSecurity_mask */
566 0, /* iSecurity_force_mode */
567 0755, /* iDir_mask */
568 0000, /* iDir_force_mode */
569 0777, /* iDir_Security_mask */
570 0, /* iDir_Security_force_mode */
571 0, /* iMaxConnections */
572 CASE_LOWER, /* iDefaultCase */
573 DEFAULT_PRINTING, /* iPrinting */
574 2, /* iOplockContentionLimit */
576 1024, /* iBlock_size */
577 0, /* iDfreeCacheTime */
578 False, /* bPreexecClose */
579 False, /* bRootpreexecClose */
580 Auto, /* case sensitive */
581 True, /* case preserve */
582 True, /* short case preserve */
583 True, /* bHideDotFiles */
584 False, /* bHideSpecialFiles */
585 False, /* bHideUnReadable */
586 False, /* bHideUnWriteableFiles */
587 True, /* bBrowseable */
588 False, /* bAccessBasedShareEnum */
589 True, /* bAvailable */
590 True, /* bRead_only */
591 True, /* bNo_set_dir */
592 False, /* bGuest_only */
593 False, /* bAdministrative_share */
594 False, /* bGuest_ok */
595 False, /* bPrint_ok */
596 False, /* bMap_system */
597 False, /* bMap_hidden */
598 True, /* bMap_archive */
599 False, /* bStoreDosAttributes */
600 False, /* bDmapiSupport */
602 Auto, /* iStrictLocking */
603 True, /* bPosixLocking */
604 True, /* bShareModes */
606 True, /* bLevel2OpLocks */
607 False, /* bOnlyUser */
608 True, /* bMangledNames */
609 false, /* bWidelinks */
610 True, /* bSymlinks */
611 False, /* bSyncAlways */
612 False, /* bStrictAllocate */
613 False, /* bStrictSync */
614 '~', /* magic char */
616 False, /* bDeleteReadonly */
617 False, /* bFakeOplocks */
618 False, /* bDeleteVetoFiles */
619 False, /* bDosFilemode */
620 True, /* bDosFiletimes */
621 False, /* bDosFiletimeResolution */
622 False, /* bFakeDirCreateTimes */
623 True, /* bBlockingLocks */
624 False, /* bInheritPerms */
625 False, /* bInheritACLS */
626 False, /* bInheritOwner */
627 False, /* bMSDfsRoot */
628 False, /* bUseClientDriver */
629 True, /* bDefaultDevmode */
630 False, /* bForcePrintername */
631 True, /* bNTAclSupport */
632 False, /* bForceUnknownAclUser */
633 False, /* bUseSendfile */
634 False, /* bProfileAcls */
635 False, /* bMap_acl_inherit */
636 False, /* bAfs_Share */
637 False, /* bEASupport */
638 True, /* bAclCheckPermissions */
639 True, /* bAclMapFullControl */
640 False, /* bAclGroupControl */
641 True, /* bChangeNotify */
642 True, /* bKernelChangeNotify */
643 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
644 0, /* iAioReadSize */
645 0, /* iAioWriteSize */
646 MAP_READONLY_YES, /* iMap_readonly */
647 #ifdef BROKEN_DIRECTORY_HANDLING
648 0, /* iDirectoryNameCacheSize */
650 100, /* iDirectoryNameCacheSize */
652 Auto, /* ismb_encrypt */
653 NULL, /* Parametric options */
658 /* local variables */
659 static struct service **ServicePtrs = NULL;
660 static int iNumServices = 0;
661 static int iServiceIndex = 0;
662 static struct db_context *ServiceHash;
663 static int *invalid_services = NULL;
664 static int num_invalid_services = 0;
665 static bool bInGlobalSection = True;
666 static bool bGlobalOnly = False;
667 static int server_role;
668 static int default_server_announce;
670 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
672 /* prototypes for the special type handlers */
673 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
674 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
675 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
676 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
677 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
678 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
679 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
680 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
681 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
682 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
683 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
684 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
686 static void set_server_role(void);
687 static void set_default_server_announce_type(void);
688 static void set_allowed_client_auth(void);
690 static void *lp_local_ptr(struct service *service, void *ptr);
692 static void add_to_file_list(const char *fname, const char *subfname);
694 static const struct enum_list enum_protocol[] = {
695 {PROTOCOL_SMB2, "SMB2"},
696 {PROTOCOL_NT1, "NT1"},
697 {PROTOCOL_LANMAN2, "LANMAN2"},
698 {PROTOCOL_LANMAN1, "LANMAN1"},
699 {PROTOCOL_CORE, "CORE"},
700 {PROTOCOL_COREPLUS, "COREPLUS"},
701 {PROTOCOL_COREPLUS, "CORE+"},
705 static const struct enum_list enum_security[] = {
706 {SEC_SHARE, "SHARE"},
708 {SEC_SERVER, "SERVER"},
709 {SEC_DOMAIN, "DOMAIN"},
716 static const struct enum_list enum_printing[] = {
717 {PRINT_SYSV, "sysv"},
719 {PRINT_HPUX, "hpux"},
723 {PRINT_LPRNG, "lprng"},
724 {PRINT_CUPS, "cups"},
725 {PRINT_IPRINT, "iprint"},
727 {PRINT_LPROS2, "os2"},
729 {PRINT_TEST, "test"},
731 #endif /* DEVELOPER */
735 static const struct enum_list enum_ldap_sasl_wrapping[] = {
737 {ADS_AUTH_SASL_SIGN, "sign"},
738 {ADS_AUTH_SASL_SEAL, "seal"},
742 static const struct enum_list enum_ldap_ssl[] = {
743 {LDAP_SSL_OFF, "no"},
744 {LDAP_SSL_OFF, "off"},
745 {LDAP_SSL_START_TLS, "start tls"},
746 {LDAP_SSL_START_TLS, "start_tls"},
750 /* LDAP Dereferencing Alias types */
751 #define SAMBA_LDAP_DEREF_NEVER 0
752 #define SAMBA_LDAP_DEREF_SEARCHING 1
753 #define SAMBA_LDAP_DEREF_FINDING 2
754 #define SAMBA_LDAP_DEREF_ALWAYS 3
756 static const struct enum_list enum_ldap_deref[] = {
757 {SAMBA_LDAP_DEREF_NEVER, "never"},
758 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
759 {SAMBA_LDAP_DEREF_FINDING, "finding"},
760 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
764 static const struct enum_list enum_ldap_passwd_sync[] = {
765 {LDAP_PASSWD_SYNC_OFF, "no"},
766 {LDAP_PASSWD_SYNC_OFF, "off"},
767 {LDAP_PASSWD_SYNC_ON, "yes"},
768 {LDAP_PASSWD_SYNC_ON, "on"},
769 {LDAP_PASSWD_SYNC_ONLY, "only"},
773 /* Types of machine we can announce as. */
774 #define ANNOUNCE_AS_NT_SERVER 1
775 #define ANNOUNCE_AS_WIN95 2
776 #define ANNOUNCE_AS_WFW 3
777 #define ANNOUNCE_AS_NT_WORKSTATION 4
779 static const struct enum_list enum_announce_as[] = {
780 {ANNOUNCE_AS_NT_SERVER, "NT"},
781 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
782 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
783 {ANNOUNCE_AS_WIN95, "win95"},
784 {ANNOUNCE_AS_WFW, "WfW"},
788 static const struct enum_list enum_map_readonly[] = {
789 {MAP_READONLY_NO, "no"},
790 {MAP_READONLY_NO, "false"},
791 {MAP_READONLY_NO, "0"},
792 {MAP_READONLY_YES, "yes"},
793 {MAP_READONLY_YES, "true"},
794 {MAP_READONLY_YES, "1"},
795 {MAP_READONLY_PERMISSIONS, "permissions"},
796 {MAP_READONLY_PERMISSIONS, "perms"},
800 static const struct enum_list enum_case[] = {
801 {CASE_LOWER, "lower"},
802 {CASE_UPPER, "upper"},
808 static const struct enum_list enum_bool_auto[] = {
819 /* Client-side offline caching policy types */
820 #define CSC_POLICY_MANUAL 0
821 #define CSC_POLICY_DOCUMENTS 1
822 #define CSC_POLICY_PROGRAMS 2
823 #define CSC_POLICY_DISABLE 3
825 static const struct enum_list enum_csc_policy[] = {
826 {CSC_POLICY_MANUAL, "manual"},
827 {CSC_POLICY_DOCUMENTS, "documents"},
828 {CSC_POLICY_PROGRAMS, "programs"},
829 {CSC_POLICY_DISABLE, "disable"},
833 /* SMB signing types. */
834 static const struct enum_list enum_smb_signing_vals[] = {
846 {Required, "required"},
847 {Required, "mandatory"},
849 {Required, "forced"},
850 {Required, "enforced"},
854 /* ACL compatibility options. */
855 static const struct enum_list enum_acl_compat_vals[] = {
856 { ACL_COMPAT_AUTO, "auto" },
857 { ACL_COMPAT_WINNT, "winnt" },
858 { ACL_COMPAT_WIN2K, "win2k" },
863 Do you want session setups at user level security with a invalid
864 password to be rejected or allowed in as guest? WinNT rejects them
865 but it can be a pain as it means "net view" needs to use a password
867 You have 3 choices in the setting of map_to_guest:
869 "Never" means session setups with an invalid password
870 are rejected. This is the default.
872 "Bad User" means session setups with an invalid password
873 are rejected, unless the username does not exist, in which case it
874 is treated as a guest login
876 "Bad Password" means session setups with an invalid password
877 are treated as a guest login
879 Note that map_to_guest only has an effect in user or server
883 static const struct enum_list enum_map_to_guest[] = {
884 {NEVER_MAP_TO_GUEST, "Never"},
885 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
886 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
887 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
891 /* Config backend options */
893 static const struct enum_list enum_config_backend[] = {
894 {CONFIG_BACKEND_FILE, "file"},
895 {CONFIG_BACKEND_REGISTRY, "registry"},
899 /* ADS kerberos ticket verification options */
901 static const struct enum_list enum_kerberos_method[] = {
902 {KERBEROS_VERIFY_SECRETS, "default"},
903 {KERBEROS_VERIFY_SECRETS, "secrets only"},
904 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
905 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
906 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
910 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
912 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
913 * screen in SWAT. This is used to exclude parameters as well as to squash all
914 * parameters that have been duplicated by pseudonyms.
916 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
917 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
918 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
921 * NOTE2: Handling of duplicated (synonym) parameters:
922 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
923 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
924 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
925 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
928 static struct parm_struct parm_table[] = {
929 {N_("Base Options"), P_SEP, P_SEPARATOR},
932 .label = "dos charset",
935 .ptr = &Globals.dos_charset,
936 .special = handle_charset,
938 .flags = FLAG_ADVANCED
941 .label = "unix charset",
944 .ptr = &Globals.unix_charset,
945 .special = handle_charset,
947 .flags = FLAG_ADVANCED
950 .label = "display charset",
953 .ptr = &Globals.display_charset,
954 .special = handle_charset,
956 .flags = FLAG_ADVANCED
962 .ptr = &sDefault.comment,
965 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
971 .ptr = &sDefault.szPath,
974 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
977 .label = "directory",
980 .ptr = &sDefault.szPath,
986 .label = "workgroup",
989 .ptr = &Globals.szWorkgroup,
990 .special = handle_workgroup,
992 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
999 .ptr = &Globals.szRealm,
1002 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1006 .label = "netbios name",
1008 .p_class = P_GLOBAL,
1009 .ptr = &Globals.szNetbiosName,
1010 .special = handle_netbios_name,
1012 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1015 .label = "netbios aliases",
1017 .p_class = P_GLOBAL,
1018 .ptr = &Globals.szNetbiosAliases,
1019 .special = handle_netbios_aliases,
1021 .flags = FLAG_ADVANCED,
1024 .label = "netbios scope",
1026 .p_class = P_GLOBAL,
1027 .ptr = &Globals.szNetbiosScope,
1028 .special = handle_netbios_scope,
1030 .flags = FLAG_ADVANCED,
1033 .label = "server string",
1035 .p_class = P_GLOBAL,
1036 .ptr = &Globals.szServerString,
1039 .flags = FLAG_BASIC | FLAG_ADVANCED,
1042 .label = "interfaces",
1044 .p_class = P_GLOBAL,
1045 .ptr = &Globals.szInterfaces,
1048 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1051 .label = "bind interfaces only",
1053 .p_class = P_GLOBAL,
1054 .ptr = &Globals.bBindInterfacesOnly,
1057 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1060 .label = "config backend",
1062 .p_class = P_GLOBAL,
1063 .ptr = &Globals.ConfigBackend,
1065 .enum_list = enum_config_backend,
1066 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1069 {N_("Security Options"), P_SEP, P_SEPARATOR},
1072 .label = "security",
1074 .p_class = P_GLOBAL,
1075 .ptr = &Globals.security,
1077 .enum_list = enum_security,
1078 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1081 .label = "auth methods",
1083 .p_class = P_GLOBAL,
1084 .ptr = &Globals.AuthMethods,
1087 .flags = FLAG_ADVANCED,
1090 .label = "encrypt passwords",
1092 .p_class = P_GLOBAL,
1093 .ptr = &Globals.bEncryptPasswords,
1096 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1099 .label = "update encrypted",
1101 .p_class = P_GLOBAL,
1102 .ptr = &Globals.bUpdateEncrypt,
1105 .flags = FLAG_ADVANCED,
1108 .label = "client schannel",
1110 .p_class = P_GLOBAL,
1111 .ptr = &Globals.clientSchannel,
1113 .enum_list = enum_bool_auto,
1114 .flags = FLAG_BASIC | FLAG_ADVANCED,
1117 .label = "server schannel",
1119 .p_class = P_GLOBAL,
1120 .ptr = &Globals.serverSchannel,
1122 .enum_list = enum_bool_auto,
1123 .flags = FLAG_BASIC | FLAG_ADVANCED,
1126 .label = "allow trusted domains",
1128 .p_class = P_GLOBAL,
1129 .ptr = &Globals.bAllowTrustedDomains,
1132 .flags = FLAG_ADVANCED,
1135 .label = "map to guest",
1137 .p_class = P_GLOBAL,
1138 .ptr = &Globals.map_to_guest,
1140 .enum_list = enum_map_to_guest,
1141 .flags = FLAG_ADVANCED,
1144 .label = "null passwords",
1146 .p_class = P_GLOBAL,
1147 .ptr = &Globals.bNullPasswords,
1150 .flags = FLAG_ADVANCED,
1153 .label = "obey pam restrictions",
1155 .p_class = P_GLOBAL,
1156 .ptr = &Globals.bObeyPamRestrictions,
1159 .flags = FLAG_ADVANCED,
1162 .label = "password server",
1164 .p_class = P_GLOBAL,
1165 .ptr = &Globals.szPasswordServer,
1168 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1171 .label = "smb passwd file",
1173 .p_class = P_GLOBAL,
1174 .ptr = &Globals.szSMBPasswdFile,
1177 .flags = FLAG_ADVANCED,
1180 .label = "private dir",
1182 .p_class = P_GLOBAL,
1183 .ptr = &Globals.szPrivateDir,
1186 .flags = FLAG_ADVANCED,
1189 .label = "passdb backend",
1191 .p_class = P_GLOBAL,
1192 .ptr = &Globals.szPassdbBackend,
1195 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1198 .label = "algorithmic rid base",
1200 .p_class = P_GLOBAL,
1201 .ptr = &Globals.AlgorithmicRidBase,
1204 .flags = FLAG_ADVANCED,
1207 .label = "root directory",
1209 .p_class = P_GLOBAL,
1210 .ptr = &Globals.szRootdir,
1213 .flags = FLAG_ADVANCED,
1216 .label = "root dir",
1218 .p_class = P_GLOBAL,
1219 .ptr = &Globals.szRootdir,
1227 .p_class = P_GLOBAL,
1228 .ptr = &Globals.szRootdir,
1234 .label = "guest account",
1236 .p_class = P_GLOBAL,
1237 .ptr = &Globals.szGuestaccount,
1240 .flags = FLAG_BASIC | FLAG_ADVANCED,
1243 .label = "enable privileges",
1245 .p_class = P_GLOBAL,
1246 .ptr = &Globals.bEnablePrivileges,
1249 .flags = FLAG_ADVANCED,
1253 .label = "pam password change",
1255 .p_class = P_GLOBAL,
1256 .ptr = &Globals.bPamPasswordChange,
1259 .flags = FLAG_ADVANCED,
1262 .label = "passwd program",
1264 .p_class = P_GLOBAL,
1265 .ptr = &Globals.szPasswdProgram,
1268 .flags = FLAG_ADVANCED,
1271 .label = "passwd chat",
1273 .p_class = P_GLOBAL,
1274 .ptr = &Globals.szPasswdChat,
1277 .flags = FLAG_ADVANCED,
1280 .label = "passwd chat debug",
1282 .p_class = P_GLOBAL,
1283 .ptr = &Globals.bPasswdChatDebug,
1286 .flags = FLAG_ADVANCED,
1289 .label = "passwd chat timeout",
1291 .p_class = P_GLOBAL,
1292 .ptr = &Globals.iPasswdChatTimeout,
1295 .flags = FLAG_ADVANCED,
1298 .label = "check password script",
1300 .p_class = P_GLOBAL,
1301 .ptr = &Globals.szCheckPasswordScript,
1304 .flags = FLAG_ADVANCED,
1307 .label = "username map",
1309 .p_class = P_GLOBAL,
1310 .ptr = &Globals.szUsernameMap,
1313 .flags = FLAG_ADVANCED,
1316 .label = "password level",
1318 .p_class = P_GLOBAL,
1319 .ptr = &Globals.pwordlevel,
1322 .flags = FLAG_ADVANCED,
1325 .label = "username level",
1327 .p_class = P_GLOBAL,
1328 .ptr = &Globals.unamelevel,
1331 .flags = FLAG_ADVANCED,
1334 .label = "unix password sync",
1336 .p_class = P_GLOBAL,
1337 .ptr = &Globals.bUnixPasswdSync,
1340 .flags = FLAG_ADVANCED,
1343 .label = "restrict anonymous",
1345 .p_class = P_GLOBAL,
1346 .ptr = &Globals.restrict_anonymous,
1349 .flags = FLAG_ADVANCED,
1352 .label = "lanman auth",
1354 .p_class = P_GLOBAL,
1355 .ptr = &Globals.bLanmanAuth,
1358 .flags = FLAG_ADVANCED,
1361 .label = "ntlm auth",
1363 .p_class = P_GLOBAL,
1364 .ptr = &Globals.bNTLMAuth,
1367 .flags = FLAG_ADVANCED,
1370 .label = "client NTLMv2 auth",
1372 .p_class = P_GLOBAL,
1373 .ptr = &Globals.bClientNTLMv2Auth,
1376 .flags = FLAG_ADVANCED,
1379 .label = "client lanman auth",
1381 .p_class = P_GLOBAL,
1382 .ptr = &Globals.bClientLanManAuth,
1385 .flags = FLAG_ADVANCED,
1388 .label = "client plaintext auth",
1390 .p_class = P_GLOBAL,
1391 .ptr = &Globals.bClientPlaintextAuth,
1394 .flags = FLAG_ADVANCED,
1397 .label = "username",
1400 .ptr = &sDefault.szUsername,
1403 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1409 .ptr = &sDefault.szUsername,
1418 .ptr = &sDefault.szUsername,
1424 .label = "invalid users",
1427 .ptr = &sDefault.szInvalidUsers,
1430 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1433 .label = "valid users",
1436 .ptr = &sDefault.szValidUsers,
1439 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1442 .label = "admin users",
1445 .ptr = &sDefault.szAdminUsers,
1448 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1451 .label = "read list",
1454 .ptr = &sDefault.readlist,
1457 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1460 .label = "write list",
1463 .ptr = &sDefault.writelist,
1466 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1469 .label = "printer admin",
1472 .ptr = &sDefault.printer_admin,
1475 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1478 .label = "force user",
1481 .ptr = &sDefault.force_user,
1484 .flags = FLAG_ADVANCED | FLAG_SHARE,
1487 .label = "force group",
1490 .ptr = &sDefault.force_group,
1493 .flags = FLAG_ADVANCED | FLAG_SHARE,
1499 .ptr = &sDefault.force_group,
1502 .flags = FLAG_ADVANCED,
1505 .label = "read only",
1508 .ptr = &sDefault.bRead_only,
1511 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1514 .label = "write ok",
1517 .ptr = &sDefault.bRead_only,
1523 .label = "writeable",
1526 .ptr = &sDefault.bRead_only,
1532 .label = "writable",
1535 .ptr = &sDefault.bRead_only,
1541 .label = "acl check permissions",
1544 .ptr = &sDefault.bAclCheckPermissions,
1547 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1550 .label = "acl group control",
1553 .ptr = &sDefault.bAclGroupControl,
1556 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1559 .label = "acl map full control",
1562 .ptr = &sDefault.bAclMapFullControl,
1565 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1568 .label = "create mask",
1571 .ptr = &sDefault.iCreate_mask,
1574 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1577 .label = "create mode",
1580 .ptr = &sDefault.iCreate_mask,
1586 .label = "force create mode",
1589 .ptr = &sDefault.iCreate_force_mode,
1592 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1595 .label = "security mask",
1598 .ptr = &sDefault.iSecurity_mask,
1601 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1604 .label = "force security mode",
1607 .ptr = &sDefault.iSecurity_force_mode,
1610 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1613 .label = "directory mask",
1616 .ptr = &sDefault.iDir_mask,
1619 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1622 .label = "directory mode",
1625 .ptr = &sDefault.iDir_mask,
1628 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1631 .label = "force directory mode",
1634 .ptr = &sDefault.iDir_force_mode,
1637 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1640 .label = "directory security mask",
1643 .ptr = &sDefault.iDir_Security_mask,
1646 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1649 .label = "force directory security mode",
1652 .ptr = &sDefault.iDir_Security_force_mode,
1655 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1658 .label = "force unknown acl user",
1661 .ptr = &sDefault.bForceUnknownAclUser,
1664 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1667 .label = "inherit permissions",
1670 .ptr = &sDefault.bInheritPerms,
1673 .flags = FLAG_ADVANCED | FLAG_SHARE,
1676 .label = "inherit acls",
1679 .ptr = &sDefault.bInheritACLS,
1682 .flags = FLAG_ADVANCED | FLAG_SHARE,
1685 .label = "inherit owner",
1688 .ptr = &sDefault.bInheritOwner,
1691 .flags = FLAG_ADVANCED | FLAG_SHARE,
1694 .label = "guest only",
1697 .ptr = &sDefault.bGuest_only,
1700 .flags = FLAG_ADVANCED | FLAG_SHARE,
1703 .label = "only guest",
1706 .ptr = &sDefault.bGuest_only,
1712 .label = "administrative share",
1715 .ptr = &sDefault.bAdministrative_share,
1718 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1722 .label = "guest ok",
1725 .ptr = &sDefault.bGuest_ok,
1728 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1734 .ptr = &sDefault.bGuest_ok,
1740 .label = "only user",
1743 .ptr = &sDefault.bOnlyUser,
1746 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1749 .label = "hosts allow",
1752 .ptr = &sDefault.szHostsallow,
1755 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1758 .label = "allow hosts",
1761 .ptr = &sDefault.szHostsallow,
1767 .label = "hosts deny",
1770 .ptr = &sDefault.szHostsdeny,
1773 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1776 .label = "deny hosts",
1779 .ptr = &sDefault.szHostsdeny,
1785 .label = "preload modules",
1787 .p_class = P_GLOBAL,
1788 .ptr = &Globals.szPreloadModules,
1791 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1794 .label = "dedicated keytab file",
1796 .p_class = P_GLOBAL,
1797 .ptr = &Globals.szDedicatedKeytabFile,
1800 .flags = FLAG_ADVANCED,
1803 .label = "kerberos method",
1805 .p_class = P_GLOBAL,
1806 .ptr = &Globals.iKerberosMethod,
1808 .enum_list = enum_kerberos_method,
1809 .flags = FLAG_ADVANCED,
1812 .label = "map untrusted to domain",
1814 .p_class = P_GLOBAL,
1815 .ptr = &Globals.bMapUntrustedToDomain,
1818 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1822 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1825 .label = "log level",
1827 .p_class = P_GLOBAL,
1828 .ptr = &Globals.szLogLevel,
1829 .special = handle_debug_list,
1831 .flags = FLAG_ADVANCED,
1834 .label = "debuglevel",
1836 .p_class = P_GLOBAL,
1837 .ptr = &Globals.szLogLevel,
1838 .special = handle_debug_list,
1845 .p_class = P_GLOBAL,
1846 .ptr = &Globals.syslog,
1849 .flags = FLAG_ADVANCED,
1852 .label = "syslog only",
1854 .p_class = P_GLOBAL,
1855 .ptr = &Globals.bSyslogOnly,
1858 .flags = FLAG_ADVANCED,
1861 .label = "log file",
1863 .p_class = P_GLOBAL,
1864 .ptr = &Globals.szLogFile,
1867 .flags = FLAG_ADVANCED,
1870 .label = "max log size",
1872 .p_class = P_GLOBAL,
1873 .ptr = &Globals.max_log_size,
1876 .flags = FLAG_ADVANCED,
1879 .label = "debug timestamp",
1881 .p_class = P_GLOBAL,
1882 .ptr = &Globals.bTimestampLogs,
1885 .flags = FLAG_ADVANCED,
1888 .label = "timestamp logs",
1890 .p_class = P_GLOBAL,
1891 .ptr = &Globals.bTimestampLogs,
1894 .flags = FLAG_ADVANCED,
1897 .label = "debug prefix timestamp",
1899 .p_class = P_GLOBAL,
1900 .ptr = &Globals.bDebugPrefixTimestamp,
1903 .flags = FLAG_ADVANCED,
1906 .label = "debug hires timestamp",
1908 .p_class = P_GLOBAL,
1909 .ptr = &Globals.bDebugHiresTimestamp,
1912 .flags = FLAG_ADVANCED,
1915 .label = "debug pid",
1917 .p_class = P_GLOBAL,
1918 .ptr = &Globals.bDebugPid,
1921 .flags = FLAG_ADVANCED,
1924 .label = "debug uid",
1926 .p_class = P_GLOBAL,
1927 .ptr = &Globals.bDebugUid,
1930 .flags = FLAG_ADVANCED,
1933 .label = "debug class",
1935 .p_class = P_GLOBAL,
1936 .ptr = &Globals.bDebugClass,
1939 .flags = FLAG_ADVANCED,
1942 .label = "enable core files",
1944 .p_class = P_GLOBAL,
1945 .ptr = &Globals.bEnableCoreFiles,
1948 .flags = FLAG_ADVANCED,
1951 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1954 .label = "allocation roundup size",
1957 .ptr = &sDefault.iallocation_roundup_size,
1960 .flags = FLAG_ADVANCED,
1963 .label = "aio read size",
1966 .ptr = &sDefault.iAioReadSize,
1969 .flags = FLAG_ADVANCED,
1972 .label = "aio write size",
1975 .ptr = &sDefault.iAioWriteSize,
1978 .flags = FLAG_ADVANCED,
1981 .label = "aio write behind",
1984 .ptr = &sDefault.szAioWriteBehind,
1987 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1990 .label = "smb ports",
1992 .p_class = P_GLOBAL,
1993 .ptr = &Globals.smb_ports,
1996 .flags = FLAG_ADVANCED,
1999 .label = "large readwrite",
2001 .p_class = P_GLOBAL,
2002 .ptr = &Globals.bLargeReadwrite,
2005 .flags = FLAG_ADVANCED,
2008 .label = "max protocol",
2010 .p_class = P_GLOBAL,
2011 .ptr = &Globals.maxprotocol,
2013 .enum_list = enum_protocol,
2014 .flags = FLAG_ADVANCED,
2017 .label = "protocol",
2019 .p_class = P_GLOBAL,
2020 .ptr = &Globals.maxprotocol,
2022 .enum_list = enum_protocol,
2023 .flags = FLAG_ADVANCED,
2026 .label = "min protocol",
2028 .p_class = P_GLOBAL,
2029 .ptr = &Globals.minprotocol,
2031 .enum_list = enum_protocol,
2032 .flags = FLAG_ADVANCED,
2035 .label = "min receivefile size",
2037 .p_class = P_GLOBAL,
2038 .ptr = &Globals.iminreceivefile,
2041 .flags = FLAG_ADVANCED,
2044 .label = "read raw",
2046 .p_class = P_GLOBAL,
2047 .ptr = &Globals.bReadRaw,
2050 .flags = FLAG_ADVANCED,
2053 .label = "write raw",
2055 .p_class = P_GLOBAL,
2056 .ptr = &Globals.bWriteRaw,
2059 .flags = FLAG_ADVANCED,
2062 .label = "disable netbios",
2064 .p_class = P_GLOBAL,
2065 .ptr = &Globals.bDisableNetbios,
2068 .flags = FLAG_ADVANCED,
2071 .label = "reset on zero vc",
2073 .p_class = P_GLOBAL,
2074 .ptr = &Globals.bResetOnZeroVC,
2077 .flags = FLAG_ADVANCED,
2080 .label = "acl compatibility",
2082 .p_class = P_GLOBAL,
2083 .ptr = &Globals.iAclCompat,
2085 .enum_list = enum_acl_compat_vals,
2086 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2089 .label = "defer sharing violations",
2091 .p_class = P_GLOBAL,
2092 .ptr = &Globals.bDeferSharingViolations,
2095 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2098 .label = "ea support",
2101 .ptr = &sDefault.bEASupport,
2104 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2107 .label = "nt acl support",
2110 .ptr = &sDefault.bNTAclSupport,
2113 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2116 .label = "nt pipe support",
2118 .p_class = P_GLOBAL,
2119 .ptr = &Globals.bNTPipeSupport,
2122 .flags = FLAG_ADVANCED,
2125 .label = "nt status support",
2127 .p_class = P_GLOBAL,
2128 .ptr = &Globals.bNTStatusSupport,
2131 .flags = FLAG_ADVANCED,
2134 .label = "profile acls",
2137 .ptr = &sDefault.bProfileAcls,
2140 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2143 .label = "announce version",
2145 .p_class = P_GLOBAL,
2146 .ptr = &Globals.szAnnounceVersion,
2149 .flags = FLAG_ADVANCED,
2152 .label = "announce as",
2154 .p_class = P_GLOBAL,
2155 .ptr = &Globals.announce_as,
2157 .enum_list = enum_announce_as,
2158 .flags = FLAG_ADVANCED,
2161 .label = "map acl inherit",
2164 .ptr = &sDefault.bMap_acl_inherit,
2167 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2170 .label = "afs share",
2173 .ptr = &sDefault.bAfs_Share,
2176 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2181 .p_class = P_GLOBAL,
2182 .ptr = &Globals.max_mux,
2185 .flags = FLAG_ADVANCED,
2188 .label = "max xmit",
2190 .p_class = P_GLOBAL,
2191 .ptr = &Globals.max_xmit,
2194 .flags = FLAG_ADVANCED,
2197 .label = "name resolve order",
2199 .p_class = P_GLOBAL,
2200 .ptr = &Globals.szNameResolveOrder,
2203 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2208 .p_class = P_GLOBAL,
2209 .ptr = &Globals.max_ttl,
2212 .flags = FLAG_ADVANCED,
2215 .label = "max wins ttl",
2217 .p_class = P_GLOBAL,
2218 .ptr = &Globals.max_wins_ttl,
2221 .flags = FLAG_ADVANCED,
2224 .label = "min wins ttl",
2226 .p_class = P_GLOBAL,
2227 .ptr = &Globals.min_wins_ttl,
2230 .flags = FLAG_ADVANCED,
2233 .label = "time server",
2235 .p_class = P_GLOBAL,
2236 .ptr = &Globals.bTimeServer,
2239 .flags = FLAG_ADVANCED,
2242 .label = "unix extensions",
2244 .p_class = P_GLOBAL,
2245 .ptr = &Globals.bUnixExtensions,
2248 .flags = FLAG_ADVANCED,
2251 .label = "use spnego",
2253 .p_class = P_GLOBAL,
2254 .ptr = &Globals.bUseSpnego,
2257 .flags = FLAG_ADVANCED,
2260 .label = "client signing",
2262 .p_class = P_GLOBAL,
2263 .ptr = &Globals.client_signing,
2265 .enum_list = enum_smb_signing_vals,
2266 .flags = FLAG_ADVANCED,
2269 .label = "server signing",
2271 .p_class = P_GLOBAL,
2272 .ptr = &Globals.server_signing,
2274 .enum_list = enum_smb_signing_vals,
2275 .flags = FLAG_ADVANCED,
2278 .label = "smb encrypt",
2281 .ptr = &sDefault.ismb_encrypt,
2283 .enum_list = enum_smb_signing_vals,
2284 .flags = FLAG_ADVANCED,
2287 .label = "client use spnego",
2289 .p_class = P_GLOBAL,
2290 .ptr = &Globals.bClientUseSpnego,
2293 .flags = FLAG_ADVANCED,
2296 .label = "client ldap sasl wrapping",
2298 .p_class = P_GLOBAL,
2299 .ptr = &Globals.client_ldap_sasl_wrapping,
2301 .enum_list = enum_ldap_sasl_wrapping,
2302 .flags = FLAG_ADVANCED,
2305 .label = "enable asu support",
2307 .p_class = P_GLOBAL,
2308 .ptr = &Globals.bASUSupport,
2311 .flags = FLAG_ADVANCED,
2314 .label = "svcctl list",
2316 .p_class = P_GLOBAL,
2317 .ptr = &Globals.szServicesList,
2320 .flags = FLAG_ADVANCED,
2323 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2326 .label = "block size",
2329 .ptr = &sDefault.iBlock_size,
2332 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2335 .label = "deadtime",
2337 .p_class = P_GLOBAL,
2338 .ptr = &Globals.deadtime,
2341 .flags = FLAG_ADVANCED,
2344 .label = "getwd cache",
2346 .p_class = P_GLOBAL,
2347 .ptr = &Globals.getwd_cache,
2350 .flags = FLAG_ADVANCED,
2353 .label = "keepalive",
2355 .p_class = P_GLOBAL,
2356 .ptr = &Globals.iKeepalive,
2359 .flags = FLAG_ADVANCED,
2362 .label = "change notify",
2365 .ptr = &sDefault.bChangeNotify,
2368 .flags = FLAG_ADVANCED | FLAG_SHARE,
2371 .label = "directory name cache size",
2374 .ptr = &sDefault.iDirectoryNameCacheSize,
2377 .flags = FLAG_ADVANCED | FLAG_SHARE,
2380 .label = "kernel change notify",
2383 .ptr = &sDefault.bKernelChangeNotify,
2386 .flags = FLAG_ADVANCED | FLAG_SHARE,
2389 .label = "lpq cache time",
2391 .p_class = P_GLOBAL,
2392 .ptr = &Globals.lpqcachetime,
2395 .flags = FLAG_ADVANCED,
2398 .label = "max smbd processes",
2400 .p_class = P_GLOBAL,
2401 .ptr = &Globals.iMaxSmbdProcesses,
2404 .flags = FLAG_ADVANCED,
2407 .label = "max connections",
2410 .ptr = &sDefault.iMaxConnections,
2413 .flags = FLAG_ADVANCED | FLAG_SHARE,
2416 .label = "paranoid server security",
2418 .p_class = P_GLOBAL,
2419 .ptr = &Globals.paranoid_server_security,
2422 .flags = FLAG_ADVANCED,
2425 .label = "max disk size",
2427 .p_class = P_GLOBAL,
2428 .ptr = &Globals.maxdisksize,
2431 .flags = FLAG_ADVANCED,
2434 .label = "max open files",
2436 .p_class = P_GLOBAL,
2437 .ptr = &Globals.max_open_files,
2440 .flags = FLAG_ADVANCED,
2443 .label = "min print space",
2446 .ptr = &sDefault.iMinPrintSpace,
2449 .flags = FLAG_ADVANCED | FLAG_PRINT,
2452 .label = "socket options",
2454 .p_class = P_GLOBAL,
2455 .ptr = &Globals.szSocketOptions,
2458 .flags = FLAG_ADVANCED,
2461 .label = "strict allocate",
2464 .ptr = &sDefault.bStrictAllocate,
2467 .flags = FLAG_ADVANCED | FLAG_SHARE,
2470 .label = "strict sync",
2473 .ptr = &sDefault.bStrictSync,
2476 .flags = FLAG_ADVANCED | FLAG_SHARE,
2479 .label = "sync always",
2482 .ptr = &sDefault.bSyncAlways,
2485 .flags = FLAG_ADVANCED | FLAG_SHARE,
2488 .label = "use mmap",
2490 .p_class = P_GLOBAL,
2491 .ptr = &Globals.bUseMmap,
2494 .flags = FLAG_ADVANCED,
2497 .label = "use sendfile",
2500 .ptr = &sDefault.bUseSendfile,
2503 .flags = FLAG_ADVANCED | FLAG_SHARE,
2506 .label = "hostname lookups",
2508 .p_class = P_GLOBAL,
2509 .ptr = &Globals.bHostnameLookups,
2512 .flags = FLAG_ADVANCED,
2515 .label = "write cache size",
2518 .ptr = &sDefault.iWriteCacheSize,
2521 .flags = FLAG_ADVANCED | FLAG_SHARE,
2524 .label = "name cache timeout",
2526 .p_class = P_GLOBAL,
2527 .ptr = &Globals.name_cache_timeout,
2530 .flags = FLAG_ADVANCED,
2533 .label = "ctdbd socket",
2535 .p_class = P_GLOBAL,
2536 .ptr = &Globals.ctdbdSocket,
2539 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2542 .label = "cluster addresses",
2544 .p_class = P_GLOBAL,
2545 .ptr = &Globals.szClusterAddresses,
2548 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2551 .label = "clustering",
2553 .p_class = P_GLOBAL,
2554 .ptr = &Globals.clustering,
2557 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2560 .label = "ctdb timeout",
2562 .p_class = P_GLOBAL,
2563 .ptr = &Globals.ctdb_timeout,
2566 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2569 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2572 .label = "max reported print jobs",
2575 .ptr = &sDefault.iMaxReportedPrintJobs,
2578 .flags = FLAG_ADVANCED | FLAG_PRINT,
2581 .label = "max print jobs",
2584 .ptr = &sDefault.iMaxPrintJobs,
2587 .flags = FLAG_ADVANCED | FLAG_PRINT,
2590 .label = "load printers",
2592 .p_class = P_GLOBAL,
2593 .ptr = &Globals.bLoadPrinters,
2596 .flags = FLAG_ADVANCED | FLAG_PRINT,
2599 .label = "printcap cache time",
2601 .p_class = P_GLOBAL,
2602 .ptr = &Globals.PrintcapCacheTime,
2605 .flags = FLAG_ADVANCED | FLAG_PRINT,
2608 .label = "printcap name",
2610 .p_class = P_GLOBAL,
2611 .ptr = &Globals.szPrintcapname,
2614 .flags = FLAG_ADVANCED | FLAG_PRINT,
2617 .label = "printcap",
2619 .p_class = P_GLOBAL,
2620 .ptr = &Globals.szPrintcapname,
2626 .label = "printable",
2629 .ptr = &sDefault.bPrint_ok,
2632 .flags = FLAG_ADVANCED | FLAG_PRINT,
2635 .label = "print ok",
2638 .ptr = &sDefault.bPrint_ok,
2644 .label = "printing",
2647 .ptr = &sDefault.iPrinting,
2648 .special = handle_printing,
2649 .enum_list = enum_printing,
2650 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2653 .label = "cups options",
2656 .ptr = &sDefault.szCupsOptions,
2659 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2662 .label = "cups server",
2664 .p_class = P_GLOBAL,
2665 .ptr = &Globals.szCupsServer,
2668 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2671 .label = "cups encrypt",
2673 .p_class = P_GLOBAL,
2674 .ptr = &Globals.CupsEncrypt,
2676 .enum_list = enum_bool_auto,
2677 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2681 .label = "cups connection timeout",
2683 .p_class = P_GLOBAL,
2684 .ptr = &Globals.cups_connection_timeout,
2687 .flags = FLAG_ADVANCED,
2690 .label = "iprint server",
2692 .p_class = P_GLOBAL,
2693 .ptr = &Globals.szIPrintServer,
2696 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2699 .label = "print command",
2702 .ptr = &sDefault.szPrintcommand,
2705 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2708 .label = "disable spoolss",
2710 .p_class = P_GLOBAL,
2711 .ptr = &Globals.bDisableSpoolss,
2714 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2717 .label = "enable spoolss",
2719 .p_class = P_GLOBAL,
2720 .ptr = &Globals.bDisableSpoolss,
2726 .label = "lpq command",
2729 .ptr = &sDefault.szLpqcommand,
2732 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2735 .label = "lprm command",
2738 .ptr = &sDefault.szLprmcommand,
2741 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2744 .label = "lppause command",
2747 .ptr = &sDefault.szLppausecommand,
2750 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2753 .label = "lpresume command",
2756 .ptr = &sDefault.szLpresumecommand,
2759 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2762 .label = "queuepause command",
2765 .ptr = &sDefault.szQueuepausecommand,
2768 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2771 .label = "queueresume command",
2774 .ptr = &sDefault.szQueueresumecommand,
2777 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2780 .label = "addport command",
2782 .p_class = P_GLOBAL,
2783 .ptr = &Globals.szAddPortCommand,
2786 .flags = FLAG_ADVANCED,
2789 .label = "enumports command",
2791 .p_class = P_GLOBAL,
2792 .ptr = &Globals.szEnumPortsCommand,
2795 .flags = FLAG_ADVANCED,
2798 .label = "addprinter command",
2800 .p_class = P_GLOBAL,
2801 .ptr = &Globals.szAddPrinterCommand,
2804 .flags = FLAG_ADVANCED,
2807 .label = "deleteprinter command",
2809 .p_class = P_GLOBAL,
2810 .ptr = &Globals.szDeletePrinterCommand,
2813 .flags = FLAG_ADVANCED,
2816 .label = "show add printer wizard",
2818 .p_class = P_GLOBAL,
2819 .ptr = &Globals.bMsAddPrinterWizard,
2822 .flags = FLAG_ADVANCED,
2825 .label = "os2 driver map",
2827 .p_class = P_GLOBAL,
2828 .ptr = &Globals.szOs2DriverMap,
2831 .flags = FLAG_ADVANCED,
2835 .label = "printer name",
2838 .ptr = &sDefault.szPrintername,
2841 .flags = FLAG_ADVANCED | FLAG_PRINT,
2847 .ptr = &sDefault.szPrintername,
2853 .label = "use client driver",
2856 .ptr = &sDefault.bUseClientDriver,
2859 .flags = FLAG_ADVANCED | FLAG_PRINT,
2862 .label = "default devmode",
2865 .ptr = &sDefault.bDefaultDevmode,
2868 .flags = FLAG_ADVANCED | FLAG_PRINT,
2871 .label = "force printername",
2874 .ptr = &sDefault.bForcePrintername,
2877 .flags = FLAG_ADVANCED | FLAG_PRINT,
2880 .label = "printjob username",
2883 .ptr = &sDefault.szPrintjobUsername,
2886 .flags = FLAG_ADVANCED | FLAG_PRINT,
2889 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2892 .label = "mangling method",
2894 .p_class = P_GLOBAL,
2895 .ptr = &Globals.szManglingMethod,
2898 .flags = FLAG_ADVANCED,
2901 .label = "mangle prefix",
2903 .p_class = P_GLOBAL,
2904 .ptr = &Globals.mangle_prefix,
2907 .flags = FLAG_ADVANCED,
2911 .label = "default case",
2914 .ptr = &sDefault.iDefaultCase,
2916 .enum_list = enum_case,
2917 .flags = FLAG_ADVANCED | FLAG_SHARE,
2920 .label = "case sensitive",
2923 .ptr = &sDefault.iCaseSensitive,
2925 .enum_list = enum_bool_auto,
2926 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2929 .label = "casesignames",
2932 .ptr = &sDefault.iCaseSensitive,
2934 .enum_list = enum_bool_auto,
2935 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2938 .label = "preserve case",
2941 .ptr = &sDefault.bCasePreserve,
2944 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2947 .label = "short preserve case",
2950 .ptr = &sDefault.bShortCasePreserve,
2953 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2956 .label = "mangling char",
2959 .ptr = &sDefault.magic_char,
2962 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2965 .label = "hide dot files",
2968 .ptr = &sDefault.bHideDotFiles,
2971 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2974 .label = "hide special files",
2977 .ptr = &sDefault.bHideSpecialFiles,
2980 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2983 .label = "hide unreadable",
2986 .ptr = &sDefault.bHideUnReadable,
2989 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2992 .label = "hide unwriteable files",
2995 .ptr = &sDefault.bHideUnWriteableFiles,
2998 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3001 .label = "delete veto files",
3004 .ptr = &sDefault.bDeleteVetoFiles,
3007 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3010 .label = "veto files",
3013 .ptr = &sDefault.szVetoFiles,
3016 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3019 .label = "hide files",
3022 .ptr = &sDefault.szHideFiles,
3025 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3028 .label = "veto oplock files",
3031 .ptr = &sDefault.szVetoOplockFiles,
3034 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3037 .label = "map archive",
3040 .ptr = &sDefault.bMap_archive,
3043 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3046 .label = "map hidden",
3049 .ptr = &sDefault.bMap_hidden,
3052 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3055 .label = "map system",
3058 .ptr = &sDefault.bMap_system,
3061 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3064 .label = "map readonly",
3067 .ptr = &sDefault.iMap_readonly,
3069 .enum_list = enum_map_readonly,
3070 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3073 .label = "mangled names",
3076 .ptr = &sDefault.bMangledNames,
3079 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3082 .label = "max stat cache size",
3084 .p_class = P_GLOBAL,
3085 .ptr = &Globals.iMaxStatCacheSize,
3088 .flags = FLAG_ADVANCED,
3091 .label = "stat cache",
3093 .p_class = P_GLOBAL,
3094 .ptr = &Globals.bStatCache,
3097 .flags = FLAG_ADVANCED,
3100 .label = "store dos attributes",
3103 .ptr = &sDefault.bStoreDosAttributes,
3106 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3109 .label = "dmapi support",
3112 .ptr = &sDefault.bDmapiSupport,
3115 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3119 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3122 .label = "machine password timeout",
3124 .p_class = P_GLOBAL,
3125 .ptr = &Globals.machine_password_timeout,
3128 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3131 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3134 .label = "add user script",
3136 .p_class = P_GLOBAL,
3137 .ptr = &Globals.szAddUserScript,
3140 .flags = FLAG_ADVANCED,
3143 .label = "rename user script",
3145 .p_class = P_GLOBAL,
3146 .ptr = &Globals.szRenameUserScript,
3149 .flags = FLAG_ADVANCED,
3152 .label = "delete user script",
3154 .p_class = P_GLOBAL,
3155 .ptr = &Globals.szDelUserScript,
3158 .flags = FLAG_ADVANCED,
3161 .label = "add group script",
3163 .p_class = P_GLOBAL,
3164 .ptr = &Globals.szAddGroupScript,
3167 .flags = FLAG_ADVANCED,
3170 .label = "delete group script",
3172 .p_class = P_GLOBAL,
3173 .ptr = &Globals.szDelGroupScript,
3176 .flags = FLAG_ADVANCED,
3179 .label = "add user to group script",
3181 .p_class = P_GLOBAL,
3182 .ptr = &Globals.szAddUserToGroupScript,
3185 .flags = FLAG_ADVANCED,
3188 .label = "delete user from group script",
3190 .p_class = P_GLOBAL,
3191 .ptr = &Globals.szDelUserFromGroupScript,
3194 .flags = FLAG_ADVANCED,
3197 .label = "set primary group script",
3199 .p_class = P_GLOBAL,
3200 .ptr = &Globals.szSetPrimaryGroupScript,
3203 .flags = FLAG_ADVANCED,
3206 .label = "add machine script",
3208 .p_class = P_GLOBAL,
3209 .ptr = &Globals.szAddMachineScript,
3212 .flags = FLAG_ADVANCED,
3215 .label = "shutdown script",
3217 .p_class = P_GLOBAL,
3218 .ptr = &Globals.szShutdownScript,
3221 .flags = FLAG_ADVANCED,
3224 .label = "abort shutdown script",
3226 .p_class = P_GLOBAL,
3227 .ptr = &Globals.szAbortShutdownScript,
3230 .flags = FLAG_ADVANCED,
3233 .label = "username map script",
3235 .p_class = P_GLOBAL,
3236 .ptr = &Globals.szUsernameMapScript,
3239 .flags = FLAG_ADVANCED,
3242 .label = "logon script",
3244 .p_class = P_GLOBAL,
3245 .ptr = &Globals.szLogonScript,
3248 .flags = FLAG_ADVANCED,
3251 .label = "logon path",
3253 .p_class = P_GLOBAL,
3254 .ptr = &Globals.szLogonPath,
3257 .flags = FLAG_ADVANCED,
3260 .label = "logon drive",
3262 .p_class = P_GLOBAL,
3263 .ptr = &Globals.szLogonDrive,
3266 .flags = FLAG_ADVANCED,
3269 .label = "logon home",
3271 .p_class = P_GLOBAL,
3272 .ptr = &Globals.szLogonHome,
3275 .flags = FLAG_ADVANCED,
3278 .label = "domain logons",
3280 .p_class = P_GLOBAL,
3281 .ptr = &Globals.bDomainLogons,
3284 .flags = FLAG_ADVANCED,
3288 .label = "init logon delayed hosts",
3290 .p_class = P_GLOBAL,
3291 .ptr = &Globals.szInitLogonDelayedHosts,
3294 .flags = FLAG_ADVANCED,
3298 .label = "init logon delay",
3300 .p_class = P_GLOBAL,
3301 .ptr = &Globals.InitLogonDelay,
3304 .flags = FLAG_ADVANCED,
3308 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3311 .label = "os level",
3313 .p_class = P_GLOBAL,
3314 .ptr = &Globals.os_level,
3317 .flags = FLAG_BASIC | FLAG_ADVANCED,
3320 .label = "lm announce",
3322 .p_class = P_GLOBAL,
3323 .ptr = &Globals.lm_announce,
3325 .enum_list = enum_bool_auto,
3326 .flags = FLAG_ADVANCED,
3329 .label = "lm interval",
3331 .p_class = P_GLOBAL,
3332 .ptr = &Globals.lm_interval,
3335 .flags = FLAG_ADVANCED,
3338 .label = "preferred master",
3340 .p_class = P_GLOBAL,
3341 .ptr = &Globals.iPreferredMaster,
3343 .enum_list = enum_bool_auto,
3344 .flags = FLAG_BASIC | FLAG_ADVANCED,
3347 .label = "prefered master",
3349 .p_class = P_GLOBAL,
3350 .ptr = &Globals.iPreferredMaster,
3352 .enum_list = enum_bool_auto,
3356 .label = "local master",
3358 .p_class = P_GLOBAL,
3359 .ptr = &Globals.bLocalMaster,
3362 .flags = FLAG_BASIC | FLAG_ADVANCED,
3365 .label = "domain master",
3367 .p_class = P_GLOBAL,
3368 .ptr = &Globals.iDomainMaster,
3370 .enum_list = enum_bool_auto,
3371 .flags = FLAG_BASIC | FLAG_ADVANCED,
3374 .label = "browse list",
3376 .p_class = P_GLOBAL,
3377 .ptr = &Globals.bBrowseList,
3380 .flags = FLAG_ADVANCED,
3383 .label = "browseable",
3386 .ptr = &sDefault.bBrowseable,
3389 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3392 .label = "browsable",
3395 .ptr = &sDefault.bBrowseable,
3401 .label = "access based share enum",
3404 .ptr = &sDefault.bAccessBasedShareEnum,
3407 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3410 .label = "enhanced browsing",
3412 .p_class = P_GLOBAL,
3413 .ptr = &Globals.enhanced_browsing,
3416 .flags = FLAG_ADVANCED,
3419 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3422 .label = "dns proxy",
3424 .p_class = P_GLOBAL,
3425 .ptr = &Globals.bDNSproxy,
3428 .flags = FLAG_ADVANCED,
3431 .label = "wins proxy",
3433 .p_class = P_GLOBAL,
3434 .ptr = &Globals.bWINSproxy,
3437 .flags = FLAG_ADVANCED,
3440 .label = "wins server",
3442 .p_class = P_GLOBAL,
3443 .ptr = &Globals.szWINSservers,
3446 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3449 .label = "wins support",
3451 .p_class = P_GLOBAL,
3452 .ptr = &Globals.bWINSsupport,
3455 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3458 .label = "wins hook",
3460 .p_class = P_GLOBAL,
3461 .ptr = &Globals.szWINSHook,
3464 .flags = FLAG_ADVANCED,
3467 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3470 .label = "blocking locks",
3473 .ptr = &sDefault.bBlockingLocks,
3476 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3479 .label = "csc policy",
3482 .ptr = &sDefault.iCSCPolicy,
3484 .enum_list = enum_csc_policy,
3485 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3488 .label = "fake oplocks",
3491 .ptr = &sDefault.bFakeOplocks,
3494 .flags = FLAG_ADVANCED | FLAG_SHARE,
3497 .label = "kernel oplocks",
3499 .p_class = P_GLOBAL,
3500 .ptr = &Globals.bKernelOplocks,
3503 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3509 .ptr = &sDefault.bLocking,
3512 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3515 .label = "lock spin time",
3517 .p_class = P_GLOBAL,
3518 .ptr = &Globals.iLockSpinTime,
3521 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3527 .ptr = &sDefault.bOpLocks,
3530 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3533 .label = "level2 oplocks",
3536 .ptr = &sDefault.bLevel2OpLocks,
3539 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3542 .label = "oplock break wait time",
3544 .p_class = P_GLOBAL,
3545 .ptr = &Globals.oplock_break_wait_time,
3548 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3551 .label = "oplock contention limit",
3554 .ptr = &sDefault.iOplockContentionLimit,
3557 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3560 .label = "posix locking",
3563 .ptr = &sDefault.bPosixLocking,
3566 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3569 .label = "strict locking",
3572 .ptr = &sDefault.iStrictLocking,
3574 .enum_list = enum_bool_auto,
3575 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3578 .label = "share modes",
3581 .ptr = &sDefault.bShareModes,
3584 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3587 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3590 .label = "ldap admin dn",
3592 .p_class = P_GLOBAL,
3593 .ptr = &Globals.szLdapAdminDn,
3596 .flags = FLAG_ADVANCED,
3599 .label = "ldap delete dn",
3601 .p_class = P_GLOBAL,
3602 .ptr = &Globals.ldap_delete_dn,
3605 .flags = FLAG_ADVANCED,
3608 .label = "ldap group suffix",
3610 .p_class = P_GLOBAL,
3611 .ptr = &Globals.szLdapGroupSuffix,
3614 .flags = FLAG_ADVANCED,
3617 .label = "ldap idmap suffix",
3619 .p_class = P_GLOBAL,
3620 .ptr = &Globals.szLdapIdmapSuffix,
3623 .flags = FLAG_ADVANCED,
3626 .label = "ldap machine suffix",
3628 .p_class = P_GLOBAL,
3629 .ptr = &Globals.szLdapMachineSuffix,
3632 .flags = FLAG_ADVANCED,
3635 .label = "ldap passwd sync",
3637 .p_class = P_GLOBAL,
3638 .ptr = &Globals.ldap_passwd_sync,
3640 .enum_list = enum_ldap_passwd_sync,
3641 .flags = FLAG_ADVANCED,
3644 .label = "ldap password sync",
3646 .p_class = P_GLOBAL,
3647 .ptr = &Globals.ldap_passwd_sync,
3649 .enum_list = enum_ldap_passwd_sync,
3653 .label = "ldap replication sleep",
3655 .p_class = P_GLOBAL,
3656 .ptr = &Globals.ldap_replication_sleep,
3659 .flags = FLAG_ADVANCED,
3662 .label = "ldap suffix",
3664 .p_class = P_GLOBAL,
3665 .ptr = &Globals.szLdapSuffix,
3668 .flags = FLAG_ADVANCED,
3671 .label = "ldap ssl",
3673 .p_class = P_GLOBAL,
3674 .ptr = &Globals.ldap_ssl,
3676 .enum_list = enum_ldap_ssl,
3677 .flags = FLAG_ADVANCED,
3680 .label = "ldap ssl ads",
3682 .p_class = P_GLOBAL,
3683 .ptr = &Globals.ldap_ssl_ads,
3686 .flags = FLAG_ADVANCED,
3689 .label = "ldap deref",
3691 .p_class = P_GLOBAL,
3692 .ptr = &Globals.ldap_deref,
3694 .enum_list = enum_ldap_deref,
3695 .flags = FLAG_ADVANCED,
3698 .label = "ldap follow referral",
3700 .p_class = P_GLOBAL,
3701 .ptr = &Globals.ldap_follow_referral,
3703 .enum_list = enum_bool_auto,
3704 .flags = FLAG_ADVANCED,
3707 .label = "ldap timeout",
3709 .p_class = P_GLOBAL,
3710 .ptr = &Globals.ldap_timeout,
3713 .flags = FLAG_ADVANCED,
3716 .label = "ldap connection timeout",
3718 .p_class = P_GLOBAL,
3719 .ptr = &Globals.ldap_connection_timeout,
3722 .flags = FLAG_ADVANCED,
3725 .label = "ldap page size",
3727 .p_class = P_GLOBAL,
3728 .ptr = &Globals.ldap_page_size,
3731 .flags = FLAG_ADVANCED,
3734 .label = "ldap user suffix",
3736 .p_class = P_GLOBAL,
3737 .ptr = &Globals.szLdapUserSuffix,
3740 .flags = FLAG_ADVANCED,
3743 .label = "ldap debug level",
3745 .p_class = P_GLOBAL,
3746 .ptr = &Globals.ldap_debug_level,
3747 .special = handle_ldap_debug_level,
3749 .flags = FLAG_ADVANCED,
3752 .label = "ldap debug threshold",
3754 .p_class = P_GLOBAL,
3755 .ptr = &Globals.ldap_debug_threshold,
3758 .flags = FLAG_ADVANCED,
3761 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3764 .label = "eventlog list",
3766 .p_class = P_GLOBAL,
3767 .ptr = &Globals.szEventLogs,
3770 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3773 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3776 .label = "add share command",
3778 .p_class = P_GLOBAL,
3779 .ptr = &Globals.szAddShareCommand,
3782 .flags = FLAG_ADVANCED,
3785 .label = "change share command",
3787 .p_class = P_GLOBAL,
3788 .ptr = &Globals.szChangeShareCommand,
3791 .flags = FLAG_ADVANCED,
3794 .label = "delete share command",
3796 .p_class = P_GLOBAL,
3797 .ptr = &Globals.szDeleteShareCommand,
3800 .flags = FLAG_ADVANCED,
3803 .label = "config file",
3805 .p_class = P_GLOBAL,
3806 .ptr = &Globals.szConfigFile,
3809 .flags = FLAG_HIDE|FLAG_META,
3814 .p_class = P_GLOBAL,
3815 .ptr = &Globals.szAutoServices,
3818 .flags = FLAG_ADVANCED,
3821 .label = "auto services",
3823 .p_class = P_GLOBAL,
3824 .ptr = &Globals.szAutoServices,
3827 .flags = FLAG_ADVANCED,
3830 .label = "lock directory",
3832 .p_class = P_GLOBAL,
3833 .ptr = &Globals.szLockDir,
3836 .flags = FLAG_ADVANCED,
3839 .label = "lock dir",
3841 .p_class = P_GLOBAL,
3842 .ptr = &Globals.szLockDir,
3848 .label = "state directory",
3850 .p_class = P_GLOBAL,
3851 .ptr = &Globals.szStateDir,
3854 .flags = FLAG_ADVANCED,
3857 .label = "cache directory",
3859 .p_class = P_GLOBAL,
3860 .ptr = &Globals.szCacheDir,
3863 .flags = FLAG_ADVANCED,
3866 .label = "pid directory",
3868 .p_class = P_GLOBAL,
3869 .ptr = &Globals.szPidDir,
3872 .flags = FLAG_ADVANCED,
3876 .label = "utmp directory",
3878 .p_class = P_GLOBAL,
3879 .ptr = &Globals.szUtmpDir,
3882 .flags = FLAG_ADVANCED,
3885 .label = "wtmp directory",
3887 .p_class = P_GLOBAL,
3888 .ptr = &Globals.szWtmpDir,
3891 .flags = FLAG_ADVANCED,
3896 .p_class = P_GLOBAL,
3897 .ptr = &Globals.bUtmp,
3900 .flags = FLAG_ADVANCED,
3904 .label = "default service",
3906 .p_class = P_GLOBAL,
3907 .ptr = &Globals.szDefaultService,
3910 .flags = FLAG_ADVANCED,
3915 .p_class = P_GLOBAL,
3916 .ptr = &Globals.szDefaultService,
3919 .flags = FLAG_ADVANCED,
3922 .label = "message command",
3924 .p_class = P_GLOBAL,
3925 .ptr = &Globals.szMsgCommand,
3928 .flags = FLAG_ADVANCED,
3931 .label = "dfree cache time",
3934 .ptr = &sDefault.iDfreeCacheTime,
3937 .flags = FLAG_ADVANCED,
3940 .label = "dfree command",
3943 .ptr = &sDefault.szDfree,
3946 .flags = FLAG_ADVANCED,
3949 .label = "get quota command",
3951 .p_class = P_GLOBAL,
3952 .ptr = &Globals.szGetQuota,
3955 .flags = FLAG_ADVANCED,
3958 .label = "set quota command",
3960 .p_class = P_GLOBAL,
3961 .ptr = &Globals.szSetQuota,
3964 .flags = FLAG_ADVANCED,
3967 .label = "remote announce",
3969 .p_class = P_GLOBAL,
3970 .ptr = &Globals.szRemoteAnnounce,
3973 .flags = FLAG_ADVANCED,
3976 .label = "remote browse sync",
3978 .p_class = P_GLOBAL,
3979 .ptr = &Globals.szRemoteBrowseSync,
3982 .flags = FLAG_ADVANCED,
3985 .label = "socket address",
3987 .p_class = P_GLOBAL,
3988 .ptr = &Globals.szSocketAddress,
3991 .flags = FLAG_ADVANCED,
3994 .label = "homedir map",
3996 .p_class = P_GLOBAL,
3997 .ptr = &Globals.szNISHomeMapName,
4000 .flags = FLAG_ADVANCED,
4003 .label = "afs username map",
4005 .p_class = P_GLOBAL,
4006 .ptr = &Globals.szAfsUsernameMap,
4009 .flags = FLAG_ADVANCED,
4012 .label = "afs token lifetime",
4014 .p_class = P_GLOBAL,
4015 .ptr = &Globals.iAfsTokenLifetime,
4018 .flags = FLAG_ADVANCED,
4021 .label = "log nt token command",
4023 .p_class = P_GLOBAL,
4024 .ptr = &Globals.szLogNtTokenCommand,
4027 .flags = FLAG_ADVANCED,
4030 .label = "time offset",
4032 .p_class = P_GLOBAL,
4033 .ptr = &extra_time_offset,
4036 .flags = FLAG_ADVANCED,
4039 .label = "NIS homedir",
4041 .p_class = P_GLOBAL,
4042 .ptr = &Globals.bNISHomeMap,
4045 .flags = FLAG_ADVANCED,
4051 .ptr = &sDefault.valid,
4060 .ptr = &sDefault.szCopy,
4061 .special = handle_copy,
4069 .ptr = &sDefault.szInclude,
4070 .special = handle_include,
4072 .flags = FLAG_HIDE|FLAG_META,
4078 .ptr = &sDefault.szPreExec,
4081 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4087 .ptr = &sDefault.szPreExec,
4090 .flags = FLAG_ADVANCED,
4093 .label = "preexec close",
4096 .ptr = &sDefault.bPreexecClose,
4099 .flags = FLAG_ADVANCED | FLAG_SHARE,
4102 .label = "postexec",
4105 .ptr = &sDefault.szPostExec,
4108 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4111 .label = "root preexec",
4114 .ptr = &sDefault.szRootPreExec,
4117 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4120 .label = "root preexec close",
4123 .ptr = &sDefault.bRootpreexecClose,
4126 .flags = FLAG_ADVANCED | FLAG_SHARE,
4129 .label = "root postexec",
4132 .ptr = &sDefault.szRootPostExec,
4135 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4138 .label = "available",
4141 .ptr = &sDefault.bAvailable,
4144 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4147 .label = "registry shares",
4149 .p_class = P_GLOBAL,
4150 .ptr = &Globals.bRegistryShares,
4153 .flags = FLAG_ADVANCED,
4156 .label = "usershare allow guests",
4158 .p_class = P_GLOBAL,
4159 .ptr = &Globals.bUsershareAllowGuests,
4162 .flags = FLAG_ADVANCED,
4165 .label = "usershare max shares",
4167 .p_class = P_GLOBAL,
4168 .ptr = &Globals.iUsershareMaxShares,
4171 .flags = FLAG_ADVANCED,
4174 .label = "usershare owner only",
4176 .p_class = P_GLOBAL,
4177 .ptr = &Globals.bUsershareOwnerOnly,
4180 .flags = FLAG_ADVANCED,
4183 .label = "usershare path",
4185 .p_class = P_GLOBAL,
4186 .ptr = &Globals.szUsersharePath,
4189 .flags = FLAG_ADVANCED,
4192 .label = "usershare prefix allow list",
4194 .p_class = P_GLOBAL,
4195 .ptr = &Globals.szUsersharePrefixAllowList,
4198 .flags = FLAG_ADVANCED,
4201 .label = "usershare prefix deny list",
4203 .p_class = P_GLOBAL,
4204 .ptr = &Globals.szUsersharePrefixDenyList,
4207 .flags = FLAG_ADVANCED,
4210 .label = "usershare template share",
4212 .p_class = P_GLOBAL,
4213 .ptr = &Globals.szUsershareTemplateShare,
4216 .flags = FLAG_ADVANCED,
4222 .ptr = &sDefault.volume,
4225 .flags = FLAG_ADVANCED | FLAG_SHARE,
4231 .ptr = &sDefault.fstype,
4234 .flags = FLAG_ADVANCED | FLAG_SHARE,
4237 .label = "set directory",
4240 .ptr = &sDefault.bNo_set_dir,
4243 .flags = FLAG_ADVANCED | FLAG_SHARE,
4246 .label = "wide links",
4249 .ptr = &sDefault.bWidelinks,
4252 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4255 .label = "follow symlinks",
4258 .ptr = &sDefault.bSymlinks,
4261 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4264 .label = "dont descend",
4267 .ptr = &sDefault.szDontdescend,
4270 .flags = FLAG_ADVANCED | FLAG_SHARE,
4273 .label = "magic script",
4276 .ptr = &sDefault.szMagicScript,
4279 .flags = FLAG_ADVANCED | FLAG_SHARE,
4282 .label = "magic output",
4285 .ptr = &sDefault.szMagicOutput,
4288 .flags = FLAG_ADVANCED | FLAG_SHARE,
4291 .label = "delete readonly",
4294 .ptr = &sDefault.bDeleteReadonly,
4297 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4300 .label = "dos filemode",
4303 .ptr = &sDefault.bDosFilemode,
4306 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4309 .label = "dos filetimes",
4312 .ptr = &sDefault.bDosFiletimes,
4315 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4318 .label = "dos filetime resolution",
4321 .ptr = &sDefault.bDosFiletimeResolution,
4324 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4327 .label = "fake directory create times",
4330 .ptr = &sDefault.bFakeDirCreateTimes,
4333 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4336 .label = "panic action",
4338 .p_class = P_GLOBAL,
4339 .ptr = &Globals.szPanicAction,
4342 .flags = FLAG_ADVANCED,
4345 .label = "perfcount module",
4347 .p_class = P_GLOBAL,
4348 .ptr = &Globals.szSMBPerfcountModule,
4351 .flags = FLAG_ADVANCED,
4354 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4357 .label = "vfs objects",
4360 .ptr = &sDefault.szVfsObjects,
4363 .flags = FLAG_ADVANCED | FLAG_SHARE,
4366 .label = "vfs object",
4369 .ptr = &sDefault.szVfsObjects,
4376 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4379 .label = "msdfs root",
4382 .ptr = &sDefault.bMSDfsRoot,
4385 .flags = FLAG_ADVANCED | FLAG_SHARE,
4388 .label = "msdfs proxy",
4391 .ptr = &sDefault.szMSDfsProxy,
4394 .flags = FLAG_ADVANCED | FLAG_SHARE,
4397 .label = "host msdfs",
4399 .p_class = P_GLOBAL,
4400 .ptr = &Globals.bHostMSDfs,
4403 .flags = FLAG_ADVANCED,
4406 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4409 .label = "passdb expand explicit",
4411 .p_class = P_GLOBAL,
4412 .ptr = &Globals.bPassdbExpandExplicit,
4415 .flags = FLAG_ADVANCED,
4418 .label = "idmap backend",
4420 .p_class = P_GLOBAL,
4421 .ptr = &Globals.szIdmapBackend,
4424 .flags = FLAG_ADVANCED,
4427 .label = "idmap alloc backend",
4429 .p_class = P_GLOBAL,
4430 .ptr = &Globals.szIdmapAllocBackend,
4433 .flags = FLAG_ADVANCED,
4436 .label = "idmap cache time",
4438 .p_class = P_GLOBAL,
4439 .ptr = &Globals.iIdmapCacheTime,
4442 .flags = FLAG_ADVANCED,
4445 .label = "idmap negative cache time",
4447 .p_class = P_GLOBAL,
4448 .ptr = &Globals.iIdmapNegativeCacheTime,
4451 .flags = FLAG_ADVANCED,
4454 .label = "idmap uid",
4456 .p_class = P_GLOBAL,
4457 .ptr = &Globals.szIdmapUID,
4458 .special = handle_idmap_uid,
4460 .flags = FLAG_ADVANCED,
4463 .label = "winbind uid",
4465 .p_class = P_GLOBAL,
4466 .ptr = &Globals.szIdmapUID,
4467 .special = handle_idmap_uid,
4472 .label = "idmap gid",
4474 .p_class = P_GLOBAL,
4475 .ptr = &Globals.szIdmapGID,
4476 .special = handle_idmap_gid,
4478 .flags = FLAG_ADVANCED,
4481 .label = "winbind gid",
4483 .p_class = P_GLOBAL,
4484 .ptr = &Globals.szIdmapGID,
4485 .special = handle_idmap_gid,
4490 .label = "template homedir",
4492 .p_class = P_GLOBAL,
4493 .ptr = &Globals.szTemplateHomedir,
4496 .flags = FLAG_ADVANCED,
4499 .label = "template shell",
4501 .p_class = P_GLOBAL,
4502 .ptr = &Globals.szTemplateShell,
4505 .flags = FLAG_ADVANCED,
4508 .label = "winbind separator",
4510 .p_class = P_GLOBAL,
4511 .ptr = &Globals.szWinbindSeparator,
4514 .flags = FLAG_ADVANCED,
4517 .label = "winbind cache time",
4519 .p_class = P_GLOBAL,
4520 .ptr = &Globals.winbind_cache_time,
4523 .flags = FLAG_ADVANCED,
4526 .label = "winbind reconnect delay",
4528 .p_class = P_GLOBAL,
4529 .ptr = &Globals.winbind_reconnect_delay,
4532 .flags = FLAG_ADVANCED,
4535 .label = "winbind enum users",
4537 .p_class = P_GLOBAL,
4538 .ptr = &Globals.bWinbindEnumUsers,
4541 .flags = FLAG_ADVANCED,
4544 .label = "winbind enum groups",
4546 .p_class = P_GLOBAL,
4547 .ptr = &Globals.bWinbindEnumGroups,
4550 .flags = FLAG_ADVANCED,
4553 .label = "winbind use default domain",
4555 .p_class = P_GLOBAL,
4556 .ptr = &Globals.bWinbindUseDefaultDomain,
4559 .flags = FLAG_ADVANCED,
4562 .label = "winbind trusted domains only",
4564 .p_class = P_GLOBAL,
4565 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4568 .flags = FLAG_ADVANCED,
4571 .label = "winbind nested groups",
4573 .p_class = P_GLOBAL,
4574 .ptr = &Globals.bWinbindNestedGroups,
4577 .flags = FLAG_ADVANCED,
4580 .label = "winbind expand groups",
4582 .p_class = P_GLOBAL,
4583 .ptr = &Globals.winbind_expand_groups,
4586 .flags = FLAG_ADVANCED,
4589 .label = "winbind nss info",
4591 .p_class = P_GLOBAL,
4592 .ptr = &Globals.szWinbindNssInfo,
4595 .flags = FLAG_ADVANCED,
4598 .label = "winbind refresh tickets",
4600 .p_class = P_GLOBAL,
4601 .ptr = &Globals.bWinbindRefreshTickets,
4604 .flags = FLAG_ADVANCED,
4607 .label = "winbind offline logon",
4609 .p_class = P_GLOBAL,
4610 .ptr = &Globals.bWinbindOfflineLogon,
4613 .flags = FLAG_ADVANCED,
4616 .label = "winbind normalize names",
4618 .p_class = P_GLOBAL,
4619 .ptr = &Globals.bWinbindNormalizeNames,
4622 .flags = FLAG_ADVANCED,
4625 .label = "winbind rpc only",
4627 .p_class = P_GLOBAL,
4628 .ptr = &Globals.bWinbindRpcOnly,
4631 .flags = FLAG_ADVANCED,
4634 .label = "create krb5 conf",
4636 .p_class = P_GLOBAL,
4637 .ptr = &Globals.bCreateKrb5Conf,
4640 .flags = FLAG_ADVANCED,
4643 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4646 /***************************************************************************
4647 Initialise the sDefault parameter structure for the printer values.
4648 ***************************************************************************/
4650 static void init_printer_values(struct service *pService)
4652 /* choose defaults depending on the type of printing */
4653 switch (pService->iPrinting) {
4658 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4659 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4660 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4665 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4666 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4667 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4668 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4669 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4670 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4671 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4677 /* set the lpq command to contain the destination printer
4678 name only. This is used by cups_queue_get() */
4679 string_set(&pService->szLpqcommand, "%p");
4680 string_set(&pService->szLprmcommand, "");
4681 string_set(&pService->szPrintcommand, "");
4682 string_set(&pService->szLppausecommand, "");
4683 string_set(&pService->szLpresumecommand, "");
4684 string_set(&pService->szQueuepausecommand, "");
4685 string_set(&pService->szQueueresumecommand, "");
4687 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4688 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4689 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4690 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4691 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4692 string_set(&pService->szQueuepausecommand, "disable '%p'");
4693 string_set(&pService->szQueueresumecommand, "enable '%p'");
4694 #endif /* HAVE_CUPS */
4699 string_set(&pService->szLpqcommand, "lpstat -o%p");
4700 string_set(&pService->szLprmcommand, "cancel %p-%j");
4701 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4702 string_set(&pService->szQueuepausecommand, "disable %p");
4703 string_set(&pService->szQueueresumecommand, "enable %p");
4705 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4706 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4711 string_set(&pService->szLpqcommand, "lpq -P%p");
4712 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4713 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4719 string_set(&pService->szPrintcommand, "vlp print %p %s");
4720 string_set(&pService->szLpqcommand, "vlp lpq %p");
4721 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4722 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4723 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4724 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4725 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4727 #endif /* DEVELOPER */
4732 * Function to return the default value for the maximum number of open
4733 * file descriptors permitted. This function tries to consult the
4734 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4735 * the smaller of those.
4737 static int max_open_files(void)
4739 int sysctl_max = MAX_OPEN_FILES;
4740 int rlimit_max = MAX_OPEN_FILES;
4742 #ifdef HAVE_SYSCTLBYNAME
4744 size_t size = sizeof(sysctl_max);
4745 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4750 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4756 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4757 rlimit_max = rl.rlim_cur;
4759 #if defined(RLIM_INFINITY)
4760 if(rl.rlim_cur == RLIM_INFINITY)
4761 rlimit_max = MAX_OPEN_FILES;
4766 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4767 DEBUG(2,("max_open_files: sysctl_max (%d) below "
4768 "minimum Windows limit (%d)\n",
4770 MIN_OPEN_FILES_WINDOWS));
4771 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4774 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4775 DEBUG(2,("rlimit_max: rlimit_max (%d) below "
4776 "minimum Windows limit (%d)\n",
4778 MIN_OPEN_FILES_WINDOWS));
4779 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4782 return MIN(sysctl_max, rlimit_max);
4786 * Common part of freeing allocated data for one parameter.
4788 static void free_one_parameter_common(void *parm_ptr,
4789 struct parm_struct parm)
4791 if ((parm.type == P_STRING) ||
4792 (parm.type == P_USTRING))
4794 string_free((char**)parm_ptr);
4795 } else if (parm.type == P_LIST) {
4796 TALLOC_FREE(*((char***)parm_ptr));
4801 * Free the allocated data for one parameter for a share
4802 * given as a service struct.
4804 static void free_one_parameter(struct service *service,
4805 struct parm_struct parm)
4809 if (parm.p_class != P_LOCAL) {
4813 parm_ptr = lp_local_ptr(service, parm.ptr);
4815 free_one_parameter_common(parm_ptr, parm);
4819 * Free the allocated parameter data of a share given
4820 * as a service struct.
4822 static void free_parameters(struct service *service)
4826 for (i=0; parm_table[i].label; i++) {
4827 free_one_parameter(service, parm_table[i]);
4832 * Free the allocated data for one parameter for a given share
4833 * specified by an snum.
4835 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4839 if (parm.ptr == NULL) {
4844 parm_ptr = parm.ptr;
4845 } else if (parm.p_class != P_LOCAL) {
4848 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4851 free_one_parameter_common(parm_ptr, parm);
4855 * Free the allocated parameter data for a share specified
4858 static void free_parameters_by_snum(int snum)
4862 for (i=0; parm_table[i].label; i++) {
4863 free_one_parameter_by_snum(snum, parm_table[i]);
4868 * Free the allocated global parameters.
4870 static void free_global_parameters(void)
4872 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4875 /***************************************************************************
4876 Initialise the global parameter structure.
4877 ***************************************************************************/
4879 static void init_globals(bool first_time_only)
4881 static bool done_init = False;
4885 /* If requested to initialize only once and we've already done it... */
4886 if (first_time_only && done_init) {
4887 /* ... then we have nothing more to do */
4892 /* The logfile can be set before this is invoked. Free it if so. */
4893 if (Globals.szLogFile != NULL) {
4894 string_free(&Globals.szLogFile);
4895 Globals.szLogFile = NULL;
4899 free_global_parameters();
4902 memset((void *)&Globals, '\0', sizeof(Globals));
4904 for (i = 0; parm_table[i].label; i++) {
4905 if ((parm_table[i].type == P_STRING ||
4906 parm_table[i].type == P_USTRING) &&
4909 string_set((char **)parm_table[i].ptr, "");
4913 string_set(&sDefault.fstype, FSTYPE_STRING);
4914 string_set(&sDefault.szPrintjobUsername, "%U");
4916 init_printer_values(&sDefault);
4919 DEBUG(3, ("Initialising global parameters\n"));
4921 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4922 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4924 /* use the new 'hash2' method by default, with a prefix of 1 */
4925 string_set(&Globals.szManglingMethod, "hash2");
4926 Globals.mangle_prefix = 1;
4928 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4930 /* using UTF8 by default allows us to support all chars */
4931 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4933 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4934 /* If the system supports nl_langinfo(), try to grab the value
4935 from the user's locale */
4936 string_set(&Globals.display_charset, "LOCALE");
4938 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4941 /* Use codepage 850 as a default for the dos character set */
4942 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4945 * Allow the default PASSWD_CHAT to be overridden in local.h.
4947 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4949 set_global_myname(myhostname());
4950 string_set(&Globals.szNetbiosName,global_myname());
4952 set_global_myworkgroup(WORKGROUP);
4953 string_set(&Globals.szWorkgroup, lp_workgroup());
4955 string_set(&Globals.szPasswdProgram, "");
4956 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4957 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4958 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4959 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4960 string_set(&Globals.szSocketAddress, "0.0.0.0");
4962 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4963 smb_panic("init_globals: ENOMEM");
4965 string_set(&Globals.szServerString, s);
4967 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4968 DEFAULT_MINOR_VERSION) < 0) {
4969 smb_panic("init_globals: ENOMEM");
4971 string_set(&Globals.szAnnounceVersion, s);
4974 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4977 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4979 string_set(&Globals.szLogonDrive, "");
4980 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4981 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4982 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4984 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4985 string_set(&Globals.szPasswordServer, "*");
4987 Globals.AlgorithmicRidBase = BASE_RID;
4989 Globals.bLoadPrinters = True;
4990 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4992 Globals.ConfigBackend = config_backend;
4994 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4995 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4996 Globals.max_xmit = 0x4104;
4997 Globals.max_mux = 50; /* This is *needed* for profile support. */
4998 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4999 Globals.bDisableSpoolss = False;
5000 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5001 Globals.pwordlevel = 0;
5002 Globals.unamelevel = 0;
5003 Globals.deadtime = 0;
5004 Globals.getwd_cache = true;
5005 Globals.bLargeReadwrite = True;
5006 Globals.max_log_size = 5000;
5007 Globals.max_open_files = max_open_files();
5008 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5009 Globals.maxprotocol = PROTOCOL_NT1;
5010 Globals.minprotocol = PROTOCOL_CORE;
5011 Globals.security = SEC_USER;
5012 Globals.paranoid_server_security = True;
5013 Globals.bEncryptPasswords = True;
5014 Globals.bUpdateEncrypt = False;
5015 Globals.clientSchannel = Auto;
5016 Globals.serverSchannel = Auto;
5017 Globals.bReadRaw = True;
5018 Globals.bWriteRaw = True;
5019 Globals.bNullPasswords = False;
5020 Globals.bObeyPamRestrictions = False;
5022 Globals.bSyslogOnly = False;
5023 Globals.bTimestampLogs = True;
5024 string_set(&Globals.szLogLevel, "0");
5025 Globals.bDebugPrefixTimestamp = False;
5026 Globals.bDebugHiresTimestamp = true;
5027 Globals.bDebugPid = False;
5028 Globals.bDebugUid = False;
5029 Globals.bDebugClass = False;
5030 Globals.bEnableCoreFiles = True;
5031 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5032 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5033 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5034 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5035 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5036 Globals.lm_interval = 60;
5037 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5038 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5039 Globals.bNISHomeMap = False;
5040 #ifdef WITH_NISPLUS_HOME
5041 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5043 string_set(&Globals.szNISHomeMapName, "auto.home");
5046 Globals.bTimeServer = False;
5047 Globals.bBindInterfacesOnly = False;
5048 Globals.bUnixPasswdSync = False;
5049 Globals.bPamPasswordChange = False;
5050 Globals.bPasswdChatDebug = False;
5051 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5052 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5053 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5054 Globals.bStatCache = True; /* use stat cache by default */
5055 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5056 Globals.restrict_anonymous = 0;
5057 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5058 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5059 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5060 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5061 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
5062 /* Note, that we will use NTLM2 session security (which is different), if it is available */
5064 Globals.map_to_guest = 0; /* By Default, "Never" */
5065 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5066 Globals.enhanced_browsing = true;
5067 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5068 #ifdef MMAP_BLACKLIST
5069 Globals.bUseMmap = False;
5071 Globals.bUseMmap = True;
5073 Globals.bUnixExtensions = True;
5074 Globals.bResetOnZeroVC = False;
5075 Globals.bCreateKrb5Conf = true;
5077 /* hostname lookups can be very expensive and are broken on
5078 a large number of sites (tridge) */
5079 Globals.bHostnameLookups = False;
5081 string_set(&Globals.szPassdbBackend, "tdbsam");
5082 string_set(&Globals.szLdapSuffix, "");
5083 string_set(&Globals.szLdapMachineSuffix, "");
5084 string_set(&Globals.szLdapUserSuffix, "");
5085 string_set(&Globals.szLdapGroupSuffix, "");
5086 string_set(&Globals.szLdapIdmapSuffix, "");
5088 string_set(&Globals.szLdapAdminDn, "");
5089 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5090 Globals.ldap_ssl_ads = False;
5091 Globals.ldap_deref = -1;
5092 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5093 Globals.ldap_delete_dn = False;
5094 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5095 Globals.ldap_follow_referral = Auto;
5096 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5097 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5098 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5100 Globals.ldap_debug_level = 0;
5101 Globals.ldap_debug_threshold = 10;
5103 /* This is what we tell the afs client. in reality we set the token
5104 * to never expire, though, when this runs out the afs client will
5105 * forget the token. Set to 0 to get NEVERDATE.*/
5106 Globals.iAfsTokenLifetime = 604800;
5107 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5109 /* these parameters are set to defaults that are more appropriate
5110 for the increasing samba install base:
5112 as a member of the workgroup, that will possibly become a
5113 _local_ master browser (lm = True). this is opposed to a forced
5114 local master browser startup (pm = True).
5116 doesn't provide WINS server service by default (wsupp = False),
5117 and doesn't provide domain master browser services by default, either.
5121 Globals.bMsAddPrinterWizard = True;
5122 Globals.os_level = 20;
5123 Globals.bLocalMaster = True;
5124 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5125 Globals.bDomainLogons = False;
5126 Globals.bBrowseList = True;
5127 Globals.bWINSsupport = False;
5128 Globals.bWINSproxy = False;
5130 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5131 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5133 Globals.bDNSproxy = True;
5135 /* this just means to use them if they exist */
5136 Globals.bKernelOplocks = True;
5138 Globals.bAllowTrustedDomains = True;
5139 string_set(&Globals.szIdmapBackend, "tdb");
5141 string_set(&Globals.szTemplateShell, "/bin/false");
5142 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5143 string_set(&Globals.szWinbindSeparator, "\\");
5145 string_set(&Globals.szCupsServer, "");
5146 string_set(&Globals.szIPrintServer, "");
5148 string_set(&Globals.ctdbdSocket, "");
5149 Globals.szClusterAddresses = NULL;
5150 Globals.clustering = False;
5151 Globals.ctdb_timeout = 0;
5153 Globals.winbind_cache_time = 300; /* 5 minutes */
5154 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5155 Globals.bWinbindEnumUsers = False;
5156 Globals.bWinbindEnumGroups = False;
5157 Globals.bWinbindUseDefaultDomain = False;
5158 Globals.bWinbindTrustedDomainsOnly = False;
5159 Globals.bWinbindNestedGroups = True;
5160 Globals.winbind_expand_groups = 1;
5161 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5162 Globals.bWinbindRefreshTickets = False;
5163 Globals.bWinbindOfflineLogon = False;
5165 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5166 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5168 Globals.bPassdbExpandExplicit = False;
5170 Globals.name_cache_timeout = 660; /* In seconds */
5172 Globals.bUseSpnego = True;
5173 Globals.bClientUseSpnego = True;
5175 Globals.client_signing = Auto;
5176 Globals.server_signing = False;
5178 Globals.bDeferSharingViolations = True;
5179 string_set(&Globals.smb_ports, SMB_PORTS);
5181 Globals.bEnablePrivileges = True;
5182 Globals.bHostMSDfs = True;
5183 Globals.bASUSupport = False;
5185 /* User defined shares. */
5186 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5187 smb_panic("init_globals: ENOMEM");
5189 string_set(&Globals.szUsersharePath, s);
5191 string_set(&Globals.szUsershareTemplateShare, "");
5192 Globals.iUsershareMaxShares = 0;
5193 /* By default disallow sharing of directories not owned by the sharer. */
5194 Globals.bUsershareOwnerOnly = True;
5195 /* By default disallow guest access to usershares. */
5196 Globals.bUsershareAllowGuests = False;
5198 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5200 /* By default no shares out of the registry */
5201 Globals.bRegistryShares = False;
5203 Globals.iminreceivefile = 0;
5205 Globals.bMapUntrustedToDomain = false;
5208 /*******************************************************************
5209 Convenience routine to grab string parameters into temporary memory
5210 and run standard_sub_basic on them. The buffers can be written to by
5211 callers without affecting the source string.
5212 ********************************************************************/
5214 static char *lp_string(const char *s)
5217 TALLOC_CTX *ctx = talloc_tos();
5219 /* The follow debug is useful for tracking down memory problems
5220 especially if you have an inner loop that is calling a lp_*()
5221 function that returns a string. Perhaps this debug should be
5222 present all the time? */
5225 DEBUG(10, ("lp_string(%s)\n", s));
5231 ret = talloc_sub_basic(ctx,
5232 get_current_username(),
5233 current_user_info.domain,
5235 if (trim_char(ret, '\"', '\"')) {
5236 if (strchr(ret,'\"') != NULL) {
5238 ret = talloc_sub_basic(ctx,
5239 get_current_username(),
5240 current_user_info.domain,
5248 In this section all the functions that are used to access the
5249 parameters from the rest of the program are defined
5252 #define FN_GLOBAL_STRING(fn_name,ptr) \
5253 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5254 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5255 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5256 #define FN_GLOBAL_LIST(fn_name,ptr) \
5257 const char **fn_name(void) {return(*(const char ***)(ptr));}
5258 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5259 bool fn_name(void) {return(*(bool *)(ptr));}
5260 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5261 char fn_name(void) {return(*(char *)(ptr));}
5262 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5263 int fn_name(void) {return(*(int *)(ptr));}
5265 #define FN_LOCAL_STRING(fn_name,val) \
5266 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5267 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5268 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5269 #define FN_LOCAL_LIST(fn_name,val) \
5270 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5271 #define FN_LOCAL_BOOL(fn_name,val) \
5272 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5273 #define FN_LOCAL_INTEGER(fn_name,val) \
5274 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5276 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5277 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5278 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5279 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5280 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5281 char *fn_name(const struct share_params *p) {return(lp_string((LP_SNUM_OK(p->service) && ServicePtrs[(p->service)]->val) ? ServicePtrs[(p->service)]->val : sDefault.val));}
5282 #define FN_LOCAL_CHAR(fn_name,val) \
5283 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5285 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5286 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5287 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5288 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5289 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5290 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5291 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5292 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5293 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5294 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5295 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5296 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5297 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5298 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5299 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5300 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5301 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5302 * build process or in smb.conf, we use that value. Otherwise they
5303 * default to the value of lp_lockdir(). */
5304 char *lp_statedir(void) {
5305 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5306 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5307 return(lp_string(*(char **)(&Globals.szStateDir) ?
5308 *(char **)(&Globals.szStateDir) : ""));
5310 return(lp_string(*(char **)(&Globals.szLockDir) ?
5311 *(char **)(&Globals.szLockDir) : ""));
5313 char *lp_cachedir(void) {
5314 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5315 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5316 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5317 *(char **)(&Globals.szCacheDir) : ""));
5319 return(lp_string(*(char **)(&Globals.szLockDir) ?
5320 *(char **)(&Globals.szLockDir) : ""));
5322 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5323 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5324 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5325 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5326 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5327 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5328 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5329 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5330 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5331 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5332 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5333 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5334 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5335 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5336 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5337 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5338 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5339 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5340 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5341 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5342 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5343 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5344 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5345 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5346 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5347 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5348 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5349 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5350 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5351 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5352 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5353 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5354 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5355 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5356 * lp_passdb_backend() should be replace by the this macro again after
5359 const char *lp_passdb_backend(void)
5361 char *delim, *quote;
5363 delim = strchr( Globals.szPassdbBackend, ' ');
5364 /* no space at all */
5365 if (delim == NULL) {
5369 quote = strchr(Globals.szPassdbBackend, '"');
5370 /* no quote char or non in the first part */
5371 if (quote == NULL || quote > delim) {
5376 quote = strchr(quote+1, '"');
5377 if (quote == NULL) {
5378 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5380 } else if (*(quote+1) == '\0') {
5381 /* space, fitting quote char, and one backend only */
5384 /* terminate string after the fitting quote char */
5389 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5390 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5391 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5392 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5395 return Globals.szPassdbBackend;
5397 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5398 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5399 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5400 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5401 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5403 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5404 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5405 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5406 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5407 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5408 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5410 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5412 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5413 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5414 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5416 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5418 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5419 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5420 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5421 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5422 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5423 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5424 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5425 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5426 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5427 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5428 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5429 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5430 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5431 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5432 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5433 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5435 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5436 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5437 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5438 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5439 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5440 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5442 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5443 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5444 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5445 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5446 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5447 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5448 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5449 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5450 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5451 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5452 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5453 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5454 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5455 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5456 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5457 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5458 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5459 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5460 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5461 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5463 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5465 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5466 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5467 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5468 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5469 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5470 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5471 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5472 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5473 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5474 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5475 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5476 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5477 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5478 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5479 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5480 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5481 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5482 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5483 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5484 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5485 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5486 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5487 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5488 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5489 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5490 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5491 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5492 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5493 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5494 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5495 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5496 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5497 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5498 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5499 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5500 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5501 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5502 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5503 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5504 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5505 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5506 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5507 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5508 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5509 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5510 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5511 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5512 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5513 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5514 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5515 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5516 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5517 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5518 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5519 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5520 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5521 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5522 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5523 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5524 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5525 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5526 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5527 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5528 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5529 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5530 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5531 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5532 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5533 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5534 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5535 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5536 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5537 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5538 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5539 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5540 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5541 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5542 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5543 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5544 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5545 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5546 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5547 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5548 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5549 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5550 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5551 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5552 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5553 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5554 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5555 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5556 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5557 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5558 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5559 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5560 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5561 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5562 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5563 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5564 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5566 FN_LOCAL_STRING(lp_preexec, szPreExec)
5567 FN_LOCAL_STRING(lp_postexec, szPostExec)
5568 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5569 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5570 FN_LOCAL_STRING(lp_servicename, szService)
5571 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5572 FN_LOCAL_STRING(lp_pathname, szPath)
5573 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5574 FN_LOCAL_STRING(lp_username, szUsername)
5575 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5576 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5577 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5578 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5579 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5580 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5581 int lp_cups_encrypt(void)
5583 #ifdef HAVE_HTTPCONNECTENCRYPT
5584 switch (Globals.CupsEncrypt) {
5586 Globals.CupsEncrypt = HTTP_ENCRYPT_REQUIRED;
5589 Globals.CupsEncrypt = HTTP_ENCRYPT_ALWAYS;
5592 Globals.CupsEncrypt = HTTP_ENCRYPT_NEVER;
5596 return Globals.CupsEncrypt;
5598 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5599 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5600 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5601 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5602 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5603 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5604 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5605 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5606 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5607 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5608 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5609 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5610 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5611 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5612 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5613 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5614 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5615 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5616 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5617 FN_LOCAL_STRING(lp_comment, comment)
5618 FN_LOCAL_STRING(lp_force_user, force_user)
5619 FN_LOCAL_STRING(lp_force_group, force_group)
5620 FN_LOCAL_LIST(lp_readlist, readlist)
5621 FN_LOCAL_LIST(lp_writelist, writelist)
5622 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5623 FN_LOCAL_STRING(lp_fstype, fstype)
5624 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5625 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5626 static FN_LOCAL_STRING(lp_volume, volume)
5627 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5628 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5629 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5630 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5631 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5632 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5633 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5634 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5635 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5636 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5637 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5638 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5639 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5640 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5641 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5642 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5643 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5644 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5645 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5646 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5647 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5648 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5649 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5650 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5651 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5652 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5653 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5654 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5655 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5656 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5657 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5658 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5659 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5660 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5661 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5662 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5663 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5664 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5665 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5666 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5667 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5668 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5669 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5670 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5671 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5672 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5673 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5674 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5675 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5676 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5677 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5678 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5679 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5680 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5681 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5682 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5683 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5684 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5685 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5686 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5687 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5688 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5689 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5690 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5691 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5692 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5693 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5694 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5695 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5696 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5697 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5698 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5699 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5700 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5701 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5702 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5703 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5704 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5705 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5706 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5707 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5708 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5709 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5710 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5711 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5712 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5713 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5714 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5715 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5716 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5717 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5718 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5719 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5720 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5721 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5722 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5723 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5724 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5725 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5727 /* local prototypes */
5729 static int map_parameter(const char *pszParmName);
5730 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5731 static const char *get_boolean(bool bool_value);
5732 static int getservicebyname(const char *pszServiceName,
5733 struct service *pserviceDest);
5734 static void copy_service(struct service *pserviceDest,
5735 struct service *pserviceSource,
5736 struct bitmap *pcopymapDest);
5737 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5739 static bool do_section(const char *pszSectionName, void *userdata);
5740 static void init_copymap(struct service *pservice);
5741 static bool hash_a_service(const char *name, int number);
5742 static void free_service_byindex(int iService);
5743 static void free_param_opts(struct param_opt_struct **popts);
5744 static char * canonicalize_servicename(const char *name);
5745 static void show_parameter(int parmIndex);
5746 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5749 * This is a helper function for parametrical options support. It returns a
5750 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5751 * parametrical functions are quite simple
5753 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5756 bool global_section = False;
5758 struct param_opt_struct *data;
5760 if (snum >= iNumServices) return NULL;
5763 data = Globals.param_opt;
5764 global_section = True;
5766 data = ServicePtrs[snum]->param_opt;
5769 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5770 DEBUG(0,("asprintf failed!\n"));
5775 if (strwicmp(data->key, param_key) == 0) {
5776 string_free(¶m_key);
5782 if (!global_section) {
5783 /* Try to fetch the same option but from globals */
5784 /* but only if we are not already working with Globals */
5785 data = Globals.param_opt;
5787 if (strwicmp(data->key, param_key) == 0) {
5788 string_free(¶m_key);
5795 string_free(¶m_key);
5801 #define MISSING_PARAMETER(name) \
5802 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5804 /*******************************************************************
5805 convenience routine to return int parameters.
5806 ********************************************************************/
5807 static int lp_int(const char *s)
5811 MISSING_PARAMETER(lp_int);
5815 return (int)strtol(s, NULL, 0);
5818 /*******************************************************************
5819 convenience routine to return unsigned long parameters.
5820 ********************************************************************/
5821 static unsigned long lp_ulong(const char *s)
5825 MISSING_PARAMETER(lp_ulong);
5829 return strtoul(s, NULL, 0);
5832 /*******************************************************************
5833 convenience routine to return boolean parameters.
5834 ********************************************************************/
5835 static bool lp_bool(const char *s)
5840 MISSING_PARAMETER(lp_bool);
5844 if (!set_boolean(s, &ret)) {
5845 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5852 /*******************************************************************
5853 convenience routine to return enum parameters.
5854 ********************************************************************/
5855 static int lp_enum(const char *s,const struct enum_list *_enum)
5859 if (!s || !*s || !_enum) {
5860 MISSING_PARAMETER(lp_enum);
5864 for (i=0; _enum[i].name; i++) {
5865 if (strequal(_enum[i].name,s))
5866 return _enum[i].value;
5869 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5873 #undef MISSING_PARAMETER
5875 /* DO NOT USE lp_parm_string ANYMORE!!!!
5876 * use lp_parm_const_string or lp_parm_talloc_string
5878 * lp_parm_string is only used to let old modules find this symbol
5880 #undef lp_parm_string
5881 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5882 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5884 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5887 /* Return parametric option from a given service. Type is a part of option before ':' */
5888 /* Parametric option has following syntax: 'Type: option = value' */
5889 /* the returned value is talloced on the talloc_tos() */
5890 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5892 struct param_opt_struct *data = get_parametrics(snum, type, option);
5894 if (data == NULL||data->value==NULL) {
5896 return lp_string(def);
5902 return lp_string(data->value);
5905 /* Return parametric option from a given service. Type is a part of option before ':' */
5906 /* Parametric option has following syntax: 'Type: option = value' */
5907 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5909 struct param_opt_struct *data = get_parametrics(snum, type, option);
5911 if (data == NULL||data->value==NULL)
5917 /* Return parametric option from a given service. Type is a part of option before ':' */
5918 /* Parametric option has following syntax: 'Type: option = value' */
5920 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5922 struct param_opt_struct *data = get_parametrics(snum, type, option);
5924 if (data == NULL||data->value==NULL)
5925 return (const char **)def;
5927 if (data->list==NULL) {
5928 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5931 return (const char **)data->list;
5934 /* Return parametric option from a given service. Type is a part of option before ':' */
5935 /* Parametric option has following syntax: 'Type: option = value' */
5937 int lp_parm_int(int snum, const char *type, const char *option, int def)
5939 struct param_opt_struct *data = get_parametrics(snum, type, option);
5941 if (data && data->value && *data->value)
5942 return lp_int(data->value);
5947 /* Return parametric option from a given service. Type is a part of option before ':' */
5948 /* Parametric option has following syntax: 'Type: option = value' */
5950 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5952 struct param_opt_struct *data = get_parametrics(snum, type, option);
5954 if (data && data->value && *data->value)
5955 return lp_ulong(data->value);
5960 /* Return parametric option from a given service. Type is a part of option before ':' */
5961 /* Parametric option has following syntax: 'Type: option = value' */
5963 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5965 struct param_opt_struct *data = get_parametrics(snum, type, option);
5967 if (data && data->value && *data->value)
5968 return lp_bool(data->value);
5973 /* Return parametric option from a given service. Type is a part of option before ':' */
5974 /* Parametric option has following syntax: 'Type: option = value' */
5976 int lp_parm_enum(int snum, const char *type, const char *option,
5977 const struct enum_list *_enum, int def)
5979 struct param_opt_struct *data = get_parametrics(snum, type, option);
5981 if (data && data->value && *data->value && _enum)
5982 return lp_enum(data->value, _enum);
5988 /***************************************************************************
5989 Initialise a service to the defaults.
5990 ***************************************************************************/
5992 static void init_service(struct service *pservice)
5994 memset((char *)pservice, '\0', sizeof(struct service));
5995 copy_service(pservice, &sDefault, NULL);
6000 * free a param_opts structure.
6001 * param_opts handling should be moved to talloc;
6002 * then this whole functions reduces to a TALLOC_FREE().
6005 static void free_param_opts(struct param_opt_struct **popts)
6007 struct param_opt_struct *opt, *next_opt;
6009 if (popts == NULL) {
6013 if (*popts != NULL) {
6014 DEBUG(5, ("Freeing parametrics:\n"));
6017 while (opt != NULL) {
6018 string_free(&opt->key);
6019 string_free(&opt->value);
6020 TALLOC_FREE(opt->list);
6021 next_opt = opt->next;
6028 /***************************************************************************
6029 Free the dynamically allocated parts of a service struct.
6030 ***************************************************************************/
6032 static void free_service(struct service *pservice)
6037 if (pservice->szService)
6038 DEBUG(5, ("free_service: Freeing service %s\n",
6039 pservice->szService));
6041 free_parameters(pservice);
6043 string_free(&pservice->szService);
6044 bitmap_free(pservice->copymap);
6046 free_param_opts(&pservice->param_opt);
6048 ZERO_STRUCTP(pservice);
6052 /***************************************************************************
6053 remove a service indexed in the ServicePtrs array from the ServiceHash
6054 and free the dynamically allocated parts
6055 ***************************************************************************/
6057 static void free_service_byindex(int idx)
6059 if ( !LP_SNUM_OK(idx) )
6062 ServicePtrs[idx]->valid = False;
6063 invalid_services[num_invalid_services++] = idx;
6065 /* we have to cleanup the hash record */
6067 if (ServicePtrs[idx]->szService) {
6068 char *canon_name = canonicalize_servicename(
6069 ServicePtrs[idx]->szService );
6071 dbwrap_delete_bystring(ServiceHash, canon_name );
6072 TALLOC_FREE(canon_name);
6075 free_service(ServicePtrs[idx]);
6078 /***************************************************************************
6079 Add a new service to the services array initialising it with the given
6081 ***************************************************************************/
6083 static int add_a_service(const struct service *pservice, const char *name)
6086 struct service tservice;
6087 int num_to_alloc = iNumServices + 1;
6089 tservice = *pservice;
6091 /* it might already exist */
6093 i = getservicebyname(name, NULL);
6095 /* Clean all parametric options for service */
6096 /* They will be added during parsing again */
6097 free_param_opts(&ServicePtrs[i]->param_opt);
6102 /* find an invalid one */
6104 if (num_invalid_services > 0) {
6105 i = invalid_services[--num_invalid_services];
6108 /* if not, then create one */
6109 if (i == iNumServices) {
6110 struct service **tsp;
6113 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6115 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6119 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6120 if (!ServicePtrs[iNumServices]) {
6121 DEBUG(0,("add_a_service: out of memory!\n"));
6126 /* enlarge invalid_services here for now... */
6127 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6129 if (tinvalid == NULL) {
6130 DEBUG(0,("add_a_service: failed to enlarge "
6131 "invalid_services!\n"));
6134 invalid_services = tinvalid;
6136 free_service_byindex(i);
6139 ServicePtrs[i]->valid = True;
6141 init_service(ServicePtrs[i]);
6142 copy_service(ServicePtrs[i], &tservice, NULL);
6144 string_set(&ServicePtrs[i]->szService, name);
6146 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6147 i, ServicePtrs[i]->szService));
6149 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6156 /***************************************************************************
6157 Convert a string to uppercase and remove whitespaces.
6158 ***************************************************************************/
6160 static char *canonicalize_servicename(const char *src)
6165 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6169 result = talloc_strdup(talloc_tos(), src);
6170 SMB_ASSERT(result != NULL);
6176 /***************************************************************************
6177 Add a name/index pair for the services array to the hash table.
6178 ***************************************************************************/
6180 static bool hash_a_service(const char *name, int idx)
6184 if ( !ServiceHash ) {
6185 DEBUG(10,("hash_a_service: creating servicehash\n"));
6186 ServiceHash = db_open_rbt(NULL);
6187 if ( !ServiceHash ) {
6188 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6193 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6196 canon_name = canonicalize_servicename( name );
6198 dbwrap_store_bystring(ServiceHash, canon_name,
6199 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6202 TALLOC_FREE(canon_name);
6207 /***************************************************************************
6208 Add a new home service, with the specified home directory, defaults coming
6210 ***************************************************************************/
6212 bool lp_add_home(const char *pszHomename, int iDefaultService,
6213 const char *user, const char *pszHomedir)
6217 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6218 pszHomedir[0] == '\0') {
6222 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6227 if (!(*(ServicePtrs[iDefaultService]->szPath))
6228 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6229 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6232 if (!(*(ServicePtrs[i]->comment))) {
6233 char *comment = NULL;
6234 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6237 string_set(&ServicePtrs[i]->comment, comment);
6241 /* set the browseable flag from the global default */
6243 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6244 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6246 ServicePtrs[i]->autoloaded = True;
6248 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6249 user, ServicePtrs[i]->szPath ));
6254 /***************************************************************************
6255 Add a new service, based on an old one.
6256 ***************************************************************************/
6258 int lp_add_service(const char *pszService, int iDefaultService)
6260 if (iDefaultService < 0) {
6261 return add_a_service(&sDefault, pszService);
6264 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6267 /***************************************************************************
6268 Add the IPC service.
6269 ***************************************************************************/
6271 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6273 char *comment = NULL;
6274 int i = add_a_service(&sDefault, ipc_name);
6279 if (asprintf(&comment, "IPC Service (%s)",
6280 Globals.szServerString) < 0) {
6284 string_set(&ServicePtrs[i]->szPath, tmpdir());
6285 string_set(&ServicePtrs[i]->szUsername, "");
6286 string_set(&ServicePtrs[i]->comment, comment);
6287 string_set(&ServicePtrs[i]->fstype, "IPC");
6288 ServicePtrs[i]->iMaxConnections = 0;
6289 ServicePtrs[i]->bAvailable = True;
6290 ServicePtrs[i]->bRead_only = True;
6291 ServicePtrs[i]->bGuest_only = False;
6292 ServicePtrs[i]->bAdministrative_share = True;
6293 ServicePtrs[i]->bGuest_ok = guest_ok;
6294 ServicePtrs[i]->bPrint_ok = False;
6295 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6297 DEBUG(3, ("adding IPC service\n"));
6303 /***************************************************************************
6304 Add a new printer service, with defaults coming from service iFrom.
6305 ***************************************************************************/
6307 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6309 const char *comment = "From Printcap";
6310 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6315 /* note that we do NOT default the availability flag to True - */
6316 /* we take it from the default service passed. This allows all */
6317 /* dynamic printers to be disabled by disabling the [printers] */
6318 /* entry (if/when the 'available' keyword is implemented!). */
6320 /* the printer name is set to the service name. */
6321 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6322 string_set(&ServicePtrs[i]->comment, comment);
6324 /* set the browseable flag from the gloabl default */
6325 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6327 /* Printers cannot be read_only. */
6328 ServicePtrs[i]->bRead_only = False;
6329 /* No share modes on printer services. */
6330 ServicePtrs[i]->bShareModes = False;
6331 /* No oplocks on printer services. */
6332 ServicePtrs[i]->bOpLocks = False;
6333 /* Printer services must be printable. */
6334 ServicePtrs[i]->bPrint_ok = True;
6336 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6342 /***************************************************************************
6343 Check whether the given parameter name is valid.
6344 Parametric options (names containing a colon) are considered valid.
6345 ***************************************************************************/
6347 bool lp_parameter_is_valid(const char *pszParmName)
6349 return ((map_parameter(pszParmName) != -1) ||
6350 (strchr(pszParmName, ':') != NULL));
6353 /***************************************************************************
6354 Check whether the given name is the name of a global parameter.
6355 Returns True for strings belonging to parameters of class
6356 P_GLOBAL, False for all other strings, also for parametric options
6357 and strings not belonging to any option.
6358 ***************************************************************************/
6360 bool lp_parameter_is_global(const char *pszParmName)
6362 int num = map_parameter(pszParmName);
6365 return (parm_table[num].p_class == P_GLOBAL);
6371 /**************************************************************************
6372 Check whether the given name is the canonical name of a parameter.
6373 Returns False if it is not a valid parameter Name.
6374 For parametric options, True is returned.
6375 **************************************************************************/
6377 bool lp_parameter_is_canonical(const char *parm_name)
6379 if (!lp_parameter_is_valid(parm_name)) {
6383 return (map_parameter(parm_name) ==
6384 map_parameter_canonical(parm_name, NULL));
6387 /**************************************************************************
6388 Determine the canonical name for a parameter.
6389 Indicate when it is an inverse (boolean) synonym instead of a
6391 **************************************************************************/
6393 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6398 if (!lp_parameter_is_valid(parm_name)) {
6403 num = map_parameter_canonical(parm_name, inverse);
6405 /* parametric option */
6406 *canon_parm = parm_name;
6408 *canon_parm = parm_table[num].label;
6415 /**************************************************************************
6416 Determine the canonical name for a parameter.
6417 Turn the value given into the inverse boolean expression when
6418 the synonym is an invers boolean synonym.
6420 Return True if parm_name is a valid parameter name and
6421 in case it is an invers boolean synonym, if the val string could
6422 successfully be converted to the reverse bool.
6423 Return false in all other cases.
6424 **************************************************************************/
6426 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6428 const char **canon_parm,
6429 const char **canon_val)
6434 if (!lp_parameter_is_valid(parm_name)) {
6440 num = map_parameter_canonical(parm_name, &inverse);
6442 /* parametric option */
6443 *canon_parm = parm_name;
6446 *canon_parm = parm_table[num].label;
6448 if (!lp_invert_boolean(val, canon_val)) {
6460 /***************************************************************************
6461 Map a parameter's string representation to something we can use.
6462 Returns False if the parameter string is not recognised, else TRUE.
6463 ***************************************************************************/
6465 static int map_parameter(const char *pszParmName)
6469 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6472 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6473 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6476 /* Warn only if it isn't parametric option */
6477 if (strchr(pszParmName, ':') == NULL)
6478 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6479 /* We do return 'fail' for parametric options as well because they are
6480 stored in different storage
6485 /***************************************************************************
6486 Map a parameter's string representation to the index of the canonical
6487 form of the parameter (it might be a synonym).
6488 Returns -1 if the parameter string is not recognised.
6489 ***************************************************************************/
6491 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6493 int parm_num, canon_num;
6494 bool loc_inverse = False;
6496 parm_num = map_parameter(pszParmName);
6497 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6498 /* invalid, parametric or no canidate for synonyms ... */
6502 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6503 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6504 parm_num = canon_num;
6510 if (inverse != NULL) {
6511 *inverse = loc_inverse;
6516 /***************************************************************************
6517 return true if parameter number parm1 is a synonym of parameter
6518 number parm2 (parm2 being the principal name).
6519 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6521 ***************************************************************************/
6523 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6525 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6526 (parm_table[parm1].flags & FLAG_HIDE) &&
6527 !(parm_table[parm2].flags & FLAG_HIDE))
6529 if (inverse != NULL) {
6530 if ((parm_table[parm1].type == P_BOOLREV) &&
6531 (parm_table[parm2].type == P_BOOL))
6543 /***************************************************************************
6544 Show one parameter's name, type, [values,] and flags.
6545 (helper functions for show_parameter_list)
6546 ***************************************************************************/
6548 static void show_parameter(int parmIndex)
6550 int enumIndex, flagIndex;
6555 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6556 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6558 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6559 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6560 FLAG_HIDE, FLAG_DOS_STRING};
6561 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6562 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6563 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6565 printf("%s=%s", parm_table[parmIndex].label,
6566 type[parm_table[parmIndex].type]);
6567 if (parm_table[parmIndex].type == P_ENUM) {
6570 parm_table[parmIndex].enum_list[enumIndex].name;
6574 enumIndex ? "|" : "",
6575 parm_table[parmIndex].enum_list[enumIndex].name);
6580 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6581 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6584 flag_names[flagIndex]);
6589 /* output synonyms */
6591 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6592 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6593 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6594 parm_table[parmIndex2].label);
6595 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6597 printf(" (synonyms: ");
6602 printf("%s%s", parm_table[parmIndex2].label,
6603 inverse ? "[i]" : "");
6613 /***************************************************************************
6614 Show all parameter's name, type, [values,] and flags.
6615 ***************************************************************************/
6617 void show_parameter_list(void)
6619 int classIndex, parmIndex;
6620 const char *section_names[] = { "local", "global", NULL};
6622 for (classIndex=0; section_names[classIndex]; classIndex++) {
6623 printf("[%s]\n", section_names[classIndex]);
6624 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6625 if (parm_table[parmIndex].p_class == classIndex) {
6626 show_parameter(parmIndex);
6632 /***************************************************************************
6633 Check if a given string correctly represents a boolean value.
6634 ***************************************************************************/
6636 bool lp_string_is_valid_boolean(const char *parm_value)
6638 return set_boolean(parm_value, NULL);
6641 /***************************************************************************
6642 Get the standard string representation of a boolean value ("yes" or "no")
6643 ***************************************************************************/
6645 static const char *get_boolean(bool bool_value)
6647 static const char *yes_str = "yes";
6648 static const char *no_str = "no";
6650 return (bool_value ? yes_str : no_str);
6653 /***************************************************************************
6654 Provide the string of the negated boolean value associated to the boolean
6655 given as a string. Returns False if the passed string does not correctly
6656 represent a boolean.
6657 ***************************************************************************/
6659 bool lp_invert_boolean(const char *str, const char **inverse_str)
6663 if (!set_boolean(str, &val)) {
6667 *inverse_str = get_boolean(!val);
6671 /***************************************************************************
6672 Provide the canonical string representation of a boolean value given
6673 as a string. Return True on success, False if the string given does
6674 not correctly represent a boolean.
6675 ***************************************************************************/
6677 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6681 if (!set_boolean(str, &val)) {
6685 *canon_str = get_boolean(val);
6689 /***************************************************************************
6690 Find a service by name. Otherwise works like get_service.
6691 ***************************************************************************/
6693 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6699 if (ServiceHash == NULL) {
6703 canon_name = canonicalize_servicename(pszServiceName);
6705 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6707 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6708 iService = *(int *)data.dptr;
6711 TALLOC_FREE(canon_name);
6713 if ((iService != -1) && (LP_SNUM_OK(iService))
6714 && (pserviceDest != NULL)) {
6715 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6721 /***************************************************************************
6722 Copy a service structure to another.
6723 If pcopymapDest is NULL then copy all fields
6724 ***************************************************************************/
6727 * Add a parametric option to a param_opt_struct,
6728 * replacing old value, if already present.
6730 static void set_param_opt(struct param_opt_struct **opt_list,
6731 const char *opt_name,
6732 const char *opt_value)
6734 struct param_opt_struct *new_opt, *opt;
6737 if (opt_list == NULL) {
6744 /* Traverse destination */
6746 /* If we already have same option, override it */
6747 if (strwicmp(opt->key, opt_name) == 0) {
6748 string_free(&opt->value);
6749 TALLOC_FREE(opt->list);
6750 opt->value = SMB_STRDUP(opt_value);
6757 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6758 new_opt->key = SMB_STRDUP(opt_name);
6759 new_opt->value = SMB_STRDUP(opt_value);
6760 new_opt->list = NULL;
6761 DLIST_ADD(*opt_list, new_opt);
6765 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6766 struct bitmap *pcopymapDest)
6769 bool bcopyall = (pcopymapDest == NULL);
6770 struct param_opt_struct *data;
6772 for (i = 0; parm_table[i].label; i++)
6773 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6774 (bcopyall || bitmap_query(pcopymapDest,i))) {
6775 void *def_ptr = parm_table[i].ptr;
6777 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6780 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6783 switch (parm_table[i].type) {
6786 *(bool *)dest_ptr = *(bool *)src_ptr;
6792 *(int *)dest_ptr = *(int *)src_ptr;
6796 *(char *)dest_ptr = *(char *)src_ptr;
6800 string_set((char **)dest_ptr,
6805 string_set((char **)dest_ptr,
6807 strupper_m(*(char **)dest_ptr);
6810 TALLOC_FREE(*((char ***)dest_ptr));
6811 *((char ***)dest_ptr) = str_list_copy(NULL,
6812 *(const char ***)src_ptr);
6820 init_copymap(pserviceDest);
6821 if (pserviceSource->copymap)
6822 bitmap_copy(pserviceDest->copymap,
6823 pserviceSource->copymap);
6826 data = pserviceSource->param_opt;
6828 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6833 /***************************************************************************
6834 Check a service for consistency. Return False if the service is in any way
6835 incomplete or faulty, else True.
6836 ***************************************************************************/
6838 bool service_ok(int iService)
6843 if (ServicePtrs[iService]->szService[0] == '\0') {
6844 DEBUG(0, ("The following message indicates an internal error:\n"));
6845 DEBUG(0, ("No service name in service entry.\n"));
6849 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6850 /* I can't see why you'd want a non-printable printer service... */
6851 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6852 if (!ServicePtrs[iService]->bPrint_ok) {
6853 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6854 ServicePtrs[iService]->szService));
6855 ServicePtrs[iService]->bPrint_ok = True;
6857 /* [printers] service must also be non-browsable. */
6858 if (ServicePtrs[iService]->bBrowseable)
6859 ServicePtrs[iService]->bBrowseable = False;
6862 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6863 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6864 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6866 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6867 ServicePtrs[iService]->szService));
6868 ServicePtrs[iService]->bAvailable = False;
6871 /* If a service is flagged unavailable, log the fact at level 1. */
6872 if (!ServicePtrs[iService]->bAvailable)
6873 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6874 ServicePtrs[iService]->szService));
6879 static struct smbconf_ctx *lp_smbconf_ctx(void)
6882 static struct smbconf_ctx *conf_ctx = NULL;
6884 if (conf_ctx == NULL) {
6885 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6886 if (!W_ERROR_IS_OK(werr)) {
6887 DEBUG(1, ("error initializing registry configuration: "
6888 "%s\n", win_errstr(werr)));
6896 static bool process_smbconf_service(struct smbconf_service *service)
6901 if (service == NULL) {
6905 ret = do_section(service->name, NULL);
6909 for (count = 0; count < service->num_params; count++) {
6910 ret = do_parameter(service->param_names[count],
6911 service->param_values[count],
6917 if (iServiceIndex >= 0) {
6918 return service_ok(iServiceIndex);
6924 * load a service from registry and activate it
6926 bool process_registry_service(const char *service_name)
6929 struct smbconf_service *service = NULL;
6930 TALLOC_CTX *mem_ctx = talloc_stackframe();
6931 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6934 if (conf_ctx == NULL) {
6938 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6940 if (!smbconf_share_exists(conf_ctx, service_name)) {
6942 * Registry does not contain data for this service (yet),
6943 * but make sure lp_load doesn't return false.
6949 werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6950 if (!W_ERROR_IS_OK(werr)) {
6954 ret = process_smbconf_service(service);
6960 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6963 TALLOC_FREE(mem_ctx);
6968 * process_registry_globals
6970 static bool process_registry_globals(void)
6974 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6976 ret = do_parameter("registry shares", "yes", NULL);
6981 return process_registry_service(GLOBAL_NAME);
6984 bool process_registry_shares(void)
6988 struct smbconf_service **service = NULL;
6989 uint32_t num_shares = 0;
6990 TALLOC_CTX *mem_ctx = talloc_stackframe();
6991 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6994 if (conf_ctx == NULL) {
6998 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6999 if (!W_ERROR_IS_OK(werr)) {
7005 for (count = 0; count < num_shares; count++) {
7006 if (strequal(service[count]->name, GLOBAL_NAME)) {
7009 ret = process_smbconf_service(service[count]);
7016 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7019 TALLOC_FREE(mem_ctx);
7023 #define MAX_INCLUDE_DEPTH 100
7025 static uint8_t include_depth;
7027 static struct file_lists {
7028 struct file_lists *next;
7032 } *file_lists = NULL;
7034 /*******************************************************************
7035 Keep a linked list of all config files so we know when one has changed
7036 it's date and needs to be reloaded.
7037 ********************************************************************/
7039 static void add_to_file_list(const char *fname, const char *subfname)
7041 struct file_lists *f = file_lists;
7044 if (f->name && !strcmp(f->name, fname))
7050 f = SMB_MALLOC_P(struct file_lists);
7053 f->next = file_lists;
7054 f->name = SMB_STRDUP(fname);
7059 f->subfname = SMB_STRDUP(subfname);
7066 f->modtime = file_modtime(subfname);
7068 time_t t = file_modtime(subfname);
7076 * Free the file lists
7078 static void free_file_list(void)
7080 struct file_lists *f;
7081 struct file_lists *next;
7086 SAFE_FREE( f->name );
7087 SAFE_FREE( f->subfname );
7096 * Utility function for outsiders to check if we're running on registry.
7098 bool lp_config_backend_is_registry(void)
7100 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7104 * Utility function to check if the config backend is FILE.
7106 bool lp_config_backend_is_file(void)
7108 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7111 /*******************************************************************
7112 Check if a config file has changed date.
7113 ********************************************************************/
7115 bool lp_file_list_changed(void)
7117 struct file_lists *f = file_lists;
7119 DEBUG(6, ("lp_file_list_changed()\n"));
7124 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7125 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7127 if (conf_ctx == NULL) {
7130 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7133 DEBUGADD(6, ("registry config changed\n"));
7138 n2 = talloc_sub_basic(talloc_tos(),
7139 get_current_username(),
7140 current_user_info.domain,
7145 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7146 f->name, n2, ctime(&f->modtime)));
7148 mod_time = file_modtime(n2);
7151 ((f->modtime != mod_time) ||
7152 (f->subfname == NULL) ||
7153 (strcmp(n2, f->subfname) != 0)))
7156 ("file %s modified: %s\n", n2,
7158 f->modtime = mod_time;
7159 SAFE_FREE(f->subfname);
7160 f->subfname = SMB_STRDUP(n2);
7172 /***************************************************************************
7173 Run standard_sub_basic on netbios name... needed because global_myname
7174 is not accessed through any lp_ macro.
7175 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7176 ***************************************************************************/
7178 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7181 char *netbios_name = talloc_sub_basic(
7182 talloc_tos(), get_current_username(), current_user_info.domain,
7185 ret = set_global_myname(netbios_name);
7186 TALLOC_FREE(netbios_name);
7187 string_set(&Globals.szNetbiosName,global_myname());
7189 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7195 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7197 if (strcmp(*ptr, pszParmValue) != 0) {
7198 string_set(ptr, pszParmValue);
7206 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7210 ret = set_global_myworkgroup(pszParmValue);
7211 string_set(&Globals.szWorkgroup,lp_workgroup());
7216 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7220 ret = set_global_scope(pszParmValue);
7221 string_set(&Globals.szNetbiosScope,global_scope());
7226 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7228 TALLOC_FREE(Globals.szNetbiosAliases);
7229 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7230 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7233 /***************************************************************************
7234 Handle the include operation.
7235 ***************************************************************************/
7236 static bool bAllowIncludeRegistry = true;
7238 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7242 if (include_depth >= MAX_INCLUDE_DEPTH) {
7243 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7248 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7249 if (!bAllowIncludeRegistry) {
7252 if (bInGlobalSection) {
7255 ret = process_registry_globals();
7259 DEBUG(1, ("\"include = registry\" only effective "
7260 "in %s section\n", GLOBAL_NAME));
7265 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7266 current_user_info.domain,
7269 add_to_file_list(pszParmValue, fname);
7271 string_set(ptr, fname);
7273 if (file_exist(fname)) {
7276 ret = pm_process(fname, do_section, do_parameter, NULL);
7282 DEBUG(2, ("Can't find include file %s\n", fname));
7287 /***************************************************************************
7288 Handle the interpretation of the copy parameter.
7289 ***************************************************************************/
7291 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7295 struct service serviceTemp;
7297 string_set(ptr, pszParmValue);
7299 init_service(&serviceTemp);
7303 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7305 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7306 if (iTemp == iServiceIndex) {
7307 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7309 copy_service(ServicePtrs[iServiceIndex],
7311 ServicePtrs[iServiceIndex]->copymap);
7315 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7319 free_service(&serviceTemp);
7323 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7325 Globals.ldap_debug_level = lp_int(pszParmValue);
7326 init_ldap_debugging();
7330 /***************************************************************************
7331 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7336 idmap uid = 1000-1999
7339 We only do simple parsing checks here. The strings are parsed into useful
7340 structures in the idmap daemon code.
7342 ***************************************************************************/
7344 /* Some lp_ routines to return idmap [ug]id information */
7346 static uid_t idmap_uid_low, idmap_uid_high;
7347 static gid_t idmap_gid_low, idmap_gid_high;
7349 bool lp_idmap_uid(uid_t *low, uid_t *high)
7351 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7355 *low = idmap_uid_low;
7358 *high = idmap_uid_high;
7363 bool lp_idmap_gid(gid_t *low, gid_t *high)
7365 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7369 *low = idmap_gid_low;
7372 *high = idmap_gid_high;
7377 /* Do some simple checks on "idmap [ug]id" parameter values */
7379 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7383 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7388 string_set(ptr, pszParmValue);
7390 idmap_uid_low = low;
7391 idmap_uid_high = high;
7396 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7400 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7405 string_set(ptr, pszParmValue);
7407 idmap_gid_low = low;
7408 idmap_gid_high = high;
7413 /***************************************************************************
7414 Handle the DEBUG level list.
7415 ***************************************************************************/
7417 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7419 string_set(ptr, pszParmValueIn);
7420 return debug_parse_levels(pszParmValueIn);
7423 /***************************************************************************
7424 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7425 ***************************************************************************/
7427 static const char *append_ldap_suffix( const char *str )
7429 const char *suffix_string;
7432 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7433 Globals.szLdapSuffix );
7434 if ( !suffix_string ) {
7435 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7439 return suffix_string;
7442 const char *lp_ldap_machine_suffix(void)
7444 if (Globals.szLdapMachineSuffix[0])
7445 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7447 return lp_string(Globals.szLdapSuffix);
7450 const char *lp_ldap_user_suffix(void)
7452 if (Globals.szLdapUserSuffix[0])
7453 return append_ldap_suffix(Globals.szLdapUserSuffix);
7455 return lp_string(Globals.szLdapSuffix);
7458 const char *lp_ldap_group_suffix(void)
7460 if (Globals.szLdapGroupSuffix[0])
7461 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7463 return lp_string(Globals.szLdapSuffix);
7466 const char *lp_ldap_idmap_suffix(void)
7468 if (Globals.szLdapIdmapSuffix[0])
7469 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7471 return lp_string(Globals.szLdapSuffix);
7474 /****************************************************************************
7475 set the value for a P_ENUM
7476 ***************************************************************************/
7478 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7483 for (i = 0; parm->enum_list[i].name; i++) {
7484 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7485 *ptr = parm->enum_list[i].value;
7489 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7490 pszParmValue, parm->label));
7493 /***************************************************************************
7494 ***************************************************************************/
7496 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7498 static int parm_num = -1;
7501 if ( parm_num == -1 )
7502 parm_num = map_parameter( "printing" );
7504 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7509 s = ServicePtrs[snum];
7511 init_printer_values( s );
7517 /***************************************************************************
7518 Initialise a copymap.
7519 ***************************************************************************/
7521 static void init_copymap(struct service *pservice)
7524 if (pservice->copymap) {
7525 bitmap_free(pservice->copymap);
7527 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7528 if (!pservice->copymap)
7530 ("Couldn't allocate copymap!! (size %d)\n",
7531 (int)NUMPARAMETERS));
7533 for (i = 0; i < NUMPARAMETERS; i++)
7534 bitmap_set(pservice->copymap, i);
7537 /***************************************************************************
7538 Return the local pointer to a parameter given a service struct and the
7539 pointer into the default structure.
7540 ***************************************************************************/
7542 static void *lp_local_ptr(struct service *service, void *ptr)
7544 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7547 /***************************************************************************
7548 Return the local pointer to a parameter given the service number and the
7549 pointer into the default structure.
7550 ***************************************************************************/
7552 void *lp_local_ptr_by_snum(int snum, void *ptr)
7554 return lp_local_ptr(ServicePtrs[snum], ptr);
7557 /***************************************************************************
7558 Process a parameter for a particular service number. If snum < 0
7559 then assume we are in the globals.
7560 ***************************************************************************/
7562 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7565 void *parm_ptr = NULL; /* where we are going to store the result */
7566 void *def_ptr = NULL;
7567 struct param_opt_struct **opt_list;
7569 parmnum = map_parameter(pszParmName);
7572 if (strchr(pszParmName, ':') == NULL) {
7573 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7579 * We've got a parametric option
7582 opt_list = (snum < 0)
7583 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7584 set_param_opt(opt_list, pszParmName, pszParmValue);
7589 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7590 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7594 def_ptr = parm_table[parmnum].ptr;
7596 /* we might point at a service, the default service or a global */
7600 if (parm_table[parmnum].p_class == P_GLOBAL) {
7602 ("Global parameter %s found in service section!\n",
7606 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7610 if (!ServicePtrs[snum]->copymap)
7611 init_copymap(ServicePtrs[snum]);
7613 /* this handles the aliases - set the copymap for other entries with
7614 the same data pointer */
7615 for (i = 0; parm_table[i].label; i++)
7616 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7617 bitmap_clear(ServicePtrs[snum]->copymap, i);
7620 /* if it is a special case then go ahead */
7621 if (parm_table[parmnum].special) {
7622 return parm_table[parmnum].special(snum, pszParmValue,
7626 /* now switch on the type of variable it is */
7627 switch (parm_table[parmnum].type)
7630 *(bool *)parm_ptr = lp_bool(pszParmValue);
7634 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7638 *(int *)parm_ptr = lp_int(pszParmValue);
7642 *(char *)parm_ptr = *pszParmValue;
7646 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7648 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7653 TALLOC_FREE(*((char ***)parm_ptr));
7654 *(char ***)parm_ptr = str_list_make_v3(
7655 talloc_autofree_context(), pszParmValue, NULL);
7659 string_set((char **)parm_ptr, pszParmValue);
7663 string_set((char **)parm_ptr, pszParmValue);
7664 strupper_m(*(char **)parm_ptr);
7668 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7677 /***************************************************************************
7678 Process a parameter.
7679 ***************************************************************************/
7681 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7684 if (!bInGlobalSection && bGlobalOnly)
7687 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7689 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7690 pszParmName, pszParmValue));
7693 /***************************************************************************
7694 Print a parameter of the specified type.
7695 ***************************************************************************/
7697 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7703 for (i = 0; p->enum_list[i].name; i++) {
7704 if (*(int *)ptr == p->enum_list[i].value) {
7706 p->enum_list[i].name);
7713 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7717 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7721 fprintf(f, "%d", *(int *)ptr);
7725 fprintf(f, "%c", *(char *)ptr);
7729 char *o = octal_string(*(int *)ptr);
7730 fprintf(f, "%s", o);
7736 if ((char ***)ptr && *(char ***)ptr) {
7737 char **list = *(char ***)ptr;
7738 for (; *list; list++) {
7739 /* surround strings with whitespace in double quotes */
7740 if ( strchr_m( *list, ' ' ) )
7741 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7743 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7750 if (*(char **)ptr) {
7751 fprintf(f, "%s", *(char **)ptr);
7759 /***************************************************************************
7760 Check if two parameters are equal.
7761 ***************************************************************************/
7763 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7768 return (*((bool *)ptr1) == *((bool *)ptr2));
7773 return (*((int *)ptr1) == *((int *)ptr2));
7776 return (*((char *)ptr1) == *((char *)ptr2));
7779 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7784 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7789 return (p1 == p2 || strequal(p1, p2));
7797 /***************************************************************************
7798 Initialize any local varients in the sDefault table.
7799 ***************************************************************************/
7801 void init_locals(void)
7806 /***************************************************************************
7807 Process a new section (service). At this stage all sections are services.
7808 Later we'll have special sections that permit server parameters to be set.
7809 Returns True on success, False on failure.
7810 ***************************************************************************/
7812 static bool do_section(const char *pszSectionName, void *userdata)
7815 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7816 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7819 /* if we were in a global section then do the local inits */
7820 if (bInGlobalSection && !isglobal)
7823 /* if we've just struck a global section, note the fact. */
7824 bInGlobalSection = isglobal;
7826 /* check for multiple global sections */
7827 if (bInGlobalSection) {
7828 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7832 if (!bInGlobalSection && bGlobalOnly)
7835 /* if we have a current service, tidy it up before moving on */
7838 if (iServiceIndex >= 0)
7839 bRetval = service_ok(iServiceIndex);
7841 /* if all is still well, move to the next record in the services array */
7843 /* We put this here to avoid an odd message order if messages are */
7844 /* issued by the post-processing of a previous section. */
7845 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7847 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7849 DEBUG(0, ("Failed to add a new service\n"));
7858 /***************************************************************************
7859 Determine if a partcular base parameter is currentl set to the default value.
7860 ***************************************************************************/
7862 static bool is_default(int i)
7864 if (!defaults_saved)
7866 switch (parm_table[i].type) {
7868 return str_list_equal((const char **)parm_table[i].def.lvalue,
7869 *(const char ***)parm_table[i].ptr);
7872 return strequal(parm_table[i].def.svalue,
7873 *(char **)parm_table[i].ptr);
7876 return parm_table[i].def.bvalue ==
7877 *(bool *)parm_table[i].ptr;
7879 return parm_table[i].def.cvalue ==
7880 *(char *)parm_table[i].ptr;
7884 return parm_table[i].def.ivalue ==
7885 *(int *)parm_table[i].ptr;
7892 /***************************************************************************
7893 Display the contents of the global structure.
7894 ***************************************************************************/
7896 static void dump_globals(FILE *f)
7899 struct param_opt_struct *data;
7901 fprintf(f, "[global]\n");
7903 for (i = 0; parm_table[i].label; i++)
7904 if (parm_table[i].p_class == P_GLOBAL &&
7905 !(parm_table[i].flags & FLAG_META) &&
7906 parm_table[i].ptr &&
7907 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7908 if (defaults_saved && is_default(i))
7910 fprintf(f, "\t%s = ", parm_table[i].label);
7911 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7914 if (Globals.param_opt != NULL) {
7915 data = Globals.param_opt;
7917 fprintf(f, "\t%s = %s\n", data->key, data->value);
7924 /***************************************************************************
7925 Return True if a local parameter is currently set to the global default.
7926 ***************************************************************************/
7928 bool lp_is_default(int snum, struct parm_struct *parm)
7930 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7932 return equal_parameter(parm->type,
7933 ((char *)ServicePtrs[snum]) + pdiff,
7934 ((char *)&sDefault) + pdiff);
7937 /***************************************************************************
7938 Display the contents of a single services record.
7939 ***************************************************************************/
7941 static void dump_a_service(struct service *pService, FILE * f)
7944 struct param_opt_struct *data;
7946 if (pService != &sDefault)
7947 fprintf(f, "[%s]\n", pService->szService);
7949 for (i = 0; parm_table[i].label; i++) {
7951 if (parm_table[i].p_class == P_LOCAL &&
7952 !(parm_table[i].flags & FLAG_META) &&
7953 parm_table[i].ptr &&
7954 (*parm_table[i].label != '-') &&
7955 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7957 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7959 if (pService == &sDefault) {
7960 if (defaults_saved && is_default(i))
7963 if (equal_parameter(parm_table[i].type,
7964 ((char *)pService) +
7966 ((char *)&sDefault) +
7971 fprintf(f, "\t%s = ", parm_table[i].label);
7972 print_parameter(&parm_table[i],
7973 ((char *)pService) + pdiff, f);
7978 if (pService->param_opt != NULL) {
7979 data = pService->param_opt;
7981 fprintf(f, "\t%s = %s\n", data->key, data->value);
7987 /***************************************************************************
7988 Display the contents of a parameter of a single services record.
7989 ***************************************************************************/
7991 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7994 bool result = False;
7997 fstring local_parm_name;
7999 const char *parm_opt_value;
8001 /* check for parametrical option */
8002 fstrcpy( local_parm_name, parm_name);
8003 parm_opt = strchr( local_parm_name, ':');
8008 if (strlen(parm_opt)) {
8009 parm_opt_value = lp_parm_const_string( snum,
8010 local_parm_name, parm_opt, NULL);
8011 if (parm_opt_value) {
8012 printf( "%s\n", parm_opt_value);
8019 /* check for a key and print the value */
8026 for (i = 0; parm_table[i].label; i++) {
8027 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8028 !(parm_table[i].flags & FLAG_META) &&
8029 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8030 parm_table[i].ptr &&
8031 (*parm_table[i].label != '-') &&
8032 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8037 ptr = parm_table[i].ptr;
8039 struct service *pService = ServicePtrs[snum];
8040 ptr = ((char *)pService) +
8041 PTR_DIFF(parm_table[i].ptr, &sDefault);
8044 print_parameter(&parm_table[i],
8055 /***************************************************************************
8056 Return info about the requested parameter (given as a string).
8057 Return NULL when the string is not a valid parameter name.
8058 ***************************************************************************/
8060 struct parm_struct *lp_get_parameter(const char *param_name)
8062 int num = map_parameter(param_name);
8068 return &parm_table[num];
8071 /***************************************************************************
8072 Return info about the next parameter in a service.
8073 snum==GLOBAL_SECTION_SNUM gives the globals.
8074 Return NULL when out of parameters.
8075 ***************************************************************************/
8077 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8080 /* do the globals */
8081 for (; parm_table[*i].label; (*i)++) {
8082 if (parm_table[*i].p_class == P_SEPARATOR)
8083 return &parm_table[(*i)++];
8085 if (!parm_table[*i].ptr
8086 || (*parm_table[*i].label == '-'))
8090 && (parm_table[*i].ptr ==
8091 parm_table[(*i) - 1].ptr))
8094 if (is_default(*i) && !allparameters)
8097 return &parm_table[(*i)++];
8100 struct service *pService = ServicePtrs[snum];
8102 for (; parm_table[*i].label; (*i)++) {
8103 if (parm_table[*i].p_class == P_SEPARATOR)
8104 return &parm_table[(*i)++];
8106 if (parm_table[*i].p_class == P_LOCAL &&
8107 parm_table[*i].ptr &&
8108 (*parm_table[*i].label != '-') &&
8110 (parm_table[*i].ptr !=
8111 parm_table[(*i) - 1].ptr)))
8114 PTR_DIFF(parm_table[*i].ptr,
8117 if (allparameters ||
8118 !equal_parameter(parm_table[*i].type,
8119 ((char *)pService) +
8121 ((char *)&sDefault) +
8124 return &parm_table[(*i)++];
8135 /***************************************************************************
8136 Display the contents of a single copy structure.
8137 ***************************************************************************/
8138 static void dump_copy_map(bool *pcopymap)
8144 printf("\n\tNon-Copied parameters:\n");
8146 for (i = 0; parm_table[i].label; i++)
8147 if (parm_table[i].p_class == P_LOCAL &&
8148 parm_table[i].ptr && !pcopymap[i] &&
8149 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8151 printf("\t\t%s\n", parm_table[i].label);
8156 /***************************************************************************
8157 Return TRUE if the passed service number is within range.
8158 ***************************************************************************/
8160 bool lp_snum_ok(int iService)
8162 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8165 /***************************************************************************
8166 Auto-load some home services.
8167 ***************************************************************************/
8169 static void lp_add_auto_services(char *str)
8179 s = SMB_STRDUP(str);
8183 homes = lp_servicenumber(HOMES_NAME);
8185 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8186 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8189 if (lp_servicenumber(p) >= 0)
8192 home = get_user_home_dir(talloc_tos(), p);
8194 if (home && home[0] && homes >= 0)
8195 lp_add_home(p, homes, p, home);
8202 /***************************************************************************
8203 Auto-load one printer.
8204 ***************************************************************************/
8206 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8208 int printers = lp_servicenumber(PRINTERS_NAME);
8211 if (lp_servicenumber(name) < 0) {
8212 lp_add_printer(name, printers);
8213 if ((i = lp_servicenumber(name)) >= 0) {
8214 string_set(&ServicePtrs[i]->comment, comment);
8215 ServicePtrs[i]->autoloaded = True;
8220 /***************************************************************************
8221 Have we loaded a services file yet?
8222 ***************************************************************************/
8224 bool lp_loaded(void)
8229 /***************************************************************************
8230 Unload unused services.
8231 ***************************************************************************/
8233 void lp_killunused(bool (*snumused) (int))
8236 for (i = 0; i < iNumServices; i++) {
8240 /* don't kill autoloaded or usershare services */
8241 if ( ServicePtrs[i]->autoloaded ||
8242 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8246 if (!snumused || !snumused(i)) {
8247 free_service_byindex(i);
8253 * Kill all except autoloaded and usershare services - convenience wrapper
8255 void lp_kill_all_services(void)
8257 lp_killunused(NULL);
8260 /***************************************************************************
8262 ***************************************************************************/
8264 void lp_killservice(int iServiceIn)
8266 if (VALID(iServiceIn)) {
8267 free_service_byindex(iServiceIn);
8271 /***************************************************************************
8272 Save the curent values of all global and sDefault parameters into the
8273 defaults union. This allows swat and testparm to show only the
8274 changed (ie. non-default) parameters.
8275 ***************************************************************************/
8277 static void lp_save_defaults(void)
8280 for (i = 0; parm_table[i].label; i++) {
8281 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8283 switch (parm_table[i].type) {
8285 parm_table[i].def.lvalue = str_list_copy(
8286 NULL, *(const char ***)parm_table[i].ptr);
8290 if (parm_table[i].ptr) {
8291 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8293 parm_table[i].def.svalue = NULL;
8298 parm_table[i].def.bvalue =
8299 *(bool *)parm_table[i].ptr;
8302 parm_table[i].def.cvalue =
8303 *(char *)parm_table[i].ptr;
8308 parm_table[i].def.ivalue =
8309 *(int *)parm_table[i].ptr;
8315 defaults_saved = True;
8318 /*******************************************************************
8319 Set the server type we will announce as via nmbd.
8320 ********************************************************************/
8322 static const struct srv_role_tab {
8324 const char *role_str;
8325 } srv_role_tab [] = {
8326 { ROLE_STANDALONE, "ROLE_STANDALONE" },
8327 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8328 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8329 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8333 const char* server_role_str(uint32 role)
8336 for (i=0; srv_role_tab[i].role_str; i++) {
8337 if (role == srv_role_tab[i].role) {
8338 return srv_role_tab[i].role_str;
8344 static void set_server_role(void)
8346 server_role = ROLE_STANDALONE;
8348 switch (lp_security()) {
8350 if (lp_domain_logons())
8351 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8354 if (lp_domain_logons())
8355 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8356 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8357 server_role = ROLE_STANDALONE;
8360 if (lp_domain_logons()) {
8361 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8362 server_role = ROLE_DOMAIN_BDC;
8365 server_role = ROLE_DOMAIN_MEMBER;
8368 if (lp_domain_logons()) {
8369 server_role = ROLE_DOMAIN_PDC;
8372 server_role = ROLE_DOMAIN_MEMBER;
8375 if (lp_domain_logons()) {
8377 if (Globals.iDomainMaster) /* auto or yes */
8378 server_role = ROLE_DOMAIN_PDC;
8380 server_role = ROLE_DOMAIN_BDC;
8384 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8388 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8391 /***********************************************************
8392 If we should send plaintext/LANMAN passwords in the clinet
8393 ************************************************************/
8395 static void set_allowed_client_auth(void)
8397 if (Globals.bClientNTLMv2Auth) {
8398 Globals.bClientLanManAuth = False;
8400 if (!Globals.bClientLanManAuth) {
8401 Globals.bClientPlaintextAuth = False;
8405 /***************************************************************************
8407 The following code allows smbd to read a user defined share file.
8408 Yes, this is my intent. Yes, I'm comfortable with that...
8410 THE FOLLOWING IS SECURITY CRITICAL CODE.
8412 It washes your clothes, it cleans your house, it guards you while you sleep...
8413 Do not f%^k with it....
8414 ***************************************************************************/
8416 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8418 /***************************************************************************
8419 Check allowed stat state of a usershare file.
8420 Ensure we print out who is dicking with us so the admin can
8421 get their sorry ass fired.
8422 ***************************************************************************/
8424 static bool check_usershare_stat(const char *fname,
8425 const SMB_STRUCT_STAT *psbuf)
8427 if (!S_ISREG(psbuf->st_ex_mode)) {
8428 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8429 "not a regular file\n",
8430 fname, (unsigned int)psbuf->st_ex_uid ));
8434 /* Ensure this doesn't have the other write bit set. */
8435 if (psbuf->st_ex_mode & S_IWOTH) {
8436 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8437 "public write. Refusing to allow as a usershare file.\n",
8438 fname, (unsigned int)psbuf->st_ex_uid ));
8442 /* Should be 10k or less. */
8443 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8444 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8445 "too large (%u) to be a user share file.\n",
8446 fname, (unsigned int)psbuf->st_ex_uid,
8447 (unsigned int)psbuf->st_ex_size ));
8454 /***************************************************************************
8455 Parse the contents of a usershare file.
8456 ***************************************************************************/
8458 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8459 SMB_STRUCT_STAT *psbuf,
8460 const char *servicename,
8464 char **pp_sharepath,
8469 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8470 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8473 SMB_STRUCT_STAT sbuf;
8474 char *sharepath = NULL;
8475 char *comment = NULL;
8477 *pp_sharepath = NULL;
8480 *pallow_guest = False;
8483 return USERSHARE_MALFORMED_FILE;
8486 if (strcmp(lines[0], "#VERSION 1") == 0) {
8488 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8491 return USERSHARE_MALFORMED_FILE;
8494 return USERSHARE_BAD_VERSION;
8497 if (strncmp(lines[1], "path=", 5) != 0) {
8498 return USERSHARE_MALFORMED_PATH;
8501 sharepath = talloc_strdup(ctx, &lines[1][5]);
8503 return USERSHARE_POSIX_ERR;
8505 trim_string(sharepath, " ", " ");
8507 if (strncmp(lines[2], "comment=", 8) != 0) {
8508 return USERSHARE_MALFORMED_COMMENT_DEF;
8511 comment = talloc_strdup(ctx, &lines[2][8]);
8513 return USERSHARE_POSIX_ERR;
8515 trim_string(comment, " ", " ");
8516 trim_char(comment, '"', '"');
8518 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8519 return USERSHARE_MALFORMED_ACL_DEF;
8522 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8523 return USERSHARE_ACL_ERR;
8527 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8528 return USERSHARE_MALFORMED_ACL_DEF;
8530 if (lines[4][9] == 'y') {
8531 *pallow_guest = True;
8535 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8536 /* Path didn't change, no checks needed. */
8537 *pp_sharepath = sharepath;
8538 *pp_comment = comment;
8539 return USERSHARE_OK;
8542 /* The path *must* be absolute. */
8543 if (sharepath[0] != '/') {
8544 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8545 servicename, sharepath));
8546 return USERSHARE_PATH_NOT_ABSOLUTE;
8549 /* If there is a usershare prefix deny list ensure one of these paths
8550 doesn't match the start of the user given path. */
8551 if (prefixdenylist) {
8553 for ( i=0; prefixdenylist[i]; i++ ) {
8554 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8555 servicename, i, prefixdenylist[i], sharepath ));
8556 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8557 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8558 "usershare prefix deny list entries.\n",
8559 servicename, sharepath));
8560 return USERSHARE_PATH_IS_DENIED;
8565 /* If there is a usershare prefix allow list ensure one of these paths
8566 does match the start of the user given path. */
8568 if (prefixallowlist) {
8570 for ( i=0; prefixallowlist[i]; i++ ) {
8571 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8572 servicename, i, prefixallowlist[i], sharepath ));
8573 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8577 if (prefixallowlist[i] == NULL) {
8578 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8579 "usershare prefix allow list entries.\n",
8580 servicename, sharepath));
8581 return USERSHARE_PATH_NOT_ALLOWED;
8585 /* Ensure this is pointing to a directory. */
8586 dp = sys_opendir(sharepath);
8589 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8590 servicename, sharepath));
8591 return USERSHARE_PATH_NOT_DIRECTORY;
8594 /* Ensure the owner of the usershare file has permission to share
8597 if (sys_stat(sharepath, &sbuf, false) == -1) {
8598 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8599 servicename, sharepath, strerror(errno) ));
8601 return USERSHARE_POSIX_ERR;
8606 if (!S_ISDIR(sbuf.st_ex_mode)) {
8607 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8608 servicename, sharepath ));
8609 return USERSHARE_PATH_NOT_DIRECTORY;
8612 /* Check if sharing is restricted to owner-only. */
8613 /* psbuf is the stat of the usershare definition file,
8614 sbuf is the stat of the target directory to be shared. */
8616 if (lp_usershare_owner_only()) {
8617 /* root can share anything. */
8618 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8619 return USERSHARE_PATH_NOT_ALLOWED;
8623 *pp_sharepath = sharepath;
8624 *pp_comment = comment;
8625 return USERSHARE_OK;
8628 /***************************************************************************
8629 Deal with a usershare file.
8632 -1 - Bad name, invalid contents.
8633 - service name already existed and not a usershare, problem
8634 with permissions to share directory etc.
8635 ***************************************************************************/
8637 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8639 SMB_STRUCT_STAT sbuf;
8640 SMB_STRUCT_STAT lsbuf;
8642 char *sharepath = NULL;
8643 char *comment = NULL;
8644 fstring service_name;
8645 char **lines = NULL;
8649 TALLOC_CTX *ctx = NULL;
8650 SEC_DESC *psd = NULL;
8651 bool guest_ok = False;
8653 /* Ensure share name doesn't contain invalid characters. */
8654 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8655 DEBUG(0,("process_usershare_file: share name %s contains "
8656 "invalid characters (any of %s)\n",
8657 file_name, INVALID_SHARENAME_CHARS ));
8661 fstrcpy(service_name, file_name);
8663 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8666 /* Minimize the race condition by doing an lstat before we
8667 open and fstat. Ensure this isn't a symlink link. */
8669 if (sys_lstat(fname, &lsbuf, false) != 0) {
8670 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8671 fname, strerror(errno) ));
8676 /* This must be a regular file, not a symlink, directory or
8677 other strange filetype. */
8678 if (!check_usershare_stat(fname, &lsbuf)) {
8684 char *canon_name = canonicalize_servicename(service_name);
8685 TDB_DATA data = dbwrap_fetch_bystring(
8686 ServiceHash, canon_name, canon_name);
8690 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8691 iService = *(int *)data.dptr;
8693 TALLOC_FREE(canon_name);
8696 if (iService != -1 &&
8697 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8698 &lsbuf.st_ex_mtime) == 0) {
8699 /* Nothing changed - Mark valid and return. */
8700 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8702 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8707 /* Try and open the file read only - no symlinks allowed. */
8709 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8711 fd = sys_open(fname, O_RDONLY, 0);
8715 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8716 fname, strerror(errno) ));
8721 /* Now fstat to be *SURE* it's a regular file. */
8722 if (sys_fstat(fd, &sbuf, false) != 0) {
8724 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8725 fname, strerror(errno) ));
8730 /* Is it the same dev/inode as was lstated ? */
8731 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8733 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8734 "Symlink spoofing going on ?\n", fname ));
8739 /* This must be a regular file, not a symlink, directory or
8740 other strange filetype. */
8741 if (!check_usershare_stat(fname, &sbuf)) {
8746 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8749 if (lines == NULL) {
8750 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8751 fname, (unsigned int)sbuf.st_ex_uid ));
8758 /* Should we allow printers to be shared... ? */
8759 ctx = talloc_init("usershare_sd_xctx");
8765 if (parse_usershare_file(ctx, &sbuf, service_name,
8766 iService, lines, numlines, &sharepath,
8767 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8768 talloc_destroy(ctx);
8775 /* Everything ok - add the service possibly using a template. */
8777 const struct service *sp = &sDefault;
8778 if (snum_template != -1) {
8779 sp = ServicePtrs[snum_template];
8782 if ((iService = add_a_service(sp, service_name)) < 0) {
8783 DEBUG(0, ("process_usershare_file: Failed to add "
8784 "new service %s\n", service_name));
8785 talloc_destroy(ctx);
8789 /* Read only is controlled by usershare ACL below. */
8790 ServicePtrs[iService]->bRead_only = False;
8793 /* Write the ACL of the new/modified share. */
8794 if (!set_share_security(service_name, psd)) {
8795 DEBUG(0, ("process_usershare_file: Failed to set share "
8796 "security for user share %s\n",
8798 lp_remove_service(iService);
8799 talloc_destroy(ctx);
8803 /* If from a template it may be marked invalid. */
8804 ServicePtrs[iService]->valid = True;
8806 /* Set the service as a valid usershare. */
8807 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8809 /* Set guest access. */
8810 if (lp_usershare_allow_guests()) {
8811 ServicePtrs[iService]->bGuest_ok = guest_ok;
8814 /* And note when it was loaded. */
8815 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8816 string_set(&ServicePtrs[iService]->szPath, sharepath);
8817 string_set(&ServicePtrs[iService]->comment, comment);
8819 talloc_destroy(ctx);
8824 /***************************************************************************
8825 Checks if a usershare entry has been modified since last load.
8826 ***************************************************************************/
8828 static bool usershare_exists(int iService, struct timespec *last_mod)
8830 SMB_STRUCT_STAT lsbuf;
8831 const char *usersharepath = Globals.szUsersharePath;
8834 if (asprintf(&fname, "%s/%s",
8836 ServicePtrs[iService]->szService) < 0) {
8840 if (sys_lstat(fname, &lsbuf, false) != 0) {
8845 if (!S_ISREG(lsbuf.st_ex_mode)) {
8851 *last_mod = lsbuf.st_ex_mtime;
8855 /***************************************************************************
8856 Load a usershare service by name. Returns a valid servicenumber or -1.
8857 ***************************************************************************/
8859 int load_usershare_service(const char *servicename)
8861 SMB_STRUCT_STAT sbuf;
8862 const char *usersharepath = Globals.szUsersharePath;
8863 int max_user_shares = Globals.iUsershareMaxShares;
8864 int snum_template = -1;
8866 if (*usersharepath == 0 || max_user_shares == 0) {
8870 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8871 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8872 usersharepath, strerror(errno) ));
8876 if (!S_ISDIR(sbuf.st_ex_mode)) {
8877 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8883 * This directory must be owned by root, and have the 't' bit set.
8884 * It also must not be writable by "other".
8888 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8890 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8892 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8893 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8898 /* Ensure the template share exists if it's set. */
8899 if (Globals.szUsershareTemplateShare[0]) {
8900 /* We can't use lp_servicenumber here as we are recommending that
8901 template shares have -valid=False set. */
8902 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8903 if (ServicePtrs[snum_template]->szService &&
8904 strequal(ServicePtrs[snum_template]->szService,
8905 Globals.szUsershareTemplateShare)) {
8910 if (snum_template == -1) {
8911 DEBUG(0,("load_usershare_service: usershare template share %s "
8912 "does not exist.\n",
8913 Globals.szUsershareTemplateShare ));
8918 return process_usershare_file(usersharepath, servicename, snum_template);
8921 /***************************************************************************
8922 Load all user defined shares from the user share directory.
8923 We only do this if we're enumerating the share list.
8924 This is the function that can delete usershares that have
8926 ***************************************************************************/
8928 int load_usershare_shares(void)
8931 SMB_STRUCT_STAT sbuf;
8932 SMB_STRUCT_DIRENT *de;
8933 int num_usershares = 0;
8934 int max_user_shares = Globals.iUsershareMaxShares;
8935 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8936 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8937 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8939 int snum_template = -1;
8940 const char *usersharepath = Globals.szUsersharePath;
8941 int ret = lp_numservices();
8943 if (max_user_shares == 0 || *usersharepath == '\0') {
8944 return lp_numservices();
8947 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8948 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8949 usersharepath, strerror(errno) ));
8954 * This directory must be owned by root, and have the 't' bit set.
8955 * It also must not be writable by "other".
8959 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8961 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8963 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8964 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8969 /* Ensure the template share exists if it's set. */
8970 if (Globals.szUsershareTemplateShare[0]) {
8971 /* We can't use lp_servicenumber here as we are recommending that
8972 template shares have -valid=False set. */
8973 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8974 if (ServicePtrs[snum_template]->szService &&
8975 strequal(ServicePtrs[snum_template]->szService,
8976 Globals.szUsershareTemplateShare)) {
8981 if (snum_template == -1) {
8982 DEBUG(0,("load_usershare_shares: usershare template share %s "
8983 "does not exist.\n",
8984 Globals.szUsershareTemplateShare ));
8989 /* Mark all existing usershares as pending delete. */
8990 for (iService = iNumServices - 1; iService >= 0; iService--) {
8991 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8992 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8996 dp = sys_opendir(usersharepath);
8998 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8999 usersharepath, strerror(errno) ));
9003 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9004 (de = sys_readdir(dp));
9005 num_dir_entries++ ) {
9007 const char *n = de->d_name;
9009 /* Ignore . and .. */
9011 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9017 /* Temporary file used when creating a share. */
9018 num_tmp_dir_entries++;
9021 /* Allow 20% tmp entries. */
9022 if (num_tmp_dir_entries > allowed_tmp_entries) {
9023 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9024 "in directory %s\n",
9025 num_tmp_dir_entries, usersharepath));
9029 r = process_usershare_file(usersharepath, n, snum_template);
9031 /* Update the services count. */
9033 if (num_usershares >= max_user_shares) {
9034 DEBUG(0,("load_usershare_shares: max user shares reached "
9035 "on file %s in directory %s\n",
9036 n, usersharepath ));
9039 } else if (r == -1) {
9040 num_bad_dir_entries++;
9043 /* Allow 20% bad entries. */
9044 if (num_bad_dir_entries > allowed_bad_entries) {
9045 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9046 "in directory %s\n",
9047 num_bad_dir_entries, usersharepath));
9051 /* Allow 20% bad entries. */
9052 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9053 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9054 "in directory %s\n",
9055 num_dir_entries, usersharepath));
9062 /* Sweep through and delete any non-refreshed usershares that are
9063 not currently in use. */
9064 for (iService = iNumServices - 1; iService >= 0; iService--) {
9065 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9066 if (conn_snum_used(iService)) {
9069 /* Remove from the share ACL db. */
9070 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9071 lp_servicename(iService) ));
9072 delete_share_security(lp_servicename(iService));
9073 free_service_byindex(iService);
9077 return lp_numservices();
9080 /********************************************************
9081 Destroy global resources allocated in this file
9082 ********************************************************/
9084 void gfree_loadparm(void)
9090 /* Free resources allocated to services */
9092 for ( i = 0; i < iNumServices; i++ ) {
9094 free_service_byindex(i);
9098 SAFE_FREE( ServicePtrs );
9101 /* Now release all resources allocated to global
9102 parameters and the default service */
9104 free_global_parameters();
9108 /***************************************************************************
9109 Allow client apps to specify that they are a client
9110 ***************************************************************************/
9111 void lp_set_in_client(bool b)
9117 /***************************************************************************
9118 Determine if we're running in a client app
9119 ***************************************************************************/
9120 bool lp_is_in_client(void)
9125 /***************************************************************************
9126 Load the services array from the services file. Return True on success,
9128 ***************************************************************************/
9130 bool lp_load_ex(const char *pszFname,
9134 bool initialize_globals,
9135 bool allow_include_registry,
9136 bool allow_registry_shares)
9143 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9145 bInGlobalSection = True;
9146 bGlobalOnly = global_only;
9147 bAllowIncludeRegistry = allow_include_registry;
9149 init_globals(! initialize_globals);
9154 if (save_defaults) {
9159 free_param_opts(&Globals.param_opt);
9161 /* We get sections first, so have to start 'behind' to make up */
9164 if (lp_config_backend_is_file()) {
9165 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9166 current_user_info.domain,
9169 smb_panic("lp_load_ex: out of memory");
9172 add_to_file_list(pszFname, n2);
9174 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9177 /* finish up the last section */
9178 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9180 if (iServiceIndex >= 0) {
9181 bRetval = service_ok(iServiceIndex);
9185 if (lp_config_backend_is_registry()) {
9186 /* config backend changed to registry in config file */
9188 * We need to use this extra global variable here to
9189 * survive restart: init_globals uses this as a default
9190 * for ConfigBackend. Otherwise, init_globals would
9191 * send us into an endless loop here.
9193 config_backend = CONFIG_BACKEND_REGISTRY;
9195 DEBUG(1, ("lp_load_ex: changing to config backend "
9197 init_globals(false);
9198 lp_kill_all_services();
9199 return lp_load_ex(pszFname, global_only, save_defaults,
9200 add_ipc, initialize_globals,
9201 allow_include_registry,
9202 allow_registry_shares);
9204 } else if (lp_config_backend_is_registry()) {
9205 bRetval = process_registry_globals();
9207 DEBUG(0, ("Illegal config backend given: %d\n",
9208 lp_config_backend()));
9212 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9213 bRetval = process_registry_shares();
9216 lp_add_auto_services(lp_auto_services());
9219 /* When 'restrict anonymous = 2' guest connections to ipc$
9221 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9222 if ( lp_enable_asu_support() ) {
9223 lp_add_ipc("ADMIN$", false);
9228 set_default_server_announce_type();
9229 set_allowed_client_auth();
9233 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9234 /* if bWINSsupport is true and we are in the client */
9235 if (lp_is_in_client() && Globals.bWINSsupport) {
9236 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9241 bAllowIncludeRegistry = true;
9246 bool lp_load(const char *pszFname,
9250 bool initialize_globals)
9252 return lp_load_ex(pszFname,
9260 bool lp_load_initial_only(const char *pszFname)
9262 return lp_load_ex(pszFname,
9271 bool lp_load_with_registry_shares(const char *pszFname,
9275 bool initialize_globals)
9277 return lp_load_ex(pszFname,
9286 /***************************************************************************
9287 Return the max number of services.
9288 ***************************************************************************/
9290 int lp_numservices(void)
9292 return (iNumServices);
9295 /***************************************************************************
9296 Display the contents of the services array in human-readable form.
9297 ***************************************************************************/
9299 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9304 defaults_saved = False;
9308 dump_a_service(&sDefault, f);
9310 for (iService = 0; iService < maxtoprint; iService++) {
9312 lp_dump_one(f, show_defaults, iService);
9316 /***************************************************************************
9317 Display the contents of one service in human-readable form.
9318 ***************************************************************************/
9320 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9323 if (ServicePtrs[snum]->szService[0] == '\0')
9325 dump_a_service(ServicePtrs[snum], f);
9329 /***************************************************************************
9330 Return the number of the service with the given name, or -1 if it doesn't
9331 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9332 getservicebyname()! This works ONLY if all services have been loaded, and
9333 does not copy the found service.
9334 ***************************************************************************/
9336 int lp_servicenumber(const char *pszServiceName)
9339 fstring serviceName;
9341 if (!pszServiceName) {
9342 return GLOBAL_SECTION_SNUM;
9345 for (iService = iNumServices - 1; iService >= 0; iService--) {
9346 if (VALID(iService) && ServicePtrs[iService]->szService) {
9348 * The substitution here is used to support %U is
9351 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9352 standard_sub_basic(get_current_username(),
9353 current_user_info.domain,
9354 serviceName,sizeof(serviceName));
9355 if (strequal(serviceName, pszServiceName)) {
9361 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9362 struct timespec last_mod;
9364 if (!usershare_exists(iService, &last_mod)) {
9365 /* Remove the share security tdb entry for it. */
9366 delete_share_security(lp_servicename(iService));
9367 /* Remove it from the array. */
9368 free_service_byindex(iService);
9369 /* Doesn't exist anymore. */
9370 return GLOBAL_SECTION_SNUM;
9373 /* Has it been modified ? If so delete and reload. */
9374 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9376 /* Remove it from the array. */
9377 free_service_byindex(iService);
9378 /* and now reload it. */
9379 iService = load_usershare_service(pszServiceName);
9384 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9385 return GLOBAL_SECTION_SNUM;
9391 bool share_defined(const char *service_name)
9393 return (lp_servicenumber(service_name) != -1);
9396 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9397 const char *sharename)
9399 struct share_params *result;
9403 if (!(sname = SMB_STRDUP(sharename))) {
9407 snum = find_service(sname);
9414 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9415 DEBUG(0, ("talloc failed\n"));
9419 result->service = snum;
9423 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9425 struct share_iterator *result;
9427 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9428 DEBUG(0, ("talloc failed\n"));
9432 result->next_id = 0;
9436 struct share_params *next_share(struct share_iterator *list)
9438 struct share_params *result;
9440 while (!lp_snum_ok(list->next_id) &&
9441 (list->next_id < lp_numservices())) {
9445 if (list->next_id >= lp_numservices()) {
9449 if (!(result = TALLOC_P(list, struct share_params))) {
9450 DEBUG(0, ("talloc failed\n"));
9454 result->service = list->next_id;
9459 struct share_params *next_printer(struct share_iterator *list)
9461 struct share_params *result;
9463 while ((result = next_share(list)) != NULL) {
9464 if (lp_print_ok(result->service)) {
9472 * This is a hack for a transition period until we transformed all code from
9473 * service numbers to struct share_params.
9476 struct share_params *snum2params_static(int snum)
9478 static struct share_params result;
9479 result.service = snum;
9483 /*******************************************************************
9484 A useful volume label function.
9485 ********************************************************************/
9487 const char *volume_label(int snum)
9490 const char *label = lp_volume(snum);
9492 label = lp_servicename(snum);
9495 /* This returns a 33 byte guarenteed null terminated string. */
9496 ret = talloc_strndup(talloc_tos(), label, 32);
9503 /*******************************************************************
9504 Set the server type we will announce as via nmbd.
9505 ********************************************************************/
9507 static void set_default_server_announce_type(void)
9509 default_server_announce = 0;
9510 default_server_announce |= SV_TYPE_WORKSTATION;
9511 default_server_announce |= SV_TYPE_SERVER;
9512 default_server_announce |= SV_TYPE_SERVER_UNIX;
9514 /* note that the flag should be set only if we have a
9515 printer service but nmbd doesn't actually load the
9516 services so we can't tell --jerry */
9518 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9520 switch (lp_announce_as()) {
9521 case ANNOUNCE_AS_NT_SERVER:
9522 default_server_announce |= SV_TYPE_SERVER_NT;
9523 /* fall through... */
9524 case ANNOUNCE_AS_NT_WORKSTATION:
9525 default_server_announce |= SV_TYPE_NT;
9527 case ANNOUNCE_AS_WIN95:
9528 default_server_announce |= SV_TYPE_WIN95_PLUS;
9530 case ANNOUNCE_AS_WFW:
9531 default_server_announce |= SV_TYPE_WFW;
9537 switch (lp_server_role()) {
9538 case ROLE_DOMAIN_MEMBER:
9539 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9541 case ROLE_DOMAIN_PDC:
9542 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9544 case ROLE_DOMAIN_BDC:
9545 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9547 case ROLE_STANDALONE:
9551 if (lp_time_server())
9552 default_server_announce |= SV_TYPE_TIME_SOURCE;
9554 if (lp_host_msdfs())
9555 default_server_announce |= SV_TYPE_DFS_SERVER;
9558 /***********************************************************
9559 returns role of Samba server
9560 ************************************************************/
9562 int lp_server_role(void)
9567 /***********************************************************
9568 If we are PDC then prefer us as DMB
9569 ************************************************************/
9571 bool lp_domain_master(void)
9573 if (Globals.iDomainMaster == Auto)
9574 return (lp_server_role() == ROLE_DOMAIN_PDC);
9576 return (bool)Globals.iDomainMaster;
9579 /***********************************************************
9580 If we are DMB then prefer us as LMB
9581 ************************************************************/
9583 bool lp_preferred_master(void)
9585 if (Globals.iPreferredMaster == Auto)
9586 return (lp_local_master() && lp_domain_master());
9588 return (bool)Globals.iPreferredMaster;
9591 /*******************************************************************
9593 ********************************************************************/
9595 void lp_remove_service(int snum)
9597 ServicePtrs[snum]->valid = False;
9598 invalid_services[num_invalid_services++] = snum;
9601 /*******************************************************************
9603 ********************************************************************/
9605 void lp_copy_service(int snum, const char *new_name)
9607 do_section(new_name, NULL);
9609 snum = lp_servicenumber(new_name);
9611 lp_do_parameter(snum, "copy", lp_servicename(snum));
9616 /*******************************************************************
9617 Get the default server type we will announce as via nmbd.
9618 ********************************************************************/
9620 int lp_default_server_announce(void)
9622 return default_server_announce;
9625 /*******************************************************************
9626 Split the announce version into major and minor numbers.
9627 ********************************************************************/
9629 int lp_major_announce_version(void)
9631 static bool got_major = False;
9632 static int major_version = DEFAULT_MAJOR_VERSION;
9637 return major_version;
9640 if ((vers = lp_announce_version()) == NULL)
9641 return major_version;
9643 if ((p = strchr_m(vers, '.')) == 0)
9644 return major_version;
9647 major_version = atoi(vers);
9648 return major_version;
9651 int lp_minor_announce_version(void)
9653 static bool got_minor = False;
9654 static int minor_version = DEFAULT_MINOR_VERSION;
9659 return minor_version;
9662 if ((vers = lp_announce_version()) == NULL)
9663 return minor_version;
9665 if ((p = strchr_m(vers, '.')) == 0)
9666 return minor_version;
9669 minor_version = atoi(p);
9670 return minor_version;
9673 /***********************************************************
9674 Set the global name resolution order (used in smbclient).
9675 ************************************************************/
9677 void lp_set_name_resolve_order(const char *new_order)
9679 string_set(&Globals.szNameResolveOrder, new_order);
9682 const char *lp_printername(int snum)
9684 const char *ret = _lp_printername(snum);
9685 if (ret == NULL || (ret != NULL && *ret == '\0'))
9686 ret = lp_const_servicename(snum);
9692 /***********************************************************
9693 Allow daemons such as winbindd to fix their logfile name.
9694 ************************************************************/
9696 void lp_set_logfile(const char *name)
9698 string_set(&Globals.szLogFile, name);
9699 debug_set_logfile(name);
9702 /*******************************************************************
9703 Return the max print jobs per queue.
9704 ********************************************************************/
9706 int lp_maxprintjobs(int snum)
9708 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9709 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9710 maxjobs = PRINT_MAX_JOBID - 1;
9715 const char *lp_printcapname(void)
9717 if ((Globals.szPrintcapname != NULL) &&
9718 (Globals.szPrintcapname[0] != '\0'))
9719 return Globals.szPrintcapname;
9721 if (sDefault.iPrinting == PRINT_CUPS) {
9729 if (sDefault.iPrinting == PRINT_BSD)
9730 return "/etc/printcap";
9732 return PRINTCAP_NAME;
9735 static uint32 spoolss_state;
9737 bool lp_disable_spoolss( void )
9739 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9740 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9742 return spoolss_state == SVCCTL_STOPPED ? True : False;
9745 void lp_set_spoolss_state( uint32 state )
9747 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9749 spoolss_state = state;
9752 uint32 lp_get_spoolss_state( void )
9754 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9757 /*******************************************************************
9758 Ensure we don't use sendfile if server smb signing is active.
9759 ********************************************************************/
9761 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9763 bool sign_active = false;
9765 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9766 if (get_Protocol() < PROTOCOL_NT1) {
9769 if (signing_state) {
9770 sign_active = smb_signing_is_active(signing_state);
9772 return (_lp_use_sendfile(snum) &&
9773 (get_remote_arch() != RA_WIN95) &&
9777 /*******************************************************************
9778 Turn off sendfile if we find the underlying OS doesn't support it.
9779 ********************************************************************/
9781 void set_use_sendfile(int snum, bool val)
9783 if (LP_SNUM_OK(snum))
9784 ServicePtrs[snum]->bUseSendfile = val;
9786 sDefault.bUseSendfile = val;
9789 /*******************************************************************
9790 Turn off storing DOS attributes if this share doesn't support it.
9791 ********************************************************************/
9793 void set_store_dos_attributes(int snum, bool val)
9795 if (!LP_SNUM_OK(snum))
9797 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9800 void lp_set_mangling_method(const char *new_method)
9802 string_set(&Globals.szManglingMethod, new_method);
9805 /*******************************************************************
9806 Global state for POSIX pathname processing.
9807 ********************************************************************/
9809 static bool posix_pathnames;
9811 bool lp_posix_pathnames(void)
9813 return posix_pathnames;
9816 /*******************************************************************
9817 Change everything needed to ensure POSIX pathname processing (currently
9819 ********************************************************************/
9821 void lp_set_posix_pathnames(void)
9823 posix_pathnames = True;
9826 /*******************************************************************
9827 Global state for POSIX lock processing - CIFS unix extensions.
9828 ********************************************************************/
9830 bool posix_default_lock_was_set;
9831 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9833 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9835 if (posix_default_lock_was_set) {
9836 return posix_cifsx_locktype;
9838 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9842 /*******************************************************************
9843 ********************************************************************/
9845 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9847 posix_default_lock_was_set = True;
9848 posix_cifsx_locktype = val;
9851 int lp_min_receive_file_size(void)
9853 if (Globals.iminreceivefile < 0) {
9856 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9859 /*******************************************************************
9860 If socket address is an empty character string, it is necessary to
9861 define it as "0.0.0.0".
9862 ********************************************************************/
9864 const char *lp_socket_address(void)
9866 char *sock_addr = Globals.szSocketAddress;
9868 if (sock_addr[0] == '\0'){
9869 string_set(&Globals.szSocketAddress, "0.0.0.0");
9871 return Globals.szSocketAddress;
9874 void lp_set_passdb_backend(const char *backend)
9876 string_set(&Globals.szPassdbBackend, backend);