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;
4659 int rlimit_max = MAX_OPEN_FILES;
4661 #ifdef HAVE_SYSCTLBYNAME
4663 size_t size = sizeof(sysctl_max);
4664 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4669 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4675 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4676 rlimit_max = rl.rlim_cur;
4678 #if defined(RLIM_INFINITY)
4679 if(rl.rlim_cur == RLIM_INFINITY)
4680 rlimit_max = MAX_OPEN_FILES;
4685 return MIN(sysctl_max, rlimit_max);
4689 * Common part of freeing allocated data for one parameter.
4691 static void free_one_parameter_common(void *parm_ptr,
4692 struct parm_struct parm)
4694 if ((parm.type == P_STRING) ||
4695 (parm.type == P_USTRING))
4697 string_free((char**)parm_ptr);
4698 } else if (parm.type == P_LIST) {
4699 TALLOC_FREE(*((char***)parm_ptr));
4704 * Free the allocated data for one parameter for a share
4705 * given as a service struct.
4707 static void free_one_parameter(struct service *service,
4708 struct parm_struct parm)
4712 if (parm.p_class != P_LOCAL) {
4716 parm_ptr = lp_local_ptr(service, parm.ptr);
4718 free_one_parameter_common(parm_ptr, parm);
4722 * Free the allocated parameter data of a share given
4723 * as a service struct.
4725 static void free_parameters(struct service *service)
4729 for (i=0; parm_table[i].label; i++) {
4730 free_one_parameter(service, parm_table[i]);
4735 * Free the allocated data for one parameter for a given share
4736 * specified by an snum.
4738 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4742 if (parm.ptr == NULL) {
4747 parm_ptr = parm.ptr;
4748 } else if (parm.p_class != P_LOCAL) {
4751 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4754 free_one_parameter_common(parm_ptr, parm);
4758 * Free the allocated parameter data for a share specified
4761 static void free_parameters_by_snum(int snum)
4765 for (i=0; parm_table[i].label; i++) {
4766 free_one_parameter_by_snum(snum, parm_table[i]);
4771 * Free the allocated global parameters.
4773 static void free_global_parameters(void)
4775 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4778 /***************************************************************************
4779 Initialise the global parameter structure.
4780 ***************************************************************************/
4782 static void init_globals(bool first_time_only)
4784 static bool done_init = False;
4788 /* If requested to initialize only once and we've already done it... */
4789 if (first_time_only && done_init) {
4790 /* ... then we have nothing more to do */
4795 /* The logfile can be set before this is invoked. Free it if so. */
4796 if (Globals.szLogFile != NULL) {
4797 string_free(&Globals.szLogFile);
4798 Globals.szLogFile = NULL;
4802 free_global_parameters();
4805 memset((void *)&Globals, '\0', sizeof(Globals));
4807 for (i = 0; parm_table[i].label; i++) {
4808 if ((parm_table[i].type == P_STRING ||
4809 parm_table[i].type == P_USTRING) &&
4812 string_set((char **)parm_table[i].ptr, "");
4816 string_set(&sDefault.fstype, FSTYPE_STRING);
4817 string_set(&sDefault.szPrintjobUsername, "%U");
4819 init_printer_values(&sDefault);
4822 DEBUG(3, ("Initialising global parameters\n"));
4824 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4825 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4827 /* use the new 'hash2' method by default, with a prefix of 1 */
4828 string_set(&Globals.szManglingMethod, "hash2");
4829 Globals.mangle_prefix = 1;
4831 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4833 /* using UTF8 by default allows us to support all chars */
4834 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4836 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4837 /* If the system supports nl_langinfo(), try to grab the value
4838 from the user's locale */
4839 string_set(&Globals.display_charset, "LOCALE");
4841 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4844 /* Use codepage 850 as a default for the dos character set */
4845 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4848 * Allow the default PASSWD_CHAT to be overridden in local.h.
4850 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4852 set_global_myname(myhostname());
4853 string_set(&Globals.szNetbiosName,global_myname());
4855 set_global_myworkgroup(WORKGROUP);
4856 string_set(&Globals.szWorkgroup, lp_workgroup());
4858 string_set(&Globals.szPasswdProgram, "");
4859 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4860 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4861 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4862 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4863 string_set(&Globals.szSocketAddress, "0.0.0.0");
4865 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4866 smb_panic("init_globals: ENOMEM");
4868 string_set(&Globals.szServerString, s);
4870 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4871 DEFAULT_MINOR_VERSION) < 0) {
4872 smb_panic("init_globals: ENOMEM");
4874 string_set(&Globals.szAnnounceVersion, s);
4877 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4880 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4882 string_set(&Globals.szLogonDrive, "");
4883 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4884 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4885 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4887 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4888 string_set(&Globals.szPasswordServer, "*");
4890 Globals.AlgorithmicRidBase = BASE_RID;
4892 Globals.bLoadPrinters = True;
4893 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4895 Globals.ConfigBackend = config_backend;
4897 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4898 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4899 Globals.max_xmit = 0x4104;
4900 Globals.max_mux = 50; /* This is *needed* for profile support. */
4901 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4902 Globals.bDisableSpoolss = False;
4903 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4904 Globals.pwordlevel = 0;
4905 Globals.unamelevel = 0;
4906 Globals.deadtime = 0;
4907 Globals.getwd_cache = true;
4908 Globals.bLargeReadwrite = True;
4909 Globals.max_log_size = 5000;
4910 Globals.max_open_files = max_open_files();
4911 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4912 Globals.maxprotocol = PROTOCOL_NT1;
4913 Globals.minprotocol = PROTOCOL_CORE;
4914 Globals.security = SEC_USER;
4915 Globals.paranoid_server_security = True;
4916 Globals.bEncryptPasswords = True;
4917 Globals.bUpdateEncrypt = False;
4918 Globals.clientSchannel = Auto;
4919 Globals.serverSchannel = Auto;
4920 Globals.bReadRaw = True;
4921 Globals.bWriteRaw = True;
4922 Globals.bNullPasswords = False;
4923 Globals.bObeyPamRestrictions = False;
4925 Globals.bSyslogOnly = False;
4926 Globals.bTimestampLogs = True;
4927 string_set(&Globals.szLogLevel, "0");
4928 Globals.bDebugPrefixTimestamp = False;
4929 Globals.bDebugHiresTimestamp = False;
4930 Globals.bDebugPid = False;
4931 Globals.bDebugUid = False;
4932 Globals.bDebugClass = False;
4933 Globals.bEnableCoreFiles = True;
4934 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4935 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4936 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4937 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4938 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4939 Globals.lm_interval = 60;
4940 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4941 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4942 Globals.bNISHomeMap = False;
4943 #ifdef WITH_NISPLUS_HOME
4944 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4946 string_set(&Globals.szNISHomeMapName, "auto.home");
4949 Globals.bTimeServer = False;
4950 Globals.bBindInterfacesOnly = False;
4951 Globals.bUnixPasswdSync = False;
4952 Globals.bPamPasswordChange = False;
4953 Globals.bPasswdChatDebug = False;
4954 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4955 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4956 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4957 Globals.bStatCache = True; /* use stat cache by default */
4958 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4959 Globals.restrict_anonymous = 0;
4960 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4961 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4962 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4963 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4964 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4965 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4967 Globals.map_to_guest = 0; /* By Default, "Never" */
4968 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4969 Globals.enhanced_browsing = true;
4970 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4971 #ifdef MMAP_BLACKLIST
4972 Globals.bUseMmap = False;
4974 Globals.bUseMmap = True;
4976 Globals.bUnixExtensions = True;
4977 Globals.bResetOnZeroVC = False;
4979 /* hostname lookups can be very expensive and are broken on
4980 a large number of sites (tridge) */
4981 Globals.bHostnameLookups = False;
4983 string_set(&Globals.szPassdbBackend, "smbpasswd");
4984 string_set(&Globals.szLdapSuffix, "");
4985 string_set(&Globals.szLdapMachineSuffix, "");
4986 string_set(&Globals.szLdapUserSuffix, "");
4987 string_set(&Globals.szLdapGroupSuffix, "");
4988 string_set(&Globals.szLdapIdmapSuffix, "");
4990 string_set(&Globals.szLdapAdminDn, "");
4991 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4992 Globals.ldap_ssl_ads = False;
4993 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4994 Globals.ldap_delete_dn = False;
4995 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4996 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4997 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4998 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5000 Globals.ldap_debug_level = 0;
5001 Globals.ldap_debug_threshold = 10;
5003 /* This is what we tell the afs client. in reality we set the token
5004 * to never expire, though, when this runs out the afs client will
5005 * forget the token. Set to 0 to get NEVERDATE.*/
5006 Globals.iAfsTokenLifetime = 604800;
5007 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5009 /* these parameters are set to defaults that are more appropriate
5010 for the increasing samba install base:
5012 as a member of the workgroup, that will possibly become a
5013 _local_ master browser (lm = True). this is opposed to a forced
5014 local master browser startup (pm = True).
5016 doesn't provide WINS server service by default (wsupp = False),
5017 and doesn't provide domain master browser services by default, either.
5021 Globals.bMsAddPrinterWizard = True;
5022 Globals.os_level = 20;
5023 Globals.bLocalMaster = True;
5024 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5025 Globals.bDomainLogons = False;
5026 Globals.bBrowseList = True;
5027 Globals.bWINSsupport = False;
5028 Globals.bWINSproxy = False;
5030 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5031 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5033 Globals.bDNSproxy = True;
5035 /* this just means to use them if they exist */
5036 Globals.bKernelOplocks = True;
5038 Globals.bAllowTrustedDomains = True;
5039 string_set(&Globals.szIdmapBackend, "tdb");
5041 string_set(&Globals.szTemplateShell, "/bin/false");
5042 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5043 string_set(&Globals.szWinbindSeparator, "\\");
5045 string_set(&Globals.szCupsServer, "");
5046 string_set(&Globals.szIPrintServer, "");
5048 string_set(&Globals.ctdbdSocket, "");
5049 Globals.szClusterAddresses = NULL;
5050 Globals.clustering = False;
5052 Globals.winbind_cache_time = 300; /* 5 minutes */
5053 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5054 Globals.bWinbindEnumUsers = False;
5055 Globals.bWinbindEnumGroups = False;
5056 Globals.bWinbindUseDefaultDomain = False;
5057 Globals.bWinbindTrustedDomainsOnly = False;
5058 Globals.bWinbindNestedGroups = True;
5059 Globals.winbind_expand_groups = 1;
5060 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5061 Globals.bWinbindRefreshTickets = False;
5062 Globals.bWinbindOfflineLogon = False;
5064 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5065 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5067 Globals.bPassdbExpandExplicit = False;
5069 Globals.name_cache_timeout = 660; /* In seconds */
5071 Globals.bUseSpnego = True;
5072 Globals.bClientUseSpnego = True;
5074 Globals.client_signing = Auto;
5075 Globals.server_signing = False;
5077 Globals.bDeferSharingViolations = True;
5078 string_set(&Globals.smb_ports, SMB_PORTS);
5080 Globals.bEnablePrivileges = True;
5081 Globals.bHostMSDfs = True;
5082 Globals.bASUSupport = False;
5084 /* User defined shares. */
5085 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5086 smb_panic("init_globals: ENOMEM");
5088 string_set(&Globals.szUsersharePath, s);
5090 string_set(&Globals.szUsershareTemplateShare, "");
5091 Globals.iUsershareMaxShares = 0;
5092 /* By default disallow sharing of directories not owned by the sharer. */
5093 Globals.bUsershareOwnerOnly = True;
5094 /* By default disallow guest access to usershares. */
5095 Globals.bUsershareAllowGuests = False;
5097 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5099 /* By default no shares out of the registry */
5100 Globals.bRegistryShares = False;
5102 Globals.iminreceivefile = 0;
5104 Globals.bMapUntrustedToDomain = false;
5107 /*******************************************************************
5108 Convenience routine to grab string parameters into temporary memory
5109 and run standard_sub_basic on them. The buffers can be written to by
5110 callers without affecting the source string.
5111 ********************************************************************/
5113 static char *lp_string(const char *s)
5116 TALLOC_CTX *ctx = talloc_tos();
5118 /* The follow debug is useful for tracking down memory problems
5119 especially if you have an inner loop that is calling a lp_*()
5120 function that returns a string. Perhaps this debug should be
5121 present all the time? */
5124 DEBUG(10, ("lp_string(%s)\n", s));
5127 ret = talloc_sub_basic(ctx,
5128 get_current_username(),
5129 current_user_info.domain,
5131 if (trim_char(ret, '\"', '\"')) {
5132 if (strchr(ret,'\"') != NULL) {
5134 ret = talloc_sub_basic(ctx,
5135 get_current_username(),
5136 current_user_info.domain,
5144 In this section all the functions that are used to access the
5145 parameters from the rest of the program are defined
5148 #define FN_GLOBAL_STRING(fn_name,ptr) \
5149 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5150 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5151 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5152 #define FN_GLOBAL_LIST(fn_name,ptr) \
5153 const char **fn_name(void) {return(*(const char ***)(ptr));}
5154 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5155 bool fn_name(void) {return(*(bool *)(ptr));}
5156 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5157 char fn_name(void) {return(*(char *)(ptr));}
5158 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5159 int fn_name(void) {return(*(int *)(ptr));}
5161 #define FN_LOCAL_STRING(fn_name,val) \
5162 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5163 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5164 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5165 #define FN_LOCAL_LIST(fn_name,val) \
5166 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5167 #define FN_LOCAL_BOOL(fn_name,val) \
5168 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5169 #define FN_LOCAL_INTEGER(fn_name,val) \
5170 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5172 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5173 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5174 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5175 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5176 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5177 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));}
5178 #define FN_LOCAL_CHAR(fn_name,val) \
5179 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5181 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5182 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5183 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5184 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5185 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5186 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5187 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5188 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5189 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5190 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5191 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5192 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5193 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5194 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5195 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5196 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5197 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5198 * build process or in smb.conf, we use that value. Otherwise they
5199 * default to the value of lp_lockdir(). */
5200 char *lp_statedir(void) {
5201 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5202 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5203 return(lp_string(*(char **)(&Globals.szStateDir) ?
5204 *(char **)(&Globals.szStateDir) : ""));
5206 return(lp_string(*(char **)(&Globals.szLockDir) ?
5207 *(char **)(&Globals.szLockDir) : ""));
5209 char *lp_cachedir(void) {
5210 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5211 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5212 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5213 *(char **)(&Globals.szCacheDir) : ""));
5215 return(lp_string(*(char **)(&Globals.szLockDir) ?
5216 *(char **)(&Globals.szLockDir) : ""));
5218 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5219 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5220 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5221 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5222 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5223 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5224 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5225 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5226 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5227 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5228 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5229 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5230 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5231 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5232 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5233 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5234 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5235 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5236 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5237 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5238 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5239 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5240 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5241 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5242 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5243 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5244 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5245 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5246 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5247 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5248 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5249 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5250 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5251 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5252 * lp_passdb_backend() should be replace by the this macro again after
5255 const char *lp_passdb_backend(void)
5257 char *delim, *quote;
5259 delim = strchr( Globals.szPassdbBackend, ' ');
5260 /* no space at all */
5261 if (delim == NULL) {
5265 quote = strchr(Globals.szPassdbBackend, '"');
5266 /* no quote char or non in the first part */
5267 if (quote == NULL || quote > delim) {
5272 quote = strchr(quote+1, '"');
5273 if (quote == NULL) {
5274 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5276 } else if (*(quote+1) == '\0') {
5277 /* space, fitting quote char, and one backend only */
5280 /* terminate string after the fitting quote char */
5285 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5286 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5287 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5288 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5291 return Globals.szPassdbBackend;
5293 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5294 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5295 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5296 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5297 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5299 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5300 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5301 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5302 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5303 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5304 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5306 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5308 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5309 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5310 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5312 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5314 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5315 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5316 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5317 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5318 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5319 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5320 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5321 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5322 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5323 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5324 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5325 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5326 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5327 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5328 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5330 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5331 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5332 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5333 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5334 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5335 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5337 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5338 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5339 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5340 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5341 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5342 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5343 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5344 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5345 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5346 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5347 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5348 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5349 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5350 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5351 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5352 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5353 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5354 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5356 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5358 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5359 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5360 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5361 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5362 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5363 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5364 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5365 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5366 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5367 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5368 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5369 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5370 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5371 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5372 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5373 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5374 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5375 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5376 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5377 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5378 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5379 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5380 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5381 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5382 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5383 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5384 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5385 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5386 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5387 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5388 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5389 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5390 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5391 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5392 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5393 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5394 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5395 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5396 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5397 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5398 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5399 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5400 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5401 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5402 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5403 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5404 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5405 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5406 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5407 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5408 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5409 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5410 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5411 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5412 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5413 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5414 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5415 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5416 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5417 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5418 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5419 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5420 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5421 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5422 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5423 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5424 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5425 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5426 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5427 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5428 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5429 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5430 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5431 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5432 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5433 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5434 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5435 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5436 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5437 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5438 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5439 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5440 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5441 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5442 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5443 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5444 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5445 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5446 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5447 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5448 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5449 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5450 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5451 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5452 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5453 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5454 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5455 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5456 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5457 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5459 FN_LOCAL_STRING(lp_preexec, szPreExec)
5460 FN_LOCAL_STRING(lp_postexec, szPostExec)
5461 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5462 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5463 FN_LOCAL_STRING(lp_servicename, szService)
5464 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5465 FN_LOCAL_STRING(lp_pathname, szPath)
5466 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5467 FN_LOCAL_STRING(lp_username, szUsername)
5468 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5469 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5470 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5471 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5472 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5473 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5474 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5475 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5476 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5477 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5478 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5479 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5480 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5481 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5482 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5483 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5484 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5485 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5486 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5487 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5488 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5489 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5490 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5491 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5492 FN_LOCAL_STRING(lp_comment, comment)
5493 FN_LOCAL_STRING(lp_force_user, force_user)
5494 FN_LOCAL_STRING(lp_force_group, force_group)
5495 FN_LOCAL_LIST(lp_readlist, readlist)
5496 FN_LOCAL_LIST(lp_writelist, writelist)
5497 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5498 FN_LOCAL_STRING(lp_fstype, fstype)
5499 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5500 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5501 static FN_LOCAL_STRING(lp_volume, volume)
5502 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5503 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5504 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5505 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5506 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5507 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5508 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5509 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5510 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5511 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5512 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5513 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5514 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5515 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5516 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5517 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5518 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5519 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5520 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5521 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5522 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5523 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5524 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5525 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5526 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5527 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5528 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5529 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5530 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5531 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5532 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5533 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5534 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5535 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5536 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5537 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5538 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5539 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5540 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5541 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5542 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5543 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5544 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5545 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5546 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5547 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5548 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5549 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5550 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5551 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5552 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5553 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5554 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5555 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5556 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5557 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5558 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5559 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5560 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5561 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5562 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5563 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5564 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5565 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5566 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5567 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5568 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5569 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5570 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5571 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5572 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5573 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5574 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5575 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5576 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5577 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5578 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5579 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5580 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5581 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5582 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5583 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5584 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5585 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5586 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5587 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5588 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5589 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5590 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5591 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5592 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5593 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5594 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5595 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5596 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5597 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5598 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5599 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5600 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5602 /* local prototypes */
5604 static int map_parameter(const char *pszParmName);
5605 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5606 static const char *get_boolean(bool bool_value);
5607 static int getservicebyname(const char *pszServiceName,
5608 struct service *pserviceDest);
5609 static void copy_service(struct service *pserviceDest,
5610 struct service *pserviceSource,
5611 struct bitmap *pcopymapDest);
5612 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5614 static bool do_section(const char *pszSectionName, void *userdata);
5615 static void init_copymap(struct service *pservice);
5616 static bool hash_a_service(const char *name, int number);
5617 static void free_service_byindex(int iService);
5618 static void free_param_opts(struct param_opt_struct **popts);
5619 static char * canonicalize_servicename(const char *name);
5620 static void show_parameter(int parmIndex);
5621 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5624 * This is a helper function for parametrical options support. It returns a
5625 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5626 * parametrical functions are quite simple
5628 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5631 bool global_section = False;
5633 struct param_opt_struct *data;
5635 if (snum >= iNumServices) return NULL;
5638 data = Globals.param_opt;
5639 global_section = True;
5641 data = ServicePtrs[snum]->param_opt;
5644 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5645 DEBUG(0,("asprintf failed!\n"));
5650 if (strwicmp(data->key, param_key) == 0) {
5651 string_free(¶m_key);
5657 if (!global_section) {
5658 /* Try to fetch the same option but from globals */
5659 /* but only if we are not already working with Globals */
5660 data = Globals.param_opt;
5662 if (strwicmp(data->key, param_key) == 0) {
5663 string_free(¶m_key);
5670 string_free(¶m_key);
5676 #define MISSING_PARAMETER(name) \
5677 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5679 /*******************************************************************
5680 convenience routine to return int parameters.
5681 ********************************************************************/
5682 static int lp_int(const char *s)
5686 MISSING_PARAMETER(lp_int);
5690 return (int)strtol(s, NULL, 0);
5693 /*******************************************************************
5694 convenience routine to return unsigned long parameters.
5695 ********************************************************************/
5696 static unsigned long lp_ulong(const char *s)
5700 MISSING_PARAMETER(lp_ulong);
5704 return strtoul(s, NULL, 0);
5707 /*******************************************************************
5708 convenience routine to return boolean parameters.
5709 ********************************************************************/
5710 static bool lp_bool(const char *s)
5715 MISSING_PARAMETER(lp_bool);
5719 if (!set_boolean(s, &ret)) {
5720 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5727 /*******************************************************************
5728 convenience routine to return enum parameters.
5729 ********************************************************************/
5730 static int lp_enum(const char *s,const struct enum_list *_enum)
5734 if (!s || !*s || !_enum) {
5735 MISSING_PARAMETER(lp_enum);
5739 for (i=0; _enum[i].name; i++) {
5740 if (strequal(_enum[i].name,s))
5741 return _enum[i].value;
5744 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5748 #undef MISSING_PARAMETER
5750 /* DO NOT USE lp_parm_string ANYMORE!!!!
5751 * use lp_parm_const_string or lp_parm_talloc_string
5753 * lp_parm_string is only used to let old modules find this symbol
5755 #undef lp_parm_string
5756 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5757 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5759 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5762 /* Return parametric option from a given service. Type is a part of option before ':' */
5763 /* Parametric option has following syntax: 'Type: option = value' */
5764 /* the returned value is talloced on the talloc_tos() */
5765 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5767 struct param_opt_struct *data = get_parametrics(snum, type, option);
5769 if (data == NULL||data->value==NULL) {
5771 return lp_string(def);
5777 return lp_string(data->value);
5780 /* Return parametric option from a given service. Type is a part of option before ':' */
5781 /* Parametric option has following syntax: 'Type: option = value' */
5782 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5784 struct param_opt_struct *data = get_parametrics(snum, type, option);
5786 if (data == NULL||data->value==NULL)
5792 /* Return parametric option from a given service. Type is a part of option before ':' */
5793 /* Parametric option has following syntax: 'Type: option = value' */
5795 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5797 struct param_opt_struct *data = get_parametrics(snum, type, option);
5799 if (data == NULL||data->value==NULL)
5800 return (const char **)def;
5802 if (data->list==NULL) {
5803 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5806 return (const char **)data->list;
5809 /* Return parametric option from a given service. Type is a part of option before ':' */
5810 /* Parametric option has following syntax: 'Type: option = value' */
5812 int lp_parm_int(int snum, const char *type, const char *option, int def)
5814 struct param_opt_struct *data = get_parametrics(snum, type, option);
5816 if (data && data->value && *data->value)
5817 return lp_int(data->value);
5822 /* Return parametric option from a given service. Type is a part of option before ':' */
5823 /* Parametric option has following syntax: 'Type: option = value' */
5825 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5827 struct param_opt_struct *data = get_parametrics(snum, type, option);
5829 if (data && data->value && *data->value)
5830 return lp_ulong(data->value);
5835 /* Return parametric option from a given service. Type is a part of option before ':' */
5836 /* Parametric option has following syntax: 'Type: option = value' */
5838 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5840 struct param_opt_struct *data = get_parametrics(snum, type, option);
5842 if (data && data->value && *data->value)
5843 return lp_bool(data->value);
5848 /* Return parametric option from a given service. Type is a part of option before ':' */
5849 /* Parametric option has following syntax: 'Type: option = value' */
5851 int lp_parm_enum(int snum, const char *type, const char *option,
5852 const struct enum_list *_enum, int def)
5854 struct param_opt_struct *data = get_parametrics(snum, type, option);
5856 if (data && data->value && *data->value && _enum)
5857 return lp_enum(data->value, _enum);
5863 /***************************************************************************
5864 Initialise a service to the defaults.
5865 ***************************************************************************/
5867 static void init_service(struct service *pservice)
5869 memset((char *)pservice, '\0', sizeof(struct service));
5870 copy_service(pservice, &sDefault, NULL);
5875 * free a param_opts structure.
5876 * param_opts handling should be moved to talloc;
5877 * then this whole functions reduces to a TALLOC_FREE().
5880 static void free_param_opts(struct param_opt_struct **popts)
5882 struct param_opt_struct *opt, *next_opt;
5884 if (popts == NULL) {
5888 if (*popts != NULL) {
5889 DEBUG(5, ("Freeing parametrics:\n"));
5892 while (opt != NULL) {
5893 string_free(&opt->key);
5894 string_free(&opt->value);
5895 TALLOC_FREE(opt->list);
5896 next_opt = opt->next;
5903 /***************************************************************************
5904 Free the dynamically allocated parts of a service struct.
5905 ***************************************************************************/
5907 static void free_service(struct service *pservice)
5912 if (pservice->szService)
5913 DEBUG(5, ("free_service: Freeing service %s\n",
5914 pservice->szService));
5916 free_parameters(pservice);
5918 string_free(&pservice->szService);
5919 bitmap_free(pservice->copymap);
5921 free_param_opts(&pservice->param_opt);
5923 ZERO_STRUCTP(pservice);
5927 /***************************************************************************
5928 remove a service indexed in the ServicePtrs array from the ServiceHash
5929 and free the dynamically allocated parts
5930 ***************************************************************************/
5932 static void free_service_byindex(int idx)
5934 if ( !LP_SNUM_OK(idx) )
5937 ServicePtrs[idx]->valid = False;
5938 invalid_services[num_invalid_services++] = idx;
5940 /* we have to cleanup the hash record */
5942 if (ServicePtrs[idx]->szService) {
5943 char *canon_name = canonicalize_servicename(
5944 ServicePtrs[idx]->szService );
5946 dbwrap_delete_bystring(ServiceHash, canon_name );
5947 TALLOC_FREE(canon_name);
5950 free_service(ServicePtrs[idx]);
5953 /***************************************************************************
5954 Add a new service to the services array initialising it with the given
5956 ***************************************************************************/
5958 static int add_a_service(const struct service *pservice, const char *name)
5961 struct service tservice;
5962 int num_to_alloc = iNumServices + 1;
5964 tservice = *pservice;
5966 /* it might already exist */
5968 i = getservicebyname(name, NULL);
5970 /* Clean all parametric options for service */
5971 /* They will be added during parsing again */
5972 free_param_opts(&ServicePtrs[i]->param_opt);
5977 /* find an invalid one */
5979 if (num_invalid_services > 0) {
5980 i = invalid_services[--num_invalid_services];
5983 /* if not, then create one */
5984 if (i == iNumServices) {
5985 struct service **tsp;
5988 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5990 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5994 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5995 if (!ServicePtrs[iNumServices]) {
5996 DEBUG(0,("add_a_service: out of memory!\n"));
6001 /* enlarge invalid_services here for now... */
6002 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6004 if (tinvalid == NULL) {
6005 DEBUG(0,("add_a_service: failed to enlarge "
6006 "invalid_services!\n"));
6009 invalid_services = tinvalid;
6011 free_service_byindex(i);
6014 ServicePtrs[i]->valid = True;
6016 init_service(ServicePtrs[i]);
6017 copy_service(ServicePtrs[i], &tservice, NULL);
6019 string_set(&ServicePtrs[i]->szService, name);
6021 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6022 i, ServicePtrs[i]->szService));
6024 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6031 /***************************************************************************
6032 Convert a string to uppercase and remove whitespaces.
6033 ***************************************************************************/
6035 static char *canonicalize_servicename(const char *src)
6040 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6044 result = talloc_strdup(talloc_tos(), src);
6045 SMB_ASSERT(result != NULL);
6051 /***************************************************************************
6052 Add a name/index pair for the services array to the hash table.
6053 ***************************************************************************/
6055 static bool hash_a_service(const char *name, int idx)
6059 if ( !ServiceHash ) {
6060 DEBUG(10,("hash_a_service: creating servicehash\n"));
6061 ServiceHash = db_open_rbt(NULL);
6062 if ( !ServiceHash ) {
6063 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6068 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6071 canon_name = canonicalize_servicename( name );
6073 dbwrap_store_bystring(ServiceHash, canon_name,
6074 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6077 TALLOC_FREE(canon_name);
6082 /***************************************************************************
6083 Add a new home service, with the specified home directory, defaults coming
6085 ***************************************************************************/
6087 bool lp_add_home(const char *pszHomename, int iDefaultService,
6088 const char *user, const char *pszHomedir)
6092 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6097 if (!(*(ServicePtrs[iDefaultService]->szPath))
6098 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6099 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6102 if (!(*(ServicePtrs[i]->comment))) {
6103 char *comment = NULL;
6104 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6107 string_set(&ServicePtrs[i]->comment, comment);
6111 /* set the browseable flag from the global default */
6113 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6114 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6116 ServicePtrs[i]->autoloaded = True;
6118 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6119 user, ServicePtrs[i]->szPath ));
6124 /***************************************************************************
6125 Add a new service, based on an old one.
6126 ***************************************************************************/
6128 int lp_add_service(const char *pszService, int iDefaultService)
6130 if (iDefaultService < 0) {
6131 return add_a_service(&sDefault, pszService);
6134 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6137 /***************************************************************************
6138 Add the IPC service.
6139 ***************************************************************************/
6141 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6143 char *comment = NULL;
6144 int i = add_a_service(&sDefault, ipc_name);
6149 if (asprintf(&comment, "IPC Service (%s)",
6150 Globals.szServerString) < 0) {
6154 string_set(&ServicePtrs[i]->szPath, tmpdir());
6155 string_set(&ServicePtrs[i]->szUsername, "");
6156 string_set(&ServicePtrs[i]->comment, comment);
6157 string_set(&ServicePtrs[i]->fstype, "IPC");
6158 ServicePtrs[i]->iMaxConnections = 0;
6159 ServicePtrs[i]->bAvailable = True;
6160 ServicePtrs[i]->bRead_only = True;
6161 ServicePtrs[i]->bGuest_only = False;
6162 ServicePtrs[i]->bAdministrative_share = True;
6163 ServicePtrs[i]->bGuest_ok = guest_ok;
6164 ServicePtrs[i]->bPrint_ok = False;
6165 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6167 DEBUG(3, ("adding IPC service\n"));
6173 /***************************************************************************
6174 Add a new printer service, with defaults coming from service iFrom.
6175 ***************************************************************************/
6177 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6179 const char *comment = "From Printcap";
6180 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6185 /* note that we do NOT default the availability flag to True - */
6186 /* we take it from the default service passed. This allows all */
6187 /* dynamic printers to be disabled by disabling the [printers] */
6188 /* entry (if/when the 'available' keyword is implemented!). */
6190 /* the printer name is set to the service name. */
6191 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6192 string_set(&ServicePtrs[i]->comment, comment);
6194 /* set the browseable flag from the gloabl default */
6195 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6197 /* Printers cannot be read_only. */
6198 ServicePtrs[i]->bRead_only = False;
6199 /* No share modes on printer services. */
6200 ServicePtrs[i]->bShareModes = False;
6201 /* No oplocks on printer services. */
6202 ServicePtrs[i]->bOpLocks = False;
6203 /* Printer services must be printable. */
6204 ServicePtrs[i]->bPrint_ok = True;
6206 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6212 /***************************************************************************
6213 Check whether the given parameter name is valid.
6214 Parametric options (names containing a colon) are considered valid.
6215 ***************************************************************************/
6217 bool lp_parameter_is_valid(const char *pszParmName)
6219 return ((map_parameter(pszParmName) != -1) ||
6220 (strchr(pszParmName, ':') != NULL));
6223 /***************************************************************************
6224 Check whether the given name is the name of a global parameter.
6225 Returns True for strings belonging to parameters of class
6226 P_GLOBAL, False for all other strings, also for parametric options
6227 and strings not belonging to any option.
6228 ***************************************************************************/
6230 bool lp_parameter_is_global(const char *pszParmName)
6232 int num = map_parameter(pszParmName);
6235 return (parm_table[num].p_class == P_GLOBAL);
6241 /**************************************************************************
6242 Check whether the given name is the canonical name of a parameter.
6243 Returns False if it is not a valid parameter Name.
6244 For parametric options, True is returned.
6245 **************************************************************************/
6247 bool lp_parameter_is_canonical(const char *parm_name)
6249 if (!lp_parameter_is_valid(parm_name)) {
6253 return (map_parameter(parm_name) ==
6254 map_parameter_canonical(parm_name, NULL));
6257 /**************************************************************************
6258 Determine the canonical name for a parameter.
6259 Indicate when it is an inverse (boolean) synonym instead of a
6261 **************************************************************************/
6263 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6268 if (!lp_parameter_is_valid(parm_name)) {
6273 num = map_parameter_canonical(parm_name, inverse);
6275 /* parametric option */
6276 *canon_parm = parm_name;
6278 *canon_parm = parm_table[num].label;
6285 /**************************************************************************
6286 Determine the canonical name for a parameter.
6287 Turn the value given into the inverse boolean expression when
6288 the synonym is an invers boolean synonym.
6290 Return True if parm_name is a valid parameter name and
6291 in case it is an invers boolean synonym, if the val string could
6292 successfully be converted to the reverse bool.
6293 Return false in all other cases.
6294 **************************************************************************/
6296 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6298 const char **canon_parm,
6299 const char **canon_val)
6304 if (!lp_parameter_is_valid(parm_name)) {
6310 num = map_parameter_canonical(parm_name, &inverse);
6312 /* parametric option */
6313 *canon_parm = parm_name;
6316 *canon_parm = parm_table[num].label;
6318 if (!lp_invert_boolean(val, canon_val)) {
6330 /***************************************************************************
6331 Map a parameter's string representation to something we can use.
6332 Returns False if the parameter string is not recognised, else TRUE.
6333 ***************************************************************************/
6335 static int map_parameter(const char *pszParmName)
6339 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6342 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6343 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6346 /* Warn only if it isn't parametric option */
6347 if (strchr(pszParmName, ':') == NULL)
6348 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6349 /* We do return 'fail' for parametric options as well because they are
6350 stored in different storage
6355 /***************************************************************************
6356 Map a parameter's string representation to the index of the canonical
6357 form of the parameter (it might be a synonym).
6358 Returns -1 if the parameter string is not recognised.
6359 ***************************************************************************/
6361 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6363 int parm_num, canon_num;
6364 bool loc_inverse = False;
6366 parm_num = map_parameter(pszParmName);
6367 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6368 /* invalid, parametric or no canidate for synonyms ... */
6372 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6373 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6374 parm_num = canon_num;
6380 if (inverse != NULL) {
6381 *inverse = loc_inverse;
6386 /***************************************************************************
6387 return true if parameter number parm1 is a synonym of parameter
6388 number parm2 (parm2 being the principal name).
6389 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6391 ***************************************************************************/
6393 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6395 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6396 (parm_table[parm1].flags & FLAG_HIDE) &&
6397 !(parm_table[parm2].flags & FLAG_HIDE))
6399 if (inverse != NULL) {
6400 if ((parm_table[parm1].type == P_BOOLREV) &&
6401 (parm_table[parm2].type == P_BOOL))
6413 /***************************************************************************
6414 Show one parameter's name, type, [values,] and flags.
6415 (helper functions for show_parameter_list)
6416 ***************************************************************************/
6418 static void show_parameter(int parmIndex)
6420 int enumIndex, flagIndex;
6425 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6426 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6428 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6429 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6430 FLAG_HIDE, FLAG_DOS_STRING};
6431 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6432 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6433 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6435 printf("%s=%s", parm_table[parmIndex].label,
6436 type[parm_table[parmIndex].type]);
6437 if (parm_table[parmIndex].type == P_ENUM) {
6440 parm_table[parmIndex].enum_list[enumIndex].name;
6444 enumIndex ? "|" : "",
6445 parm_table[parmIndex].enum_list[enumIndex].name);
6450 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6451 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6454 flag_names[flagIndex]);
6459 /* output synonyms */
6461 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6462 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6463 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6464 parm_table[parmIndex2].label);
6465 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6467 printf(" (synonyms: ");
6472 printf("%s%s", parm_table[parmIndex2].label,
6473 inverse ? "[i]" : "");
6483 /***************************************************************************
6484 Show all parameter's name, type, [values,] and flags.
6485 ***************************************************************************/
6487 void show_parameter_list(void)
6489 int classIndex, parmIndex;
6490 const char *section_names[] = { "local", "global", NULL};
6492 for (classIndex=0; section_names[classIndex]; classIndex++) {
6493 printf("[%s]\n", section_names[classIndex]);
6494 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6495 if (parm_table[parmIndex].p_class == classIndex) {
6496 show_parameter(parmIndex);
6502 /***************************************************************************
6503 Check if a given string correctly represents a boolean value.
6504 ***************************************************************************/
6506 bool lp_string_is_valid_boolean(const char *parm_value)
6508 return set_boolean(parm_value, NULL);
6511 /***************************************************************************
6512 Get the standard string representation of a boolean value ("yes" or "no")
6513 ***************************************************************************/
6515 static const char *get_boolean(bool bool_value)
6517 static const char *yes_str = "yes";
6518 static const char *no_str = "no";
6520 return (bool_value ? yes_str : no_str);
6523 /***************************************************************************
6524 Provide the string of the negated boolean value associated to the boolean
6525 given as a string. Returns False if the passed string does not correctly
6526 represent a boolean.
6527 ***************************************************************************/
6529 bool lp_invert_boolean(const char *str, const char **inverse_str)
6533 if (!set_boolean(str, &val)) {
6537 *inverse_str = get_boolean(!val);
6541 /***************************************************************************
6542 Provide the canonical string representation of a boolean value given
6543 as a string. Return True on success, False if the string given does
6544 not correctly represent a boolean.
6545 ***************************************************************************/
6547 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6551 if (!set_boolean(str, &val)) {
6555 *canon_str = get_boolean(val);
6559 /***************************************************************************
6560 Find a service by name. Otherwise works like get_service.
6561 ***************************************************************************/
6563 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6569 if (ServiceHash == NULL) {
6573 canon_name = canonicalize_servicename(pszServiceName);
6575 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6577 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6578 iService = *(int *)data.dptr;
6581 TALLOC_FREE(canon_name);
6583 if ((iService != -1) && (LP_SNUM_OK(iService))
6584 && (pserviceDest != NULL)) {
6585 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6591 /***************************************************************************
6592 Copy a service structure to another.
6593 If pcopymapDest is NULL then copy all fields
6594 ***************************************************************************/
6597 * Add a parametric option to a param_opt_struct,
6598 * replacing old value, if already present.
6600 static void set_param_opt(struct param_opt_struct **opt_list,
6601 const char *opt_name,
6602 const char *opt_value)
6604 struct param_opt_struct *new_opt, *opt;
6607 if (opt_list == NULL) {
6614 /* Traverse destination */
6616 /* If we already have same option, override it */
6617 if (strwicmp(opt->key, opt_name) == 0) {
6618 string_free(&opt->value);
6619 TALLOC_FREE(opt->list);
6620 opt->value = SMB_STRDUP(opt_value);
6627 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6628 new_opt->key = SMB_STRDUP(opt_name);
6629 new_opt->value = SMB_STRDUP(opt_value);
6630 new_opt->list = NULL;
6631 DLIST_ADD(*opt_list, new_opt);
6635 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6636 struct bitmap *pcopymapDest)
6639 bool bcopyall = (pcopymapDest == NULL);
6640 struct param_opt_struct *data;
6642 for (i = 0; parm_table[i].label; i++)
6643 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6644 (bcopyall || bitmap_query(pcopymapDest,i))) {
6645 void *def_ptr = parm_table[i].ptr;
6647 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6650 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6653 switch (parm_table[i].type) {
6656 *(bool *)dest_ptr = *(bool *)src_ptr;
6662 *(int *)dest_ptr = *(int *)src_ptr;
6666 *(char *)dest_ptr = *(char *)src_ptr;
6670 string_set((char **)dest_ptr,
6675 string_set((char **)dest_ptr,
6677 strupper_m(*(char **)dest_ptr);
6680 TALLOC_FREE(*((char ***)dest_ptr));
6681 *((char ***)dest_ptr) = str_list_copy(NULL,
6682 *(const char ***)src_ptr);
6690 init_copymap(pserviceDest);
6691 if (pserviceSource->copymap)
6692 bitmap_copy(pserviceDest->copymap,
6693 pserviceSource->copymap);
6696 data = pserviceSource->param_opt;
6698 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6703 /***************************************************************************
6704 Check a service for consistency. Return False if the service is in any way
6705 incomplete or faulty, else True.
6706 ***************************************************************************/
6708 bool service_ok(int iService)
6713 if (ServicePtrs[iService]->szService[0] == '\0') {
6714 DEBUG(0, ("The following message indicates an internal error:\n"));
6715 DEBUG(0, ("No service name in service entry.\n"));
6719 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6720 /* I can't see why you'd want a non-printable printer service... */
6721 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6722 if (!ServicePtrs[iService]->bPrint_ok) {
6723 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6724 ServicePtrs[iService]->szService));
6725 ServicePtrs[iService]->bPrint_ok = True;
6727 /* [printers] service must also be non-browsable. */
6728 if (ServicePtrs[iService]->bBrowseable)
6729 ServicePtrs[iService]->bBrowseable = False;
6732 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6733 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6734 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6736 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6737 ServicePtrs[iService]->szService));
6738 ServicePtrs[iService]->bAvailable = False;
6741 /* If a service is flagged unavailable, log the fact at level 1. */
6742 if (!ServicePtrs[iService]->bAvailable)
6743 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6744 ServicePtrs[iService]->szService));
6749 static struct smbconf_ctx *lp_smbconf_ctx(void)
6752 static struct smbconf_ctx *conf_ctx = NULL;
6754 if (conf_ctx == NULL) {
6755 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6756 if (!W_ERROR_IS_OK(werr)) {
6757 DEBUG(1, ("error initializing registry configuration: "
6758 "%s\n", win_errstr(werr)));
6766 static bool process_smbconf_service(struct smbconf_service *service)
6771 if (service == NULL) {
6775 ret = do_section(service->name, NULL);
6779 for (count = 0; count < service->num_params; count++) {
6780 ret = do_parameter(service->param_names[count],
6781 service->param_values[count],
6791 * process_registry_globals
6793 static bool process_registry_globals(void)
6796 struct smbconf_service *service = NULL;
6797 TALLOC_CTX *mem_ctx = talloc_stackframe();
6798 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6801 if (conf_ctx == NULL) {
6805 ret = do_parameter("registry shares", "yes", NULL);
6810 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6811 /* nothing to read from the registry yet but make sure lp_load
6812 * doesn't return false */
6817 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6818 if (!W_ERROR_IS_OK(werr)) {
6822 ret = process_smbconf_service(service);
6828 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6831 TALLOC_FREE(mem_ctx);
6835 static bool process_registry_shares(void)
6839 struct smbconf_service **service = NULL;
6840 uint32_t num_shares = 0;
6841 TALLOC_CTX *mem_ctx = talloc_stackframe();
6842 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6845 if (conf_ctx == NULL) {
6849 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6850 if (!W_ERROR_IS_OK(werr)) {
6856 for (count = 0; count < num_shares; count++) {
6857 if (strequal(service[count]->name, GLOBAL_NAME)) {
6860 ret = process_smbconf_service(service[count]);
6867 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6870 TALLOC_FREE(mem_ctx);
6874 static struct file_lists {
6875 struct file_lists *next;
6879 } *file_lists = NULL;
6881 /*******************************************************************
6882 Keep a linked list of all config files so we know when one has changed
6883 it's date and needs to be reloaded.
6884 ********************************************************************/
6886 static void add_to_file_list(const char *fname, const char *subfname)
6888 struct file_lists *f = file_lists;
6891 if (f->name && !strcmp(f->name, fname))
6897 f = SMB_MALLOC_P(struct file_lists);
6900 f->next = file_lists;
6901 f->name = SMB_STRDUP(fname);
6906 f->subfname = SMB_STRDUP(subfname);
6912 f->modtime = file_modtime(subfname);
6914 time_t t = file_modtime(subfname);
6921 * Utility function for outsiders to check if we're running on registry.
6923 bool lp_config_backend_is_registry(void)
6925 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6929 * Utility function to check if the config backend is FILE.
6931 bool lp_config_backend_is_file(void)
6933 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6936 /*******************************************************************
6937 Check if a config file has changed date.
6938 ********************************************************************/
6940 bool lp_file_list_changed(void)
6942 struct file_lists *f = file_lists;
6944 DEBUG(6, ("lp_file_list_changed()\n"));
6946 if (lp_config_backend_is_registry()) {
6947 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6949 if (conf_ctx == NULL) {
6952 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6953 DEBUGADD(6, ("registry config changed\n"));
6962 n2 = alloc_sub_basic(get_current_username(),
6963 current_user_info.domain,
6968 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6969 f->name, n2, ctime(&f->modtime)));
6971 mod_time = file_modtime(n2);
6973 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6975 ("file %s modified: %s\n", n2,
6977 f->modtime = mod_time;
6978 SAFE_FREE(f->subfname);
6979 f->subfname = n2; /* Passing ownership of
6980 return from alloc_sub_basic
6991 /***************************************************************************
6992 Run standard_sub_basic on netbios name... needed because global_myname
6993 is not accessed through any lp_ macro.
6994 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6995 ***************************************************************************/
6997 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7000 char *netbios_name = alloc_sub_basic(get_current_username(),
7001 current_user_info.domain,
7004 ret = set_global_myname(netbios_name);
7005 SAFE_FREE(netbios_name);
7006 string_set(&Globals.szNetbiosName,global_myname());
7008 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7014 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7016 if (strcmp(*ptr, pszParmValue) != 0) {
7017 string_set(ptr, pszParmValue);
7025 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7029 ret = set_global_myworkgroup(pszParmValue);
7030 string_set(&Globals.szWorkgroup,lp_workgroup());
7035 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7039 ret = set_global_scope(pszParmValue);
7040 string_set(&Globals.szNetbiosScope,global_scope());
7045 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7047 TALLOC_FREE(Globals.szNetbiosAliases);
7048 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7049 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7052 /***************************************************************************
7053 Handle the include operation.
7054 ***************************************************************************/
7055 static bool bAllowIncludeRegistry = true;
7057 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7061 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7062 if (!bAllowIncludeRegistry) {
7065 if (bInGlobalSection) {
7066 return process_registry_globals();
7068 DEBUG(1, ("\"include = registry\" only effective "
7069 "in %s section\n", GLOBAL_NAME));
7074 fname = alloc_sub_basic(get_current_username(),
7075 current_user_info.domain,
7078 add_to_file_list(pszParmValue, fname);
7080 string_set(ptr, fname);
7082 if (file_exist(fname)) {
7083 bool ret = pm_process(fname, do_section, do_parameter, NULL);
7088 DEBUG(2, ("Can't find include file %s\n", fname));
7093 /***************************************************************************
7094 Handle the interpretation of the copy parameter.
7095 ***************************************************************************/
7097 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7101 struct service serviceTemp;
7103 string_set(ptr, pszParmValue);
7105 init_service(&serviceTemp);
7109 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7111 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7112 if (iTemp == iServiceIndex) {
7113 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7115 copy_service(ServicePtrs[iServiceIndex],
7117 ServicePtrs[iServiceIndex]->copymap);
7121 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7125 free_service(&serviceTemp);
7129 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7131 Globals.ldap_debug_level = lp_int(pszParmValue);
7132 init_ldap_debugging();
7136 /***************************************************************************
7137 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7142 idmap uid = 1000-1999
7145 We only do simple parsing checks here. The strings are parsed into useful
7146 structures in the idmap daemon code.
7148 ***************************************************************************/
7150 /* Some lp_ routines to return idmap [ug]id information */
7152 static uid_t idmap_uid_low, idmap_uid_high;
7153 static gid_t idmap_gid_low, idmap_gid_high;
7155 bool lp_idmap_uid(uid_t *low, uid_t *high)
7157 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7161 *low = idmap_uid_low;
7164 *high = idmap_uid_high;
7169 bool lp_idmap_gid(gid_t *low, gid_t *high)
7171 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7175 *low = idmap_gid_low;
7178 *high = idmap_gid_high;
7183 /* Do some simple checks on "idmap [ug]id" parameter values */
7185 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7189 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7194 string_set(ptr, pszParmValue);
7196 idmap_uid_low = low;
7197 idmap_uid_high = high;
7202 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7206 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7211 string_set(ptr, pszParmValue);
7213 idmap_gid_low = low;
7214 idmap_gid_high = high;
7219 /***************************************************************************
7220 Handle the DEBUG level list.
7221 ***************************************************************************/
7223 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7225 string_set(ptr, pszParmValueIn);
7226 return debug_parse_levels(pszParmValueIn);
7229 /***************************************************************************
7230 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7231 ***************************************************************************/
7233 static const char *append_ldap_suffix( const char *str )
7235 const char *suffix_string;
7238 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7239 Globals.szLdapSuffix );
7240 if ( !suffix_string ) {
7241 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7245 return suffix_string;
7248 const char *lp_ldap_machine_suffix(void)
7250 if (Globals.szLdapMachineSuffix[0])
7251 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7253 return lp_string(Globals.szLdapSuffix);
7256 const char *lp_ldap_user_suffix(void)
7258 if (Globals.szLdapUserSuffix[0])
7259 return append_ldap_suffix(Globals.szLdapUserSuffix);
7261 return lp_string(Globals.szLdapSuffix);
7264 const char *lp_ldap_group_suffix(void)
7266 if (Globals.szLdapGroupSuffix[0])
7267 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7269 return lp_string(Globals.szLdapSuffix);
7272 const char *lp_ldap_idmap_suffix(void)
7274 if (Globals.szLdapIdmapSuffix[0])
7275 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7277 return lp_string(Globals.szLdapSuffix);
7280 /****************************************************************************
7281 set the value for a P_ENUM
7282 ***************************************************************************/
7284 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7289 for (i = 0; parm->enum_list[i].name; i++) {
7290 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7291 *ptr = parm->enum_list[i].value;
7295 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7296 pszParmValue, parm->label));
7299 /***************************************************************************
7300 ***************************************************************************/
7302 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7304 static int parm_num = -1;
7307 if ( parm_num == -1 )
7308 parm_num = map_parameter( "printing" );
7310 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7315 s = ServicePtrs[snum];
7317 init_printer_values( s );
7323 /***************************************************************************
7324 Initialise a copymap.
7325 ***************************************************************************/
7327 static void init_copymap(struct service *pservice)
7330 if (pservice->copymap) {
7331 bitmap_free(pservice->copymap);
7333 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7334 if (!pservice->copymap)
7336 ("Couldn't allocate copymap!! (size %d)\n",
7337 (int)NUMPARAMETERS));
7339 for (i = 0; i < NUMPARAMETERS; i++)
7340 bitmap_set(pservice->copymap, i);
7343 /***************************************************************************
7344 Return the local pointer to a parameter given a service struct and the
7345 pointer into the default structure.
7346 ***************************************************************************/
7348 static void *lp_local_ptr(struct service *service, void *ptr)
7350 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7353 /***************************************************************************
7354 Return the local pointer to a parameter given the service number and the
7355 pointer into the default structure.
7356 ***************************************************************************/
7358 void *lp_local_ptr_by_snum(int snum, void *ptr)
7360 return lp_local_ptr(ServicePtrs[snum], ptr);
7363 /***************************************************************************
7364 Process a parameter for a particular service number. If snum < 0
7365 then assume we are in the globals.
7366 ***************************************************************************/
7368 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7371 void *parm_ptr = NULL; /* where we are going to store the result */
7372 void *def_ptr = NULL;
7373 struct param_opt_struct **opt_list;
7375 parmnum = map_parameter(pszParmName);
7378 if (strchr(pszParmName, ':') == NULL) {
7379 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7385 * We've got a parametric option
7388 opt_list = (snum < 0)
7389 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7390 set_param_opt(opt_list, pszParmName, pszParmValue);
7395 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7396 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7400 def_ptr = parm_table[parmnum].ptr;
7402 /* we might point at a service, the default service or a global */
7406 if (parm_table[parmnum].p_class == P_GLOBAL) {
7408 ("Global parameter %s found in service section!\n",
7412 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7416 if (!ServicePtrs[snum]->copymap)
7417 init_copymap(ServicePtrs[snum]);
7419 /* this handles the aliases - set the copymap for other entries with
7420 the same data pointer */
7421 for (i = 0; parm_table[i].label; i++)
7422 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7423 bitmap_clear(ServicePtrs[snum]->copymap, i);
7426 /* if it is a special case then go ahead */
7427 if (parm_table[parmnum].special) {
7428 return parm_table[parmnum].special(snum, pszParmValue,
7432 /* now switch on the type of variable it is */
7433 switch (parm_table[parmnum].type)
7436 *(bool *)parm_ptr = lp_bool(pszParmValue);
7440 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7444 *(int *)parm_ptr = lp_int(pszParmValue);
7448 *(char *)parm_ptr = *pszParmValue;
7452 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7454 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7459 TALLOC_FREE(*((char ***)parm_ptr));
7460 *(char ***)parm_ptr = str_list_make_v3(
7461 talloc_autofree_context(), pszParmValue, NULL);
7465 string_set((char **)parm_ptr, pszParmValue);
7469 string_set((char **)parm_ptr, pszParmValue);
7470 strupper_m(*(char **)parm_ptr);
7474 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7483 /***************************************************************************
7484 Process a parameter.
7485 ***************************************************************************/
7487 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7490 if (!bInGlobalSection && bGlobalOnly)
7493 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7495 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7496 pszParmName, pszParmValue));
7499 /***************************************************************************
7500 Print a parameter of the specified type.
7501 ***************************************************************************/
7503 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7509 for (i = 0; p->enum_list[i].name; i++) {
7510 if (*(int *)ptr == p->enum_list[i].value) {
7512 p->enum_list[i].name);
7519 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7523 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7527 fprintf(f, "%d", *(int *)ptr);
7531 fprintf(f, "%c", *(char *)ptr);
7535 char *o = octal_string(*(int *)ptr);
7536 fprintf(f, "%s", o);
7542 if ((char ***)ptr && *(char ***)ptr) {
7543 char **list = *(char ***)ptr;
7544 for (; *list; list++) {
7545 /* surround strings with whitespace in double quotes */
7546 if ( strchr_m( *list, ' ' ) )
7547 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7549 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7556 if (*(char **)ptr) {
7557 fprintf(f, "%s", *(char **)ptr);
7565 /***************************************************************************
7566 Check if two parameters are equal.
7567 ***************************************************************************/
7569 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7574 return (*((bool *)ptr1) == *((bool *)ptr2));
7579 return (*((int *)ptr1) == *((int *)ptr2));
7582 return (*((char *)ptr1) == *((char *)ptr2));
7585 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7590 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7595 return (p1 == p2 || strequal(p1, p2));
7603 /***************************************************************************
7604 Initialize any local varients in the sDefault table.
7605 ***************************************************************************/
7607 void init_locals(void)
7612 /***************************************************************************
7613 Process a new section (service). At this stage all sections are services.
7614 Later we'll have special sections that permit server parameters to be set.
7615 Returns True on success, False on failure.
7616 ***************************************************************************/
7618 static bool do_section(const char *pszSectionName, void *userdata)
7621 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7622 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7625 /* if we were in a global section then do the local inits */
7626 if (bInGlobalSection && !isglobal)
7629 /* if we've just struck a global section, note the fact. */
7630 bInGlobalSection = isglobal;
7632 /* check for multiple global sections */
7633 if (bInGlobalSection) {
7634 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7638 if (!bInGlobalSection && bGlobalOnly)
7641 /* if we have a current service, tidy it up before moving on */
7644 if (iServiceIndex >= 0)
7645 bRetval = service_ok(iServiceIndex);
7647 /* if all is still well, move to the next record in the services array */
7649 /* We put this here to avoid an odd message order if messages are */
7650 /* issued by the post-processing of a previous section. */
7651 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7653 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7655 DEBUG(0, ("Failed to add a new service\n"));
7664 /***************************************************************************
7665 Determine if a partcular base parameter is currentl set to the default value.
7666 ***************************************************************************/
7668 static bool is_default(int i)
7670 if (!defaults_saved)
7672 switch (parm_table[i].type) {
7674 return str_list_equal((const char **)parm_table[i].def.lvalue,
7675 *(const char ***)parm_table[i].ptr);
7678 return strequal(parm_table[i].def.svalue,
7679 *(char **)parm_table[i].ptr);
7682 return parm_table[i].def.bvalue ==
7683 *(bool *)parm_table[i].ptr;
7685 return parm_table[i].def.cvalue ==
7686 *(char *)parm_table[i].ptr;
7690 return parm_table[i].def.ivalue ==
7691 *(int *)parm_table[i].ptr;
7698 /***************************************************************************
7699 Display the contents of the global structure.
7700 ***************************************************************************/
7702 static void dump_globals(FILE *f)
7705 struct param_opt_struct *data;
7707 fprintf(f, "[global]\n");
7709 for (i = 0; parm_table[i].label; i++)
7710 if (parm_table[i].p_class == P_GLOBAL &&
7711 parm_table[i].ptr &&
7712 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7713 if (defaults_saved && is_default(i))
7715 fprintf(f, "\t%s = ", parm_table[i].label);
7716 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7719 if (Globals.param_opt != NULL) {
7720 data = Globals.param_opt;
7722 fprintf(f, "\t%s = %s\n", data->key, data->value);
7729 /***************************************************************************
7730 Return True if a local parameter is currently set to the global default.
7731 ***************************************************************************/
7733 bool lp_is_default(int snum, struct parm_struct *parm)
7735 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7737 return equal_parameter(parm->type,
7738 ((char *)ServicePtrs[snum]) + pdiff,
7739 ((char *)&sDefault) + pdiff);
7742 /***************************************************************************
7743 Display the contents of a single services record.
7744 ***************************************************************************/
7746 static void dump_a_service(struct service *pService, FILE * f)
7749 struct param_opt_struct *data;
7751 if (pService != &sDefault)
7752 fprintf(f, "[%s]\n", pService->szService);
7754 for (i = 0; parm_table[i].label; i++) {
7756 if (parm_table[i].p_class == P_LOCAL &&
7757 parm_table[i].ptr &&
7758 (*parm_table[i].label != '-') &&
7759 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7762 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7764 if (pService == &sDefault) {
7765 if (defaults_saved && is_default(i))
7768 if (equal_parameter(parm_table[i].type,
7769 ((char *)pService) +
7771 ((char *)&sDefault) +
7776 fprintf(f, "\t%s = ", parm_table[i].label);
7777 print_parameter(&parm_table[i],
7778 ((char *)pService) + pdiff, f);
7783 if (pService->param_opt != NULL) {
7784 data = pService->param_opt;
7786 fprintf(f, "\t%s = %s\n", data->key, data->value);
7792 /***************************************************************************
7793 Display the contents of a parameter of a single services record.
7794 ***************************************************************************/
7796 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7799 bool result = False;
7802 fstring local_parm_name;
7804 const char *parm_opt_value;
7806 /* check for parametrical option */
7807 fstrcpy( local_parm_name, parm_name);
7808 parm_opt = strchr( local_parm_name, ':');
7813 if (strlen(parm_opt)) {
7814 parm_opt_value = lp_parm_const_string( snum,
7815 local_parm_name, parm_opt, NULL);
7816 if (parm_opt_value) {
7817 printf( "%s\n", parm_opt_value);
7824 /* check for a key and print the value */
7831 for (i = 0; parm_table[i].label; i++) {
7832 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7833 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7834 parm_table[i].ptr &&
7835 (*parm_table[i].label != '-') &&
7836 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7841 ptr = parm_table[i].ptr;
7843 struct service *pService = ServicePtrs[snum];
7844 ptr = ((char *)pService) +
7845 PTR_DIFF(parm_table[i].ptr, &sDefault);
7848 print_parameter(&parm_table[i],
7859 /***************************************************************************
7860 Return info about the requested parameter (given as a string).
7861 Return NULL when the string is not a valid parameter name.
7862 ***************************************************************************/
7864 struct parm_struct *lp_get_parameter(const char *param_name)
7866 int num = map_parameter(param_name);
7872 return &parm_table[num];
7875 /***************************************************************************
7876 Return info about the next parameter in a service.
7877 snum==GLOBAL_SECTION_SNUM gives the globals.
7878 Return NULL when out of parameters.
7879 ***************************************************************************/
7881 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7884 /* do the globals */
7885 for (; parm_table[*i].label; (*i)++) {
7886 if (parm_table[*i].p_class == P_SEPARATOR)
7887 return &parm_table[(*i)++];
7889 if (!parm_table[*i].ptr
7890 || (*parm_table[*i].label == '-'))
7894 && (parm_table[*i].ptr ==
7895 parm_table[(*i) - 1].ptr))
7898 if (is_default(*i) && !allparameters)
7901 return &parm_table[(*i)++];
7904 struct service *pService = ServicePtrs[snum];
7906 for (; parm_table[*i].label; (*i)++) {
7907 if (parm_table[*i].p_class == P_SEPARATOR)
7908 return &parm_table[(*i)++];
7910 if (parm_table[*i].p_class == P_LOCAL &&
7911 parm_table[*i].ptr &&
7912 (*parm_table[*i].label != '-') &&
7914 (parm_table[*i].ptr !=
7915 parm_table[(*i) - 1].ptr)))
7918 PTR_DIFF(parm_table[*i].ptr,
7921 if (allparameters ||
7922 !equal_parameter(parm_table[*i].type,
7923 ((char *)pService) +
7925 ((char *)&sDefault) +
7928 return &parm_table[(*i)++];
7939 /***************************************************************************
7940 Display the contents of a single copy structure.
7941 ***************************************************************************/
7942 static void dump_copy_map(bool *pcopymap)
7948 printf("\n\tNon-Copied parameters:\n");
7950 for (i = 0; parm_table[i].label; i++)
7951 if (parm_table[i].p_class == P_LOCAL &&
7952 parm_table[i].ptr && !pcopymap[i] &&
7953 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7955 printf("\t\t%s\n", parm_table[i].label);
7960 /***************************************************************************
7961 Return TRUE if the passed service number is within range.
7962 ***************************************************************************/
7964 bool lp_snum_ok(int iService)
7966 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7969 /***************************************************************************
7970 Auto-load some home services.
7971 ***************************************************************************/
7973 static void lp_add_auto_services(char *str)
7983 s = SMB_STRDUP(str);
7987 homes = lp_servicenumber(HOMES_NAME);
7989 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7990 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7993 if (lp_servicenumber(p) >= 0)
7996 home = get_user_home_dir(talloc_tos(), p);
7998 if (home && homes >= 0)
7999 lp_add_home(p, homes, p, home);
8006 /***************************************************************************
8007 Auto-load one printer.
8008 ***************************************************************************/
8010 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8012 int printers = lp_servicenumber(PRINTERS_NAME);
8015 if (lp_servicenumber(name) < 0) {
8016 lp_add_printer(name, printers);
8017 if ((i = lp_servicenumber(name)) >= 0) {
8018 string_set(&ServicePtrs[i]->comment, comment);
8019 ServicePtrs[i]->autoloaded = True;
8024 /***************************************************************************
8025 Have we loaded a services file yet?
8026 ***************************************************************************/
8028 bool lp_loaded(void)
8033 /***************************************************************************
8034 Unload unused services.
8035 ***************************************************************************/
8037 void lp_killunused(bool (*snumused) (int))
8040 for (i = 0; i < iNumServices; i++) {
8044 /* don't kill autoloaded or usershare services */
8045 if ( ServicePtrs[i]->autoloaded ||
8046 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8050 if (!snumused || !snumused(i)) {
8051 free_service_byindex(i);
8057 * Kill all except autoloaded and usershare services - convenience wrapper
8059 void lp_kill_all_services(void)
8061 lp_killunused(NULL);
8064 /***************************************************************************
8066 ***************************************************************************/
8068 void lp_killservice(int iServiceIn)
8070 if (VALID(iServiceIn)) {
8071 free_service_byindex(iServiceIn);
8075 /***************************************************************************
8076 Save the curent values of all global and sDefault parameters into the
8077 defaults union. This allows swat and testparm to show only the
8078 changed (ie. non-default) parameters.
8079 ***************************************************************************/
8081 static void lp_save_defaults(void)
8084 for (i = 0; parm_table[i].label; i++) {
8085 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8087 switch (parm_table[i].type) {
8089 parm_table[i].def.lvalue = str_list_copy(
8090 NULL, *(const char ***)parm_table[i].ptr);
8094 if (parm_table[i].ptr) {
8095 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8097 parm_table[i].def.svalue = NULL;
8102 parm_table[i].def.bvalue =
8103 *(bool *)parm_table[i].ptr;
8106 parm_table[i].def.cvalue =
8107 *(char *)parm_table[i].ptr;
8112 parm_table[i].def.ivalue =
8113 *(int *)parm_table[i].ptr;
8119 defaults_saved = True;
8122 /*******************************************************************
8123 Set the server type we will announce as via nmbd.
8124 ********************************************************************/
8126 static const struct srv_role_tab {
8128 const char *role_str;
8129 } srv_role_tab [] = {
8130 { ROLE_STANDALONE, "ROLE_STANDALONE" },
8131 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8132 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8133 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8137 const char* server_role_str(uint32 role)
8140 for (i=0; srv_role_tab[i].role_str; i++) {
8141 if (role == srv_role_tab[i].role) {
8142 return srv_role_tab[i].role_str;
8148 static void set_server_role(void)
8150 server_role = ROLE_STANDALONE;
8152 switch (lp_security()) {
8154 if (lp_domain_logons())
8155 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8158 if (lp_domain_logons())
8159 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8160 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8161 server_role = ROLE_STANDALONE;
8164 if (lp_domain_logons()) {
8165 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8166 server_role = ROLE_DOMAIN_BDC;
8169 server_role = ROLE_DOMAIN_MEMBER;
8172 if (lp_domain_logons()) {
8173 server_role = ROLE_DOMAIN_PDC;
8176 server_role = ROLE_DOMAIN_MEMBER;
8179 if (lp_domain_logons()) {
8181 if (Globals.iDomainMaster) /* auto or yes */
8182 server_role = ROLE_DOMAIN_PDC;
8184 server_role = ROLE_DOMAIN_BDC;
8188 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8192 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8195 /***********************************************************
8196 If we should send plaintext/LANMAN passwords in the clinet
8197 ************************************************************/
8199 static void set_allowed_client_auth(void)
8201 if (Globals.bClientNTLMv2Auth) {
8202 Globals.bClientLanManAuth = False;
8204 if (!Globals.bClientLanManAuth) {
8205 Globals.bClientPlaintextAuth = False;
8209 /***************************************************************************
8211 The following code allows smbd to read a user defined share file.
8212 Yes, this is my intent. Yes, I'm comfortable with that...
8214 THE FOLLOWING IS SECURITY CRITICAL CODE.
8216 It washes your clothes, it cleans your house, it guards you while you sleep...
8217 Do not f%^k with it....
8218 ***************************************************************************/
8220 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8222 /***************************************************************************
8223 Check allowed stat state of a usershare file.
8224 Ensure we print out who is dicking with us so the admin can
8225 get their sorry ass fired.
8226 ***************************************************************************/
8228 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8230 if (!S_ISREG(psbuf->st_mode)) {
8231 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8232 "not a regular file\n",
8233 fname, (unsigned int)psbuf->st_uid ));
8237 /* Ensure this doesn't have the other write bit set. */
8238 if (psbuf->st_mode & S_IWOTH) {
8239 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8240 "public write. Refusing to allow as a usershare file.\n",
8241 fname, (unsigned int)psbuf->st_uid ));
8245 /* Should be 10k or less. */
8246 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8247 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8248 "too large (%u) to be a user share file.\n",
8249 fname, (unsigned int)psbuf->st_uid,
8250 (unsigned int)psbuf->st_size ));
8257 /***************************************************************************
8258 Parse the contents of a usershare file.
8259 ***************************************************************************/
8261 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8262 SMB_STRUCT_STAT *psbuf,
8263 const char *servicename,
8267 char **pp_sharepath,
8272 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8273 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8276 SMB_STRUCT_STAT sbuf;
8277 char *sharepath = NULL;
8278 char *comment = NULL;
8280 *pp_sharepath = NULL;
8283 *pallow_guest = False;
8286 return USERSHARE_MALFORMED_FILE;
8289 if (strcmp(lines[0], "#VERSION 1") == 0) {
8291 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8294 return USERSHARE_MALFORMED_FILE;
8297 return USERSHARE_BAD_VERSION;
8300 if (strncmp(lines[1], "path=", 5) != 0) {
8301 return USERSHARE_MALFORMED_PATH;
8304 sharepath = talloc_strdup(ctx, &lines[1][5]);
8306 return USERSHARE_POSIX_ERR;
8308 trim_string(sharepath, " ", " ");
8310 if (strncmp(lines[2], "comment=", 8) != 0) {
8311 return USERSHARE_MALFORMED_COMMENT_DEF;
8314 comment = talloc_strdup(ctx, &lines[2][8]);
8316 return USERSHARE_POSIX_ERR;
8318 trim_string(comment, " ", " ");
8319 trim_char(comment, '"', '"');
8321 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8322 return USERSHARE_MALFORMED_ACL_DEF;
8325 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8326 return USERSHARE_ACL_ERR;
8330 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8331 return USERSHARE_MALFORMED_ACL_DEF;
8333 if (lines[4][9] == 'y') {
8334 *pallow_guest = True;
8338 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8339 /* Path didn't change, no checks needed. */
8340 *pp_sharepath = sharepath;
8341 *pp_comment = comment;
8342 return USERSHARE_OK;
8345 /* The path *must* be absolute. */
8346 if (sharepath[0] != '/') {
8347 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8348 servicename, sharepath));
8349 return USERSHARE_PATH_NOT_ABSOLUTE;
8352 /* If there is a usershare prefix deny list ensure one of these paths
8353 doesn't match the start of the user given path. */
8354 if (prefixdenylist) {
8356 for ( i=0; prefixdenylist[i]; i++ ) {
8357 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8358 servicename, i, prefixdenylist[i], sharepath ));
8359 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8360 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8361 "usershare prefix deny list entries.\n",
8362 servicename, sharepath));
8363 return USERSHARE_PATH_IS_DENIED;
8368 /* If there is a usershare prefix allow list ensure one of these paths
8369 does match the start of the user given path. */
8371 if (prefixallowlist) {
8373 for ( i=0; prefixallowlist[i]; i++ ) {
8374 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8375 servicename, i, prefixallowlist[i], sharepath ));
8376 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8380 if (prefixallowlist[i] == NULL) {
8381 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8382 "usershare prefix allow list entries.\n",
8383 servicename, sharepath));
8384 return USERSHARE_PATH_NOT_ALLOWED;
8388 /* Ensure this is pointing to a directory. */
8389 dp = sys_opendir(sharepath);
8392 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8393 servicename, sharepath));
8394 return USERSHARE_PATH_NOT_DIRECTORY;
8397 /* Ensure the owner of the usershare file has permission to share
8400 if (sys_stat(sharepath, &sbuf) == -1) {
8401 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8402 servicename, sharepath, strerror(errno) ));
8404 return USERSHARE_POSIX_ERR;
8409 if (!S_ISDIR(sbuf.st_mode)) {
8410 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8411 servicename, sharepath ));
8412 return USERSHARE_PATH_NOT_DIRECTORY;
8415 /* Check if sharing is restricted to owner-only. */
8416 /* psbuf is the stat of the usershare definition file,
8417 sbuf is the stat of the target directory to be shared. */
8419 if (lp_usershare_owner_only()) {
8420 /* root can share anything. */
8421 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8422 return USERSHARE_PATH_NOT_ALLOWED;
8426 *pp_sharepath = sharepath;
8427 *pp_comment = comment;
8428 return USERSHARE_OK;
8431 /***************************************************************************
8432 Deal with a usershare file.
8435 -1 - Bad name, invalid contents.
8436 - service name already existed and not a usershare, problem
8437 with permissions to share directory etc.
8438 ***************************************************************************/
8440 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8442 SMB_STRUCT_STAT sbuf;
8443 SMB_STRUCT_STAT lsbuf;
8445 char *sharepath = NULL;
8446 char *comment = NULL;
8447 fstring service_name;
8448 char **lines = NULL;
8452 TALLOC_CTX *ctx = NULL;
8453 SEC_DESC *psd = NULL;
8454 bool guest_ok = False;
8456 /* Ensure share name doesn't contain invalid characters. */
8457 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8458 DEBUG(0,("process_usershare_file: share name %s contains "
8459 "invalid characters (any of %s)\n",
8460 file_name, INVALID_SHARENAME_CHARS ));
8464 fstrcpy(service_name, file_name);
8466 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8469 /* Minimize the race condition by doing an lstat before we
8470 open and fstat. Ensure this isn't a symlink link. */
8472 if (sys_lstat(fname, &lsbuf) != 0) {
8473 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8474 fname, strerror(errno) ));
8479 /* This must be a regular file, not a symlink, directory or
8480 other strange filetype. */
8481 if (!check_usershare_stat(fname, &lsbuf)) {
8487 char *canon_name = canonicalize_servicename(service_name);
8488 TDB_DATA data = dbwrap_fetch_bystring(
8489 ServiceHash, canon_name, canon_name);
8493 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8494 iService = *(int *)data.dptr;
8496 TALLOC_FREE(canon_name);
8499 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8500 /* Nothing changed - Mark valid and return. */
8501 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8503 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8508 /* Try and open the file read only - no symlinks allowed. */
8510 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8512 fd = sys_open(fname, O_RDONLY, 0);
8516 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8517 fname, strerror(errno) ));
8522 /* Now fstat to be *SURE* it's a regular file. */
8523 if (sys_fstat(fd, &sbuf) != 0) {
8525 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8526 fname, strerror(errno) ));
8531 /* Is it the same dev/inode as was lstated ? */
8532 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8534 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8535 "Symlink spoofing going on ?\n", fname ));
8540 /* This must be a regular file, not a symlink, directory or
8541 other strange filetype. */
8542 if (!check_usershare_stat(fname, &sbuf)) {
8547 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8550 if (lines == NULL) {
8551 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8552 fname, (unsigned int)sbuf.st_uid ));
8559 /* Should we allow printers to be shared... ? */
8560 ctx = talloc_init("usershare_sd_xctx");
8566 if (parse_usershare_file(ctx, &sbuf, service_name,
8567 iService, lines, numlines, &sharepath,
8568 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8569 talloc_destroy(ctx);
8576 /* Everything ok - add the service possibly using a template. */
8578 const struct service *sp = &sDefault;
8579 if (snum_template != -1) {
8580 sp = ServicePtrs[snum_template];
8583 if ((iService = add_a_service(sp, service_name)) < 0) {
8584 DEBUG(0, ("process_usershare_file: Failed to add "
8585 "new service %s\n", service_name));
8586 talloc_destroy(ctx);
8590 /* Read only is controlled by usershare ACL below. */
8591 ServicePtrs[iService]->bRead_only = False;
8594 /* Write the ACL of the new/modified share. */
8595 if (!set_share_security(service_name, psd)) {
8596 DEBUG(0, ("process_usershare_file: Failed to set share "
8597 "security for user share %s\n",
8599 lp_remove_service(iService);
8600 talloc_destroy(ctx);
8604 /* If from a template it may be marked invalid. */
8605 ServicePtrs[iService]->valid = True;
8607 /* Set the service as a valid usershare. */
8608 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8610 /* Set guest access. */
8611 if (lp_usershare_allow_guests()) {
8612 ServicePtrs[iService]->bGuest_ok = guest_ok;
8615 /* And note when it was loaded. */
8616 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8617 string_set(&ServicePtrs[iService]->szPath, sharepath);
8618 string_set(&ServicePtrs[iService]->comment, comment);
8620 talloc_destroy(ctx);
8625 /***************************************************************************
8626 Checks if a usershare entry has been modified since last load.
8627 ***************************************************************************/
8629 static bool usershare_exists(int iService, time_t *last_mod)
8631 SMB_STRUCT_STAT lsbuf;
8632 const char *usersharepath = Globals.szUsersharePath;
8635 if (asprintf(&fname, "%s/%s",
8637 ServicePtrs[iService]->szService) < 0) {
8641 if (sys_lstat(fname, &lsbuf) != 0) {
8646 if (!S_ISREG(lsbuf.st_mode)) {
8652 *last_mod = lsbuf.st_mtime;
8656 /***************************************************************************
8657 Load a usershare service by name. Returns a valid servicenumber or -1.
8658 ***************************************************************************/
8660 int load_usershare_service(const char *servicename)
8662 SMB_STRUCT_STAT sbuf;
8663 const char *usersharepath = Globals.szUsersharePath;
8664 int max_user_shares = Globals.iUsershareMaxShares;
8665 int snum_template = -1;
8667 if (*usersharepath == 0 || max_user_shares == 0) {
8671 if (sys_stat(usersharepath, &sbuf) != 0) {
8672 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8673 usersharepath, strerror(errno) ));
8677 if (!S_ISDIR(sbuf.st_mode)) {
8678 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8684 * This directory must be owned by root, and have the 't' bit set.
8685 * It also must not be writable by "other".
8689 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8691 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8693 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8694 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8699 /* Ensure the template share exists if it's set. */
8700 if (Globals.szUsershareTemplateShare[0]) {
8701 /* We can't use lp_servicenumber here as we are recommending that
8702 template shares have -valid=False set. */
8703 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8704 if (ServicePtrs[snum_template]->szService &&
8705 strequal(ServicePtrs[snum_template]->szService,
8706 Globals.szUsershareTemplateShare)) {
8711 if (snum_template == -1) {
8712 DEBUG(0,("load_usershare_service: usershare template share %s "
8713 "does not exist.\n",
8714 Globals.szUsershareTemplateShare ));
8719 return process_usershare_file(usersharepath, servicename, snum_template);
8722 /***************************************************************************
8723 Load all user defined shares from the user share directory.
8724 We only do this if we're enumerating the share list.
8725 This is the function that can delete usershares that have
8727 ***************************************************************************/
8729 int load_usershare_shares(void)
8732 SMB_STRUCT_STAT sbuf;
8733 SMB_STRUCT_DIRENT *de;
8734 int num_usershares = 0;
8735 int max_user_shares = Globals.iUsershareMaxShares;
8736 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8737 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8738 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8740 int snum_template = -1;
8741 const char *usersharepath = Globals.szUsersharePath;
8742 int ret = lp_numservices();
8744 if (max_user_shares == 0 || *usersharepath == '\0') {
8745 return lp_numservices();
8748 if (sys_stat(usersharepath, &sbuf) != 0) {
8749 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8750 usersharepath, strerror(errno) ));
8755 * This directory must be owned by root, and have the 't' bit set.
8756 * It also must not be writable by "other".
8760 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8762 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8764 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8765 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8770 /* Ensure the template share exists if it's set. */
8771 if (Globals.szUsershareTemplateShare[0]) {
8772 /* We can't use lp_servicenumber here as we are recommending that
8773 template shares have -valid=False set. */
8774 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8775 if (ServicePtrs[snum_template]->szService &&
8776 strequal(ServicePtrs[snum_template]->szService,
8777 Globals.szUsershareTemplateShare)) {
8782 if (snum_template == -1) {
8783 DEBUG(0,("load_usershare_shares: usershare template share %s "
8784 "does not exist.\n",
8785 Globals.szUsershareTemplateShare ));
8790 /* Mark all existing usershares as pending delete. */
8791 for (iService = iNumServices - 1; iService >= 0; iService--) {
8792 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8793 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8797 dp = sys_opendir(usersharepath);
8799 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8800 usersharepath, strerror(errno) ));
8804 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8805 (de = sys_readdir(dp));
8806 num_dir_entries++ ) {
8808 const char *n = de->d_name;
8810 /* Ignore . and .. */
8812 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8818 /* Temporary file used when creating a share. */
8819 num_tmp_dir_entries++;
8822 /* Allow 20% tmp entries. */
8823 if (num_tmp_dir_entries > allowed_tmp_entries) {
8824 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8825 "in directory %s\n",
8826 num_tmp_dir_entries, usersharepath));
8830 r = process_usershare_file(usersharepath, n, snum_template);
8832 /* Update the services count. */
8834 if (num_usershares >= max_user_shares) {
8835 DEBUG(0,("load_usershare_shares: max user shares reached "
8836 "on file %s in directory %s\n",
8837 n, usersharepath ));
8840 } else if (r == -1) {
8841 num_bad_dir_entries++;
8844 /* Allow 20% bad entries. */
8845 if (num_bad_dir_entries > allowed_bad_entries) {
8846 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8847 "in directory %s\n",
8848 num_bad_dir_entries, usersharepath));
8852 /* Allow 20% bad entries. */
8853 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8854 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8855 "in directory %s\n",
8856 num_dir_entries, usersharepath));
8863 /* Sweep through and delete any non-refreshed usershares that are
8864 not currently in use. */
8865 for (iService = iNumServices - 1; iService >= 0; iService--) {
8866 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8867 if (conn_snum_used(iService)) {
8870 /* Remove from the share ACL db. */
8871 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8872 lp_servicename(iService) ));
8873 delete_share_security(lp_servicename(iService));
8874 free_service_byindex(iService);
8878 return lp_numservices();
8881 /********************************************************
8882 Destroy global resources allocated in this file
8883 ********************************************************/
8885 void gfree_loadparm(void)
8887 struct file_lists *f;
8888 struct file_lists *next;
8891 /* Free the file lists */
8896 SAFE_FREE( f->name );
8897 SAFE_FREE( f->subfname );
8903 /* Free resources allocated to services */
8905 for ( i = 0; i < iNumServices; i++ ) {
8907 free_service_byindex(i);
8911 SAFE_FREE( ServicePtrs );
8914 /* Now release all resources allocated to global
8915 parameters and the default service */
8917 free_global_parameters();
8921 /***************************************************************************
8922 Allow client apps to specify that they are a client
8923 ***************************************************************************/
8924 void lp_set_in_client(bool b)
8930 /***************************************************************************
8931 Determine if we're running in a client app
8932 ***************************************************************************/
8933 bool lp_is_in_client(void)
8938 /***************************************************************************
8939 Load the services array from the services file. Return True on success,
8941 ***************************************************************************/
8943 bool lp_load_ex(const char *pszFname,
8947 bool initialize_globals,
8948 bool allow_include_registry,
8949 bool allow_registry_shares)
8956 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8958 bInGlobalSection = True;
8959 bGlobalOnly = global_only;
8960 bAllowIncludeRegistry = allow_include_registry;
8962 init_globals(! initialize_globals);
8965 if (save_defaults) {
8970 free_param_opts(&Globals.param_opt);
8972 /* We get sections first, so have to start 'behind' to make up */
8975 if (lp_config_backend_is_file()) {
8976 n2 = alloc_sub_basic(get_current_username(),
8977 current_user_info.domain,
8980 smb_panic("lp_load_ex: out of memory");
8983 add_to_file_list(pszFname, n2);
8985 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8988 /* finish up the last section */
8989 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8991 if (iServiceIndex >= 0) {
8992 bRetval = service_ok(iServiceIndex);
8996 if (lp_config_backend_is_registry()) {
8997 /* config backend changed to registry in config file */
8999 * We need to use this extra global variable here to
9000 * survive restart: init_globals uses this as a default
9001 * for ConfigBackend. Otherwise, init_globals would
9002 * send us into an endless loop here.
9004 config_backend = CONFIG_BACKEND_REGISTRY;
9006 DEBUG(1, ("lp_load_ex: changing to config backend "
9008 init_globals(false);
9009 lp_kill_all_services();
9010 return lp_load_ex(pszFname, global_only, save_defaults,
9011 add_ipc, initialize_globals,
9012 allow_include_registry,
9013 allow_registry_shares);
9015 } else if (lp_config_backend_is_registry()) {
9016 bRetval = process_registry_globals();
9018 DEBUG(0, ("Illegal config backend given: %d\n",
9019 lp_config_backend()));
9023 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9024 bRetval = process_registry_shares();
9027 lp_add_auto_services(lp_auto_services());
9030 /* When 'restrict anonymous = 2' guest connections to ipc$
9032 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9033 if ( lp_enable_asu_support() ) {
9034 lp_add_ipc("ADMIN$", false);
9039 set_default_server_announce_type();
9040 set_allowed_client_auth();
9044 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9045 /* if bWINSsupport is true and we are in the client */
9046 if (lp_is_in_client() && Globals.bWINSsupport) {
9047 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9052 bAllowIncludeRegistry = true;
9057 bool lp_load(const char *pszFname,
9061 bool initialize_globals)
9063 return lp_load_ex(pszFname,
9071 bool lp_load_initial_only(const char *pszFname)
9073 return lp_load_ex(pszFname,
9082 bool lp_load_with_registry_shares(const char *pszFname,
9086 bool initialize_globals)
9088 return lp_load_ex(pszFname,
9097 /***************************************************************************
9098 Return the max number of services.
9099 ***************************************************************************/
9101 int lp_numservices(void)
9103 return (iNumServices);
9106 /***************************************************************************
9107 Display the contents of the services array in human-readable form.
9108 ***************************************************************************/
9110 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9115 defaults_saved = False;
9119 dump_a_service(&sDefault, f);
9121 for (iService = 0; iService < maxtoprint; iService++) {
9123 lp_dump_one(f, show_defaults, iService);
9127 /***************************************************************************
9128 Display the contents of one service in human-readable form.
9129 ***************************************************************************/
9131 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9134 if (ServicePtrs[snum]->szService[0] == '\0')
9136 dump_a_service(ServicePtrs[snum], f);
9140 /***************************************************************************
9141 Return the number of the service with the given name, or -1 if it doesn't
9142 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9143 getservicebyname()! This works ONLY if all services have been loaded, and
9144 does not copy the found service.
9145 ***************************************************************************/
9147 int lp_servicenumber(const char *pszServiceName)
9150 fstring serviceName;
9152 if (!pszServiceName) {
9153 return GLOBAL_SECTION_SNUM;
9156 for (iService = iNumServices - 1; iService >= 0; iService--) {
9157 if (VALID(iService) && ServicePtrs[iService]->szService) {
9159 * The substitution here is used to support %U is
9162 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9163 standard_sub_basic(get_current_username(),
9164 current_user_info.domain,
9165 serviceName,sizeof(serviceName));
9166 if (strequal(serviceName, pszServiceName)) {
9172 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9175 if (!usershare_exists(iService, &last_mod)) {
9176 /* Remove the share security tdb entry for it. */
9177 delete_share_security(lp_servicename(iService));
9178 /* Remove it from the array. */
9179 free_service_byindex(iService);
9180 /* Doesn't exist anymore. */
9181 return GLOBAL_SECTION_SNUM;
9184 /* Has it been modified ? If so delete and reload. */
9185 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9186 /* Remove it from the array. */
9187 free_service_byindex(iService);
9188 /* and now reload it. */
9189 iService = load_usershare_service(pszServiceName);
9194 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9195 return GLOBAL_SECTION_SNUM;
9201 bool share_defined(const char *service_name)
9203 return (lp_servicenumber(service_name) != -1);
9206 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9207 const char *sharename)
9209 struct share_params *result;
9213 if (!(sname = SMB_STRDUP(sharename))) {
9217 snum = find_service(sname);
9224 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9225 DEBUG(0, ("talloc failed\n"));
9229 result->service = snum;
9233 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9235 struct share_iterator *result;
9237 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9238 DEBUG(0, ("talloc failed\n"));
9242 result->next_id = 0;
9246 struct share_params *next_share(struct share_iterator *list)
9248 struct share_params *result;
9250 while (!lp_snum_ok(list->next_id) &&
9251 (list->next_id < lp_numservices())) {
9255 if (list->next_id >= lp_numservices()) {
9259 if (!(result = TALLOC_P(list, struct share_params))) {
9260 DEBUG(0, ("talloc failed\n"));
9264 result->service = list->next_id;
9269 struct share_params *next_printer(struct share_iterator *list)
9271 struct share_params *result;
9273 while ((result = next_share(list)) != NULL) {
9274 if (lp_print_ok(result->service)) {
9282 * This is a hack for a transition period until we transformed all code from
9283 * service numbers to struct share_params.
9286 struct share_params *snum2params_static(int snum)
9288 static struct share_params result;
9289 result.service = snum;
9293 /*******************************************************************
9294 A useful volume label function.
9295 ********************************************************************/
9297 const char *volume_label(int snum)
9300 const char *label = lp_volume(snum);
9302 label = lp_servicename(snum);
9305 /* This returns a 33 byte guarenteed null terminated string. */
9306 ret = talloc_strndup(talloc_tos(), label, 32);
9313 /*******************************************************************
9314 Set the server type we will announce as via nmbd.
9315 ********************************************************************/
9317 static void set_default_server_announce_type(void)
9319 default_server_announce = 0;
9320 default_server_announce |= SV_TYPE_WORKSTATION;
9321 default_server_announce |= SV_TYPE_SERVER;
9322 default_server_announce |= SV_TYPE_SERVER_UNIX;
9324 /* note that the flag should be set only if we have a
9325 printer service but nmbd doesn't actually load the
9326 services so we can't tell --jerry */
9328 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9330 switch (lp_announce_as()) {
9331 case ANNOUNCE_AS_NT_SERVER:
9332 default_server_announce |= SV_TYPE_SERVER_NT;
9333 /* fall through... */
9334 case ANNOUNCE_AS_NT_WORKSTATION:
9335 default_server_announce |= SV_TYPE_NT;
9337 case ANNOUNCE_AS_WIN95:
9338 default_server_announce |= SV_TYPE_WIN95_PLUS;
9340 case ANNOUNCE_AS_WFW:
9341 default_server_announce |= SV_TYPE_WFW;
9347 switch (lp_server_role()) {
9348 case ROLE_DOMAIN_MEMBER:
9349 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9351 case ROLE_DOMAIN_PDC:
9352 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9354 case ROLE_DOMAIN_BDC:
9355 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9357 case ROLE_STANDALONE:
9361 if (lp_time_server())
9362 default_server_announce |= SV_TYPE_TIME_SOURCE;
9364 if (lp_host_msdfs())
9365 default_server_announce |= SV_TYPE_DFS_SERVER;
9368 /***********************************************************
9369 returns role of Samba server
9370 ************************************************************/
9372 int lp_server_role(void)
9377 /***********************************************************
9378 If we are PDC then prefer us as DMB
9379 ************************************************************/
9381 bool lp_domain_master(void)
9383 if (Globals.iDomainMaster == Auto)
9384 return (lp_server_role() == ROLE_DOMAIN_PDC);
9386 return (bool)Globals.iDomainMaster;
9389 /***********************************************************
9390 If we are DMB then prefer us as LMB
9391 ************************************************************/
9393 bool lp_preferred_master(void)
9395 if (Globals.iPreferredMaster == Auto)
9396 return (lp_local_master() && lp_domain_master());
9398 return (bool)Globals.iPreferredMaster;
9401 /*******************************************************************
9403 ********************************************************************/
9405 void lp_remove_service(int snum)
9407 ServicePtrs[snum]->valid = False;
9408 invalid_services[num_invalid_services++] = snum;
9411 /*******************************************************************
9413 ********************************************************************/
9415 void lp_copy_service(int snum, const char *new_name)
9417 do_section(new_name, NULL);
9419 snum = lp_servicenumber(new_name);
9421 lp_do_parameter(snum, "copy", lp_servicename(snum));
9426 /*******************************************************************
9427 Get the default server type we will announce as via nmbd.
9428 ********************************************************************/
9430 int lp_default_server_announce(void)
9432 return default_server_announce;
9435 /*******************************************************************
9436 Split the announce version into major and minor numbers.
9437 ********************************************************************/
9439 int lp_major_announce_version(void)
9441 static bool got_major = False;
9442 static int major_version = DEFAULT_MAJOR_VERSION;
9447 return major_version;
9450 if ((vers = lp_announce_version()) == NULL)
9451 return major_version;
9453 if ((p = strchr_m(vers, '.')) == 0)
9454 return major_version;
9457 major_version = atoi(vers);
9458 return major_version;
9461 int lp_minor_announce_version(void)
9463 static bool got_minor = False;
9464 static int minor_version = DEFAULT_MINOR_VERSION;
9469 return minor_version;
9472 if ((vers = lp_announce_version()) == NULL)
9473 return minor_version;
9475 if ((p = strchr_m(vers, '.')) == 0)
9476 return minor_version;
9479 minor_version = atoi(p);
9480 return minor_version;
9483 /***********************************************************
9484 Set the global name resolution order (used in smbclient).
9485 ************************************************************/
9487 void lp_set_name_resolve_order(const char *new_order)
9489 string_set(&Globals.szNameResolveOrder, new_order);
9492 const char *lp_printername(int snum)
9494 const char *ret = _lp_printername(snum);
9495 if (ret == NULL || (ret != NULL && *ret == '\0'))
9496 ret = lp_const_servicename(snum);
9502 /***********************************************************
9503 Allow daemons such as winbindd to fix their logfile name.
9504 ************************************************************/
9506 void lp_set_logfile(const char *name)
9508 string_set(&Globals.szLogFile, name);
9509 debug_set_logfile(name);
9512 /*******************************************************************
9513 Return the max print jobs per queue.
9514 ********************************************************************/
9516 int lp_maxprintjobs(int snum)
9518 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9519 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9520 maxjobs = PRINT_MAX_JOBID - 1;
9525 const char *lp_printcapname(void)
9527 if ((Globals.szPrintcapname != NULL) &&
9528 (Globals.szPrintcapname[0] != '\0'))
9529 return Globals.szPrintcapname;
9531 if (sDefault.iPrinting == PRINT_CUPS) {
9539 if (sDefault.iPrinting == PRINT_BSD)
9540 return "/etc/printcap";
9542 return PRINTCAP_NAME;
9545 /*******************************************************************
9546 Ensure we don't use sendfile if server smb signing is active.
9547 ********************************************************************/
9549 static uint32 spoolss_state;
9551 bool lp_disable_spoolss( void )
9553 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9554 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9556 return spoolss_state == SVCCTL_STOPPED ? True : False;
9559 void lp_set_spoolss_state( uint32 state )
9561 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9563 spoolss_state = state;
9566 uint32 lp_get_spoolss_state( void )
9568 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9571 /*******************************************************************
9572 Ensure we don't use sendfile if server smb signing is active.
9573 ********************************************************************/
9575 bool lp_use_sendfile(int snum)
9577 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9578 if (Protocol < PROTOCOL_NT1) {
9581 return (_lp_use_sendfile(snum) &&
9582 (get_remote_arch() != RA_WIN95) &&
9583 !srv_is_signing_active());
9586 /*******************************************************************
9587 Turn off sendfile if we find the underlying OS doesn't support it.
9588 ********************************************************************/
9590 void set_use_sendfile(int snum, bool val)
9592 if (LP_SNUM_OK(snum))
9593 ServicePtrs[snum]->bUseSendfile = val;
9595 sDefault.bUseSendfile = val;
9598 /*******************************************************************
9599 Turn off storing DOS attributes if this share doesn't support it.
9600 ********************************************************************/
9602 void set_store_dos_attributes(int snum, bool val)
9604 if (!LP_SNUM_OK(snum))
9606 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9609 void lp_set_mangling_method(const char *new_method)
9611 string_set(&Globals.szManglingMethod, new_method);
9614 /*******************************************************************
9615 Global state for POSIX pathname processing.
9616 ********************************************************************/
9618 static bool posix_pathnames;
9620 bool lp_posix_pathnames(void)
9622 return posix_pathnames;
9625 /*******************************************************************
9626 Change everything needed to ensure POSIX pathname processing (currently
9628 ********************************************************************/
9630 void lp_set_posix_pathnames(void)
9632 posix_pathnames = True;
9635 /*******************************************************************
9636 Global state for POSIX lock processing - CIFS unix extensions.
9637 ********************************************************************/
9639 bool posix_default_lock_was_set;
9640 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9642 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9644 if (posix_default_lock_was_set) {
9645 return posix_cifsx_locktype;
9647 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9651 /*******************************************************************
9652 ********************************************************************/
9654 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9656 posix_default_lock_was_set = True;
9657 posix_cifsx_locktype = val;
9660 int lp_min_receive_file_size(void)
9662 if (Globals.iminreceivefile < 0) {
9665 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9668 /*******************************************************************
9669 If socket address is an empty character string, it is necessary to
9670 define it as "0.0.0.0".
9671 ********************************************************************/
9673 const char *lp_socket_address(void)
9675 char *sock_addr = Globals.szSocketAddress;
9677 if (sock_addr[0] == '\0'){
9678 string_set(&Globals.szSocketAddress, "0.0.0.0");
9680 return Globals.szSocketAddress;