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
59 extern enum protocol_types Protocol;
60 extern userdom_struct current_user_info;
63 #define GLOBAL_NAME "global"
67 #define PRINTERS_NAME "printers"
71 #define HOMES_NAME "homes"
74 /* the special value for the include parameter
75 * to be interpreted not as a file name but to
76 * trigger loading of the global smb.conf options
78 #ifndef INCLUDE_REGISTRY_NAME
79 #define INCLUDE_REGISTRY_NAME "registry"
82 static bool in_client = False; /* Not in the client by default */
83 static struct smbconf_csn conf_last_csn;
85 #define CONFIG_BACKEND_FILE 0
86 #define CONFIG_BACKEND_REGISTRY 1
88 static int config_backend = CONFIG_BACKEND_FILE;
90 /* some helpful bits */
91 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
92 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
94 #define USERSHARE_VALID 1
95 #define USERSHARE_PENDING_DELETE 2
97 static bool defaults_saved = False;
99 struct param_opt_struct {
100 struct param_opt_struct *prev, *next;
107 * This structure describes global (ie., server-wide) parameters.
114 char *display_charset;
115 char *szPrintcapname;
116 char *szAddPortCommand;
117 char *szEnumPortsCommand;
118 char *szAddPrinterCommand;
119 char *szDeletePrinterCommand;
120 char *szOs2DriverMap;
126 char *szDefaultService;
130 char *szServerString;
131 char *szAutoServices;
132 char *szPasswdProgram;
136 char *szSMBPasswdFile;
138 char *szPassdbBackend;
139 char **szPreloadModules;
140 char *szPasswordServer;
141 char *szSocketOptions;
143 char *szAfsUsernameMap;
144 int iAfsTokenLifetime;
145 char *szLogNtTokenCommand;
151 char **szWINSservers;
153 char *szRemoteAnnounce;
154 char *szRemoteBrowseSync;
155 char *szSocketAddress;
156 char *szNISHomeMapName;
157 char *szAnnounceVersion; /* This is initialised in init_globals */
160 char **szNetbiosAliases;
161 char *szNetbiosScope;
162 char *szNameResolveOrder;
164 char *szAddUserScript;
165 char *szRenameUserScript;
166 char *szDelUserScript;
167 char *szAddGroupScript;
168 char *szDelGroupScript;
169 char *szAddUserToGroupScript;
170 char *szDelUserFromGroupScript;
171 char *szSetPrimaryGroupScript;
172 char *szAddMachineScript;
173 char *szShutdownScript;
174 char *szAbortShutdownScript;
175 char *szUsernameMapScript;
176 char *szCheckPasswordScript;
183 bool bPassdbExpandExplicit;
184 int AlgorithmicRidBase;
185 char *szTemplateHomedir;
186 char *szTemplateShell;
187 char *szWinbindSeparator;
188 bool bWinbindEnumUsers;
189 bool bWinbindEnumGroups;
190 bool bWinbindUseDefaultDomain;
191 bool bWinbindTrustedDomainsOnly;
192 bool bWinbindNestedGroups;
193 int winbind_expand_groups;
194 bool bWinbindRefreshTickets;
195 bool bWinbindOfflineLogon;
196 bool bWinbindNormalizeNames;
197 bool bWinbindRpcOnly;
198 char *szIdmapBackend;
199 char *szIdmapAllocBackend;
200 char *szAddShareCommand;
201 char *szChangeShareCommand;
202 char *szDeleteShareCommand;
204 char *szGuestaccount;
205 char *szManglingMethod;
206 char **szServicesList;
207 char *szUsersharePath;
208 char *szUsershareTemplateShare;
209 char **szUsersharePrefixAllowList;
210 char **szUsersharePrefixDenyList;
217 int open_files_db_hash_size;
226 bool paranoid_server_security;
229 int iMaxSmbdProcesses;
230 bool bDisableSpoolss;
233 bool enhanced_browsing;
239 int announce_as; /* This is initialised in init_globals */
240 int machine_password_timeout;
242 int oplock_break_wait_time;
243 int winbind_cache_time;
244 int winbind_reconnect_delay;
245 int winbind_max_idle_children;
246 char **szWinbindNssInfo;
248 char *szLdapMachineSuffix;
249 char *szLdapUserSuffix;
250 char *szLdapIdmapSuffix;
251 char *szLdapGroupSuffix;
256 int ldap_debug_level;
257 int ldap_debug_threshold;
260 char *szIPrintServer;
262 char **szClusterAddresses;
264 int ldap_passwd_sync;
265 int ldap_replication_sleep;
266 int ldap_timeout; /* This is initialised in init_globals */
267 int ldap_connection_timeout;
270 bool bMsAddPrinterWizard;
275 int iPreferredMaster;
278 char **szInitLogonDelayedHosts;
280 bool bEncryptPasswords;
285 bool bObeyPamRestrictions;
287 int PrintcapCacheTime;
288 bool bLargeReadwrite;
295 bool bBindInterfacesOnly;
296 bool bPamPasswordChange;
297 bool bUnixPasswdSync;
298 bool bPasswdChatDebug;
299 int iPasswdChatTimeout;
303 bool bNTStatusSupport;
305 int iMaxStatCacheSize;
307 bool bAllowTrustedDomains;
311 bool bClientLanManAuth;
312 bool bClientNTLMv2Auth;
313 bool bClientPlaintextAuth;
314 bool bClientUseSpnego;
315 bool bDebugPrefixTimestamp;
316 bool bDebugHiresTimestamp;
320 bool bEnableCoreFiles;
323 bool bHostnameLookups;
324 bool bUnixExtensions;
325 bool bDisableNetbios;
326 char * szDedicatedKeytabFile;
328 bool bDeferSharingViolations;
329 bool bEnablePrivileges;
331 bool bUsershareOwnerOnly;
332 bool bUsershareAllowGuests;
333 bool bRegistryShares;
334 int restrict_anonymous;
335 int name_cache_timeout;
338 int client_ldap_sasl_wrapping;
339 int iUsershareMaxShares;
341 int iIdmapNegativeCacheTime;
345 struct param_opt_struct *param_opt;
346 int cups_connection_timeout;
347 char *szSMBPerfcountModule;
348 bool bMapUntrustedToDomain;
351 static struct global Globals;
354 * This structure describes a single service.
360 time_t usershare_last_mod;
364 char **szInvalidUsers;
372 char *szRootPostExec;
374 char *szPrintcommand;
377 char *szLppausecommand;
378 char *szLpresumecommand;
379 char *szQueuepausecommand;
380 char *szQueueresumecommand;
382 char *szPrintjobUsername;
390 char *szVetoOplockFiles;
396 char **printer_admin;
401 char *szAioWriteBehind;
405 int iMaxReportedPrintJobs;
408 int iCreate_force_mode;
410 int iSecurity_force_mode;
413 int iDir_Security_mask;
414 int iDir_Security_force_mode;
418 int iOplockContentionLimit;
423 bool bRootpreexecClose;
426 bool bShortCasePreserve;
428 bool bHideSpecialFiles;
429 bool bHideUnReadable;
430 bool bHideUnWriteableFiles;
432 bool bAccessBasedShareEnum;
437 bool bAdministrative_share;
443 bool bStoreDosAttributes;
456 bool bStrictAllocate;
459 struct bitmap *copymap;
460 bool bDeleteReadonly;
462 bool bDeleteVetoFiles;
465 bool bDosFiletimeResolution;
466 bool bFakeDirCreateTimes;
472 bool bUseClientDriver;
473 bool bDefaultDevmode;
474 bool bForcePrintername;
476 bool bForceUnknownAclUser;
479 bool bMap_acl_inherit;
482 bool bAclCheckPermissions;
483 bool bAclMapFullControl;
484 bool bAclGroupControl;
486 bool bKernelChangeNotify;
487 int iallocation_roundup_size;
491 int iDirectoryNameCacheSize;
493 struct param_opt_struct *param_opt;
495 char dummy[3]; /* for alignment */
499 /* This is a default service used to prime a services structure */
500 static struct service sDefault = {
502 False, /* not autoloaded */
503 0, /* not a usershare */
504 (time_t)0, /* No last mod time */
505 NULL, /* szService */
507 NULL, /* szUsername */
508 NULL, /* szInvalidUsers */
509 NULL, /* szValidUsers */
510 NULL, /* szAdminUsers */
512 NULL, /* szInclude */
513 NULL, /* szPreExec */
514 NULL, /* szPostExec */
515 NULL, /* szRootPreExec */
516 NULL, /* szRootPostExec */
517 NULL, /* szCupsOptions */
518 NULL, /* szPrintcommand */
519 NULL, /* szLpqcommand */
520 NULL, /* szLprmcommand */
521 NULL, /* szLppausecommand */
522 NULL, /* szLpresumecommand */
523 NULL, /* szQueuepausecommand */
524 NULL, /* szQueueresumecommand */
525 NULL, /* szPrintername */
526 NULL, /* szPrintjobUsername */
527 NULL, /* szDontdescend */
528 NULL, /* szHostsallow */
529 NULL, /* szHostsdeny */
530 NULL, /* szMagicScript */
531 NULL, /* szMagicOutput */
532 NULL, /* szVetoFiles */
533 NULL, /* szHideFiles */
534 NULL, /* szVetoOplockFiles */
536 NULL, /* force user */
537 NULL, /* force group */
539 NULL, /* writelist */
540 NULL, /* printer admin */
543 NULL, /* vfs objects */
544 NULL, /* szMSDfsProxy */
545 NULL, /* szAioWriteBehind */
547 0, /* iMinPrintSpace */
548 1000, /* iMaxPrintJobs */
549 0, /* iMaxReportedPrintJobs */
550 0, /* iWriteCacheSize */
551 0744, /* iCreate_mask */
552 0000, /* iCreate_force_mode */
553 0777, /* iSecurity_mask */
554 0, /* iSecurity_force_mode */
555 0755, /* iDir_mask */
556 0000, /* iDir_force_mode */
557 0777, /* iDir_Security_mask */
558 0, /* iDir_Security_force_mode */
559 0, /* iMaxConnections */
560 CASE_LOWER, /* iDefaultCase */
561 DEFAULT_PRINTING, /* iPrinting */
562 2, /* iOplockContentionLimit */
564 1024, /* iBlock_size */
565 0, /* iDfreeCacheTime */
566 False, /* bPreexecClose */
567 False, /* bRootpreexecClose */
568 Auto, /* case sensitive */
569 True, /* case preserve */
570 True, /* short case preserve */
571 True, /* bHideDotFiles */
572 False, /* bHideSpecialFiles */
573 False, /* bHideUnReadable */
574 False, /* bHideUnWriteableFiles */
575 True, /* bBrowseable */
576 False, /* bAccessBasedShareEnum */
577 True, /* bAvailable */
578 True, /* bRead_only */
579 True, /* bNo_set_dir */
580 False, /* bGuest_only */
581 False, /* bAdministrative_share */
582 False, /* bGuest_ok */
583 False, /* bPrint_ok */
584 False, /* bMap_system */
585 False, /* bMap_hidden */
586 True, /* bMap_archive */
587 False, /* bStoreDosAttributes */
588 False, /* bDmapiSupport */
590 Auto, /* iStrictLocking */
591 True, /* bPosixLocking */
592 True, /* bShareModes */
594 True, /* bLevel2OpLocks */
595 False, /* bOnlyUser */
596 True, /* bMangledNames */
597 True, /* bWidelinks */
598 True, /* bSymlinks */
599 False, /* bSyncAlways */
600 False, /* bStrictAllocate */
601 False, /* bStrictSync */
602 '~', /* magic char */
604 False, /* bDeleteReadonly */
605 False, /* bFakeOplocks */
606 False, /* bDeleteVetoFiles */
607 False, /* bDosFilemode */
608 True, /* bDosFiletimes */
609 False, /* bDosFiletimeResolution */
610 False, /* bFakeDirCreateTimes */
611 True, /* bBlockingLocks */
612 False, /* bInheritPerms */
613 False, /* bInheritACLS */
614 False, /* bInheritOwner */
615 False, /* bMSDfsRoot */
616 False, /* bUseClientDriver */
617 True, /* bDefaultDevmode */
618 False, /* bForcePrintername */
619 True, /* bNTAclSupport */
620 False, /* bForceUnknownAclUser */
621 False, /* bUseSendfile */
622 False, /* bProfileAcls */
623 False, /* bMap_acl_inherit */
624 False, /* bAfs_Share */
625 False, /* bEASupport */
626 True, /* bAclCheckPermissions */
627 True, /* bAclMapFullControl */
628 False, /* bAclGroupControl */
629 True, /* bChangeNotify */
630 True, /* bKernelChangeNotify */
631 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
632 0, /* iAioReadSize */
633 0, /* iAioWriteSize */
634 MAP_READONLY_YES, /* iMap_readonly */
635 #ifdef BROKEN_DIRECTORY_HANDLING
636 0, /* iDirectoryNameCacheSize */
638 100, /* iDirectoryNameCacheSize */
640 Auto, /* ismb_encrypt */
641 NULL, /* Parametric options */
646 /* local variables */
647 static struct service **ServicePtrs = NULL;
648 static int iNumServices = 0;
649 static int iServiceIndex = 0;
650 static struct db_context *ServiceHash;
651 static int *invalid_services = NULL;
652 static int num_invalid_services = 0;
653 static bool bInGlobalSection = True;
654 static bool bGlobalOnly = False;
655 static int server_role;
656 static int default_server_announce;
658 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
660 /* prototypes for the special type handlers */
661 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
662 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
663 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
664 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
665 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
666 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
667 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
668 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
669 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
670 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
671 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
672 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
674 static void set_server_role(void);
675 static void set_default_server_announce_type(void);
676 static void set_allowed_client_auth(void);
678 static void *lp_local_ptr(struct service *service, void *ptr);
680 static const struct enum_list enum_protocol[] = {
681 {PROTOCOL_NT1, "NT1"},
682 {PROTOCOL_LANMAN2, "LANMAN2"},
683 {PROTOCOL_LANMAN1, "LANMAN1"},
684 {PROTOCOL_CORE, "CORE"},
685 {PROTOCOL_COREPLUS, "COREPLUS"},
686 {PROTOCOL_COREPLUS, "CORE+"},
690 static const struct enum_list enum_security[] = {
691 {SEC_SHARE, "SHARE"},
693 {SEC_SERVER, "SERVER"},
694 {SEC_DOMAIN, "DOMAIN"},
701 static const struct enum_list enum_printing[] = {
702 {PRINT_SYSV, "sysv"},
704 {PRINT_HPUX, "hpux"},
708 {PRINT_LPRNG, "lprng"},
709 {PRINT_CUPS, "cups"},
710 {PRINT_IPRINT, "iprint"},
712 {PRINT_LPROS2, "os2"},
714 {PRINT_TEST, "test"},
716 #endif /* DEVELOPER */
720 static const struct enum_list enum_ldap_sasl_wrapping[] = {
722 {ADS_AUTH_SASL_SIGN, "sign"},
723 {ADS_AUTH_SASL_SEAL, "seal"},
727 static const struct enum_list enum_ldap_ssl[] = {
728 {LDAP_SSL_OFF, "no"},
729 {LDAP_SSL_OFF, "off"},
730 {LDAP_SSL_START_TLS, "start tls"},
731 {LDAP_SSL_START_TLS, "start_tls"},
735 static const struct enum_list enum_ldap_passwd_sync[] = {
736 {LDAP_PASSWD_SYNC_OFF, "no"},
737 {LDAP_PASSWD_SYNC_OFF, "off"},
738 {LDAP_PASSWD_SYNC_ON, "yes"},
739 {LDAP_PASSWD_SYNC_ON, "on"},
740 {LDAP_PASSWD_SYNC_ONLY, "only"},
744 /* Types of machine we can announce as. */
745 #define ANNOUNCE_AS_NT_SERVER 1
746 #define ANNOUNCE_AS_WIN95 2
747 #define ANNOUNCE_AS_WFW 3
748 #define ANNOUNCE_AS_NT_WORKSTATION 4
750 static const struct enum_list enum_announce_as[] = {
751 {ANNOUNCE_AS_NT_SERVER, "NT"},
752 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
753 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
754 {ANNOUNCE_AS_WIN95, "win95"},
755 {ANNOUNCE_AS_WFW, "WfW"},
759 static const struct enum_list enum_map_readonly[] = {
760 {MAP_READONLY_NO, "no"},
761 {MAP_READONLY_NO, "false"},
762 {MAP_READONLY_NO, "0"},
763 {MAP_READONLY_YES, "yes"},
764 {MAP_READONLY_YES, "true"},
765 {MAP_READONLY_YES, "1"},
766 {MAP_READONLY_PERMISSIONS, "permissions"},
767 {MAP_READONLY_PERMISSIONS, "perms"},
771 static const struct enum_list enum_case[] = {
772 {CASE_LOWER, "lower"},
773 {CASE_UPPER, "upper"},
777 static const struct enum_list enum_bool_auto[] = {
788 /* Client-side offline caching policy types */
789 #define CSC_POLICY_MANUAL 0
790 #define CSC_POLICY_DOCUMENTS 1
791 #define CSC_POLICY_PROGRAMS 2
792 #define CSC_POLICY_DISABLE 3
794 static const struct enum_list enum_csc_policy[] = {
795 {CSC_POLICY_MANUAL, "manual"},
796 {CSC_POLICY_DOCUMENTS, "documents"},
797 {CSC_POLICY_PROGRAMS, "programs"},
798 {CSC_POLICY_DISABLE, "disable"},
802 /* SMB signing types. */
803 static const struct enum_list enum_smb_signing_vals[] = {
815 {Required, "required"},
816 {Required, "mandatory"},
818 {Required, "forced"},
819 {Required, "enforced"},
823 /* ACL compatibility options. */
824 static const struct enum_list enum_acl_compat_vals[] = {
825 { ACL_COMPAT_AUTO, "auto" },
826 { ACL_COMPAT_WINNT, "winnt" },
827 { ACL_COMPAT_WIN2K, "win2k" },
832 Do you want session setups at user level security with a invalid
833 password to be rejected or allowed in as guest? WinNT rejects them
834 but it can be a pain as it means "net view" needs to use a password
836 You have 3 choices in the setting of map_to_guest:
838 "Never" means session setups with an invalid password
839 are rejected. This is the default.
841 "Bad User" means session setups with an invalid password
842 are rejected, unless the username does not exist, in which case it
843 is treated as a guest login
845 "Bad Password" means session setups with an invalid password
846 are treated as a guest login
848 Note that map_to_guest only has an effect in user or server
852 static const struct enum_list enum_map_to_guest[] = {
853 {NEVER_MAP_TO_GUEST, "Never"},
854 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
855 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
856 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
860 /* Config backend options */
862 static const struct enum_list enum_config_backend[] = {
863 {CONFIG_BACKEND_FILE, "file"},
864 {CONFIG_BACKEND_REGISTRY, "registry"},
868 /* ADS kerberos ticket verification options */
870 static const struct enum_list enum_kerberos_method[] = {
871 {KERBEROS_VERIFY_SECRETS, "default"},
872 {KERBEROS_VERIFY_SECRETS, "secrets only"},
873 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
874 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
875 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
879 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
881 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
882 * screen in SWAT. This is used to exclude parameters as well as to squash all
883 * parameters that have been duplicated by pseudonyms.
885 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
886 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
887 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
890 * NOTE2: Handling of duplicated (synonym) paramters:
891 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
892 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
893 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
894 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
897 static struct parm_struct parm_table[] = {
898 {N_("Base Options"), P_SEP, P_SEPARATOR},
901 .label = "dos charset",
904 .ptr = &Globals.dos_charset,
905 .special = handle_charset,
907 .flags = FLAG_ADVANCED
910 .label = "unix charset",
913 .ptr = &Globals.unix_charset,
914 .special = handle_charset,
916 .flags = FLAG_ADVANCED
919 .label = "display charset",
922 .ptr = &Globals.display_charset,
923 .special = handle_charset,
925 .flags = FLAG_ADVANCED
931 .ptr = &sDefault.comment,
934 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
940 .ptr = &sDefault.szPath,
943 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
946 .label = "directory",
949 .ptr = &sDefault.szPath,
955 .label = "workgroup",
958 .ptr = &Globals.szWorkgroup,
959 .special = handle_workgroup,
961 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
968 .ptr = &Globals.szRealm,
971 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
975 .label = "netbios name",
978 .ptr = &Globals.szNetbiosName,
979 .special = handle_netbios_name,
981 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
984 .label = "netbios aliases",
987 .ptr = &Globals.szNetbiosAliases,
988 .special = handle_netbios_aliases,
990 .flags = FLAG_ADVANCED,
993 .label = "netbios scope",
996 .ptr = &Globals.szNetbiosScope,
997 .special = handle_netbios_scope,
999 .flags = FLAG_ADVANCED,
1002 .label = "server string",
1004 .p_class = P_GLOBAL,
1005 .ptr = &Globals.szServerString,
1008 .flags = FLAG_BASIC | FLAG_ADVANCED,
1011 .label = "interfaces",
1013 .p_class = P_GLOBAL,
1014 .ptr = &Globals.szInterfaces,
1017 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1020 .label = "bind interfaces only",
1022 .p_class = P_GLOBAL,
1023 .ptr = &Globals.bBindInterfacesOnly,
1026 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1029 .label = "config backend",
1031 .p_class = P_GLOBAL,
1032 .ptr = &Globals.ConfigBackend,
1034 .enum_list = enum_config_backend,
1035 .flags = FLAG_ADVANCED,
1038 {N_("Security Options"), P_SEP, P_SEPARATOR},
1041 .label = "security",
1043 .p_class = P_GLOBAL,
1044 .ptr = &Globals.security,
1046 .enum_list = enum_security,
1047 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1050 .label = "auth methods",
1052 .p_class = P_GLOBAL,
1053 .ptr = &Globals.AuthMethods,
1056 .flags = FLAG_ADVANCED,
1059 .label = "encrypt passwords",
1061 .p_class = P_GLOBAL,
1062 .ptr = &Globals.bEncryptPasswords,
1065 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1068 .label = "update encrypted",
1070 .p_class = P_GLOBAL,
1071 .ptr = &Globals.bUpdateEncrypt,
1074 .flags = FLAG_ADVANCED,
1077 .label = "client schannel",
1079 .p_class = P_GLOBAL,
1080 .ptr = &Globals.clientSchannel,
1082 .enum_list = enum_bool_auto,
1083 .flags = FLAG_BASIC | FLAG_ADVANCED,
1086 .label = "server schannel",
1088 .p_class = P_GLOBAL,
1089 .ptr = &Globals.serverSchannel,
1091 .enum_list = enum_bool_auto,
1092 .flags = FLAG_BASIC | FLAG_ADVANCED,
1095 .label = "allow trusted domains",
1097 .p_class = P_GLOBAL,
1098 .ptr = &Globals.bAllowTrustedDomains,
1101 .flags = FLAG_ADVANCED,
1104 .label = "map to guest",
1106 .p_class = P_GLOBAL,
1107 .ptr = &Globals.map_to_guest,
1109 .enum_list = enum_map_to_guest,
1110 .flags = FLAG_ADVANCED,
1113 .label = "null passwords",
1115 .p_class = P_GLOBAL,
1116 .ptr = &Globals.bNullPasswords,
1119 .flags = FLAG_ADVANCED,
1122 .label = "obey pam restrictions",
1124 .p_class = P_GLOBAL,
1125 .ptr = &Globals.bObeyPamRestrictions,
1128 .flags = FLAG_ADVANCED,
1131 .label = "password server",
1133 .p_class = P_GLOBAL,
1134 .ptr = &Globals.szPasswordServer,
1137 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1140 .label = "smb passwd file",
1142 .p_class = P_GLOBAL,
1143 .ptr = &Globals.szSMBPasswdFile,
1146 .flags = FLAG_ADVANCED,
1149 .label = "private dir",
1151 .p_class = P_GLOBAL,
1152 .ptr = &Globals.szPrivateDir,
1155 .flags = FLAG_ADVANCED,
1158 .label = "passdb backend",
1160 .p_class = P_GLOBAL,
1161 .ptr = &Globals.szPassdbBackend,
1164 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1167 .label = "algorithmic rid base",
1169 .p_class = P_GLOBAL,
1170 .ptr = &Globals.AlgorithmicRidBase,
1173 .flags = FLAG_ADVANCED,
1176 .label = "root directory",
1178 .p_class = P_GLOBAL,
1179 .ptr = &Globals.szRootdir,
1182 .flags = FLAG_ADVANCED,
1185 .label = "root dir",
1187 .p_class = P_GLOBAL,
1188 .ptr = &Globals.szRootdir,
1196 .p_class = P_GLOBAL,
1197 .ptr = &Globals.szRootdir,
1203 .label = "guest account",
1205 .p_class = P_GLOBAL,
1206 .ptr = &Globals.szGuestaccount,
1209 .flags = FLAG_BASIC | FLAG_ADVANCED,
1212 .label = "enable privileges",
1214 .p_class = P_GLOBAL,
1215 .ptr = &Globals.bEnablePrivileges,
1218 .flags = FLAG_ADVANCED,
1222 .label = "pam password change",
1224 .p_class = P_GLOBAL,
1225 .ptr = &Globals.bPamPasswordChange,
1228 .flags = FLAG_ADVANCED,
1231 .label = "passwd program",
1233 .p_class = P_GLOBAL,
1234 .ptr = &Globals.szPasswdProgram,
1237 .flags = FLAG_ADVANCED,
1240 .label = "passwd chat",
1242 .p_class = P_GLOBAL,
1243 .ptr = &Globals.szPasswdChat,
1246 .flags = FLAG_ADVANCED,
1249 .label = "passwd chat debug",
1251 .p_class = P_GLOBAL,
1252 .ptr = &Globals.bPasswdChatDebug,
1255 .flags = FLAG_ADVANCED,
1258 .label = "passwd chat timeout",
1260 .p_class = P_GLOBAL,
1261 .ptr = &Globals.iPasswdChatTimeout,
1264 .flags = FLAG_ADVANCED,
1267 .label = "check password script",
1269 .p_class = P_GLOBAL,
1270 .ptr = &Globals.szCheckPasswordScript,
1273 .flags = FLAG_ADVANCED,
1276 .label = "username map",
1278 .p_class = P_GLOBAL,
1279 .ptr = &Globals.szUsernameMap,
1282 .flags = FLAG_ADVANCED,
1285 .label = "password level",
1287 .p_class = P_GLOBAL,
1288 .ptr = &Globals.pwordlevel,
1291 .flags = FLAG_ADVANCED,
1294 .label = "username level",
1296 .p_class = P_GLOBAL,
1297 .ptr = &Globals.unamelevel,
1300 .flags = FLAG_ADVANCED,
1303 .label = "unix password sync",
1305 .p_class = P_GLOBAL,
1306 .ptr = &Globals.bUnixPasswdSync,
1309 .flags = FLAG_ADVANCED,
1312 .label = "restrict anonymous",
1314 .p_class = P_GLOBAL,
1315 .ptr = &Globals.restrict_anonymous,
1318 .flags = FLAG_ADVANCED,
1321 .label = "lanman auth",
1323 .p_class = P_GLOBAL,
1324 .ptr = &Globals.bLanmanAuth,
1327 .flags = FLAG_ADVANCED,
1330 .label = "ntlm auth",
1332 .p_class = P_GLOBAL,
1333 .ptr = &Globals.bNTLMAuth,
1336 .flags = FLAG_ADVANCED,
1339 .label = "client NTLMv2 auth",
1341 .p_class = P_GLOBAL,
1342 .ptr = &Globals.bClientNTLMv2Auth,
1345 .flags = FLAG_ADVANCED,
1348 .label = "client lanman auth",
1350 .p_class = P_GLOBAL,
1351 .ptr = &Globals.bClientLanManAuth,
1354 .flags = FLAG_ADVANCED,
1357 .label = "client plaintext auth",
1359 .p_class = P_GLOBAL,
1360 .ptr = &Globals.bClientPlaintextAuth,
1363 .flags = FLAG_ADVANCED,
1366 .label = "username",
1369 .ptr = &sDefault.szUsername,
1372 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1378 .ptr = &sDefault.szUsername,
1387 .ptr = &sDefault.szUsername,
1393 .label = "invalid users",
1396 .ptr = &sDefault.szInvalidUsers,
1399 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1402 .label = "valid users",
1405 .ptr = &sDefault.szValidUsers,
1408 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1411 .label = "admin users",
1414 .ptr = &sDefault.szAdminUsers,
1417 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1420 .label = "read list",
1423 .ptr = &sDefault.readlist,
1426 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1429 .label = "write list",
1432 .ptr = &sDefault.writelist,
1435 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1438 .label = "printer admin",
1441 .ptr = &sDefault.printer_admin,
1444 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1447 .label = "force user",
1450 .ptr = &sDefault.force_user,
1453 .flags = FLAG_ADVANCED | FLAG_SHARE,
1456 .label = "force group",
1459 .ptr = &sDefault.force_group,
1462 .flags = FLAG_ADVANCED | FLAG_SHARE,
1468 .ptr = &sDefault.force_group,
1471 .flags = FLAG_ADVANCED,
1474 .label = "read only",
1477 .ptr = &sDefault.bRead_only,
1480 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1483 .label = "write ok",
1486 .ptr = &sDefault.bRead_only,
1492 .label = "writeable",
1495 .ptr = &sDefault.bRead_only,
1501 .label = "writable",
1504 .ptr = &sDefault.bRead_only,
1510 .label = "acl check permissions",
1513 .ptr = &sDefault.bAclCheckPermissions,
1516 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1519 .label = "acl group control",
1522 .ptr = &sDefault.bAclGroupControl,
1525 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1528 .label = "acl map full control",
1531 .ptr = &sDefault.bAclMapFullControl,
1534 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1537 .label = "create mask",
1540 .ptr = &sDefault.iCreate_mask,
1543 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1546 .label = "create mode",
1549 .ptr = &sDefault.iCreate_mask,
1555 .label = "force create mode",
1558 .ptr = &sDefault.iCreate_force_mode,
1561 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1564 .label = "security mask",
1567 .ptr = &sDefault.iSecurity_mask,
1570 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1573 .label = "force security mode",
1576 .ptr = &sDefault.iSecurity_force_mode,
1579 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1582 .label = "directory mask",
1585 .ptr = &sDefault.iDir_mask,
1588 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1591 .label = "directory mode",
1594 .ptr = &sDefault.iDir_mask,
1597 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1600 .label = "force directory mode",
1603 .ptr = &sDefault.iDir_force_mode,
1606 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1609 .label = "directory security mask",
1612 .ptr = &sDefault.iDir_Security_mask,
1615 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1618 .label = "force directory security mode",
1621 .ptr = &sDefault.iDir_Security_force_mode,
1624 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1627 .label = "force unknown acl user",
1630 .ptr = &sDefault.bForceUnknownAclUser,
1633 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1636 .label = "inherit permissions",
1639 .ptr = &sDefault.bInheritPerms,
1642 .flags = FLAG_ADVANCED | FLAG_SHARE,
1645 .label = "inherit acls",
1648 .ptr = &sDefault.bInheritACLS,
1651 .flags = FLAG_ADVANCED | FLAG_SHARE,
1654 .label = "inherit owner",
1657 .ptr = &sDefault.bInheritOwner,
1660 .flags = FLAG_ADVANCED | FLAG_SHARE,
1663 .label = "guest only",
1666 .ptr = &sDefault.bGuest_only,
1669 .flags = FLAG_ADVANCED | FLAG_SHARE,
1672 .label = "only guest",
1675 .ptr = &sDefault.bGuest_only,
1681 .label = "administrative share",
1684 .ptr = &sDefault.bAdministrative_share,
1687 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1691 .label = "guest ok",
1694 .ptr = &sDefault.bGuest_ok,
1697 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1703 .ptr = &sDefault.bGuest_ok,
1709 .label = "only user",
1712 .ptr = &sDefault.bOnlyUser,
1715 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1718 .label = "hosts allow",
1721 .ptr = &sDefault.szHostsallow,
1724 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1727 .label = "allow hosts",
1730 .ptr = &sDefault.szHostsallow,
1736 .label = "hosts deny",
1739 .ptr = &sDefault.szHostsdeny,
1742 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1745 .label = "deny hosts",
1748 .ptr = &sDefault.szHostsdeny,
1754 .label = "preload modules",
1756 .p_class = P_GLOBAL,
1757 .ptr = &Globals.szPreloadModules,
1760 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1763 .label = "dedicated keytab file",
1765 .p_class = P_GLOBAL,
1766 .ptr = &Globals.szDedicatedKeytabFile,
1769 .flags = FLAG_ADVANCED,
1772 .label = "kerberos method",
1774 .p_class = P_GLOBAL,
1775 .ptr = &Globals.iKerberosMethod,
1777 .enum_list = enum_kerberos_method,
1778 .flags = FLAG_ADVANCED,
1781 .label = "map untrusted to domain",
1783 .p_class = P_GLOBAL,
1784 .ptr = &Globals.bMapUntrustedToDomain,
1787 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1791 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1794 .label = "log level",
1796 .p_class = P_GLOBAL,
1797 .ptr = &Globals.szLogLevel,
1798 .special = handle_debug_list,
1800 .flags = FLAG_ADVANCED,
1803 .label = "debuglevel",
1805 .p_class = P_GLOBAL,
1806 .ptr = &Globals.szLogLevel,
1807 .special = handle_debug_list,
1814 .p_class = P_GLOBAL,
1815 .ptr = &Globals.syslog,
1818 .flags = FLAG_ADVANCED,
1821 .label = "syslog only",
1823 .p_class = P_GLOBAL,
1824 .ptr = &Globals.bSyslogOnly,
1827 .flags = FLAG_ADVANCED,
1830 .label = "log file",
1832 .p_class = P_GLOBAL,
1833 .ptr = &Globals.szLogFile,
1836 .flags = FLAG_ADVANCED,
1839 .label = "max log size",
1841 .p_class = P_GLOBAL,
1842 .ptr = &Globals.max_log_size,
1845 .flags = FLAG_ADVANCED,
1848 .label = "debug timestamp",
1850 .p_class = P_GLOBAL,
1851 .ptr = &Globals.bTimestampLogs,
1854 .flags = FLAG_ADVANCED,
1857 .label = "timestamp logs",
1859 .p_class = P_GLOBAL,
1860 .ptr = &Globals.bTimestampLogs,
1863 .flags = FLAG_ADVANCED,
1866 .label = "debug prefix timestamp",
1868 .p_class = P_GLOBAL,
1869 .ptr = &Globals.bDebugPrefixTimestamp,
1872 .flags = FLAG_ADVANCED,
1875 .label = "debug hires timestamp",
1877 .p_class = P_GLOBAL,
1878 .ptr = &Globals.bDebugHiresTimestamp,
1881 .flags = FLAG_ADVANCED,
1884 .label = "debug pid",
1886 .p_class = P_GLOBAL,
1887 .ptr = &Globals.bDebugPid,
1890 .flags = FLAG_ADVANCED,
1893 .label = "debug uid",
1895 .p_class = P_GLOBAL,
1896 .ptr = &Globals.bDebugUid,
1899 .flags = FLAG_ADVANCED,
1902 .label = "debug class",
1904 .p_class = P_GLOBAL,
1905 .ptr = &Globals.bDebugClass,
1908 .flags = FLAG_ADVANCED,
1911 .label = "enable core files",
1913 .p_class = P_GLOBAL,
1914 .ptr = &Globals.bEnableCoreFiles,
1917 .flags = FLAG_ADVANCED,
1920 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1923 .label = "allocation roundup size",
1926 .ptr = &sDefault.iallocation_roundup_size,
1929 .flags = FLAG_ADVANCED,
1932 .label = "aio read size",
1935 .ptr = &sDefault.iAioReadSize,
1938 .flags = FLAG_ADVANCED,
1941 .label = "aio write size",
1944 .ptr = &sDefault.iAioWriteSize,
1947 .flags = FLAG_ADVANCED,
1950 .label = "aio write behind",
1953 .ptr = &sDefault.szAioWriteBehind,
1956 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1959 .label = "smb ports",
1961 .p_class = P_GLOBAL,
1962 .ptr = &Globals.smb_ports,
1965 .flags = FLAG_ADVANCED,
1968 .label = "large readwrite",
1970 .p_class = P_GLOBAL,
1971 .ptr = &Globals.bLargeReadwrite,
1974 .flags = FLAG_ADVANCED,
1977 .label = "max protocol",
1979 .p_class = P_GLOBAL,
1980 .ptr = &Globals.maxprotocol,
1982 .enum_list = enum_protocol,
1983 .flags = FLAG_ADVANCED,
1986 .label = "protocol",
1988 .p_class = P_GLOBAL,
1989 .ptr = &Globals.maxprotocol,
1991 .enum_list = enum_protocol,
1992 .flags = FLAG_ADVANCED,
1995 .label = "min protocol",
1997 .p_class = P_GLOBAL,
1998 .ptr = &Globals.minprotocol,
2000 .enum_list = enum_protocol,
2001 .flags = FLAG_ADVANCED,
2004 .label = "min receivefile size",
2006 .p_class = P_GLOBAL,
2007 .ptr = &Globals.iminreceivefile,
2010 .flags = FLAG_ADVANCED,
2013 .label = "read raw",
2015 .p_class = P_GLOBAL,
2016 .ptr = &Globals.bReadRaw,
2019 .flags = FLAG_ADVANCED,
2022 .label = "write raw",
2024 .p_class = P_GLOBAL,
2025 .ptr = &Globals.bWriteRaw,
2028 .flags = FLAG_ADVANCED,
2031 .label = "disable netbios",
2033 .p_class = P_GLOBAL,
2034 .ptr = &Globals.bDisableNetbios,
2037 .flags = FLAG_ADVANCED,
2040 .label = "reset on zero vc",
2042 .p_class = P_GLOBAL,
2043 .ptr = &Globals.bResetOnZeroVC,
2046 .flags = FLAG_ADVANCED,
2049 .label = "acl compatibility",
2051 .p_class = P_GLOBAL,
2052 .ptr = &Globals.iAclCompat,
2054 .enum_list = enum_acl_compat_vals,
2055 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2058 .label = "defer sharing violations",
2060 .p_class = P_GLOBAL,
2061 .ptr = &Globals.bDeferSharingViolations,
2064 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2067 .label = "ea support",
2070 .ptr = &sDefault.bEASupport,
2073 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2076 .label = "nt acl support",
2079 .ptr = &sDefault.bNTAclSupport,
2082 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2085 .label = "nt pipe support",
2087 .p_class = P_GLOBAL,
2088 .ptr = &Globals.bNTPipeSupport,
2091 .flags = FLAG_ADVANCED,
2094 .label = "nt status support",
2096 .p_class = P_GLOBAL,
2097 .ptr = &Globals.bNTStatusSupport,
2100 .flags = FLAG_ADVANCED,
2103 .label = "profile acls",
2106 .ptr = &sDefault.bProfileAcls,
2109 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2112 .label = "announce version",
2114 .p_class = P_GLOBAL,
2115 .ptr = &Globals.szAnnounceVersion,
2118 .flags = FLAG_ADVANCED,
2121 .label = "announce as",
2123 .p_class = P_GLOBAL,
2124 .ptr = &Globals.announce_as,
2126 .enum_list = enum_announce_as,
2127 .flags = FLAG_ADVANCED,
2130 .label = "map acl inherit",
2133 .ptr = &sDefault.bMap_acl_inherit,
2136 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2139 .label = "afs share",
2142 .ptr = &sDefault.bAfs_Share,
2145 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2150 .p_class = P_GLOBAL,
2151 .ptr = &Globals.max_mux,
2154 .flags = FLAG_ADVANCED,
2157 .label = "max xmit",
2159 .p_class = P_GLOBAL,
2160 .ptr = &Globals.max_xmit,
2163 .flags = FLAG_ADVANCED,
2166 .label = "name resolve order",
2168 .p_class = P_GLOBAL,
2169 .ptr = &Globals.szNameResolveOrder,
2172 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2177 .p_class = P_GLOBAL,
2178 .ptr = &Globals.max_ttl,
2181 .flags = FLAG_ADVANCED,
2184 .label = "max wins ttl",
2186 .p_class = P_GLOBAL,
2187 .ptr = &Globals.max_wins_ttl,
2190 .flags = FLAG_ADVANCED,
2193 .label = "min wins ttl",
2195 .p_class = P_GLOBAL,
2196 .ptr = &Globals.min_wins_ttl,
2199 .flags = FLAG_ADVANCED,
2202 .label = "time server",
2204 .p_class = P_GLOBAL,
2205 .ptr = &Globals.bTimeServer,
2208 .flags = FLAG_ADVANCED,
2211 .label = "unix extensions",
2213 .p_class = P_GLOBAL,
2214 .ptr = &Globals.bUnixExtensions,
2217 .flags = FLAG_ADVANCED,
2220 .label = "use spnego",
2222 .p_class = P_GLOBAL,
2223 .ptr = &Globals.bUseSpnego,
2226 .flags = FLAG_ADVANCED,
2229 .label = "client signing",
2231 .p_class = P_GLOBAL,
2232 .ptr = &Globals.client_signing,
2234 .enum_list = enum_smb_signing_vals,
2235 .flags = FLAG_ADVANCED,
2238 .label = "server signing",
2240 .p_class = P_GLOBAL,
2241 .ptr = &Globals.server_signing,
2243 .enum_list = enum_smb_signing_vals,
2244 .flags = FLAG_ADVANCED,
2247 .label = "smb encrypt",
2250 .ptr = &sDefault.ismb_encrypt,
2252 .enum_list = enum_smb_signing_vals,
2253 .flags = FLAG_ADVANCED,
2256 .label = "client use spnego",
2258 .p_class = P_GLOBAL,
2259 .ptr = &Globals.bClientUseSpnego,
2262 .flags = FLAG_ADVANCED,
2265 .label = "client ldap sasl wrapping",
2267 .p_class = P_GLOBAL,
2268 .ptr = &Globals.client_ldap_sasl_wrapping,
2270 .enum_list = enum_ldap_sasl_wrapping,
2271 .flags = FLAG_ADVANCED,
2274 .label = "enable asu support",
2276 .p_class = P_GLOBAL,
2277 .ptr = &Globals.bASUSupport,
2280 .flags = FLAG_ADVANCED,
2283 .label = "svcctl list",
2285 .p_class = P_GLOBAL,
2286 .ptr = &Globals.szServicesList,
2289 .flags = FLAG_ADVANCED,
2292 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2295 .label = "block size",
2298 .ptr = &sDefault.iBlock_size,
2301 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2304 .label = "deadtime",
2306 .p_class = P_GLOBAL,
2307 .ptr = &Globals.deadtime,
2310 .flags = FLAG_ADVANCED,
2313 .label = "getwd cache",
2315 .p_class = P_GLOBAL,
2316 .ptr = &Globals.getwd_cache,
2319 .flags = FLAG_ADVANCED,
2322 .label = "keepalive",
2324 .p_class = P_GLOBAL,
2325 .ptr = &Globals.iKeepalive,
2328 .flags = FLAG_ADVANCED,
2331 .label = "change notify",
2334 .ptr = &sDefault.bChangeNotify,
2337 .flags = FLAG_ADVANCED | FLAG_SHARE,
2340 .label = "directory name cache size",
2343 .ptr = &sDefault.iDirectoryNameCacheSize,
2346 .flags = FLAG_ADVANCED | FLAG_SHARE,
2349 .label = "kernel change notify",
2352 .ptr = &sDefault.bKernelChangeNotify,
2355 .flags = FLAG_ADVANCED | FLAG_SHARE,
2358 .label = "lpq cache time",
2360 .p_class = P_GLOBAL,
2361 .ptr = &Globals.lpqcachetime,
2364 .flags = FLAG_ADVANCED,
2367 .label = "max smbd processes",
2369 .p_class = P_GLOBAL,
2370 .ptr = &Globals.iMaxSmbdProcesses,
2373 .flags = FLAG_ADVANCED,
2376 .label = "max connections",
2379 .ptr = &sDefault.iMaxConnections,
2382 .flags = FLAG_ADVANCED | FLAG_SHARE,
2385 .label = "paranoid server security",
2387 .p_class = P_GLOBAL,
2388 .ptr = &Globals.paranoid_server_security,
2391 .flags = FLAG_ADVANCED,
2394 .label = "max disk size",
2396 .p_class = P_GLOBAL,
2397 .ptr = &Globals.maxdisksize,
2400 .flags = FLAG_ADVANCED,
2403 .label = "max open files",
2405 .p_class = P_GLOBAL,
2406 .ptr = &Globals.max_open_files,
2409 .flags = FLAG_ADVANCED,
2412 .label = "min print space",
2415 .ptr = &sDefault.iMinPrintSpace,
2418 .flags = FLAG_ADVANCED | FLAG_PRINT,
2421 .label = "socket options",
2423 .p_class = P_GLOBAL,
2424 .ptr = &Globals.szSocketOptions,
2427 .flags = FLAG_ADVANCED,
2430 .label = "strict allocate",
2433 .ptr = &sDefault.bStrictAllocate,
2436 .flags = FLAG_ADVANCED | FLAG_SHARE,
2439 .label = "strict sync",
2442 .ptr = &sDefault.bStrictSync,
2445 .flags = FLAG_ADVANCED | FLAG_SHARE,
2448 .label = "sync always",
2451 .ptr = &sDefault.bSyncAlways,
2454 .flags = FLAG_ADVANCED | FLAG_SHARE,
2457 .label = "use mmap",
2459 .p_class = P_GLOBAL,
2460 .ptr = &Globals.bUseMmap,
2463 .flags = FLAG_ADVANCED,
2466 .label = "use sendfile",
2469 .ptr = &sDefault.bUseSendfile,
2472 .flags = FLAG_ADVANCED | FLAG_SHARE,
2475 .label = "hostname lookups",
2477 .p_class = P_GLOBAL,
2478 .ptr = &Globals.bHostnameLookups,
2481 .flags = FLAG_ADVANCED,
2484 .label = "write cache size",
2487 .ptr = &sDefault.iWriteCacheSize,
2490 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2493 .label = "name cache timeout",
2495 .p_class = P_GLOBAL,
2496 .ptr = &Globals.name_cache_timeout,
2499 .flags = FLAG_ADVANCED,
2502 .label = "ctdbd socket",
2504 .p_class = P_GLOBAL,
2505 .ptr = &Globals.ctdbdSocket,
2508 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2511 .label = "cluster addresses",
2513 .p_class = P_GLOBAL,
2514 .ptr = &Globals.szClusterAddresses,
2517 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2520 .label = "clustering",
2522 .p_class = P_GLOBAL,
2523 .ptr = &Globals.clustering,
2526 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2529 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2532 .label = "max reported print jobs",
2535 .ptr = &sDefault.iMaxReportedPrintJobs,
2538 .flags = FLAG_ADVANCED | FLAG_PRINT,
2541 .label = "max print jobs",
2544 .ptr = &sDefault.iMaxPrintJobs,
2547 .flags = FLAG_ADVANCED | FLAG_PRINT,
2550 .label = "load printers",
2552 .p_class = P_GLOBAL,
2553 .ptr = &Globals.bLoadPrinters,
2556 .flags = FLAG_ADVANCED | FLAG_PRINT,
2559 .label = "printcap cache time",
2561 .p_class = P_GLOBAL,
2562 .ptr = &Globals.PrintcapCacheTime,
2565 .flags = FLAG_ADVANCED | FLAG_PRINT,
2568 .label = "printcap name",
2570 .p_class = P_GLOBAL,
2571 .ptr = &Globals.szPrintcapname,
2574 .flags = FLAG_ADVANCED | FLAG_PRINT,
2577 .label = "printcap",
2579 .p_class = P_GLOBAL,
2580 .ptr = &Globals.szPrintcapname,
2586 .label = "printable",
2589 .ptr = &sDefault.bPrint_ok,
2592 .flags = FLAG_ADVANCED | FLAG_PRINT,
2595 .label = "print ok",
2598 .ptr = &sDefault.bPrint_ok,
2604 .label = "printing",
2607 .ptr = &sDefault.iPrinting,
2608 .special = handle_printing,
2609 .enum_list = enum_printing,
2610 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2613 .label = "cups options",
2616 .ptr = &sDefault.szCupsOptions,
2619 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2622 .label = "cups server",
2624 .p_class = P_GLOBAL,
2625 .ptr = &Globals.szCupsServer,
2628 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2631 .label = "cups connection timeout",
2633 .p_class = P_GLOBAL,
2634 .ptr = &Globals.cups_connection_timeout,
2637 .flags = FLAG_ADVANCED,
2640 .label = "iprint server",
2642 .p_class = P_GLOBAL,
2643 .ptr = &Globals.szIPrintServer,
2646 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2649 .label = "print command",
2652 .ptr = &sDefault.szPrintcommand,
2655 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2658 .label = "disable spoolss",
2660 .p_class = P_GLOBAL,
2661 .ptr = &Globals.bDisableSpoolss,
2664 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2667 .label = "enable spoolss",
2669 .p_class = P_GLOBAL,
2670 .ptr = &Globals.bDisableSpoolss,
2676 .label = "lpq command",
2679 .ptr = &sDefault.szLpqcommand,
2682 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2685 .label = "lprm command",
2688 .ptr = &sDefault.szLprmcommand,
2691 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2694 .label = "lppause command",
2697 .ptr = &sDefault.szLppausecommand,
2700 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2703 .label = "lpresume command",
2706 .ptr = &sDefault.szLpresumecommand,
2709 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2712 .label = "queuepause command",
2715 .ptr = &sDefault.szQueuepausecommand,
2718 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2721 .label = "queueresume command",
2724 .ptr = &sDefault.szQueueresumecommand,
2727 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2730 .label = "addport command",
2732 .p_class = P_GLOBAL,
2733 .ptr = &Globals.szAddPortCommand,
2736 .flags = FLAG_ADVANCED,
2739 .label = "enumports command",
2741 .p_class = P_GLOBAL,
2742 .ptr = &Globals.szEnumPortsCommand,
2745 .flags = FLAG_ADVANCED,
2748 .label = "addprinter command",
2750 .p_class = P_GLOBAL,
2751 .ptr = &Globals.szAddPrinterCommand,
2754 .flags = FLAG_ADVANCED,
2757 .label = "deleteprinter command",
2759 .p_class = P_GLOBAL,
2760 .ptr = &Globals.szDeletePrinterCommand,
2763 .flags = FLAG_ADVANCED,
2766 .label = "show add printer wizard",
2768 .p_class = P_GLOBAL,
2769 .ptr = &Globals.bMsAddPrinterWizard,
2772 .flags = FLAG_ADVANCED,
2775 .label = "os2 driver map",
2777 .p_class = P_GLOBAL,
2778 .ptr = &Globals.szOs2DriverMap,
2781 .flags = FLAG_ADVANCED,
2785 .label = "printer name",
2788 .ptr = &sDefault.szPrintername,
2791 .flags = FLAG_ADVANCED | FLAG_PRINT,
2797 .ptr = &sDefault.szPrintername,
2803 .label = "use client driver",
2806 .ptr = &sDefault.bUseClientDriver,
2809 .flags = FLAG_ADVANCED | FLAG_PRINT,
2812 .label = "default devmode",
2815 .ptr = &sDefault.bDefaultDevmode,
2818 .flags = FLAG_ADVANCED | FLAG_PRINT,
2821 .label = "force printername",
2824 .ptr = &sDefault.bForcePrintername,
2827 .flags = FLAG_ADVANCED | FLAG_PRINT,
2830 .label = "printjob username",
2833 .ptr = &sDefault.szPrintjobUsername,
2836 .flags = FLAG_ADVANCED | FLAG_PRINT,
2839 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2842 .label = "mangling method",
2844 .p_class = P_GLOBAL,
2845 .ptr = &Globals.szManglingMethod,
2848 .flags = FLAG_ADVANCED,
2851 .label = "mangle prefix",
2853 .p_class = P_GLOBAL,
2854 .ptr = &Globals.mangle_prefix,
2857 .flags = FLAG_ADVANCED,
2861 .label = "default case",
2864 .ptr = &sDefault.iDefaultCase,
2866 .enum_list = enum_case,
2867 .flags = FLAG_ADVANCED | FLAG_SHARE,
2870 .label = "case sensitive",
2873 .ptr = &sDefault.iCaseSensitive,
2875 .enum_list = enum_bool_auto,
2876 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2879 .label = "casesignames",
2882 .ptr = &sDefault.iCaseSensitive,
2884 .enum_list = enum_bool_auto,
2885 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2888 .label = "preserve case",
2891 .ptr = &sDefault.bCasePreserve,
2894 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2897 .label = "short preserve case",
2900 .ptr = &sDefault.bShortCasePreserve,
2903 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2906 .label = "mangling char",
2909 .ptr = &sDefault.magic_char,
2912 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2915 .label = "hide dot files",
2918 .ptr = &sDefault.bHideDotFiles,
2921 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2924 .label = "hide special files",
2927 .ptr = &sDefault.bHideSpecialFiles,
2930 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2933 .label = "hide unreadable",
2936 .ptr = &sDefault.bHideUnReadable,
2939 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2942 .label = "hide unwriteable files",
2945 .ptr = &sDefault.bHideUnWriteableFiles,
2948 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2951 .label = "delete veto files",
2954 .ptr = &sDefault.bDeleteVetoFiles,
2957 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2960 .label = "veto files",
2963 .ptr = &sDefault.szVetoFiles,
2966 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2969 .label = "hide files",
2972 .ptr = &sDefault.szHideFiles,
2975 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2978 .label = "veto oplock files",
2981 .ptr = &sDefault.szVetoOplockFiles,
2984 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2987 .label = "map archive",
2990 .ptr = &sDefault.bMap_archive,
2993 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2996 .label = "map hidden",
2999 .ptr = &sDefault.bMap_hidden,
3002 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3005 .label = "map system",
3008 .ptr = &sDefault.bMap_system,
3011 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3014 .label = "map readonly",
3017 .ptr = &sDefault.iMap_readonly,
3019 .enum_list = enum_map_readonly,
3020 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3023 .label = "mangled names",
3026 .ptr = &sDefault.bMangledNames,
3029 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3032 .label = "max stat cache size",
3034 .p_class = P_GLOBAL,
3035 .ptr = &Globals.iMaxStatCacheSize,
3038 .flags = FLAG_ADVANCED,
3041 .label = "stat cache",
3043 .p_class = P_GLOBAL,
3044 .ptr = &Globals.bStatCache,
3047 .flags = FLAG_ADVANCED,
3050 .label = "store dos attributes",
3053 .ptr = &sDefault.bStoreDosAttributes,
3056 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3059 .label = "dmapi support",
3062 .ptr = &sDefault.bDmapiSupport,
3065 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3069 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3072 .label = "machine password timeout",
3074 .p_class = P_GLOBAL,
3075 .ptr = &Globals.machine_password_timeout,
3078 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3081 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3084 .label = "add user script",
3086 .p_class = P_GLOBAL,
3087 .ptr = &Globals.szAddUserScript,
3090 .flags = FLAG_ADVANCED,
3093 .label = "rename user script",
3095 .p_class = P_GLOBAL,
3096 .ptr = &Globals.szRenameUserScript,
3099 .flags = FLAG_ADVANCED,
3102 .label = "delete user script",
3104 .p_class = P_GLOBAL,
3105 .ptr = &Globals.szDelUserScript,
3108 .flags = FLAG_ADVANCED,
3111 .label = "add group script",
3113 .p_class = P_GLOBAL,
3114 .ptr = &Globals.szAddGroupScript,
3117 .flags = FLAG_ADVANCED,
3120 .label = "delete group script",
3122 .p_class = P_GLOBAL,
3123 .ptr = &Globals.szDelGroupScript,
3126 .flags = FLAG_ADVANCED,
3129 .label = "add user to group script",
3131 .p_class = P_GLOBAL,
3132 .ptr = &Globals.szAddUserToGroupScript,
3135 .flags = FLAG_ADVANCED,
3138 .label = "delete user from group script",
3140 .p_class = P_GLOBAL,
3141 .ptr = &Globals.szDelUserFromGroupScript,
3144 .flags = FLAG_ADVANCED,
3147 .label = "set primary group script",
3149 .p_class = P_GLOBAL,
3150 .ptr = &Globals.szSetPrimaryGroupScript,
3153 .flags = FLAG_ADVANCED,
3156 .label = "add machine script",
3158 .p_class = P_GLOBAL,
3159 .ptr = &Globals.szAddMachineScript,
3162 .flags = FLAG_ADVANCED,
3165 .label = "shutdown script",
3167 .p_class = P_GLOBAL,
3168 .ptr = &Globals.szShutdownScript,
3171 .flags = FLAG_ADVANCED,
3174 .label = "abort shutdown script",
3176 .p_class = P_GLOBAL,
3177 .ptr = &Globals.szAbortShutdownScript,
3180 .flags = FLAG_ADVANCED,
3183 .label = "username map script",
3185 .p_class = P_GLOBAL,
3186 .ptr = &Globals.szUsernameMapScript,
3189 .flags = FLAG_ADVANCED,
3192 .label = "logon script",
3194 .p_class = P_GLOBAL,
3195 .ptr = &Globals.szLogonScript,
3198 .flags = FLAG_ADVANCED,
3201 .label = "logon path",
3203 .p_class = P_GLOBAL,
3204 .ptr = &Globals.szLogonPath,
3207 .flags = FLAG_ADVANCED,
3210 .label = "logon drive",
3212 .p_class = P_GLOBAL,
3213 .ptr = &Globals.szLogonDrive,
3216 .flags = FLAG_ADVANCED,
3219 .label = "logon home",
3221 .p_class = P_GLOBAL,
3222 .ptr = &Globals.szLogonHome,
3225 .flags = FLAG_ADVANCED,
3228 .label = "domain logons",
3230 .p_class = P_GLOBAL,
3231 .ptr = &Globals.bDomainLogons,
3234 .flags = FLAG_ADVANCED,
3238 .label = "init logon delayed hosts",
3240 .p_class = P_GLOBAL,
3241 .ptr = &Globals.szInitLogonDelayedHosts,
3242 .flags = FLAG_ADVANCED,
3246 .label = "init logon delay",
3248 .p_class = P_GLOBAL,
3249 .ptr = &Globals.InitLogonDelay,
3250 .flags = FLAG_ADVANCED,
3254 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3257 .label = "os level",
3259 .p_class = P_GLOBAL,
3260 .ptr = &Globals.os_level,
3263 .flags = FLAG_BASIC | FLAG_ADVANCED,
3266 .label = "lm announce",
3268 .p_class = P_GLOBAL,
3269 .ptr = &Globals.lm_announce,
3271 .enum_list = enum_bool_auto,
3272 .flags = FLAG_ADVANCED,
3275 .label = "lm interval",
3277 .p_class = P_GLOBAL,
3278 .ptr = &Globals.lm_interval,
3281 .flags = FLAG_ADVANCED,
3284 .label = "preferred master",
3286 .p_class = P_GLOBAL,
3287 .ptr = &Globals.iPreferredMaster,
3289 .enum_list = enum_bool_auto,
3290 .flags = FLAG_BASIC | FLAG_ADVANCED,
3293 .label = "prefered master",
3295 .p_class = P_GLOBAL,
3296 .ptr = &Globals.iPreferredMaster,
3298 .enum_list = enum_bool_auto,
3302 .label = "local master",
3304 .p_class = P_GLOBAL,
3305 .ptr = &Globals.bLocalMaster,
3308 .flags = FLAG_BASIC | FLAG_ADVANCED,
3311 .label = "domain master",
3313 .p_class = P_GLOBAL,
3314 .ptr = &Globals.iDomainMaster,
3316 .enum_list = enum_bool_auto,
3317 .flags = FLAG_BASIC | FLAG_ADVANCED,
3320 .label = "browse list",
3322 .p_class = P_GLOBAL,
3323 .ptr = &Globals.bBrowseList,
3326 .flags = FLAG_ADVANCED,
3329 .label = "browseable",
3332 .ptr = &sDefault.bBrowseable,
3335 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3338 .label = "access based share enum",
3341 .ptr = &sDefault.bAccessBasedShareEnum,
3344 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3347 .label = "browsable",
3350 .ptr = &sDefault.bBrowseable,
3356 .label = "enhanced browsing",
3358 .p_class = P_GLOBAL,
3359 .ptr = &Globals.enhanced_browsing,
3362 .flags = FLAG_ADVANCED,
3365 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3368 .label = "dns proxy",
3370 .p_class = P_GLOBAL,
3371 .ptr = &Globals.bDNSproxy,
3374 .flags = FLAG_ADVANCED,
3377 .label = "wins proxy",
3379 .p_class = P_GLOBAL,
3380 .ptr = &Globals.bWINSproxy,
3383 .flags = FLAG_ADVANCED,
3386 .label = "wins server",
3388 .p_class = P_GLOBAL,
3389 .ptr = &Globals.szWINSservers,
3392 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3395 .label = "wins support",
3397 .p_class = P_GLOBAL,
3398 .ptr = &Globals.bWINSsupport,
3401 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3404 .label = "wins hook",
3406 .p_class = P_GLOBAL,
3407 .ptr = &Globals.szWINSHook,
3410 .flags = FLAG_ADVANCED,
3413 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3416 .label = "blocking locks",
3419 .ptr = &sDefault.bBlockingLocks,
3422 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3425 .label = "csc policy",
3428 .ptr = &sDefault.iCSCPolicy,
3430 .enum_list = enum_csc_policy,
3431 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3434 .label = "fake oplocks",
3437 .ptr = &sDefault.bFakeOplocks,
3440 .flags = FLAG_ADVANCED | FLAG_SHARE,
3443 .label = "kernel oplocks",
3445 .p_class = P_GLOBAL,
3446 .ptr = &Globals.bKernelOplocks,
3449 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3455 .ptr = &sDefault.bLocking,
3458 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3461 .label = "lock spin time",
3463 .p_class = P_GLOBAL,
3464 .ptr = &Globals.iLockSpinTime,
3467 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3473 .ptr = &sDefault.bOpLocks,
3476 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3479 .label = "level2 oplocks",
3482 .ptr = &sDefault.bLevel2OpLocks,
3485 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3488 .label = "oplock break wait time",
3490 .p_class = P_GLOBAL,
3491 .ptr = &Globals.oplock_break_wait_time,
3494 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3497 .label = "oplock contention limit",
3500 .ptr = &sDefault.iOplockContentionLimit,
3503 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3506 .label = "posix locking",
3509 .ptr = &sDefault.bPosixLocking,
3512 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3515 .label = "strict locking",
3518 .ptr = &sDefault.iStrictLocking,
3520 .enum_list = enum_bool_auto,
3521 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3524 .label = "share modes",
3527 .ptr = &sDefault.bShareModes,
3530 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3533 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3536 .label = "ldap admin dn",
3538 .p_class = P_GLOBAL,
3539 .ptr = &Globals.szLdapAdminDn,
3542 .flags = FLAG_ADVANCED,
3545 .label = "ldap delete dn",
3547 .p_class = P_GLOBAL,
3548 .ptr = &Globals.ldap_delete_dn,
3551 .flags = FLAG_ADVANCED,
3554 .label = "ldap group suffix",
3556 .p_class = P_GLOBAL,
3557 .ptr = &Globals.szLdapGroupSuffix,
3560 .flags = FLAG_ADVANCED,
3563 .label = "ldap idmap suffix",
3565 .p_class = P_GLOBAL,
3566 .ptr = &Globals.szLdapIdmapSuffix,
3569 .flags = FLAG_ADVANCED,
3572 .label = "ldap machine suffix",
3574 .p_class = P_GLOBAL,
3575 .ptr = &Globals.szLdapMachineSuffix,
3578 .flags = FLAG_ADVANCED,
3581 .label = "ldap passwd sync",
3583 .p_class = P_GLOBAL,
3584 .ptr = &Globals.ldap_passwd_sync,
3586 .enum_list = enum_ldap_passwd_sync,
3587 .flags = FLAG_ADVANCED,
3590 .label = "ldap password sync",
3592 .p_class = P_GLOBAL,
3593 .ptr = &Globals.ldap_passwd_sync,
3595 .enum_list = enum_ldap_passwd_sync,
3599 .label = "ldap replication sleep",
3601 .p_class = P_GLOBAL,
3602 .ptr = &Globals.ldap_replication_sleep,
3605 .flags = FLAG_ADVANCED,
3608 .label = "ldap suffix",
3610 .p_class = P_GLOBAL,
3611 .ptr = &Globals.szLdapSuffix,
3614 .flags = FLAG_ADVANCED,
3617 .label = "ldap ssl",
3619 .p_class = P_GLOBAL,
3620 .ptr = &Globals.ldap_ssl,
3622 .enum_list = enum_ldap_ssl,
3623 .flags = FLAG_ADVANCED,
3626 .label = "ldap ssl ads",
3628 .p_class = P_GLOBAL,
3629 .ptr = &Globals.ldap_ssl_ads,
3632 .flags = FLAG_ADVANCED,
3635 .label = "ldap timeout",
3637 .p_class = P_GLOBAL,
3638 .ptr = &Globals.ldap_timeout,
3641 .flags = FLAG_ADVANCED,
3644 .label = "ldap connection timeout",
3646 .p_class = P_GLOBAL,
3647 .ptr = &Globals.ldap_connection_timeout,
3650 .flags = FLAG_ADVANCED,
3653 .label = "ldap page size",
3655 .p_class = P_GLOBAL,
3656 .ptr = &Globals.ldap_page_size,
3659 .flags = FLAG_ADVANCED,
3662 .label = "ldap user suffix",
3664 .p_class = P_GLOBAL,
3665 .ptr = &Globals.szLdapUserSuffix,
3668 .flags = FLAG_ADVANCED,
3671 .label = "ldap debug level",
3673 .p_class = P_GLOBAL,
3674 .ptr = &Globals.ldap_debug_level,
3675 .special = handle_ldap_debug_level,
3677 .flags = FLAG_ADVANCED,
3680 .label = "ldap debug threshold",
3682 .p_class = P_GLOBAL,
3683 .ptr = &Globals.ldap_debug_threshold,
3686 .flags = FLAG_ADVANCED,
3689 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3692 .label = "eventlog list",
3694 .p_class = P_GLOBAL,
3695 .ptr = &Globals.szEventLogs,
3698 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3701 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3704 .label = "add share command",
3706 .p_class = P_GLOBAL,
3707 .ptr = &Globals.szAddShareCommand,
3710 .flags = FLAG_ADVANCED,
3713 .label = "change share command",
3715 .p_class = P_GLOBAL,
3716 .ptr = &Globals.szChangeShareCommand,
3719 .flags = FLAG_ADVANCED,
3722 .label = "delete share command",
3724 .p_class = P_GLOBAL,
3725 .ptr = &Globals.szDeleteShareCommand,
3728 .flags = FLAG_ADVANCED,
3731 .label = "config file",
3733 .p_class = P_GLOBAL,
3734 .ptr = &Globals.szConfigFile,
3742 .p_class = P_GLOBAL,
3743 .ptr = &Globals.szAutoServices,
3746 .flags = FLAG_ADVANCED,
3749 .label = "auto services",
3751 .p_class = P_GLOBAL,
3752 .ptr = &Globals.szAutoServices,
3755 .flags = FLAG_ADVANCED,
3758 .label = "lock directory",
3760 .p_class = P_GLOBAL,
3761 .ptr = &Globals.szLockDir,
3764 .flags = FLAG_ADVANCED,
3767 .label = "lock dir",
3769 .p_class = P_GLOBAL,
3770 .ptr = &Globals.szLockDir,
3776 .label = "state directory",
3778 .p_class = P_GLOBAL,
3779 .ptr = &Globals.szStateDir,
3782 .flags = FLAG_ADVANCED,
3785 .label = "cache directory",
3787 .p_class = P_GLOBAL,
3788 .ptr = &Globals.szCacheDir,
3791 .flags = FLAG_ADVANCED,
3794 .label = "pid directory",
3796 .p_class = P_GLOBAL,
3797 .ptr = &Globals.szPidDir,
3800 .flags = FLAG_ADVANCED,
3804 .label = "utmp directory",
3806 .p_class = P_GLOBAL,
3807 .ptr = &Globals.szUtmpDir,
3810 .flags = FLAG_ADVANCED,
3813 .label = "wtmp directory",
3815 .p_class = P_GLOBAL,
3816 .ptr = &Globals.szWtmpDir,
3819 .flags = FLAG_ADVANCED,
3824 .p_class = P_GLOBAL,
3825 .ptr = &Globals.bUtmp,
3828 .flags = FLAG_ADVANCED,
3832 .label = "default service",
3834 .p_class = P_GLOBAL,
3835 .ptr = &Globals.szDefaultService,
3838 .flags = FLAG_ADVANCED,
3843 .p_class = P_GLOBAL,
3844 .ptr = &Globals.szDefaultService,
3847 .flags = FLAG_ADVANCED,
3850 .label = "message command",
3852 .p_class = P_GLOBAL,
3853 .ptr = &Globals.szMsgCommand,
3856 .flags = FLAG_ADVANCED,
3859 .label = "dfree cache time",
3862 .ptr = &sDefault.iDfreeCacheTime,
3865 .flags = FLAG_ADVANCED,
3868 .label = "dfree command",
3871 .ptr = &sDefault.szDfree,
3874 .flags = FLAG_ADVANCED,
3877 .label = "get quota command",
3879 .p_class = P_GLOBAL,
3880 .ptr = &Globals.szGetQuota,
3883 .flags = FLAG_ADVANCED,
3886 .label = "set quota command",
3888 .p_class = P_GLOBAL,
3889 .ptr = &Globals.szSetQuota,
3892 .flags = FLAG_ADVANCED,
3895 .label = "remote announce",
3897 .p_class = P_GLOBAL,
3898 .ptr = &Globals.szRemoteAnnounce,
3901 .flags = FLAG_ADVANCED,
3904 .label = "remote browse sync",
3906 .p_class = P_GLOBAL,
3907 .ptr = &Globals.szRemoteBrowseSync,
3910 .flags = FLAG_ADVANCED,
3913 .label = "socket address",
3915 .p_class = P_GLOBAL,
3916 .ptr = &Globals.szSocketAddress,
3919 .flags = FLAG_ADVANCED,
3922 .label = "homedir map",
3924 .p_class = P_GLOBAL,
3925 .ptr = &Globals.szNISHomeMapName,
3928 .flags = FLAG_ADVANCED,
3931 .label = "afs username map",
3933 .p_class = P_GLOBAL,
3934 .ptr = &Globals.szAfsUsernameMap,
3937 .flags = FLAG_ADVANCED,
3940 .label = "afs token lifetime",
3942 .p_class = P_GLOBAL,
3943 .ptr = &Globals.iAfsTokenLifetime,
3946 .flags = FLAG_ADVANCED,
3949 .label = "log nt token command",
3951 .p_class = P_GLOBAL,
3952 .ptr = &Globals.szLogNtTokenCommand,
3955 .flags = FLAG_ADVANCED,
3958 .label = "time offset",
3960 .p_class = P_GLOBAL,
3961 .ptr = &extra_time_offset,
3964 .flags = FLAG_ADVANCED,
3967 .label = "NIS homedir",
3969 .p_class = P_GLOBAL,
3970 .ptr = &Globals.bNISHomeMap,
3973 .flags = FLAG_ADVANCED,
3979 .ptr = &sDefault.valid,
3988 .ptr = &sDefault.szCopy,
3989 .special = handle_copy,
3997 .ptr = &sDefault.szInclude,
3998 .special = handle_include,
4006 .ptr = &sDefault.szPreExec,
4009 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4015 .ptr = &sDefault.szPreExec,
4018 .flags = FLAG_ADVANCED,
4021 .label = "preexec close",
4024 .ptr = &sDefault.bPreexecClose,
4027 .flags = FLAG_ADVANCED | FLAG_SHARE,
4030 .label = "postexec",
4033 .ptr = &sDefault.szPostExec,
4036 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4039 .label = "root preexec",
4042 .ptr = &sDefault.szRootPreExec,
4045 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4048 .label = "root preexec close",
4051 .ptr = &sDefault.bRootpreexecClose,
4054 .flags = FLAG_ADVANCED | FLAG_SHARE,
4057 .label = "root postexec",
4060 .ptr = &sDefault.szRootPostExec,
4063 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4066 .label = "available",
4069 .ptr = &sDefault.bAvailable,
4072 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4075 .label = "registry shares",
4077 .p_class = P_GLOBAL,
4078 .ptr = &Globals.bRegistryShares,
4081 .flags = FLAG_ADVANCED,
4084 .label = "usershare allow guests",
4086 .p_class = P_GLOBAL,
4087 .ptr = &Globals.bUsershareAllowGuests,
4090 .flags = FLAG_ADVANCED,
4093 .label = "usershare max shares",
4095 .p_class = P_GLOBAL,
4096 .ptr = &Globals.iUsershareMaxShares,
4099 .flags = FLAG_ADVANCED,
4102 .label = "usershare owner only",
4104 .p_class = P_GLOBAL,
4105 .ptr = &Globals.bUsershareOwnerOnly,
4108 .flags = FLAG_ADVANCED,
4111 .label = "usershare path",
4113 .p_class = P_GLOBAL,
4114 .ptr = &Globals.szUsersharePath,
4117 .flags = FLAG_ADVANCED,
4120 .label = "usershare prefix allow list",
4122 .p_class = P_GLOBAL,
4123 .ptr = &Globals.szUsersharePrefixAllowList,
4126 .flags = FLAG_ADVANCED,
4129 .label = "usershare prefix deny list",
4131 .p_class = P_GLOBAL,
4132 .ptr = &Globals.szUsersharePrefixDenyList,
4135 .flags = FLAG_ADVANCED,
4138 .label = "usershare template share",
4140 .p_class = P_GLOBAL,
4141 .ptr = &Globals.szUsershareTemplateShare,
4144 .flags = FLAG_ADVANCED,
4150 .ptr = &sDefault.volume,
4153 .flags = FLAG_ADVANCED | FLAG_SHARE,
4159 .ptr = &sDefault.fstype,
4162 .flags = FLAG_ADVANCED | FLAG_SHARE,
4165 .label = "set directory",
4168 .ptr = &sDefault.bNo_set_dir,
4171 .flags = FLAG_ADVANCED | FLAG_SHARE,
4174 .label = "wide links",
4177 .ptr = &sDefault.bWidelinks,
4180 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4183 .label = "follow symlinks",
4186 .ptr = &sDefault.bSymlinks,
4189 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4192 .label = "dont descend",
4195 .ptr = &sDefault.szDontdescend,
4198 .flags = FLAG_ADVANCED | FLAG_SHARE,
4201 .label = "magic script",
4204 .ptr = &sDefault.szMagicScript,
4207 .flags = FLAG_ADVANCED | FLAG_SHARE,
4210 .label = "magic output",
4213 .ptr = &sDefault.szMagicOutput,
4216 .flags = FLAG_ADVANCED | FLAG_SHARE,
4219 .label = "delete readonly",
4222 .ptr = &sDefault.bDeleteReadonly,
4225 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4228 .label = "dos filemode",
4231 .ptr = &sDefault.bDosFilemode,
4234 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4237 .label = "dos filetimes",
4240 .ptr = &sDefault.bDosFiletimes,
4243 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4246 .label = "dos filetime resolution",
4249 .ptr = &sDefault.bDosFiletimeResolution,
4252 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4255 .label = "fake directory create times",
4258 .ptr = &sDefault.bFakeDirCreateTimes,
4261 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4264 .label = "panic action",
4266 .p_class = P_GLOBAL,
4267 .ptr = &Globals.szPanicAction,
4270 .flags = FLAG_ADVANCED,
4273 .label = "perfcount module",
4275 .p_class = P_GLOBAL,
4276 .ptr = &Globals.szSMBPerfcountModule,
4279 .flags = FLAG_ADVANCED,
4282 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4285 .label = "vfs objects",
4288 .ptr = &sDefault.szVfsObjects,
4291 .flags = FLAG_ADVANCED | FLAG_SHARE,
4294 .label = "vfs object",
4297 .ptr = &sDefault.szVfsObjects,
4304 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4307 .label = "msdfs root",
4310 .ptr = &sDefault.bMSDfsRoot,
4313 .flags = FLAG_ADVANCED | FLAG_SHARE,
4316 .label = "msdfs proxy",
4319 .ptr = &sDefault.szMSDfsProxy,
4322 .flags = FLAG_ADVANCED | FLAG_SHARE,
4325 .label = "host msdfs",
4327 .p_class = P_GLOBAL,
4328 .ptr = &Globals.bHostMSDfs,
4331 .flags = FLAG_ADVANCED,
4334 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4337 .label = "passdb expand explicit",
4339 .p_class = P_GLOBAL,
4340 .ptr = &Globals.bPassdbExpandExplicit,
4343 .flags = FLAG_ADVANCED,
4346 .label = "idmap backend",
4348 .p_class = P_GLOBAL,
4349 .ptr = &Globals.szIdmapBackend,
4352 .flags = FLAG_ADVANCED,
4355 .label = "idmap alloc backend",
4357 .p_class = P_GLOBAL,
4358 .ptr = &Globals.szIdmapAllocBackend,
4361 .flags = FLAG_ADVANCED,
4364 .label = "idmap cache time",
4366 .p_class = P_GLOBAL,
4367 .ptr = &Globals.iIdmapCacheTime,
4370 .flags = FLAG_ADVANCED,
4373 .label = "idmap negative cache time",
4375 .p_class = P_GLOBAL,
4376 .ptr = &Globals.iIdmapNegativeCacheTime,
4379 .flags = FLAG_ADVANCED,
4382 .label = "idmap uid",
4384 .p_class = P_GLOBAL,
4385 .ptr = &Globals.szIdmapUID,
4386 .special = handle_idmap_uid,
4388 .flags = FLAG_ADVANCED,
4391 .label = "winbind uid",
4393 .p_class = P_GLOBAL,
4394 .ptr = &Globals.szIdmapUID,
4395 .special = handle_idmap_uid,
4400 .label = "idmap gid",
4402 .p_class = P_GLOBAL,
4403 .ptr = &Globals.szIdmapGID,
4404 .special = handle_idmap_gid,
4406 .flags = FLAG_ADVANCED,
4409 .label = "winbind gid",
4411 .p_class = P_GLOBAL,
4412 .ptr = &Globals.szIdmapGID,
4413 .special = handle_idmap_gid,
4418 .label = "template homedir",
4420 .p_class = P_GLOBAL,
4421 .ptr = &Globals.szTemplateHomedir,
4424 .flags = FLAG_ADVANCED,
4427 .label = "template shell",
4429 .p_class = P_GLOBAL,
4430 .ptr = &Globals.szTemplateShell,
4433 .flags = FLAG_ADVANCED,
4436 .label = "winbind separator",
4438 .p_class = P_GLOBAL,
4439 .ptr = &Globals.szWinbindSeparator,
4442 .flags = FLAG_ADVANCED,
4445 .label = "winbind cache time",
4447 .p_class = P_GLOBAL,
4448 .ptr = &Globals.winbind_cache_time,
4451 .flags = FLAG_ADVANCED,
4454 .label = "winbind reconnect delay",
4456 .p_class = P_GLOBAL,
4457 .ptr = &Globals.winbind_reconnect_delay,
4460 .flags = FLAG_ADVANCED,
4463 .label = "winbind enum users",
4465 .p_class = P_GLOBAL,
4466 .ptr = &Globals.bWinbindEnumUsers,
4469 .flags = FLAG_ADVANCED,
4472 .label = "winbind enum groups",
4474 .p_class = P_GLOBAL,
4475 .ptr = &Globals.bWinbindEnumGroups,
4478 .flags = FLAG_ADVANCED,
4481 .label = "winbind use default domain",
4483 .p_class = P_GLOBAL,
4484 .ptr = &Globals.bWinbindUseDefaultDomain,
4487 .flags = FLAG_ADVANCED,
4490 .label = "winbind trusted domains only",
4492 .p_class = P_GLOBAL,
4493 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4496 .flags = FLAG_ADVANCED,
4499 .label = "winbind nested groups",
4501 .p_class = P_GLOBAL,
4502 .ptr = &Globals.bWinbindNestedGroups,
4505 .flags = FLAG_ADVANCED,
4508 .label = "winbind expand groups",
4510 .p_class = P_GLOBAL,
4511 .ptr = &Globals.winbind_expand_groups,
4514 .flags = FLAG_ADVANCED,
4517 .label = "winbind nss info",
4519 .p_class = P_GLOBAL,
4520 .ptr = &Globals.szWinbindNssInfo,
4523 .flags = FLAG_ADVANCED,
4526 .label = "winbind refresh tickets",
4528 .p_class = P_GLOBAL,
4529 .ptr = &Globals.bWinbindRefreshTickets,
4532 .flags = FLAG_ADVANCED,
4535 .label = "winbind offline logon",
4537 .p_class = P_GLOBAL,
4538 .ptr = &Globals.bWinbindOfflineLogon,
4541 .flags = FLAG_ADVANCED,
4544 .label = "winbind normalize names",
4546 .p_class = P_GLOBAL,
4547 .ptr = &Globals.bWinbindNormalizeNames,
4550 .flags = FLAG_ADVANCED,
4553 .label = "winbind rpc only",
4555 .p_class = P_GLOBAL,
4556 .ptr = &Globals.bWinbindRpcOnly,
4559 .flags = FLAG_ADVANCED,
4562 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4565 /***************************************************************************
4566 Initialise the sDefault parameter structure for the printer values.
4567 ***************************************************************************/
4569 static void init_printer_values(struct service *pService)
4571 /* choose defaults depending on the type of printing */
4572 switch (pService->iPrinting) {
4577 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4578 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4579 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4584 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4585 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4586 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4587 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4588 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4589 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4590 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4596 /* set the lpq command to contain the destination printer
4597 name only. This is used by cups_queue_get() */
4598 string_set(&pService->szLpqcommand, "%p");
4599 string_set(&pService->szLprmcommand, "");
4600 string_set(&pService->szPrintcommand, "");
4601 string_set(&pService->szLppausecommand, "");
4602 string_set(&pService->szLpresumecommand, "");
4603 string_set(&pService->szQueuepausecommand, "");
4604 string_set(&pService->szQueueresumecommand, "");
4606 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4607 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4608 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4609 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4610 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4611 string_set(&pService->szQueuepausecommand, "disable '%p'");
4612 string_set(&pService->szQueueresumecommand, "enable '%p'");
4613 #endif /* HAVE_CUPS */
4618 string_set(&pService->szLpqcommand, "lpstat -o%p");
4619 string_set(&pService->szLprmcommand, "cancel %p-%j");
4620 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4621 string_set(&pService->szQueuepausecommand, "disable %p");
4622 string_set(&pService->szQueueresumecommand, "enable %p");
4624 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4625 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4630 string_set(&pService->szLpqcommand, "lpq -P%p");
4631 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4632 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4638 string_set(&pService->szPrintcommand, "vlp print %p %s");
4639 string_set(&pService->szLpqcommand, "vlp lpq %p");
4640 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4641 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4642 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4643 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4644 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4646 #endif /* DEVELOPER */
4651 * Function to return the default value for the maximum number of open
4652 * file descriptors permitted. This function tries to consult the
4653 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4654 * the smaller of those.
4656 static int max_open_files(void)
4658 int sysctl_max = MAX_OPEN_FILES;
4660 bool sysctl_worked = false, rlimit_worked = false;
4662 #ifdef HAVE_SYSCTLBYNAME
4663 size_t size = sizeof(sysctl_max);
4664 if (sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,0)==0)
4665 sysctl_worked = true;
4668 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4669 rlimit_worked = true;
4671 if (sysctl_worked) {
4672 if ((!rlimit_worked) ||
4673 (rl.rlim_cur == RLIM_INFINITY) ||
4674 (rl.rlim_cur > sysctl_max))
4679 if ((!rlimit_worked) ||
4680 (rl.rlim_cur == RLIM_INFINITY))
4681 return MAX_OPEN_FILES;
4688 * Common part of freeing allocated data for one parameter.
4690 static void free_one_parameter_common(void *parm_ptr,
4691 struct parm_struct parm)
4693 if ((parm.type == P_STRING) ||
4694 (parm.type == P_USTRING))
4696 string_free((char**)parm_ptr);
4697 } else if (parm.type == P_LIST) {
4698 TALLOC_FREE(*((char***)parm_ptr));
4703 * Free the allocated data for one parameter for a share
4704 * given as a service struct.
4706 static void free_one_parameter(struct service *service,
4707 struct parm_struct parm)
4711 if (parm.p_class != P_LOCAL) {
4715 parm_ptr = lp_local_ptr(service, parm.ptr);
4717 free_one_parameter_common(parm_ptr, parm);
4721 * Free the allocated parameter data of a share given
4722 * as a service struct.
4724 static void free_parameters(struct service *service)
4728 for (i=0; parm_table[i].label; i++) {
4729 free_one_parameter(service, parm_table[i]);
4734 * Free the allocated data for one parameter for a given share
4735 * specified by an snum.
4737 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4741 if (parm.ptr == NULL) {
4746 parm_ptr = parm.ptr;
4747 } else if (parm.p_class != P_LOCAL) {
4750 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4753 free_one_parameter_common(parm_ptr, parm);
4757 * Free the allocated parameter data for a share specified
4760 static void free_parameters_by_snum(int snum)
4764 for (i=0; parm_table[i].label; i++) {
4765 free_one_parameter_by_snum(snum, parm_table[i]);
4770 * Free the allocated global parameters.
4772 static void free_global_parameters(void)
4774 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4777 /***************************************************************************
4778 Initialise the global parameter structure.
4779 ***************************************************************************/
4781 static void init_globals(bool first_time_only)
4783 static bool done_init = False;
4787 /* If requested to initialize only once and we've already done it... */
4788 if (first_time_only && done_init) {
4789 /* ... then we have nothing more to do */
4794 /* The logfile can be set before this is invoked. Free it if so. */
4795 if (Globals.szLogFile != NULL) {
4796 string_free(&Globals.szLogFile);
4797 Globals.szLogFile = NULL;
4801 free_global_parameters();
4804 memset((void *)&Globals, '\0', sizeof(Globals));
4806 for (i = 0; parm_table[i].label; i++) {
4807 if ((parm_table[i].type == P_STRING ||
4808 parm_table[i].type == P_USTRING) &&
4811 string_set((char **)parm_table[i].ptr, "");
4815 string_set(&sDefault.fstype, FSTYPE_STRING);
4816 string_set(&sDefault.szPrintjobUsername, "%U");
4818 init_printer_values(&sDefault);
4821 DEBUG(3, ("Initialising global parameters\n"));
4823 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4824 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4826 /* use the new 'hash2' method by default, with a prefix of 1 */
4827 string_set(&Globals.szManglingMethod, "hash2");
4828 Globals.mangle_prefix = 1;
4830 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4832 /* using UTF8 by default allows us to support all chars */
4833 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4835 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4836 /* If the system supports nl_langinfo(), try to grab the value
4837 from the user's locale */
4838 string_set(&Globals.display_charset, "LOCALE");
4840 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4843 /* Use codepage 850 as a default for the dos character set */
4844 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4847 * Allow the default PASSWD_CHAT to be overridden in local.h.
4849 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4851 set_global_myname(myhostname());
4852 string_set(&Globals.szNetbiosName,global_myname());
4854 set_global_myworkgroup(WORKGROUP);
4855 string_set(&Globals.szWorkgroup, lp_workgroup());
4857 string_set(&Globals.szPasswdProgram, "");
4858 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4859 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4860 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4861 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4862 string_set(&Globals.szSocketAddress, "0.0.0.0");
4864 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4865 smb_panic("init_globals: ENOMEM");
4867 string_set(&Globals.szServerString, s);
4869 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4870 DEFAULT_MINOR_VERSION) < 0) {
4871 smb_panic("init_globals: ENOMEM");
4873 string_set(&Globals.szAnnounceVersion, s);
4876 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4879 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4881 string_set(&Globals.szLogonDrive, "");
4882 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4883 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4884 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4886 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4887 string_set(&Globals.szPasswordServer, "*");
4889 Globals.AlgorithmicRidBase = BASE_RID;
4891 Globals.bLoadPrinters = True;
4892 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4894 Globals.ConfigBackend = config_backend;
4896 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4897 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4898 Globals.max_xmit = 0x4104;
4899 Globals.max_mux = 50; /* This is *needed* for profile support. */
4900 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4901 Globals.bDisableSpoolss = False;
4902 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4903 Globals.pwordlevel = 0;
4904 Globals.unamelevel = 0;
4905 Globals.deadtime = 0;
4906 Globals.getwd_cache = true;
4907 Globals.bLargeReadwrite = True;
4908 Globals.max_log_size = 5000;
4909 Globals.max_open_files = max_open_files();
4910 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4911 Globals.maxprotocol = PROTOCOL_NT1;
4912 Globals.minprotocol = PROTOCOL_CORE;
4913 Globals.security = SEC_USER;
4914 Globals.paranoid_server_security = True;
4915 Globals.bEncryptPasswords = True;
4916 Globals.bUpdateEncrypt = False;
4917 Globals.clientSchannel = Auto;
4918 Globals.serverSchannel = Auto;
4919 Globals.bReadRaw = True;
4920 Globals.bWriteRaw = True;
4921 Globals.bNullPasswords = False;
4922 Globals.bObeyPamRestrictions = False;
4924 Globals.bSyslogOnly = False;
4925 Globals.bTimestampLogs = True;
4926 string_set(&Globals.szLogLevel, "0");
4927 Globals.bDebugPrefixTimestamp = False;
4928 Globals.bDebugHiresTimestamp = False;
4929 Globals.bDebugPid = False;
4930 Globals.bDebugUid = False;
4931 Globals.bDebugClass = False;
4932 Globals.bEnableCoreFiles = True;
4933 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4934 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4935 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4936 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4937 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4938 Globals.lm_interval = 60;
4939 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4940 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4941 Globals.bNISHomeMap = False;
4942 #ifdef WITH_NISPLUS_HOME
4943 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4945 string_set(&Globals.szNISHomeMapName, "auto.home");
4948 Globals.bTimeServer = False;
4949 Globals.bBindInterfacesOnly = False;
4950 Globals.bUnixPasswdSync = False;
4951 Globals.bPamPasswordChange = False;
4952 Globals.bPasswdChatDebug = False;
4953 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4954 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4955 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4956 Globals.bStatCache = True; /* use stat cache by default */
4957 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4958 Globals.restrict_anonymous = 0;
4959 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4960 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4961 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4962 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4963 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4964 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4966 Globals.map_to_guest = 0; /* By Default, "Never" */
4967 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4968 Globals.enhanced_browsing = true;
4969 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4970 #ifdef MMAP_BLACKLIST
4971 Globals.bUseMmap = False;
4973 Globals.bUseMmap = True;
4975 Globals.bUnixExtensions = True;
4976 Globals.bResetOnZeroVC = False;
4978 /* hostname lookups can be very expensive and are broken on
4979 a large number of sites (tridge) */
4980 Globals.bHostnameLookups = False;
4982 string_set(&Globals.szPassdbBackend, "smbpasswd");
4983 string_set(&Globals.szLdapSuffix, "");
4984 string_set(&Globals.szLdapMachineSuffix, "");
4985 string_set(&Globals.szLdapUserSuffix, "");
4986 string_set(&Globals.szLdapGroupSuffix, "");
4987 string_set(&Globals.szLdapIdmapSuffix, "");
4989 string_set(&Globals.szLdapAdminDn, "");
4990 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4991 Globals.ldap_ssl_ads = False;
4992 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4993 Globals.ldap_delete_dn = False;
4994 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4995 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4996 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4997 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4999 Globals.ldap_debug_level = 0;
5000 Globals.ldap_debug_threshold = 10;
5002 /* This is what we tell the afs client. in reality we set the token
5003 * to never expire, though, when this runs out the afs client will
5004 * forget the token. Set to 0 to get NEVERDATE.*/
5005 Globals.iAfsTokenLifetime = 604800;
5006 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5008 /* these parameters are set to defaults that are more appropriate
5009 for the increasing samba install base:
5011 as a member of the workgroup, that will possibly become a
5012 _local_ master browser (lm = True). this is opposed to a forced
5013 local master browser startup (pm = True).
5015 doesn't provide WINS server service by default (wsupp = False),
5016 and doesn't provide domain master browser services by default, either.
5020 Globals.bMsAddPrinterWizard = True;
5021 Globals.os_level = 20;
5022 Globals.bLocalMaster = True;
5023 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5024 Globals.bDomainLogons = False;
5025 Globals.bBrowseList = True;
5026 Globals.bWINSsupport = False;
5027 Globals.bWINSproxy = False;
5029 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5030 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5032 Globals.bDNSproxy = True;
5034 /* this just means to use them if they exist */
5035 Globals.bKernelOplocks = True;
5037 Globals.bAllowTrustedDomains = True;
5038 string_set(&Globals.szIdmapBackend, "tdb");
5040 string_set(&Globals.szTemplateShell, "/bin/false");
5041 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5042 string_set(&Globals.szWinbindSeparator, "\\");
5044 string_set(&Globals.szCupsServer, "");
5045 string_set(&Globals.szIPrintServer, "");
5047 string_set(&Globals.ctdbdSocket, "");
5048 Globals.szClusterAddresses = NULL;
5049 Globals.clustering = False;
5051 Globals.winbind_cache_time = 300; /* 5 minutes */
5052 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5053 Globals.bWinbindEnumUsers = False;
5054 Globals.bWinbindEnumGroups = False;
5055 Globals.bWinbindUseDefaultDomain = False;
5056 Globals.bWinbindTrustedDomainsOnly = False;
5057 Globals.bWinbindNestedGroups = True;
5058 Globals.winbind_expand_groups = 1;
5059 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5060 Globals.bWinbindRefreshTickets = False;
5061 Globals.bWinbindOfflineLogon = False;
5063 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5064 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5066 Globals.bPassdbExpandExplicit = False;
5068 Globals.name_cache_timeout = 660; /* In seconds */
5070 Globals.bUseSpnego = True;
5071 Globals.bClientUseSpnego = True;
5073 Globals.client_signing = Auto;
5074 Globals.server_signing = False;
5076 Globals.bDeferSharingViolations = True;
5077 string_set(&Globals.smb_ports, SMB_PORTS);
5079 Globals.bEnablePrivileges = True;
5080 Globals.bHostMSDfs = True;
5081 Globals.bASUSupport = False;
5083 /* User defined shares. */
5084 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5085 smb_panic("init_globals: ENOMEM");
5087 string_set(&Globals.szUsersharePath, s);
5089 string_set(&Globals.szUsershareTemplateShare, "");
5090 Globals.iUsershareMaxShares = 0;
5091 /* By default disallow sharing of directories not owned by the sharer. */
5092 Globals.bUsershareOwnerOnly = True;
5093 /* By default disallow guest access to usershares. */
5094 Globals.bUsershareAllowGuests = False;
5096 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5098 /* By default no shares out of the registry */
5099 Globals.bRegistryShares = False;
5101 Globals.iminreceivefile = 0;
5103 Globals.bMapUntrustedToDomain = false;
5106 /*******************************************************************
5107 Convenience routine to grab string parameters into temporary memory
5108 and run standard_sub_basic on them. The buffers can be written to by
5109 callers without affecting the source string.
5110 ********************************************************************/
5112 static char *lp_string(const char *s)
5115 TALLOC_CTX *ctx = talloc_tos();
5117 /* The follow debug is useful for tracking down memory problems
5118 especially if you have an inner loop that is calling a lp_*()
5119 function that returns a string. Perhaps this debug should be
5120 present all the time? */
5123 DEBUG(10, ("lp_string(%s)\n", s));
5126 ret = talloc_sub_basic(ctx,
5127 get_current_username(),
5128 current_user_info.domain,
5130 if (trim_char(ret, '\"', '\"')) {
5131 if (strchr(ret,'\"') != NULL) {
5133 ret = talloc_sub_basic(ctx,
5134 get_current_username(),
5135 current_user_info.domain,
5143 In this section all the functions that are used to access the
5144 parameters from the rest of the program are defined
5147 #define FN_GLOBAL_STRING(fn_name,ptr) \
5148 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5149 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5150 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5151 #define FN_GLOBAL_LIST(fn_name,ptr) \
5152 const char **fn_name(void) {return(*(const char ***)(ptr));}
5153 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5154 bool fn_name(void) {return(*(bool *)(ptr));}
5155 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5156 char fn_name(void) {return(*(char *)(ptr));}
5157 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5158 int fn_name(void) {return(*(int *)(ptr));}
5160 #define FN_LOCAL_STRING(fn_name,val) \
5161 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5162 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5163 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5164 #define FN_LOCAL_LIST(fn_name,val) \
5165 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5166 #define FN_LOCAL_BOOL(fn_name,val) \
5167 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5168 #define FN_LOCAL_INTEGER(fn_name,val) \
5169 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5171 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5172 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5173 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5174 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5175 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5176 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));}
5177 #define FN_LOCAL_CHAR(fn_name,val) \
5178 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5180 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5181 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5182 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5183 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5184 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5185 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5186 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5187 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5188 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5189 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5190 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5191 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5192 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5193 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5194 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5195 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5196 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5197 * build process or in smb.conf, we use that value. Otherwise they
5198 * default to the value of lp_lockdir(). */
5199 char *lp_statedir(void) {
5200 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5201 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5202 return(lp_string(*(char **)(&Globals.szStateDir) ?
5203 *(char **)(&Globals.szStateDir) : ""));
5205 return(lp_string(*(char **)(&Globals.szLockDir) ?
5206 *(char **)(&Globals.szLockDir) : ""));
5208 char *lp_cachedir(void) {
5209 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5210 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5211 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5212 *(char **)(&Globals.szCacheDir) : ""));
5214 return(lp_string(*(char **)(&Globals.szLockDir) ?
5215 *(char **)(&Globals.szLockDir) : ""));
5217 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5218 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5219 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5220 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5221 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5222 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5223 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5224 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5225 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5226 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5227 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5228 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5229 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5230 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5231 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5232 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5233 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5234 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5235 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5236 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5237 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5238 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5239 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5240 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5241 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5242 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5243 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5244 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5245 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5246 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5247 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5248 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5249 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5250 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5251 * lp_passdb_backend() should be replace by the this macro again after
5254 const char *lp_passdb_backend(void)
5256 char *delim, *quote;
5258 delim = strchr( Globals.szPassdbBackend, ' ');
5259 /* no space at all */
5260 if (delim == NULL) {
5264 quote = strchr(Globals.szPassdbBackend, '"');
5265 /* no quote char or non in the first part */
5266 if (quote == NULL || quote > delim) {
5271 quote = strchr(quote+1, '"');
5272 if (quote == NULL) {
5273 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5275 } else if (*(quote+1) == '\0') {
5276 /* space, fitting quote char, and one backend only */
5279 /* terminate string after the fitting quote char */
5284 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5285 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5286 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5287 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5290 return Globals.szPassdbBackend;
5292 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5293 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5294 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5295 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5296 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5298 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5299 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5300 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5301 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5302 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5303 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5305 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5307 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5308 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5309 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5311 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5313 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5314 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5315 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5316 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5317 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5318 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5319 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5320 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5321 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5322 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5323 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5324 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5325 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5326 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5327 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5329 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5330 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5331 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5332 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5333 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5334 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5336 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5337 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5338 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5339 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5340 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5341 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5342 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5343 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5344 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5345 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5346 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5347 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5348 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5349 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5350 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5351 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5352 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5353 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5355 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5357 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5358 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5359 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5360 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5361 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5362 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5363 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5364 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5365 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5366 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5367 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5368 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5369 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5370 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5371 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5372 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5373 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5374 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5375 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5376 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5377 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5378 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5379 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5380 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5381 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5382 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5383 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5384 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5385 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5386 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5387 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5388 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5389 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5390 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5391 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5392 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5393 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5394 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5395 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5396 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5397 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5398 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5399 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5400 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5401 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5402 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5403 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5404 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5405 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5406 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5407 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5408 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5409 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5410 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5411 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5412 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5413 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5414 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5415 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5416 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5417 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5418 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5419 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5420 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5421 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5422 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5423 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5424 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5425 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5426 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5427 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5428 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5429 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5430 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5431 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5432 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5433 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5434 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5435 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5436 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5437 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5438 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5439 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5440 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5441 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5442 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5443 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5444 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5445 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5446 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5447 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5448 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5449 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5450 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5451 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5452 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5453 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5454 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5455 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5456 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5458 FN_LOCAL_STRING(lp_preexec, szPreExec)
5459 FN_LOCAL_STRING(lp_postexec, szPostExec)
5460 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5461 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5462 FN_LOCAL_STRING(lp_servicename, szService)
5463 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5464 FN_LOCAL_STRING(lp_pathname, szPath)
5465 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5466 FN_LOCAL_STRING(lp_username, szUsername)
5467 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5468 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5469 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5470 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5471 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5472 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5473 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5474 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5475 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5476 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5477 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5478 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5479 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5480 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5481 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5482 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5483 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5484 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5485 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5486 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5487 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5488 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5489 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5490 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5491 FN_LOCAL_STRING(lp_comment, comment)
5492 FN_LOCAL_STRING(lp_force_user, force_user)
5493 FN_LOCAL_STRING(lp_force_group, force_group)
5494 FN_LOCAL_LIST(lp_readlist, readlist)
5495 FN_LOCAL_LIST(lp_writelist, writelist)
5496 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5497 FN_LOCAL_STRING(lp_fstype, fstype)
5498 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5499 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5500 static FN_LOCAL_STRING(lp_volume, volume)
5501 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5502 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5503 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5504 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5505 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5506 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5507 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5508 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5509 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5510 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5511 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5512 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5513 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5514 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5515 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5516 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5517 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5518 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5519 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5520 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5521 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5522 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5523 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5524 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5525 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5526 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5527 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5528 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5529 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5530 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5531 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5532 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5533 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5534 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5535 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5536 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5537 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5538 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5539 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5540 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5541 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5542 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5543 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5544 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5545 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5546 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5547 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5548 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5549 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5550 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5551 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5552 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5553 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5554 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5555 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5556 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5557 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5558 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5559 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5560 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5561 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5562 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5563 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5564 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5565 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5566 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5567 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5568 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5569 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5570 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5571 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5572 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5573 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5574 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5575 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5576 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5577 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5578 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5579 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5580 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5581 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5582 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5583 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5584 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5585 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5586 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5587 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5588 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5589 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5590 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5591 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5592 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5593 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5594 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5595 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5596 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5597 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5598 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5599 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5601 /* local prototypes */
5603 static int map_parameter(const char *pszParmName);
5604 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5605 static const char *get_boolean(bool bool_value);
5606 static int getservicebyname(const char *pszServiceName,
5607 struct service *pserviceDest);
5608 static void copy_service(struct service *pserviceDest,
5609 struct service *pserviceSource,
5610 struct bitmap *pcopymapDest);
5611 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5613 static bool do_section(const char *pszSectionName, void *userdata);
5614 static void init_copymap(struct service *pservice);
5615 static bool hash_a_service(const char *name, int number);
5616 static void free_service_byindex(int iService);
5617 static void free_param_opts(struct param_opt_struct **popts);
5618 static char * canonicalize_servicename(const char *name);
5619 static void show_parameter(int parmIndex);
5620 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5623 * This is a helper function for parametrical options support. It returns a
5624 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5625 * parametrical functions are quite simple
5627 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5630 bool global_section = False;
5632 struct param_opt_struct *data;
5634 if (snum >= iNumServices) return NULL;
5637 data = Globals.param_opt;
5638 global_section = True;
5640 data = ServicePtrs[snum]->param_opt;
5643 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5644 DEBUG(0,("asprintf failed!\n"));
5649 if (strwicmp(data->key, param_key) == 0) {
5650 string_free(¶m_key);
5656 if (!global_section) {
5657 /* Try to fetch the same option but from globals */
5658 /* but only if we are not already working with Globals */
5659 data = Globals.param_opt;
5661 if (strwicmp(data->key, param_key) == 0) {
5662 string_free(¶m_key);
5669 string_free(¶m_key);
5675 #define MISSING_PARAMETER(name) \
5676 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5678 /*******************************************************************
5679 convenience routine to return int parameters.
5680 ********************************************************************/
5681 static int lp_int(const char *s)
5685 MISSING_PARAMETER(lp_int);
5689 return (int)strtol(s, NULL, 0);
5692 /*******************************************************************
5693 convenience routine to return unsigned long parameters.
5694 ********************************************************************/
5695 static unsigned long lp_ulong(const char *s)
5699 MISSING_PARAMETER(lp_ulong);
5703 return strtoul(s, NULL, 0);
5706 /*******************************************************************
5707 convenience routine to return boolean parameters.
5708 ********************************************************************/
5709 static bool lp_bool(const char *s)
5714 MISSING_PARAMETER(lp_bool);
5718 if (!set_boolean(s, &ret)) {
5719 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5726 /*******************************************************************
5727 convenience routine to return enum parameters.
5728 ********************************************************************/
5729 static int lp_enum(const char *s,const struct enum_list *_enum)
5733 if (!s || !*s || !_enum) {
5734 MISSING_PARAMETER(lp_enum);
5738 for (i=0; _enum[i].name; i++) {
5739 if (strequal(_enum[i].name,s))
5740 return _enum[i].value;
5743 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5747 #undef MISSING_PARAMETER
5749 /* DO NOT USE lp_parm_string ANYMORE!!!!
5750 * use lp_parm_const_string or lp_parm_talloc_string
5752 * lp_parm_string is only used to let old modules find this symbol
5754 #undef lp_parm_string
5755 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5756 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5758 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5761 /* Return parametric option from a given service. Type is a part of option before ':' */
5762 /* Parametric option has following syntax: 'Type: option = value' */
5763 /* the returned value is talloced on the talloc_tos() */
5764 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5766 struct param_opt_struct *data = get_parametrics(snum, type, option);
5768 if (data == NULL||data->value==NULL) {
5770 return lp_string(def);
5776 return lp_string(data->value);
5779 /* Return parametric option from a given service. Type is a part of option before ':' */
5780 /* Parametric option has following syntax: 'Type: option = value' */
5781 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5783 struct param_opt_struct *data = get_parametrics(snum, type, option);
5785 if (data == NULL||data->value==NULL)
5791 /* Return parametric option from a given service. Type is a part of option before ':' */
5792 /* Parametric option has following syntax: 'Type: option = value' */
5794 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5796 struct param_opt_struct *data = get_parametrics(snum, type, option);
5798 if (data == NULL||data->value==NULL)
5799 return (const char **)def;
5801 if (data->list==NULL) {
5802 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5805 return (const char **)data->list;
5808 /* Return parametric option from a given service. Type is a part of option before ':' */
5809 /* Parametric option has following syntax: 'Type: option = value' */
5811 int lp_parm_int(int snum, const char *type, const char *option, int def)
5813 struct param_opt_struct *data = get_parametrics(snum, type, option);
5815 if (data && data->value && *data->value)
5816 return lp_int(data->value);
5821 /* Return parametric option from a given service. Type is a part of option before ':' */
5822 /* Parametric option has following syntax: 'Type: option = value' */
5824 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5826 struct param_opt_struct *data = get_parametrics(snum, type, option);
5828 if (data && data->value && *data->value)
5829 return lp_ulong(data->value);
5834 /* Return parametric option from a given service. Type is a part of option before ':' */
5835 /* Parametric option has following syntax: 'Type: option = value' */
5837 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5839 struct param_opt_struct *data = get_parametrics(snum, type, option);
5841 if (data && data->value && *data->value)
5842 return lp_bool(data->value);
5847 /* Return parametric option from a given service. Type is a part of option before ':' */
5848 /* Parametric option has following syntax: 'Type: option = value' */
5850 int lp_parm_enum(int snum, const char *type, const char *option,
5851 const struct enum_list *_enum, int def)
5853 struct param_opt_struct *data = get_parametrics(snum, type, option);
5855 if (data && data->value && *data->value && _enum)
5856 return lp_enum(data->value, _enum);
5862 /***************************************************************************
5863 Initialise a service to the defaults.
5864 ***************************************************************************/
5866 static void init_service(struct service *pservice)
5868 memset((char *)pservice, '\0', sizeof(struct service));
5869 copy_service(pservice, &sDefault, NULL);
5874 * free a param_opts structure.
5875 * param_opts handling should be moved to talloc;
5876 * then this whole functions reduces to a TALLOC_FREE().
5879 static void free_param_opts(struct param_opt_struct **popts)
5881 struct param_opt_struct *opt, *next_opt;
5883 if (popts == NULL) {
5887 if (*popts != NULL) {
5888 DEBUG(5, ("Freeing parametrics:\n"));
5891 while (opt != NULL) {
5892 string_free(&opt->key);
5893 string_free(&opt->value);
5894 TALLOC_FREE(opt->list);
5895 next_opt = opt->next;
5902 /***************************************************************************
5903 Free the dynamically allocated parts of a service struct.
5904 ***************************************************************************/
5906 static void free_service(struct service *pservice)
5911 if (pservice->szService)
5912 DEBUG(5, ("free_service: Freeing service %s\n",
5913 pservice->szService));
5915 free_parameters(pservice);
5917 string_free(&pservice->szService);
5918 bitmap_free(pservice->copymap);
5920 free_param_opts(&pservice->param_opt);
5922 ZERO_STRUCTP(pservice);
5926 /***************************************************************************
5927 remove a service indexed in the ServicePtrs array from the ServiceHash
5928 and free the dynamically allocated parts
5929 ***************************************************************************/
5931 static void free_service_byindex(int idx)
5933 if ( !LP_SNUM_OK(idx) )
5936 ServicePtrs[idx]->valid = False;
5937 invalid_services[num_invalid_services++] = idx;
5939 /* we have to cleanup the hash record */
5941 if (ServicePtrs[idx]->szService) {
5942 char *canon_name = canonicalize_servicename(
5943 ServicePtrs[idx]->szService );
5945 dbwrap_delete_bystring(ServiceHash, canon_name );
5946 TALLOC_FREE(canon_name);
5949 free_service(ServicePtrs[idx]);
5952 /***************************************************************************
5953 Add a new service to the services array initialising it with the given
5955 ***************************************************************************/
5957 static int add_a_service(const struct service *pservice, const char *name)
5960 struct service tservice;
5961 int num_to_alloc = iNumServices + 1;
5963 tservice = *pservice;
5965 /* it might already exist */
5967 i = getservicebyname(name, NULL);
5969 /* Clean all parametric options for service */
5970 /* They will be added during parsing again */
5971 free_param_opts(&ServicePtrs[i]->param_opt);
5976 /* find an invalid one */
5978 if (num_invalid_services > 0) {
5979 i = invalid_services[--num_invalid_services];
5982 /* if not, then create one */
5983 if (i == iNumServices) {
5984 struct service **tsp;
5987 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5989 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5993 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5994 if (!ServicePtrs[iNumServices]) {
5995 DEBUG(0,("add_a_service: out of memory!\n"));
6000 /* enlarge invalid_services here for now... */
6001 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6003 if (tinvalid == NULL) {
6004 DEBUG(0,("add_a_service: failed to enlarge "
6005 "invalid_services!\n"));
6008 invalid_services = tinvalid;
6010 free_service_byindex(i);
6013 ServicePtrs[i]->valid = True;
6015 init_service(ServicePtrs[i]);
6016 copy_service(ServicePtrs[i], &tservice, NULL);
6018 string_set(&ServicePtrs[i]->szService, name);
6020 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6021 i, ServicePtrs[i]->szService));
6023 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6030 /***************************************************************************
6031 Convert a string to uppercase and remove whitespaces.
6032 ***************************************************************************/
6034 static char *canonicalize_servicename(const char *src)
6039 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6043 result = talloc_strdup(talloc_tos(), src);
6044 SMB_ASSERT(result != NULL);
6050 /***************************************************************************
6051 Add a name/index pair for the services array to the hash table.
6052 ***************************************************************************/
6054 static bool hash_a_service(const char *name, int idx)
6058 if ( !ServiceHash ) {
6059 DEBUG(10,("hash_a_service: creating servicehash\n"));
6060 ServiceHash = db_open_rbt(NULL);
6061 if ( !ServiceHash ) {
6062 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6067 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6070 canon_name = canonicalize_servicename( name );
6072 dbwrap_store_bystring(ServiceHash, canon_name,
6073 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6076 TALLOC_FREE(canon_name);
6081 /***************************************************************************
6082 Add a new home service, with the specified home directory, defaults coming
6084 ***************************************************************************/
6086 bool lp_add_home(const char *pszHomename, int iDefaultService,
6087 const char *user, const char *pszHomedir)
6091 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6096 if (!(*(ServicePtrs[iDefaultService]->szPath))
6097 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6098 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6101 if (!(*(ServicePtrs[i]->comment))) {
6102 char *comment = NULL;
6103 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6106 string_set(&ServicePtrs[i]->comment, comment);
6110 /* set the browseable flag from the global default */
6112 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6113 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6115 ServicePtrs[i]->autoloaded = True;
6117 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6118 user, ServicePtrs[i]->szPath ));
6123 /***************************************************************************
6124 Add a new service, based on an old one.
6125 ***************************************************************************/
6127 int lp_add_service(const char *pszService, int iDefaultService)
6129 if (iDefaultService < 0) {
6130 return add_a_service(&sDefault, pszService);
6133 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6136 /***************************************************************************
6137 Add the IPC service.
6138 ***************************************************************************/
6140 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6142 char *comment = NULL;
6143 int i = add_a_service(&sDefault, ipc_name);
6148 if (asprintf(&comment, "IPC Service (%s)",
6149 Globals.szServerString) < 0) {
6153 string_set(&ServicePtrs[i]->szPath, tmpdir());
6154 string_set(&ServicePtrs[i]->szUsername, "");
6155 string_set(&ServicePtrs[i]->comment, comment);
6156 string_set(&ServicePtrs[i]->fstype, "IPC");
6157 ServicePtrs[i]->iMaxConnections = 0;
6158 ServicePtrs[i]->bAvailable = True;
6159 ServicePtrs[i]->bRead_only = True;
6160 ServicePtrs[i]->bGuest_only = False;
6161 ServicePtrs[i]->bAdministrative_share = True;
6162 ServicePtrs[i]->bGuest_ok = guest_ok;
6163 ServicePtrs[i]->bPrint_ok = False;
6164 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6166 DEBUG(3, ("adding IPC service\n"));
6172 /***************************************************************************
6173 Add a new printer service, with defaults coming from service iFrom.
6174 ***************************************************************************/
6176 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6178 const char *comment = "From Printcap";
6179 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6184 /* note that we do NOT default the availability flag to True - */
6185 /* we take it from the default service passed. This allows all */
6186 /* dynamic printers to be disabled by disabling the [printers] */
6187 /* entry (if/when the 'available' keyword is implemented!). */
6189 /* the printer name is set to the service name. */
6190 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6191 string_set(&ServicePtrs[i]->comment, comment);
6193 /* set the browseable flag from the gloabl default */
6194 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6196 /* Printers cannot be read_only. */
6197 ServicePtrs[i]->bRead_only = False;
6198 /* No share modes on printer services. */
6199 ServicePtrs[i]->bShareModes = False;
6200 /* No oplocks on printer services. */
6201 ServicePtrs[i]->bOpLocks = False;
6202 /* Printer services must be printable. */
6203 ServicePtrs[i]->bPrint_ok = True;
6205 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6211 /***************************************************************************
6212 Check whether the given parameter name is valid.
6213 Parametric options (names containing a colon) are considered valid.
6214 ***************************************************************************/
6216 bool lp_parameter_is_valid(const char *pszParmName)
6218 return ((map_parameter(pszParmName) != -1) ||
6219 (strchr(pszParmName, ':') != NULL));
6222 /***************************************************************************
6223 Check whether the given name is the name of a global parameter.
6224 Returns True for strings belonging to parameters of class
6225 P_GLOBAL, False for all other strings, also for parametric options
6226 and strings not belonging to any option.
6227 ***************************************************************************/
6229 bool lp_parameter_is_global(const char *pszParmName)
6231 int num = map_parameter(pszParmName);
6234 return (parm_table[num].p_class == P_GLOBAL);
6240 /**************************************************************************
6241 Check whether the given name is the canonical name of a parameter.
6242 Returns False if it is not a valid parameter Name.
6243 For parametric options, True is returned.
6244 **************************************************************************/
6246 bool lp_parameter_is_canonical(const char *parm_name)
6248 if (!lp_parameter_is_valid(parm_name)) {
6252 return (map_parameter(parm_name) ==
6253 map_parameter_canonical(parm_name, NULL));
6256 /**************************************************************************
6257 Determine the canonical name for a parameter.
6258 Indicate when it is an inverse (boolean) synonym instead of a
6260 **************************************************************************/
6262 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6267 if (!lp_parameter_is_valid(parm_name)) {
6272 num = map_parameter_canonical(parm_name, inverse);
6274 /* parametric option */
6275 *canon_parm = parm_name;
6277 *canon_parm = parm_table[num].label;
6284 /**************************************************************************
6285 Determine the canonical name for a parameter.
6286 Turn the value given into the inverse boolean expression when
6287 the synonym is an invers boolean synonym.
6289 Return True if parm_name is a valid parameter name and
6290 in case it is an invers boolean synonym, if the val string could
6291 successfully be converted to the reverse bool.
6292 Return false in all other cases.
6293 **************************************************************************/
6295 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6297 const char **canon_parm,
6298 const char **canon_val)
6303 if (!lp_parameter_is_valid(parm_name)) {
6309 num = map_parameter_canonical(parm_name, &inverse);
6311 /* parametric option */
6312 *canon_parm = parm_name;
6315 *canon_parm = parm_table[num].label;
6317 if (!lp_invert_boolean(val, canon_val)) {
6329 /***************************************************************************
6330 Map a parameter's string representation to something we can use.
6331 Returns False if the parameter string is not recognised, else TRUE.
6332 ***************************************************************************/
6334 static int map_parameter(const char *pszParmName)
6338 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6341 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6342 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6345 /* Warn only if it isn't parametric option */
6346 if (strchr(pszParmName, ':') == NULL)
6347 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6348 /* We do return 'fail' for parametric options as well because they are
6349 stored in different storage
6354 /***************************************************************************
6355 Map a parameter's string representation to the index of the canonical
6356 form of the parameter (it might be a synonym).
6357 Returns -1 if the parameter string is not recognised.
6358 ***************************************************************************/
6360 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6362 int parm_num, canon_num;
6363 bool loc_inverse = False;
6365 parm_num = map_parameter(pszParmName);
6366 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6367 /* invalid, parametric or no canidate for synonyms ... */
6371 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6372 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6373 parm_num = canon_num;
6379 if (inverse != NULL) {
6380 *inverse = loc_inverse;
6385 /***************************************************************************
6386 return true if parameter number parm1 is a synonym of parameter
6387 number parm2 (parm2 being the principal name).
6388 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6390 ***************************************************************************/
6392 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6394 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6395 (parm_table[parm1].flags & FLAG_HIDE) &&
6396 !(parm_table[parm2].flags & FLAG_HIDE))
6398 if (inverse != NULL) {
6399 if ((parm_table[parm1].type == P_BOOLREV) &&
6400 (parm_table[parm2].type == P_BOOL))
6412 /***************************************************************************
6413 Show one parameter's name, type, [values,] and flags.
6414 (helper functions for show_parameter_list)
6415 ***************************************************************************/
6417 static void show_parameter(int parmIndex)
6419 int enumIndex, flagIndex;
6424 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6425 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6427 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6428 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6429 FLAG_HIDE, FLAG_DOS_STRING};
6430 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6431 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6432 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6434 printf("%s=%s", parm_table[parmIndex].label,
6435 type[parm_table[parmIndex].type]);
6436 if (parm_table[parmIndex].type == P_ENUM) {
6439 parm_table[parmIndex].enum_list[enumIndex].name;
6443 enumIndex ? "|" : "",
6444 parm_table[parmIndex].enum_list[enumIndex].name);
6449 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6450 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6453 flag_names[flagIndex]);
6458 /* output synonyms */
6460 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6461 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6462 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6463 parm_table[parmIndex2].label);
6464 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6466 printf(" (synonyms: ");
6471 printf("%s%s", parm_table[parmIndex2].label,
6472 inverse ? "[i]" : "");
6482 /***************************************************************************
6483 Show all parameter's name, type, [values,] and flags.
6484 ***************************************************************************/
6486 void show_parameter_list(void)
6488 int classIndex, parmIndex;
6489 const char *section_names[] = { "local", "global", NULL};
6491 for (classIndex=0; section_names[classIndex]; classIndex++) {
6492 printf("[%s]\n", section_names[classIndex]);
6493 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6494 if (parm_table[parmIndex].p_class == classIndex) {
6495 show_parameter(parmIndex);
6501 /***************************************************************************
6502 Check if a given string correctly represents a boolean value.
6503 ***************************************************************************/
6505 bool lp_string_is_valid_boolean(const char *parm_value)
6507 return set_boolean(parm_value, NULL);
6510 /***************************************************************************
6511 Get the standard string representation of a boolean value ("yes" or "no")
6512 ***************************************************************************/
6514 static const char *get_boolean(bool bool_value)
6516 static const char *yes_str = "yes";
6517 static const char *no_str = "no";
6519 return (bool_value ? yes_str : no_str);
6522 /***************************************************************************
6523 Provide the string of the negated boolean value associated to the boolean
6524 given as a string. Returns False if the passed string does not correctly
6525 represent a boolean.
6526 ***************************************************************************/
6528 bool lp_invert_boolean(const char *str, const char **inverse_str)
6532 if (!set_boolean(str, &val)) {
6536 *inverse_str = get_boolean(!val);
6540 /***************************************************************************
6541 Provide the canonical string representation of a boolean value given
6542 as a string. Return True on success, False if the string given does
6543 not correctly represent a boolean.
6544 ***************************************************************************/
6546 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6550 if (!set_boolean(str, &val)) {
6554 *canon_str = get_boolean(val);
6558 /***************************************************************************
6559 Find a service by name. Otherwise works like get_service.
6560 ***************************************************************************/
6562 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6568 if (ServiceHash == NULL) {
6572 canon_name = canonicalize_servicename(pszServiceName);
6574 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6576 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6577 iService = *(int *)data.dptr;
6580 TALLOC_FREE(canon_name);
6582 if ((iService != -1) && (LP_SNUM_OK(iService))
6583 && (pserviceDest != NULL)) {
6584 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6590 /***************************************************************************
6591 Copy a service structure to another.
6592 If pcopymapDest is NULL then copy all fields
6593 ***************************************************************************/
6596 * Add a parametric option to a param_opt_struct,
6597 * replacing old value, if already present.
6599 static void set_param_opt(struct param_opt_struct **opt_list,
6600 const char *opt_name,
6601 const char *opt_value)
6603 struct param_opt_struct *new_opt, *opt;
6606 if (opt_list == NULL) {
6613 /* Traverse destination */
6615 /* If we already have same option, override it */
6616 if (strwicmp(opt->key, opt_name) == 0) {
6617 string_free(&opt->value);
6618 TALLOC_FREE(opt->list);
6619 opt->value = SMB_STRDUP(opt_value);
6626 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6627 new_opt->key = SMB_STRDUP(opt_name);
6628 new_opt->value = SMB_STRDUP(opt_value);
6629 new_opt->list = NULL;
6630 DLIST_ADD(*opt_list, new_opt);
6634 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6635 struct bitmap *pcopymapDest)
6638 bool bcopyall = (pcopymapDest == NULL);
6639 struct param_opt_struct *data;
6641 for (i = 0; parm_table[i].label; i++)
6642 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6643 (bcopyall || bitmap_query(pcopymapDest,i))) {
6644 void *def_ptr = parm_table[i].ptr;
6646 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6649 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6652 switch (parm_table[i].type) {
6655 *(bool *)dest_ptr = *(bool *)src_ptr;
6661 *(int *)dest_ptr = *(int *)src_ptr;
6665 *(char *)dest_ptr = *(char *)src_ptr;
6669 string_set((char **)dest_ptr,
6674 string_set((char **)dest_ptr,
6676 strupper_m(*(char **)dest_ptr);
6679 TALLOC_FREE(*((char ***)dest_ptr));
6680 *((char ***)dest_ptr) = str_list_copy(NULL,
6681 *(const char ***)src_ptr);
6689 init_copymap(pserviceDest);
6690 if (pserviceSource->copymap)
6691 bitmap_copy(pserviceDest->copymap,
6692 pserviceSource->copymap);
6695 data = pserviceSource->param_opt;
6697 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6702 /***************************************************************************
6703 Check a service for consistency. Return False if the service is in any way
6704 incomplete or faulty, else True.
6705 ***************************************************************************/
6707 bool service_ok(int iService)
6712 if (ServicePtrs[iService]->szService[0] == '\0') {
6713 DEBUG(0, ("The following message indicates an internal error:\n"));
6714 DEBUG(0, ("No service name in service entry.\n"));
6718 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6719 /* I can't see why you'd want a non-printable printer service... */
6720 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6721 if (!ServicePtrs[iService]->bPrint_ok) {
6722 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6723 ServicePtrs[iService]->szService));
6724 ServicePtrs[iService]->bPrint_ok = True;
6726 /* [printers] service must also be non-browsable. */
6727 if (ServicePtrs[iService]->bBrowseable)
6728 ServicePtrs[iService]->bBrowseable = False;
6731 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6732 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6733 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6735 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6736 ServicePtrs[iService]->szService));
6737 ServicePtrs[iService]->bAvailable = False;
6740 /* If a service is flagged unavailable, log the fact at level 1. */
6741 if (!ServicePtrs[iService]->bAvailable)
6742 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6743 ServicePtrs[iService]->szService));
6748 static struct smbconf_ctx *lp_smbconf_ctx(void)
6751 static struct smbconf_ctx *conf_ctx = NULL;
6753 if (conf_ctx == NULL) {
6754 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6755 if (!W_ERROR_IS_OK(werr)) {
6756 DEBUG(1, ("error initializing registry configuration: "
6757 "%s\n", win_errstr(werr)));
6765 static bool process_smbconf_service(struct smbconf_service *service)
6770 if (service == NULL) {
6774 ret = do_section(service->name, NULL);
6778 for (count = 0; count < service->num_params; count++) {
6779 ret = do_parameter(service->param_names[count],
6780 service->param_values[count],
6790 * process_registry_globals
6792 static bool process_registry_globals(void)
6795 struct smbconf_service *service = NULL;
6796 TALLOC_CTX *mem_ctx = talloc_stackframe();
6797 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6800 if (conf_ctx == NULL) {
6804 ret = do_parameter("registry shares", "yes", NULL);
6809 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6810 /* nothing to read from the registry yet but make sure lp_load
6811 * doesn't return false */
6816 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6817 if (!W_ERROR_IS_OK(werr)) {
6821 ret = process_smbconf_service(service);
6827 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6830 TALLOC_FREE(mem_ctx);
6834 static bool process_registry_shares(void)
6838 struct smbconf_service **service = NULL;
6839 uint32_t num_shares = 0;
6840 TALLOC_CTX *mem_ctx = talloc_stackframe();
6841 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6844 if (conf_ctx == NULL) {
6848 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6849 if (!W_ERROR_IS_OK(werr)) {
6855 for (count = 0; count < num_shares; count++) {
6856 if (strequal(service[count]->name, GLOBAL_NAME)) {
6859 ret = process_smbconf_service(service[count]);
6866 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6869 TALLOC_FREE(mem_ctx);
6873 static struct file_lists {
6874 struct file_lists *next;
6878 } *file_lists = NULL;
6880 /*******************************************************************
6881 Keep a linked list of all config files so we know when one has changed
6882 it's date and needs to be reloaded.
6883 ********************************************************************/
6885 static void add_to_file_list(const char *fname, const char *subfname)
6887 struct file_lists *f = file_lists;
6890 if (f->name && !strcmp(f->name, fname))
6896 f = SMB_MALLOC_P(struct file_lists);
6899 f->next = file_lists;
6900 f->name = SMB_STRDUP(fname);
6905 f->subfname = SMB_STRDUP(subfname);
6911 f->modtime = file_modtime(subfname);
6913 time_t t = file_modtime(subfname);
6920 * Utility function for outsiders to check if we're running on registry.
6922 bool lp_config_backend_is_registry(void)
6924 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6928 * Utility function to check if the config backend is FILE.
6930 bool lp_config_backend_is_file(void)
6932 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6935 /*******************************************************************
6936 Check if a config file has changed date.
6937 ********************************************************************/
6939 bool lp_file_list_changed(void)
6941 struct file_lists *f = file_lists;
6943 DEBUG(6, ("lp_file_list_changed()\n"));
6945 if (lp_config_backend_is_registry()) {
6946 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6948 if (conf_ctx == NULL) {
6951 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6952 DEBUGADD(6, ("registry config changed\n"));
6961 n2 = alloc_sub_basic(get_current_username(),
6962 current_user_info.domain,
6967 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6968 f->name, n2, ctime(&f->modtime)));
6970 mod_time = file_modtime(n2);
6972 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6974 ("file %s modified: %s\n", n2,
6976 f->modtime = mod_time;
6977 SAFE_FREE(f->subfname);
6978 f->subfname = n2; /* Passing ownership of
6979 return from alloc_sub_basic
6990 /***************************************************************************
6991 Run standard_sub_basic on netbios name... needed because global_myname
6992 is not accessed through any lp_ macro.
6993 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6994 ***************************************************************************/
6996 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6999 char *netbios_name = alloc_sub_basic(get_current_username(),
7000 current_user_info.domain,
7003 ret = set_global_myname(netbios_name);
7004 SAFE_FREE(netbios_name);
7005 string_set(&Globals.szNetbiosName,global_myname());
7007 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7013 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7015 if (strcmp(*ptr, pszParmValue) != 0) {
7016 string_set(ptr, pszParmValue);
7024 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7028 ret = set_global_myworkgroup(pszParmValue);
7029 string_set(&Globals.szWorkgroup,lp_workgroup());
7034 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7038 ret = set_global_scope(pszParmValue);
7039 string_set(&Globals.szNetbiosScope,global_scope());
7044 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7046 TALLOC_FREE(Globals.szNetbiosAliases);
7047 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7048 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7051 /***************************************************************************
7052 Handle the include operation.
7053 ***************************************************************************/
7054 static bool bAllowIncludeRegistry = true;
7056 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7060 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7061 if (!bAllowIncludeRegistry) {
7064 if (bInGlobalSection) {
7065 return process_registry_globals();
7067 DEBUG(1, ("\"include = registry\" only effective "
7068 "in %s section\n", GLOBAL_NAME));
7073 fname = alloc_sub_basic(get_current_username(),
7074 current_user_info.domain,
7077 add_to_file_list(pszParmValue, fname);
7079 string_set(ptr, fname);
7081 if (file_exist(fname)) {
7082 bool ret = pm_process(fname, do_section, do_parameter, NULL);
7087 DEBUG(2, ("Can't find include file %s\n", fname));
7092 /***************************************************************************
7093 Handle the interpretation of the copy parameter.
7094 ***************************************************************************/
7096 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7100 struct service serviceTemp;
7102 string_set(ptr, pszParmValue);
7104 init_service(&serviceTemp);
7108 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7110 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7111 if (iTemp == iServiceIndex) {
7112 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7114 copy_service(ServicePtrs[iServiceIndex],
7116 ServicePtrs[iServiceIndex]->copymap);
7120 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7124 free_service(&serviceTemp);
7128 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7130 Globals.ldap_debug_level = lp_int(pszParmValue);
7131 init_ldap_debugging();
7135 /***************************************************************************
7136 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7141 idmap uid = 1000-1999
7144 We only do simple parsing checks here. The strings are parsed into useful
7145 structures in the idmap daemon code.
7147 ***************************************************************************/
7149 /* Some lp_ routines to return idmap [ug]id information */
7151 static uid_t idmap_uid_low, idmap_uid_high;
7152 static gid_t idmap_gid_low, idmap_gid_high;
7154 bool lp_idmap_uid(uid_t *low, uid_t *high)
7156 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7160 *low = idmap_uid_low;
7163 *high = idmap_uid_high;
7168 bool lp_idmap_gid(gid_t *low, gid_t *high)
7170 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7174 *low = idmap_gid_low;
7177 *high = idmap_gid_high;
7182 /* Do some simple checks on "idmap [ug]id" parameter values */
7184 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7188 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7193 string_set(ptr, pszParmValue);
7195 idmap_uid_low = low;
7196 idmap_uid_high = high;
7201 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7205 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7210 string_set(ptr, pszParmValue);
7212 idmap_gid_low = low;
7213 idmap_gid_high = high;
7218 /***************************************************************************
7219 Handle the DEBUG level list.
7220 ***************************************************************************/
7222 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7224 string_set(ptr, pszParmValueIn);
7225 return debug_parse_levels(pszParmValueIn);
7228 /***************************************************************************
7229 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7230 ***************************************************************************/
7232 static const char *append_ldap_suffix( const char *str )
7234 const char *suffix_string;
7237 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7238 Globals.szLdapSuffix );
7239 if ( !suffix_string ) {
7240 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7244 return suffix_string;
7247 const char *lp_ldap_machine_suffix(void)
7249 if (Globals.szLdapMachineSuffix[0])
7250 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7252 return lp_string(Globals.szLdapSuffix);
7255 const char *lp_ldap_user_suffix(void)
7257 if (Globals.szLdapUserSuffix[0])
7258 return append_ldap_suffix(Globals.szLdapUserSuffix);
7260 return lp_string(Globals.szLdapSuffix);
7263 const char *lp_ldap_group_suffix(void)
7265 if (Globals.szLdapGroupSuffix[0])
7266 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7268 return lp_string(Globals.szLdapSuffix);
7271 const char *lp_ldap_idmap_suffix(void)
7273 if (Globals.szLdapIdmapSuffix[0])
7274 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7276 return lp_string(Globals.szLdapSuffix);
7279 /****************************************************************************
7280 set the value for a P_ENUM
7281 ***************************************************************************/
7283 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7288 for (i = 0; parm->enum_list[i].name; i++) {
7289 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7290 *ptr = parm->enum_list[i].value;
7294 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7295 pszParmValue, parm->label));
7298 /***************************************************************************
7299 ***************************************************************************/
7301 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7303 static int parm_num = -1;
7306 if ( parm_num == -1 )
7307 parm_num = map_parameter( "printing" );
7309 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7314 s = ServicePtrs[snum];
7316 init_printer_values( s );
7322 /***************************************************************************
7323 Initialise a copymap.
7324 ***************************************************************************/
7326 static void init_copymap(struct service *pservice)
7329 if (pservice->copymap) {
7330 bitmap_free(pservice->copymap);
7332 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7333 if (!pservice->copymap)
7335 ("Couldn't allocate copymap!! (size %d)\n",
7336 (int)NUMPARAMETERS));
7338 for (i = 0; i < NUMPARAMETERS; i++)
7339 bitmap_set(pservice->copymap, i);
7342 /***************************************************************************
7343 Return the local pointer to a parameter given a service struct and the
7344 pointer into the default structure.
7345 ***************************************************************************/
7347 static void *lp_local_ptr(struct service *service, void *ptr)
7349 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7352 /***************************************************************************
7353 Return the local pointer to a parameter given the service number and the
7354 pointer into the default structure.
7355 ***************************************************************************/
7357 void *lp_local_ptr_by_snum(int snum, void *ptr)
7359 return lp_local_ptr(ServicePtrs[snum], ptr);
7362 /***************************************************************************
7363 Process a parameter for a particular service number. If snum < 0
7364 then assume we are in the globals.
7365 ***************************************************************************/
7367 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7370 void *parm_ptr = NULL; /* where we are going to store the result */
7371 void *def_ptr = NULL;
7372 struct param_opt_struct **opt_list;
7374 parmnum = map_parameter(pszParmName);
7377 if (strchr(pszParmName, ':') == NULL) {
7378 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7384 * We've got a parametric option
7387 opt_list = (snum < 0)
7388 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7389 set_param_opt(opt_list, pszParmName, pszParmValue);
7394 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7395 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7399 def_ptr = parm_table[parmnum].ptr;
7401 /* we might point at a service, the default service or a global */
7405 if (parm_table[parmnum].p_class == P_GLOBAL) {
7407 ("Global parameter %s found in service section!\n",
7411 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7415 if (!ServicePtrs[snum]->copymap)
7416 init_copymap(ServicePtrs[snum]);
7418 /* this handles the aliases - set the copymap for other entries with
7419 the same data pointer */
7420 for (i = 0; parm_table[i].label; i++)
7421 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7422 bitmap_clear(ServicePtrs[snum]->copymap, i);
7425 /* if it is a special case then go ahead */
7426 if (parm_table[parmnum].special) {
7427 return parm_table[parmnum].special(snum, pszParmValue,
7431 /* now switch on the type of variable it is */
7432 switch (parm_table[parmnum].type)
7435 *(bool *)parm_ptr = lp_bool(pszParmValue);
7439 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7443 *(int *)parm_ptr = lp_int(pszParmValue);
7447 *(char *)parm_ptr = *pszParmValue;
7451 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7453 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7458 TALLOC_FREE(*((char ***)parm_ptr));
7459 *(char ***)parm_ptr = str_list_make_v3(
7460 talloc_autofree_context(), pszParmValue, NULL);
7464 string_set((char **)parm_ptr, pszParmValue);
7468 string_set((char **)parm_ptr, pszParmValue);
7469 strupper_m(*(char **)parm_ptr);
7473 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7482 /***************************************************************************
7483 Process a parameter.
7484 ***************************************************************************/
7486 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7489 if (!bInGlobalSection && bGlobalOnly)
7492 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7494 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7495 pszParmName, pszParmValue));
7498 /***************************************************************************
7499 Print a parameter of the specified type.
7500 ***************************************************************************/
7502 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7508 for (i = 0; p->enum_list[i].name; i++) {
7509 if (*(int *)ptr == p->enum_list[i].value) {
7511 p->enum_list[i].name);
7518 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7522 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7526 fprintf(f, "%d", *(int *)ptr);
7530 fprintf(f, "%c", *(char *)ptr);
7534 char *o = octal_string(*(int *)ptr);
7535 fprintf(f, "%s", o);
7541 if ((char ***)ptr && *(char ***)ptr) {
7542 char **list = *(char ***)ptr;
7543 for (; *list; list++) {
7544 /* surround strings with whitespace in double quotes */
7545 if ( strchr_m( *list, ' ' ) )
7546 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7548 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7555 if (*(char **)ptr) {
7556 fprintf(f, "%s", *(char **)ptr);
7564 /***************************************************************************
7565 Check if two parameters are equal.
7566 ***************************************************************************/
7568 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7573 return (*((bool *)ptr1) == *((bool *)ptr2));
7578 return (*((int *)ptr1) == *((int *)ptr2));
7581 return (*((char *)ptr1) == *((char *)ptr2));
7584 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7589 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7594 return (p1 == p2 || strequal(p1, p2));
7602 /***************************************************************************
7603 Initialize any local varients in the sDefault table.
7604 ***************************************************************************/
7606 void init_locals(void)
7611 /***************************************************************************
7612 Process a new section (service). At this stage all sections are services.
7613 Later we'll have special sections that permit server parameters to be set.
7614 Returns True on success, False on failure.
7615 ***************************************************************************/
7617 static bool do_section(const char *pszSectionName, void *userdata)
7620 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7621 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7624 /* if we were in a global section then do the local inits */
7625 if (bInGlobalSection && !isglobal)
7628 /* if we've just struck a global section, note the fact. */
7629 bInGlobalSection = isglobal;
7631 /* check for multiple global sections */
7632 if (bInGlobalSection) {
7633 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7637 if (!bInGlobalSection && bGlobalOnly)
7640 /* if we have a current service, tidy it up before moving on */
7643 if (iServiceIndex >= 0)
7644 bRetval = service_ok(iServiceIndex);
7646 /* if all is still well, move to the next record in the services array */
7648 /* We put this here to avoid an odd message order if messages are */
7649 /* issued by the post-processing of a previous section. */
7650 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7652 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7654 DEBUG(0, ("Failed to add a new service\n"));
7663 /***************************************************************************
7664 Determine if a partcular base parameter is currentl set to the default value.
7665 ***************************************************************************/
7667 static bool is_default(int i)
7669 if (!defaults_saved)
7671 switch (parm_table[i].type) {
7673 return str_list_equal((const char **)parm_table[i].def.lvalue,
7674 *(const char ***)parm_table[i].ptr);
7677 return strequal(parm_table[i].def.svalue,
7678 *(char **)parm_table[i].ptr);
7681 return parm_table[i].def.bvalue ==
7682 *(bool *)parm_table[i].ptr;
7684 return parm_table[i].def.cvalue ==
7685 *(char *)parm_table[i].ptr;
7689 return parm_table[i].def.ivalue ==
7690 *(int *)parm_table[i].ptr;
7697 /***************************************************************************
7698 Display the contents of the global structure.
7699 ***************************************************************************/
7701 static void dump_globals(FILE *f)
7704 struct param_opt_struct *data;
7706 fprintf(f, "[global]\n");
7708 for (i = 0; parm_table[i].label; i++)
7709 if (parm_table[i].p_class == P_GLOBAL &&
7710 parm_table[i].ptr &&
7711 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7712 if (defaults_saved && is_default(i))
7714 fprintf(f, "\t%s = ", parm_table[i].label);
7715 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7718 if (Globals.param_opt != NULL) {
7719 data = Globals.param_opt;
7721 fprintf(f, "\t%s = %s\n", data->key, data->value);
7728 /***************************************************************************
7729 Return True if a local parameter is currently set to the global default.
7730 ***************************************************************************/
7732 bool lp_is_default(int snum, struct parm_struct *parm)
7734 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7736 return equal_parameter(parm->type,
7737 ((char *)ServicePtrs[snum]) + pdiff,
7738 ((char *)&sDefault) + pdiff);
7741 /***************************************************************************
7742 Display the contents of a single services record.
7743 ***************************************************************************/
7745 static void dump_a_service(struct service *pService, FILE * f)
7748 struct param_opt_struct *data;
7750 if (pService != &sDefault)
7751 fprintf(f, "[%s]\n", pService->szService);
7753 for (i = 0; parm_table[i].label; i++) {
7755 if (parm_table[i].p_class == P_LOCAL &&
7756 parm_table[i].ptr &&
7757 (*parm_table[i].label != '-') &&
7758 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7761 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7763 if (pService == &sDefault) {
7764 if (defaults_saved && is_default(i))
7767 if (equal_parameter(parm_table[i].type,
7768 ((char *)pService) +
7770 ((char *)&sDefault) +
7775 fprintf(f, "\t%s = ", parm_table[i].label);
7776 print_parameter(&parm_table[i],
7777 ((char *)pService) + pdiff, f);
7782 if (pService->param_opt != NULL) {
7783 data = pService->param_opt;
7785 fprintf(f, "\t%s = %s\n", data->key, data->value);
7791 /***************************************************************************
7792 Display the contents of a parameter of a single services record.
7793 ***************************************************************************/
7795 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7798 bool result = False;
7801 fstring local_parm_name;
7803 const char *parm_opt_value;
7805 /* check for parametrical option */
7806 fstrcpy( local_parm_name, parm_name);
7807 parm_opt = strchr( local_parm_name, ':');
7812 if (strlen(parm_opt)) {
7813 parm_opt_value = lp_parm_const_string( snum,
7814 local_parm_name, parm_opt, NULL);
7815 if (parm_opt_value) {
7816 printf( "%s\n", parm_opt_value);
7823 /* check for a key and print the value */
7830 for (i = 0; parm_table[i].label; i++) {
7831 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7832 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7833 parm_table[i].ptr &&
7834 (*parm_table[i].label != '-') &&
7835 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7840 ptr = parm_table[i].ptr;
7842 struct service *pService = ServicePtrs[snum];
7843 ptr = ((char *)pService) +
7844 PTR_DIFF(parm_table[i].ptr, &sDefault);
7847 print_parameter(&parm_table[i],
7858 /***************************************************************************
7859 Return info about the requested parameter (given as a string).
7860 Return NULL when the string is not a valid parameter name.
7861 ***************************************************************************/
7863 struct parm_struct *lp_get_parameter(const char *param_name)
7865 int num = map_parameter(param_name);
7871 return &parm_table[num];
7874 /***************************************************************************
7875 Return info about the next parameter in a service.
7876 snum==GLOBAL_SECTION_SNUM gives the globals.
7877 Return NULL when out of parameters.
7878 ***************************************************************************/
7880 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7883 /* do the globals */
7884 for (; parm_table[*i].label; (*i)++) {
7885 if (parm_table[*i].p_class == P_SEPARATOR)
7886 return &parm_table[(*i)++];
7888 if (!parm_table[*i].ptr
7889 || (*parm_table[*i].label == '-'))
7893 && (parm_table[*i].ptr ==
7894 parm_table[(*i) - 1].ptr))
7897 if (is_default(*i) && !allparameters)
7900 return &parm_table[(*i)++];
7903 struct service *pService = ServicePtrs[snum];
7905 for (; parm_table[*i].label; (*i)++) {
7906 if (parm_table[*i].p_class == P_SEPARATOR)
7907 return &parm_table[(*i)++];
7909 if (parm_table[*i].p_class == P_LOCAL &&
7910 parm_table[*i].ptr &&
7911 (*parm_table[*i].label != '-') &&
7913 (parm_table[*i].ptr !=
7914 parm_table[(*i) - 1].ptr)))
7917 PTR_DIFF(parm_table[*i].ptr,
7920 if (allparameters ||
7921 !equal_parameter(parm_table[*i].type,
7922 ((char *)pService) +
7924 ((char *)&sDefault) +
7927 return &parm_table[(*i)++];
7938 /***************************************************************************
7939 Display the contents of a single copy structure.
7940 ***************************************************************************/
7941 static void dump_copy_map(bool *pcopymap)
7947 printf("\n\tNon-Copied parameters:\n");
7949 for (i = 0; parm_table[i].label; i++)
7950 if (parm_table[i].p_class == P_LOCAL &&
7951 parm_table[i].ptr && !pcopymap[i] &&
7952 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7954 printf("\t\t%s\n", parm_table[i].label);
7959 /***************************************************************************
7960 Return TRUE if the passed service number is within range.
7961 ***************************************************************************/
7963 bool lp_snum_ok(int iService)
7965 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7968 /***************************************************************************
7969 Auto-load some home services.
7970 ***************************************************************************/
7972 static void lp_add_auto_services(char *str)
7982 s = SMB_STRDUP(str);
7986 homes = lp_servicenumber(HOMES_NAME);
7988 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7989 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7992 if (lp_servicenumber(p) >= 0)
7995 home = get_user_home_dir(talloc_tos(), p);
7997 if (home && homes >= 0)
7998 lp_add_home(p, homes, p, home);
8005 /***************************************************************************
8006 Auto-load one printer.
8007 ***************************************************************************/
8009 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8011 int printers = lp_servicenumber(PRINTERS_NAME);
8014 if (lp_servicenumber(name) < 0) {
8015 lp_add_printer(name, printers);
8016 if ((i = lp_servicenumber(name)) >= 0) {
8017 string_set(&ServicePtrs[i]->comment, comment);
8018 ServicePtrs[i]->autoloaded = True;
8023 /***************************************************************************
8024 Have we loaded a services file yet?
8025 ***************************************************************************/
8027 bool lp_loaded(void)
8032 /***************************************************************************
8033 Unload unused services.
8034 ***************************************************************************/
8036 void lp_killunused(bool (*snumused) (int))
8039 for (i = 0; i < iNumServices; i++) {
8043 /* don't kill autoloaded or usershare services */
8044 if ( ServicePtrs[i]->autoloaded ||
8045 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8049 if (!snumused || !snumused(i)) {
8050 free_service_byindex(i);
8056 * Kill all except autoloaded and usershare services - convenience wrapper
8058 void lp_kill_all_services(void)
8060 lp_killunused(NULL);
8063 /***************************************************************************
8065 ***************************************************************************/
8067 void lp_killservice(int iServiceIn)
8069 if (VALID(iServiceIn)) {
8070 free_service_byindex(iServiceIn);
8074 /***************************************************************************
8075 Save the curent values of all global and sDefault parameters into the
8076 defaults union. This allows swat and testparm to show only the
8077 changed (ie. non-default) parameters.
8078 ***************************************************************************/
8080 static void lp_save_defaults(void)
8083 for (i = 0; parm_table[i].label; i++) {
8084 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8086 switch (parm_table[i].type) {
8088 parm_table[i].def.lvalue = str_list_copy(
8089 NULL, *(const char ***)parm_table[i].ptr);
8093 if (parm_table[i].ptr) {
8094 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8096 parm_table[i].def.svalue = NULL;
8101 parm_table[i].def.bvalue =
8102 *(bool *)parm_table[i].ptr;
8105 parm_table[i].def.cvalue =
8106 *(char *)parm_table[i].ptr;
8111 parm_table[i].def.ivalue =
8112 *(int *)parm_table[i].ptr;
8118 defaults_saved = True;
8121 /*******************************************************************
8122 Set the server type we will announce as via nmbd.
8123 ********************************************************************/
8125 static const struct srv_role_tab {
8127 const char *role_str;
8128 } srv_role_tab [] = {
8129 { ROLE_STANDALONE, "ROLE_STANDALONE" },
8130 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8131 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8132 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8136 const char* server_role_str(uint32 role)
8139 for (i=0; srv_role_tab[i].role_str; i++) {
8140 if (role == srv_role_tab[i].role) {
8141 return srv_role_tab[i].role_str;
8147 static void set_server_role(void)
8149 server_role = ROLE_STANDALONE;
8151 switch (lp_security()) {
8153 if (lp_domain_logons())
8154 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8157 if (lp_domain_logons())
8158 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8159 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8160 server_role = ROLE_STANDALONE;
8163 if (lp_domain_logons()) {
8164 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8165 server_role = ROLE_DOMAIN_BDC;
8168 server_role = ROLE_DOMAIN_MEMBER;
8171 if (lp_domain_logons()) {
8172 server_role = ROLE_DOMAIN_PDC;
8175 server_role = ROLE_DOMAIN_MEMBER;
8178 if (lp_domain_logons()) {
8180 if (Globals.iDomainMaster) /* auto or yes */
8181 server_role = ROLE_DOMAIN_PDC;
8183 server_role = ROLE_DOMAIN_BDC;
8187 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8191 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8194 /***********************************************************
8195 If we should send plaintext/LANMAN passwords in the clinet
8196 ************************************************************/
8198 static void set_allowed_client_auth(void)
8200 if (Globals.bClientNTLMv2Auth) {
8201 Globals.bClientLanManAuth = False;
8203 if (!Globals.bClientLanManAuth) {
8204 Globals.bClientPlaintextAuth = False;
8208 /***************************************************************************
8210 The following code allows smbd to read a user defined share file.
8211 Yes, this is my intent. Yes, I'm comfortable with that...
8213 THE FOLLOWING IS SECURITY CRITICAL CODE.
8215 It washes your clothes, it cleans your house, it guards you while you sleep...
8216 Do not f%^k with it....
8217 ***************************************************************************/
8219 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8221 /***************************************************************************
8222 Check allowed stat state of a usershare file.
8223 Ensure we print out who is dicking with us so the admin can
8224 get their sorry ass fired.
8225 ***************************************************************************/
8227 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8229 if (!S_ISREG(psbuf->st_mode)) {
8230 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8231 "not a regular file\n",
8232 fname, (unsigned int)psbuf->st_uid ));
8236 /* Ensure this doesn't have the other write bit set. */
8237 if (psbuf->st_mode & S_IWOTH) {
8238 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8239 "public write. Refusing to allow as a usershare file.\n",
8240 fname, (unsigned int)psbuf->st_uid ));
8244 /* Should be 10k or less. */
8245 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8246 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8247 "too large (%u) to be a user share file.\n",
8248 fname, (unsigned int)psbuf->st_uid,
8249 (unsigned int)psbuf->st_size ));
8256 /***************************************************************************
8257 Parse the contents of a usershare file.
8258 ***************************************************************************/
8260 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8261 SMB_STRUCT_STAT *psbuf,
8262 const char *servicename,
8266 char **pp_sharepath,
8271 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8272 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8275 SMB_STRUCT_STAT sbuf;
8276 char *sharepath = NULL;
8277 char *comment = NULL;
8279 *pp_sharepath = NULL;
8282 *pallow_guest = False;
8285 return USERSHARE_MALFORMED_FILE;
8288 if (strcmp(lines[0], "#VERSION 1") == 0) {
8290 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8293 return USERSHARE_MALFORMED_FILE;
8296 return USERSHARE_BAD_VERSION;
8299 if (strncmp(lines[1], "path=", 5) != 0) {
8300 return USERSHARE_MALFORMED_PATH;
8303 sharepath = talloc_strdup(ctx, &lines[1][5]);
8305 return USERSHARE_POSIX_ERR;
8307 trim_string(sharepath, " ", " ");
8309 if (strncmp(lines[2], "comment=", 8) != 0) {
8310 return USERSHARE_MALFORMED_COMMENT_DEF;
8313 comment = talloc_strdup(ctx, &lines[2][8]);
8315 return USERSHARE_POSIX_ERR;
8317 trim_string(comment, " ", " ");
8318 trim_char(comment, '"', '"');
8320 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8321 return USERSHARE_MALFORMED_ACL_DEF;
8324 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8325 return USERSHARE_ACL_ERR;
8329 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8330 return USERSHARE_MALFORMED_ACL_DEF;
8332 if (lines[4][9] == 'y') {
8333 *pallow_guest = True;
8337 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8338 /* Path didn't change, no checks needed. */
8339 *pp_sharepath = sharepath;
8340 *pp_comment = comment;
8341 return USERSHARE_OK;
8344 /* The path *must* be absolute. */
8345 if (sharepath[0] != '/') {
8346 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8347 servicename, sharepath));
8348 return USERSHARE_PATH_NOT_ABSOLUTE;
8351 /* If there is a usershare prefix deny list ensure one of these paths
8352 doesn't match the start of the user given path. */
8353 if (prefixdenylist) {
8355 for ( i=0; prefixdenylist[i]; i++ ) {
8356 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8357 servicename, i, prefixdenylist[i], sharepath ));
8358 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8359 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8360 "usershare prefix deny list entries.\n",
8361 servicename, sharepath));
8362 return USERSHARE_PATH_IS_DENIED;
8367 /* If there is a usershare prefix allow list ensure one of these paths
8368 does match the start of the user given path. */
8370 if (prefixallowlist) {
8372 for ( i=0; prefixallowlist[i]; i++ ) {
8373 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8374 servicename, i, prefixallowlist[i], sharepath ));
8375 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8379 if (prefixallowlist[i] == NULL) {
8380 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8381 "usershare prefix allow list entries.\n",
8382 servicename, sharepath));
8383 return USERSHARE_PATH_NOT_ALLOWED;
8387 /* Ensure this is pointing to a directory. */
8388 dp = sys_opendir(sharepath);
8391 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8392 servicename, sharepath));
8393 return USERSHARE_PATH_NOT_DIRECTORY;
8396 /* Ensure the owner of the usershare file has permission to share
8399 if (sys_stat(sharepath, &sbuf) == -1) {
8400 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8401 servicename, sharepath, strerror(errno) ));
8403 return USERSHARE_POSIX_ERR;
8408 if (!S_ISDIR(sbuf.st_mode)) {
8409 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8410 servicename, sharepath ));
8411 return USERSHARE_PATH_NOT_DIRECTORY;
8414 /* Check if sharing is restricted to owner-only. */
8415 /* psbuf is the stat of the usershare definition file,
8416 sbuf is the stat of the target directory to be shared. */
8418 if (lp_usershare_owner_only()) {
8419 /* root can share anything. */
8420 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8421 return USERSHARE_PATH_NOT_ALLOWED;
8425 *pp_sharepath = sharepath;
8426 *pp_comment = comment;
8427 return USERSHARE_OK;
8430 /***************************************************************************
8431 Deal with a usershare file.
8434 -1 - Bad name, invalid contents.
8435 - service name already existed and not a usershare, problem
8436 with permissions to share directory etc.
8437 ***************************************************************************/
8439 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8441 SMB_STRUCT_STAT sbuf;
8442 SMB_STRUCT_STAT lsbuf;
8444 char *sharepath = NULL;
8445 char *comment = NULL;
8446 fstring service_name;
8447 char **lines = NULL;
8451 TALLOC_CTX *ctx = NULL;
8452 SEC_DESC *psd = NULL;
8453 bool guest_ok = False;
8455 /* Ensure share name doesn't contain invalid characters. */
8456 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8457 DEBUG(0,("process_usershare_file: share name %s contains "
8458 "invalid characters (any of %s)\n",
8459 file_name, INVALID_SHARENAME_CHARS ));
8463 fstrcpy(service_name, file_name);
8465 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8468 /* Minimize the race condition by doing an lstat before we
8469 open and fstat. Ensure this isn't a symlink link. */
8471 if (sys_lstat(fname, &lsbuf) != 0) {
8472 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8473 fname, strerror(errno) ));
8478 /* This must be a regular file, not a symlink, directory or
8479 other strange filetype. */
8480 if (!check_usershare_stat(fname, &lsbuf)) {
8486 char *canon_name = canonicalize_servicename(service_name);
8487 TDB_DATA data = dbwrap_fetch_bystring(
8488 ServiceHash, canon_name, canon_name);
8492 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8493 iService = *(int *)data.dptr;
8495 TALLOC_FREE(canon_name);
8498 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8499 /* Nothing changed - Mark valid and return. */
8500 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8502 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8507 /* Try and open the file read only - no symlinks allowed. */
8509 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8511 fd = sys_open(fname, O_RDONLY, 0);
8515 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8516 fname, strerror(errno) ));
8521 /* Now fstat to be *SURE* it's a regular file. */
8522 if (sys_fstat(fd, &sbuf) != 0) {
8524 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8525 fname, strerror(errno) ));
8530 /* Is it the same dev/inode as was lstated ? */
8531 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8533 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8534 "Symlink spoofing going on ?\n", fname ));
8539 /* This must be a regular file, not a symlink, directory or
8540 other strange filetype. */
8541 if (!check_usershare_stat(fname, &sbuf)) {
8546 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8549 if (lines == NULL) {
8550 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8551 fname, (unsigned int)sbuf.st_uid ));
8558 /* Should we allow printers to be shared... ? */
8559 ctx = talloc_init("usershare_sd_xctx");
8565 if (parse_usershare_file(ctx, &sbuf, service_name,
8566 iService, lines, numlines, &sharepath,
8567 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8568 talloc_destroy(ctx);
8575 /* Everything ok - add the service possibly using a template. */
8577 const struct service *sp = &sDefault;
8578 if (snum_template != -1) {
8579 sp = ServicePtrs[snum_template];
8582 if ((iService = add_a_service(sp, service_name)) < 0) {
8583 DEBUG(0, ("process_usershare_file: Failed to add "
8584 "new service %s\n", service_name));
8585 talloc_destroy(ctx);
8589 /* Read only is controlled by usershare ACL below. */
8590 ServicePtrs[iService]->bRead_only = False;
8593 /* Write the ACL of the new/modified share. */
8594 if (!set_share_security(service_name, psd)) {
8595 DEBUG(0, ("process_usershare_file: Failed to set share "
8596 "security for user share %s\n",
8598 lp_remove_service(iService);
8599 talloc_destroy(ctx);
8603 /* If from a template it may be marked invalid. */
8604 ServicePtrs[iService]->valid = True;
8606 /* Set the service as a valid usershare. */
8607 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8609 /* Set guest access. */
8610 if (lp_usershare_allow_guests()) {
8611 ServicePtrs[iService]->bGuest_ok = guest_ok;
8614 /* And note when it was loaded. */
8615 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8616 string_set(&ServicePtrs[iService]->szPath, sharepath);
8617 string_set(&ServicePtrs[iService]->comment, comment);
8619 talloc_destroy(ctx);
8624 /***************************************************************************
8625 Checks if a usershare entry has been modified since last load.
8626 ***************************************************************************/
8628 static bool usershare_exists(int iService, time_t *last_mod)
8630 SMB_STRUCT_STAT lsbuf;
8631 const char *usersharepath = Globals.szUsersharePath;
8634 if (asprintf(&fname, "%s/%s",
8636 ServicePtrs[iService]->szService) < 0) {
8640 if (sys_lstat(fname, &lsbuf) != 0) {
8645 if (!S_ISREG(lsbuf.st_mode)) {
8651 *last_mod = lsbuf.st_mtime;
8655 /***************************************************************************
8656 Load a usershare service by name. Returns a valid servicenumber or -1.
8657 ***************************************************************************/
8659 int load_usershare_service(const char *servicename)
8661 SMB_STRUCT_STAT sbuf;
8662 const char *usersharepath = Globals.szUsersharePath;
8663 int max_user_shares = Globals.iUsershareMaxShares;
8664 int snum_template = -1;
8666 if (*usersharepath == 0 || max_user_shares == 0) {
8670 if (sys_stat(usersharepath, &sbuf) != 0) {
8671 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8672 usersharepath, strerror(errno) ));
8676 if (!S_ISDIR(sbuf.st_mode)) {
8677 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8683 * This directory must be owned by root, and have the 't' bit set.
8684 * It also must not be writable by "other".
8688 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8690 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8692 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8693 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8698 /* Ensure the template share exists if it's set. */
8699 if (Globals.szUsershareTemplateShare[0]) {
8700 /* We can't use lp_servicenumber here as we are recommending that
8701 template shares have -valid=False set. */
8702 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8703 if (ServicePtrs[snum_template]->szService &&
8704 strequal(ServicePtrs[snum_template]->szService,
8705 Globals.szUsershareTemplateShare)) {
8710 if (snum_template == -1) {
8711 DEBUG(0,("load_usershare_service: usershare template share %s "
8712 "does not exist.\n",
8713 Globals.szUsershareTemplateShare ));
8718 return process_usershare_file(usersharepath, servicename, snum_template);
8721 /***************************************************************************
8722 Load all user defined shares from the user share directory.
8723 We only do this if we're enumerating the share list.
8724 This is the function that can delete usershares that have
8726 ***************************************************************************/
8728 int load_usershare_shares(void)
8731 SMB_STRUCT_STAT sbuf;
8732 SMB_STRUCT_DIRENT *de;
8733 int num_usershares = 0;
8734 int max_user_shares = Globals.iUsershareMaxShares;
8735 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8736 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8737 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8739 int snum_template = -1;
8740 const char *usersharepath = Globals.szUsersharePath;
8741 int ret = lp_numservices();
8743 if (max_user_shares == 0 || *usersharepath == '\0') {
8744 return lp_numservices();
8747 if (sys_stat(usersharepath, &sbuf) != 0) {
8748 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8749 usersharepath, strerror(errno) ));
8754 * This directory must be owned by root, and have the 't' bit set.
8755 * It also must not be writable by "other".
8759 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8761 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8763 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8764 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8769 /* Ensure the template share exists if it's set. */
8770 if (Globals.szUsershareTemplateShare[0]) {
8771 /* We can't use lp_servicenumber here as we are recommending that
8772 template shares have -valid=False set. */
8773 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8774 if (ServicePtrs[snum_template]->szService &&
8775 strequal(ServicePtrs[snum_template]->szService,
8776 Globals.szUsershareTemplateShare)) {
8781 if (snum_template == -1) {
8782 DEBUG(0,("load_usershare_shares: usershare template share %s "
8783 "does not exist.\n",
8784 Globals.szUsershareTemplateShare ));
8789 /* Mark all existing usershares as pending delete. */
8790 for (iService = iNumServices - 1; iService >= 0; iService--) {
8791 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8792 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8796 dp = sys_opendir(usersharepath);
8798 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8799 usersharepath, strerror(errno) ));
8803 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8804 (de = sys_readdir(dp));
8805 num_dir_entries++ ) {
8807 const char *n = de->d_name;
8809 /* Ignore . and .. */
8811 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8817 /* Temporary file used when creating a share. */
8818 num_tmp_dir_entries++;
8821 /* Allow 20% tmp entries. */
8822 if (num_tmp_dir_entries > allowed_tmp_entries) {
8823 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8824 "in directory %s\n",
8825 num_tmp_dir_entries, usersharepath));
8829 r = process_usershare_file(usersharepath, n, snum_template);
8831 /* Update the services count. */
8833 if (num_usershares >= max_user_shares) {
8834 DEBUG(0,("load_usershare_shares: max user shares reached "
8835 "on file %s in directory %s\n",
8836 n, usersharepath ));
8839 } else if (r == -1) {
8840 num_bad_dir_entries++;
8843 /* Allow 20% bad entries. */
8844 if (num_bad_dir_entries > allowed_bad_entries) {
8845 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8846 "in directory %s\n",
8847 num_bad_dir_entries, usersharepath));
8851 /* Allow 20% bad entries. */
8852 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8853 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8854 "in directory %s\n",
8855 num_dir_entries, usersharepath));
8862 /* Sweep through and delete any non-refreshed usershares that are
8863 not currently in use. */
8864 for (iService = iNumServices - 1; iService >= 0; iService--) {
8865 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8866 if (conn_snum_used(iService)) {
8869 /* Remove from the share ACL db. */
8870 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8871 lp_servicename(iService) ));
8872 delete_share_security(lp_servicename(iService));
8873 free_service_byindex(iService);
8877 return lp_numservices();
8880 /********************************************************
8881 Destroy global resources allocated in this file
8882 ********************************************************/
8884 void gfree_loadparm(void)
8886 struct file_lists *f;
8887 struct file_lists *next;
8890 /* Free the file lists */
8895 SAFE_FREE( f->name );
8896 SAFE_FREE( f->subfname );
8902 /* Free resources allocated to services */
8904 for ( i = 0; i < iNumServices; i++ ) {
8906 free_service_byindex(i);
8910 SAFE_FREE( ServicePtrs );
8913 /* Now release all resources allocated to global
8914 parameters and the default service */
8916 free_global_parameters();
8920 /***************************************************************************
8921 Allow client apps to specify that they are a client
8922 ***************************************************************************/
8923 void lp_set_in_client(bool b)
8929 /***************************************************************************
8930 Determine if we're running in a client app
8931 ***************************************************************************/
8932 bool lp_is_in_client(void)
8937 /***************************************************************************
8938 Load the services array from the services file. Return True on success,
8940 ***************************************************************************/
8942 bool lp_load_ex(const char *pszFname,
8946 bool initialize_globals,
8947 bool allow_include_registry,
8948 bool allow_registry_shares)
8955 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8957 bInGlobalSection = True;
8958 bGlobalOnly = global_only;
8959 bAllowIncludeRegistry = allow_include_registry;
8961 init_globals(! initialize_globals);
8964 if (save_defaults) {
8969 free_param_opts(&Globals.param_opt);
8971 /* We get sections first, so have to start 'behind' to make up */
8974 if (lp_config_backend_is_file()) {
8975 n2 = alloc_sub_basic(get_current_username(),
8976 current_user_info.domain,
8979 smb_panic("lp_load_ex: out of memory");
8982 add_to_file_list(pszFname, n2);
8984 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8987 /* finish up the last section */
8988 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8990 if (iServiceIndex >= 0) {
8991 bRetval = service_ok(iServiceIndex);
8995 if (lp_config_backend_is_registry()) {
8996 /* config backend changed to registry in config file */
8998 * We need to use this extra global variable here to
8999 * survive restart: init_globals uses this as a default
9000 * for ConfigBackend. Otherwise, init_globals would
9001 * send us into an endless loop here.
9003 config_backend = CONFIG_BACKEND_REGISTRY;
9005 DEBUG(1, ("lp_load_ex: changing to config backend "
9007 init_globals(false);
9008 lp_kill_all_services();
9009 return lp_load_ex(pszFname, global_only, save_defaults,
9010 add_ipc, initialize_globals,
9011 allow_include_registry,
9012 allow_registry_shares);
9014 } else if (lp_config_backend_is_registry()) {
9015 bRetval = process_registry_globals();
9017 DEBUG(0, ("Illegal config backend given: %d\n",
9018 lp_config_backend()));
9022 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9023 bRetval = process_registry_shares();
9026 lp_add_auto_services(lp_auto_services());
9029 /* When 'restrict anonymous = 2' guest connections to ipc$
9031 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9032 if ( lp_enable_asu_support() ) {
9033 lp_add_ipc("ADMIN$", false);
9038 set_default_server_announce_type();
9039 set_allowed_client_auth();
9043 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9044 /* if bWINSsupport is true and we are in the client */
9045 if (lp_is_in_client() && Globals.bWINSsupport) {
9046 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9051 bAllowIncludeRegistry = true;
9056 bool lp_load(const char *pszFname,
9060 bool initialize_globals)
9062 return lp_load_ex(pszFname,
9070 bool lp_load_initial_only(const char *pszFname)
9072 return lp_load_ex(pszFname,
9081 bool lp_load_with_registry_shares(const char *pszFname,
9085 bool initialize_globals)
9087 return lp_load_ex(pszFname,
9096 /***************************************************************************
9097 Return the max number of services.
9098 ***************************************************************************/
9100 int lp_numservices(void)
9102 return (iNumServices);
9105 /***************************************************************************
9106 Display the contents of the services array in human-readable form.
9107 ***************************************************************************/
9109 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9114 defaults_saved = False;
9118 dump_a_service(&sDefault, f);
9120 for (iService = 0; iService < maxtoprint; iService++) {
9122 lp_dump_one(f, show_defaults, iService);
9126 /***************************************************************************
9127 Display the contents of one service in human-readable form.
9128 ***************************************************************************/
9130 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9133 if (ServicePtrs[snum]->szService[0] == '\0')
9135 dump_a_service(ServicePtrs[snum], f);
9139 /***************************************************************************
9140 Return the number of the service with the given name, or -1 if it doesn't
9141 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9142 getservicebyname()! This works ONLY if all services have been loaded, and
9143 does not copy the found service.
9144 ***************************************************************************/
9146 int lp_servicenumber(const char *pszServiceName)
9149 fstring serviceName;
9151 if (!pszServiceName) {
9152 return GLOBAL_SECTION_SNUM;
9155 for (iService = iNumServices - 1; iService >= 0; iService--) {
9156 if (VALID(iService) && ServicePtrs[iService]->szService) {
9158 * The substitution here is used to support %U is
9161 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9162 standard_sub_basic(get_current_username(),
9163 current_user_info.domain,
9164 serviceName,sizeof(serviceName));
9165 if (strequal(serviceName, pszServiceName)) {
9171 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9174 if (!usershare_exists(iService, &last_mod)) {
9175 /* Remove the share security tdb entry for it. */
9176 delete_share_security(lp_servicename(iService));
9177 /* Remove it from the array. */
9178 free_service_byindex(iService);
9179 /* Doesn't exist anymore. */
9180 return GLOBAL_SECTION_SNUM;
9183 /* Has it been modified ? If so delete and reload. */
9184 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9185 /* Remove it from the array. */
9186 free_service_byindex(iService);
9187 /* and now reload it. */
9188 iService = load_usershare_service(pszServiceName);
9193 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9194 return GLOBAL_SECTION_SNUM;
9200 bool share_defined(const char *service_name)
9202 return (lp_servicenumber(service_name) != -1);
9205 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9206 const char *sharename)
9208 struct share_params *result;
9212 if (!(sname = SMB_STRDUP(sharename))) {
9216 snum = find_service(sname);
9223 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9224 DEBUG(0, ("talloc failed\n"));
9228 result->service = snum;
9232 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9234 struct share_iterator *result;
9236 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9237 DEBUG(0, ("talloc failed\n"));
9241 result->next_id = 0;
9245 struct share_params *next_share(struct share_iterator *list)
9247 struct share_params *result;
9249 while (!lp_snum_ok(list->next_id) &&
9250 (list->next_id < lp_numservices())) {
9254 if (list->next_id >= lp_numservices()) {
9258 if (!(result = TALLOC_P(list, struct share_params))) {
9259 DEBUG(0, ("talloc failed\n"));
9263 result->service = list->next_id;
9268 struct share_params *next_printer(struct share_iterator *list)
9270 struct share_params *result;
9272 while ((result = next_share(list)) != NULL) {
9273 if (lp_print_ok(result->service)) {
9281 * This is a hack for a transition period until we transformed all code from
9282 * service numbers to struct share_params.
9285 struct share_params *snum2params_static(int snum)
9287 static struct share_params result;
9288 result.service = snum;
9292 /*******************************************************************
9293 A useful volume label function.
9294 ********************************************************************/
9296 const char *volume_label(int snum)
9299 const char *label = lp_volume(snum);
9301 label = lp_servicename(snum);
9304 /* This returns a 33 byte guarenteed null terminated string. */
9305 ret = talloc_strndup(talloc_tos(), label, 32);
9312 /*******************************************************************
9313 Set the server type we will announce as via nmbd.
9314 ********************************************************************/
9316 static void set_default_server_announce_type(void)
9318 default_server_announce = 0;
9319 default_server_announce |= SV_TYPE_WORKSTATION;
9320 default_server_announce |= SV_TYPE_SERVER;
9321 default_server_announce |= SV_TYPE_SERVER_UNIX;
9323 /* note that the flag should be set only if we have a
9324 printer service but nmbd doesn't actually load the
9325 services so we can't tell --jerry */
9327 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9329 switch (lp_announce_as()) {
9330 case ANNOUNCE_AS_NT_SERVER:
9331 default_server_announce |= SV_TYPE_SERVER_NT;
9332 /* fall through... */
9333 case ANNOUNCE_AS_NT_WORKSTATION:
9334 default_server_announce |= SV_TYPE_NT;
9336 case ANNOUNCE_AS_WIN95:
9337 default_server_announce |= SV_TYPE_WIN95_PLUS;
9339 case ANNOUNCE_AS_WFW:
9340 default_server_announce |= SV_TYPE_WFW;
9346 switch (lp_server_role()) {
9347 case ROLE_DOMAIN_MEMBER:
9348 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9350 case ROLE_DOMAIN_PDC:
9351 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9353 case ROLE_DOMAIN_BDC:
9354 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9356 case ROLE_STANDALONE:
9360 if (lp_time_server())
9361 default_server_announce |= SV_TYPE_TIME_SOURCE;
9363 if (lp_host_msdfs())
9364 default_server_announce |= SV_TYPE_DFS_SERVER;
9367 /***********************************************************
9368 returns role of Samba server
9369 ************************************************************/
9371 int lp_server_role(void)
9376 /***********************************************************
9377 If we are PDC then prefer us as DMB
9378 ************************************************************/
9380 bool lp_domain_master(void)
9382 if (Globals.iDomainMaster == Auto)
9383 return (lp_server_role() == ROLE_DOMAIN_PDC);
9385 return (bool)Globals.iDomainMaster;
9388 /***********************************************************
9389 If we are DMB then prefer us as LMB
9390 ************************************************************/
9392 bool lp_preferred_master(void)
9394 if (Globals.iPreferredMaster == Auto)
9395 return (lp_local_master() && lp_domain_master());
9397 return (bool)Globals.iPreferredMaster;
9400 /*******************************************************************
9402 ********************************************************************/
9404 void lp_remove_service(int snum)
9406 ServicePtrs[snum]->valid = False;
9407 invalid_services[num_invalid_services++] = snum;
9410 /*******************************************************************
9412 ********************************************************************/
9414 void lp_copy_service(int snum, const char *new_name)
9416 do_section(new_name, NULL);
9418 snum = lp_servicenumber(new_name);
9420 lp_do_parameter(snum, "copy", lp_servicename(snum));
9425 /*******************************************************************
9426 Get the default server type we will announce as via nmbd.
9427 ********************************************************************/
9429 int lp_default_server_announce(void)
9431 return default_server_announce;
9434 /*******************************************************************
9435 Split the announce version into major and minor numbers.
9436 ********************************************************************/
9438 int lp_major_announce_version(void)
9440 static bool got_major = False;
9441 static int major_version = DEFAULT_MAJOR_VERSION;
9446 return major_version;
9449 if ((vers = lp_announce_version()) == NULL)
9450 return major_version;
9452 if ((p = strchr_m(vers, '.')) == 0)
9453 return major_version;
9456 major_version = atoi(vers);
9457 return major_version;
9460 int lp_minor_announce_version(void)
9462 static bool got_minor = False;
9463 static int minor_version = DEFAULT_MINOR_VERSION;
9468 return minor_version;
9471 if ((vers = lp_announce_version()) == NULL)
9472 return minor_version;
9474 if ((p = strchr_m(vers, '.')) == 0)
9475 return minor_version;
9478 minor_version = atoi(p);
9479 return minor_version;
9482 /***********************************************************
9483 Set the global name resolution order (used in smbclient).
9484 ************************************************************/
9486 void lp_set_name_resolve_order(const char *new_order)
9488 string_set(&Globals.szNameResolveOrder, new_order);
9491 const char *lp_printername(int snum)
9493 const char *ret = _lp_printername(snum);
9494 if (ret == NULL || (ret != NULL && *ret == '\0'))
9495 ret = lp_const_servicename(snum);
9501 /***********************************************************
9502 Allow daemons such as winbindd to fix their logfile name.
9503 ************************************************************/
9505 void lp_set_logfile(const char *name)
9507 string_set(&Globals.szLogFile, name);
9508 debug_set_logfile(name);
9511 /*******************************************************************
9512 Return the max print jobs per queue.
9513 ********************************************************************/
9515 int lp_maxprintjobs(int snum)
9517 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9518 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9519 maxjobs = PRINT_MAX_JOBID - 1;
9524 const char *lp_printcapname(void)
9526 if ((Globals.szPrintcapname != NULL) &&
9527 (Globals.szPrintcapname[0] != '\0'))
9528 return Globals.szPrintcapname;
9530 if (sDefault.iPrinting == PRINT_CUPS) {
9538 if (sDefault.iPrinting == PRINT_BSD)
9539 return "/etc/printcap";
9541 return PRINTCAP_NAME;
9544 /*******************************************************************
9545 Ensure we don't use sendfile if server smb signing is active.
9546 ********************************************************************/
9548 static uint32 spoolss_state;
9550 bool lp_disable_spoolss( void )
9552 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9553 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9555 return spoolss_state == SVCCTL_STOPPED ? True : False;
9558 void lp_set_spoolss_state( uint32 state )
9560 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9562 spoolss_state = state;
9565 uint32 lp_get_spoolss_state( void )
9567 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9570 /*******************************************************************
9571 Ensure we don't use sendfile if server smb signing is active.
9572 ********************************************************************/
9574 bool lp_use_sendfile(int snum)
9576 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9577 if (Protocol < PROTOCOL_NT1) {
9580 return (_lp_use_sendfile(snum) &&
9581 (get_remote_arch() != RA_WIN95) &&
9582 !srv_is_signing_active());
9585 /*******************************************************************
9586 Turn off sendfile if we find the underlying OS doesn't support it.
9587 ********************************************************************/
9589 void set_use_sendfile(int snum, bool val)
9591 if (LP_SNUM_OK(snum))
9592 ServicePtrs[snum]->bUseSendfile = val;
9594 sDefault.bUseSendfile = val;
9597 /*******************************************************************
9598 Turn off storing DOS attributes if this share doesn't support it.
9599 ********************************************************************/
9601 void set_store_dos_attributes(int snum, bool val)
9603 if (!LP_SNUM_OK(snum))
9605 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9608 void lp_set_mangling_method(const char *new_method)
9610 string_set(&Globals.szManglingMethod, new_method);
9613 /*******************************************************************
9614 Global state for POSIX pathname processing.
9615 ********************************************************************/
9617 static bool posix_pathnames;
9619 bool lp_posix_pathnames(void)
9621 return posix_pathnames;
9624 /*******************************************************************
9625 Change everything needed to ensure POSIX pathname processing (currently
9627 ********************************************************************/
9629 void lp_set_posix_pathnames(void)
9631 posix_pathnames = True;
9634 /*******************************************************************
9635 Global state for POSIX lock processing - CIFS unix extensions.
9636 ********************************************************************/
9638 bool posix_default_lock_was_set;
9639 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9641 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9643 if (posix_default_lock_was_set) {
9644 return posix_cifsx_locktype;
9646 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9650 /*******************************************************************
9651 ********************************************************************/
9653 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9655 posix_default_lock_was_set = True;
9656 posix_cifsx_locktype = val;
9659 int lp_min_receive_file_size(void)
9661 if (Globals.iminreceivefile < 0) {
9664 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9667 /*******************************************************************
9668 If socket address is an empty character string, it is necessary to
9669 define it as "0.0.0.0".
9670 ********************************************************************/
9672 const char *lp_socket_address(void)
9674 char *sock_addr = Globals.szSocketAddress;
9676 if (sock_addr[0] == '\0'){
9677 string_set(&Globals.szSocketAddress, "0.0.0.0");
9679 return Globals.szSocketAddress;