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
58 extern enum protocol_types Protocol;
59 extern userdom_struct current_user_info;
62 #define GLOBAL_NAME "global"
66 #define PRINTERS_NAME "printers"
70 #define HOMES_NAME "homes"
73 /* the special value for the include parameter
74 * to be interpreted not as a file name but to
75 * trigger loading of the global smb.conf options
77 #ifndef INCLUDE_REGISTRY_NAME
78 #define INCLUDE_REGISTRY_NAME "registry"
81 static bool in_client = False; /* Not in the client by default */
82 static struct smbconf_csn conf_last_csn;
84 #define CONFIG_BACKEND_FILE 0
85 #define CONFIG_BACKEND_REGISTRY 1
87 static int config_backend = CONFIG_BACKEND_FILE;
89 /* some helpful bits */
90 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
91 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
93 #define USERSHARE_VALID 1
94 #define USERSHARE_PENDING_DELETE 2
96 extern int extra_time_offset;
98 static bool defaults_saved = False;
100 struct param_opt_struct {
101 struct param_opt_struct *prev, *next;
108 * This structure describes global (ie., server-wide) parameters.
115 char *display_charset;
116 char *szPrintcapname;
117 char *szAddPortCommand;
118 char *szEnumPortsCommand;
119 char *szAddPrinterCommand;
120 char *szDeletePrinterCommand;
121 char *szOs2DriverMap;
125 char *szDefaultService;
129 char *szServerString;
130 char *szAutoServices;
131 char *szPasswdProgram;
135 char *szSMBPasswdFile;
137 char *szPassdbBackend;
138 char **szPreloadModules;
139 char *szPasswordServer;
140 char *szSocketOptions;
142 char *szAfsUsernameMap;
143 int iAfsTokenLifetime;
144 char *szLogNtTokenCommand;
150 char **szWINSservers;
152 char *szRemoteAnnounce;
153 char *szRemoteBrowseSync;
154 char *szSocketAddress;
155 char *szNISHomeMapName;
156 char *szAnnounceVersion; /* This is initialised in init_globals */
159 char **szNetbiosAliases;
160 char *szNetbiosScope;
161 char *szNameResolveOrder;
163 char *szAddUserScript;
164 char *szRenameUserScript;
165 char *szDelUserScript;
166 char *szAddGroupScript;
167 char *szDelGroupScript;
168 char *szAddUserToGroupScript;
169 char *szDelUserFromGroupScript;
170 char *szSetPrimaryGroupScript;
171 char *szAddMachineScript;
172 char *szShutdownScript;
173 char *szAbortShutdownScript;
174 char *szUsernameMapScript;
175 char *szCheckPasswordScript;
182 bool bPassdbExpandExplicit;
183 int AlgorithmicRidBase;
184 char *szTemplateHomedir;
185 char *szTemplateShell;
186 char *szWinbindSeparator;
187 bool bWinbindEnumUsers;
188 bool bWinbindEnumGroups;
189 bool bWinbindUseDefaultDomain;
190 bool bWinbindTrustedDomainsOnly;
191 bool bWinbindNestedGroups;
192 int winbind_expand_groups;
193 bool bWinbindRefreshTickets;
194 bool bWinbindOfflineLogon;
195 bool bWinbindNormalizeNames;
196 bool bWinbindRpcOnly;
197 char **szIdmapDomains;
198 char **szIdmapBackend; /* deprecated */
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_max_idle_children;
245 char **szWinbindNssInfo;
247 char *szLdapMachineSuffix;
248 char *szLdapUserSuffix;
249 char *szLdapIdmapSuffix;
250 char *szLdapGroupSuffix;
254 int ldap_debug_level;
255 int ldap_debug_threshold;
258 char *szIPrintServer;
260 char **szClusterAddresses;
262 int ldap_passwd_sync;
263 int ldap_replication_sleep;
264 int ldap_timeout; /* This is initialised in init_globals */
265 int ldap_connection_timeout;
268 bool bMsAddPrinterWizard;
273 int iPreferredMaster;
276 char **szInitLogonDelayedHosts;
278 bool bEncryptPasswords;
283 bool bObeyPamRestrictions;
285 int PrintcapCacheTime;
286 bool bLargeReadwrite;
293 bool bBindInterfacesOnly;
294 bool bPamPasswordChange;
295 bool bUnixPasswdSync;
296 bool bPasswdChatDebug;
297 int iPasswdChatTimeout;
301 bool bNTStatusSupport;
303 int iMaxStatCacheSize;
305 bool bAllowTrustedDomains;
309 bool bClientLanManAuth;
310 bool bClientNTLMv2Auth;
311 bool bClientPlaintextAuth;
312 bool bClientUseSpnego;
313 bool bDebugPrefixTimestamp;
314 bool bDebugHiresTimestamp;
318 bool bEnableCoreFiles;
321 bool bHostnameLookups;
322 bool bUnixExtensions;
323 bool bDisableNetbios;
324 bool bUseKerberosKeytab;
325 bool bDeferSharingViolations;
326 bool bEnablePrivileges;
328 bool bUsershareOwnerOnly;
329 bool bUsershareAllowGuests;
330 bool bRegistryShares;
331 int restrict_anonymous;
332 int name_cache_timeout;
335 int client_ldap_sasl_wrapping;
336 int iUsershareMaxShares;
338 int iIdmapNegativeCacheTime;
342 struct param_opt_struct *param_opt;
345 static struct global Globals;
348 * This structure describes a single service.
354 time_t usershare_last_mod;
358 char **szInvalidUsers;
366 char *szRootPostExec;
368 char *szPrintcommand;
371 char *szLppausecommand;
372 char *szLpresumecommand;
373 char *szQueuepausecommand;
374 char *szQueueresumecommand;
376 char *szPrintjobUsername;
384 char *szVetoOplockFiles;
390 char **printer_admin;
395 char *szAioWriteBehind;
399 int iMaxReportedPrintJobs;
402 int iCreate_force_mode;
404 int iSecurity_force_mode;
407 int iDir_Security_mask;
408 int iDir_Security_force_mode;
412 int iOplockContentionLimit;
417 bool bRootpreexecClose;
420 bool bShortCasePreserve;
422 bool bHideSpecialFiles;
423 bool bHideUnReadable;
424 bool bHideUnWriteableFiles;
430 bool bAdministrative_share;
436 bool bStoreDosAttributes;
449 bool bStrictAllocate;
452 struct bitmap *copymap;
453 bool bDeleteReadonly;
455 bool bDeleteVetoFiles;
458 bool bDosFiletimeResolution;
459 bool bFakeDirCreateTimes;
465 bool bUseClientDriver;
466 bool bDefaultDevmode;
467 bool bForcePrintername;
469 bool bForceUnknownAclUser;
472 bool bMap_acl_inherit;
475 bool bAclCheckPermissions;
476 bool bAclMapFullControl;
477 bool bAclGroupControl;
479 bool bKernelChangeNotify;
480 int iallocation_roundup_size;
484 int iDirectoryNameCacheSize;
486 struct param_opt_struct *param_opt;
488 char dummy[3]; /* for alignment */
492 /* This is a default service used to prime a services structure */
493 static struct service sDefault = {
495 False, /* not autoloaded */
496 0, /* not a usershare */
497 (time_t)0, /* No last mod time */
498 NULL, /* szService */
500 NULL, /* szUsername */
501 NULL, /* szInvalidUsers */
502 NULL, /* szValidUsers */
503 NULL, /* szAdminUsers */
505 NULL, /* szInclude */
506 NULL, /* szPreExec */
507 NULL, /* szPostExec */
508 NULL, /* szRootPreExec */
509 NULL, /* szRootPostExec */
510 NULL, /* szCupsOptions */
511 NULL, /* szPrintcommand */
512 NULL, /* szLpqcommand */
513 NULL, /* szLprmcommand */
514 NULL, /* szLppausecommand */
515 NULL, /* szLpresumecommand */
516 NULL, /* szQueuepausecommand */
517 NULL, /* szQueueresumecommand */
518 NULL, /* szPrintername */
519 NULL, /* szPrintjobUsername */
520 NULL, /* szDontdescend */
521 NULL, /* szHostsallow */
522 NULL, /* szHostsdeny */
523 NULL, /* szMagicScript */
524 NULL, /* szMagicOutput */
525 NULL, /* szVetoFiles */
526 NULL, /* szHideFiles */
527 NULL, /* szVetoOplockFiles */
529 NULL, /* force user */
530 NULL, /* force group */
532 NULL, /* writelist */
533 NULL, /* printer admin */
536 NULL, /* vfs objects */
537 NULL, /* szMSDfsProxy */
538 NULL, /* szAioWriteBehind */
540 0, /* iMinPrintSpace */
541 1000, /* iMaxPrintJobs */
542 0, /* iMaxReportedPrintJobs */
543 0, /* iWriteCacheSize */
544 0744, /* iCreate_mask */
545 0000, /* iCreate_force_mode */
546 0777, /* iSecurity_mask */
547 0, /* iSecurity_force_mode */
548 0755, /* iDir_mask */
549 0000, /* iDir_force_mode */
550 0777, /* iDir_Security_mask */
551 0, /* iDir_Security_force_mode */
552 0, /* iMaxConnections */
553 CASE_LOWER, /* iDefaultCase */
554 DEFAULT_PRINTING, /* iPrinting */
555 2, /* iOplockContentionLimit */
557 1024, /* iBlock_size */
558 0, /* iDfreeCacheTime */
559 False, /* bPreexecClose */
560 False, /* bRootpreexecClose */
561 Auto, /* case sensitive */
562 True, /* case preserve */
563 True, /* short case preserve */
564 True, /* bHideDotFiles */
565 False, /* bHideSpecialFiles */
566 False, /* bHideUnReadable */
567 False, /* bHideUnWriteableFiles */
568 True, /* bBrowseable */
569 True, /* bAvailable */
570 True, /* bRead_only */
571 True, /* bNo_set_dir */
572 False, /* bGuest_only */
573 False, /* bAdministrative_share */
574 False, /* bGuest_ok */
575 False, /* bPrint_ok */
576 False, /* bMap_system */
577 False, /* bMap_hidden */
578 True, /* bMap_archive */
579 False, /* bStoreDosAttributes */
580 False, /* bDmapiSupport */
582 Auto, /* iStrictLocking */
583 True, /* bPosixLocking */
584 True, /* bShareModes */
586 True, /* bLevel2OpLocks */
587 False, /* bOnlyUser */
588 True, /* bMangledNames */
589 True, /* bWidelinks */
590 True, /* bSymlinks */
591 False, /* bSyncAlways */
592 False, /* bStrictAllocate */
593 False, /* bStrictSync */
594 '~', /* magic char */
596 False, /* bDeleteReadonly */
597 False, /* bFakeOplocks */
598 False, /* bDeleteVetoFiles */
599 False, /* bDosFilemode */
600 True, /* bDosFiletimes */
601 False, /* bDosFiletimeResolution */
602 False, /* bFakeDirCreateTimes */
603 True, /* bBlockingLocks */
604 False, /* bInheritPerms */
605 False, /* bInheritACLS */
606 False, /* bInheritOwner */
607 False, /* bMSDfsRoot */
608 False, /* bUseClientDriver */
609 True, /* bDefaultDevmode */
610 False, /* bForcePrintername */
611 True, /* bNTAclSupport */
612 False, /* bForceUnknownAclUser */
613 False, /* bUseSendfile */
614 False, /* bProfileAcls */
615 False, /* bMap_acl_inherit */
616 False, /* bAfs_Share */
617 False, /* bEASupport */
618 True, /* bAclCheckPermissions */
619 True, /* bAclMapFullControl */
620 False, /* bAclGroupControl */
621 True, /* bChangeNotify */
622 True, /* bKernelChangeNotify */
623 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
624 0, /* iAioReadSize */
625 0, /* iAioWriteSize */
626 MAP_READONLY_YES, /* iMap_readonly */
627 #ifdef BROKEN_DIRECTORY_HANDLING
628 0, /* iDirectoryNameCacheSize */
630 100, /* iDirectoryNameCacheSize */
632 Auto, /* ismb_encrypt */
633 NULL, /* Parametric options */
638 /* local variables */
639 static struct service **ServicePtrs = NULL;
640 static int iNumServices = 0;
641 static int iServiceIndex = 0;
642 static struct db_context *ServiceHash;
643 static int *invalid_services = NULL;
644 static int num_invalid_services = 0;
645 static bool bInGlobalSection = True;
646 static bool bGlobalOnly = False;
647 static int server_role;
648 static int default_server_announce;
650 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
652 /* prototypes for the special type handlers */
653 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
654 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
655 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
656 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
657 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
658 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
659 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
660 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
661 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
662 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
663 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
664 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
666 static void set_server_role(void);
667 static void set_default_server_announce_type(void);
668 static void set_allowed_client_auth(void);
670 static const struct enum_list enum_protocol[] = {
671 {PROTOCOL_NT1, "NT1"},
672 {PROTOCOL_LANMAN2, "LANMAN2"},
673 {PROTOCOL_LANMAN1, "LANMAN1"},
674 {PROTOCOL_CORE, "CORE"},
675 {PROTOCOL_COREPLUS, "COREPLUS"},
676 {PROTOCOL_COREPLUS, "CORE+"},
680 static const struct enum_list enum_security[] = {
681 {SEC_SHARE, "SHARE"},
683 {SEC_SERVER, "SERVER"},
684 {SEC_DOMAIN, "DOMAIN"},
691 static const struct enum_list enum_printing[] = {
692 {PRINT_SYSV, "sysv"},
694 {PRINT_HPUX, "hpux"},
698 {PRINT_LPRNG, "lprng"},
699 {PRINT_CUPS, "cups"},
700 {PRINT_IPRINT, "iprint"},
702 {PRINT_LPROS2, "os2"},
704 {PRINT_TEST, "test"},
706 #endif /* DEVELOPER */
710 static const struct enum_list enum_ldap_sasl_wrapping[] = {
712 {ADS_AUTH_SASL_SIGN, "sign"},
713 {ADS_AUTH_SASL_SEAL, "seal"},
717 static const struct enum_list enum_ldap_ssl[] = {
718 {LDAP_SSL_OFF, "no"},
719 {LDAP_SSL_OFF, "No"},
720 {LDAP_SSL_OFF, "off"},
721 {LDAP_SSL_OFF, "Off"},
722 {LDAP_SSL_START_TLS, "start tls"},
723 {LDAP_SSL_START_TLS, "Start_tls"},
727 static const struct enum_list enum_ldap_passwd_sync[] = {
728 {LDAP_PASSWD_SYNC_OFF, "no"},
729 {LDAP_PASSWD_SYNC_OFF, "No"},
730 {LDAP_PASSWD_SYNC_OFF, "off"},
731 {LDAP_PASSWD_SYNC_OFF, "Off"},
732 {LDAP_PASSWD_SYNC_ON, "Yes"},
733 {LDAP_PASSWD_SYNC_ON, "yes"},
734 {LDAP_PASSWD_SYNC_ON, "on"},
735 {LDAP_PASSWD_SYNC_ON, "On"},
736 {LDAP_PASSWD_SYNC_ONLY, "Only"},
737 {LDAP_PASSWD_SYNC_ONLY, "only"},
741 /* Types of machine we can announce as. */
742 #define ANNOUNCE_AS_NT_SERVER 1
743 #define ANNOUNCE_AS_WIN95 2
744 #define ANNOUNCE_AS_WFW 3
745 #define ANNOUNCE_AS_NT_WORKSTATION 4
747 static const struct enum_list enum_announce_as[] = {
748 {ANNOUNCE_AS_NT_SERVER, "NT"},
749 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
750 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
751 {ANNOUNCE_AS_WIN95, "win95"},
752 {ANNOUNCE_AS_WFW, "WfW"},
756 static const struct enum_list enum_map_readonly[] = {
757 {MAP_READONLY_NO, "no"},
758 {MAP_READONLY_NO, "false"},
759 {MAP_READONLY_NO, "0"},
760 {MAP_READONLY_YES, "yes"},
761 {MAP_READONLY_YES, "true"},
762 {MAP_READONLY_YES, "1"},
763 {MAP_READONLY_PERMISSIONS, "permissions"},
764 {MAP_READONLY_PERMISSIONS, "perms"},
768 static const struct enum_list enum_case[] = {
769 {CASE_LOWER, "lower"},
770 {CASE_UPPER, "upper"},
774 static const struct enum_list enum_bool_auto[] = {
785 /* Client-side offline caching policy types */
786 #define CSC_POLICY_MANUAL 0
787 #define CSC_POLICY_DOCUMENTS 1
788 #define CSC_POLICY_PROGRAMS 2
789 #define CSC_POLICY_DISABLE 3
791 static const struct enum_list enum_csc_policy[] = {
792 {CSC_POLICY_MANUAL, "manual"},
793 {CSC_POLICY_DOCUMENTS, "documents"},
794 {CSC_POLICY_PROGRAMS, "programs"},
795 {CSC_POLICY_DISABLE, "disable"},
799 /* SMB signing types. */
800 static const struct enum_list enum_smb_signing_vals[] = {
812 {Required, "required"},
813 {Required, "mandatory"},
815 {Required, "forced"},
816 {Required, "enforced"},
820 /* ACL compatibility options. */
821 static const struct enum_list enum_acl_compat_vals[] = {
822 { ACL_COMPAT_AUTO, "auto" },
823 { ACL_COMPAT_WINNT, "winnt" },
824 { ACL_COMPAT_WIN2K, "win2k" },
829 Do you want session setups at user level security with a invalid
830 password to be rejected or allowed in as guest? WinNT rejects them
831 but it can be a pain as it means "net view" needs to use a password
833 You have 3 choices in the setting of map_to_guest:
835 "Never" means session setups with an invalid password
836 are rejected. This is the default.
838 "Bad User" means session setups with an invalid password
839 are rejected, unless the username does not exist, in which case it
840 is treated as a guest login
842 "Bad Password" means session setups with an invalid password
843 are treated as a guest login
845 Note that map_to_guest only has an effect in user or server
849 static const struct enum_list enum_map_to_guest[] = {
850 {NEVER_MAP_TO_GUEST, "Never"},
851 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
852 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
853 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
857 /* Config backend options */
859 static const struct enum_list enum_config_backend[] = {
860 {CONFIG_BACKEND_FILE, "file"},
861 {CONFIG_BACKEND_REGISTRY, "registry"},
865 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
867 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
868 * screen in SWAT. This is used to exclude parameters as well as to squash all
869 * parameters that have been duplicated by pseudonyms.
871 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
872 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
873 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
876 * NOTE2: Handling of duplicated (synonym) paramters:
877 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
878 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
879 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
880 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
883 static struct parm_struct parm_table[] = {
884 {N_("Base Options"), P_SEP, P_SEPARATOR},
887 .label = "dos charset",
890 .ptr = &Globals.dos_charset,
891 .special = handle_charset,
893 .flags = FLAG_ADVANCED
896 .label = "unix charset",
899 .ptr = &Globals.unix_charset,
900 .special = handle_charset,
902 .flags = FLAG_ADVANCED
905 .label = "display charset",
908 .ptr = &Globals.display_charset,
909 .special = handle_charset,
911 .flags = FLAG_ADVANCED
917 .ptr = &sDefault.comment,
920 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
926 .ptr = &sDefault.szPath,
929 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
932 .label = "directory",
935 .ptr = &sDefault.szPath,
941 .label = "workgroup",
944 .ptr = &Globals.szWorkgroup,
945 .special = handle_workgroup,
947 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
954 .ptr = &Globals.szRealm,
957 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
961 .label = "netbios name",
964 .ptr = &Globals.szNetbiosName,
965 .special = handle_netbios_name,
967 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
970 .label = "netbios aliases",
973 .ptr = &Globals.szNetbiosAliases,
974 .special = handle_netbios_aliases,
976 .flags = FLAG_ADVANCED,
979 .label = "netbios scope",
982 .ptr = &Globals.szNetbiosScope,
983 .special = handle_netbios_scope,
985 .flags = FLAG_ADVANCED,
988 .label = "server string",
991 .ptr = &Globals.szServerString,
994 .flags = FLAG_BASIC | FLAG_ADVANCED,
997 .label = "interfaces",
1000 .ptr = &Globals.szInterfaces,
1003 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1006 .label = "bind interfaces only",
1008 .p_class = P_GLOBAL,
1009 .ptr = &Globals.bBindInterfacesOnly,
1012 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1015 .label = "config backend",
1017 .p_class = P_GLOBAL,
1018 .ptr = &Globals.ConfigBackend,
1020 .enum_list = enum_config_backend,
1021 .flags = FLAG_ADVANCED,
1024 {N_("Security Options"), P_SEP, P_SEPARATOR},
1027 .label = "security",
1029 .p_class = P_GLOBAL,
1030 .ptr = &Globals.security,
1032 .enum_list = enum_security,
1033 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1036 .label = "auth methods",
1038 .p_class = P_GLOBAL,
1039 .ptr = &Globals.AuthMethods,
1042 .flags = FLAG_ADVANCED,
1045 .label = "encrypt passwords",
1047 .p_class = P_GLOBAL,
1048 .ptr = &Globals.bEncryptPasswords,
1051 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1054 .label = "update encrypted",
1056 .p_class = P_GLOBAL,
1057 .ptr = &Globals.bUpdateEncrypt,
1060 .flags = FLAG_ADVANCED,
1063 .label = "client schannel",
1065 .p_class = P_GLOBAL,
1066 .ptr = &Globals.clientSchannel,
1068 .enum_list = enum_bool_auto,
1069 .flags = FLAG_BASIC | FLAG_ADVANCED,
1072 .label = "server schannel",
1074 .p_class = P_GLOBAL,
1075 .ptr = &Globals.serverSchannel,
1077 .enum_list = enum_bool_auto,
1078 .flags = FLAG_BASIC | FLAG_ADVANCED,
1081 .label = "allow trusted domains",
1083 .p_class = P_GLOBAL,
1084 .ptr = &Globals.bAllowTrustedDomains,
1087 .flags = FLAG_ADVANCED,
1090 .label = "map to guest",
1092 .p_class = P_GLOBAL,
1093 .ptr = &Globals.map_to_guest,
1095 .enum_list = enum_map_to_guest,
1096 .flags = FLAG_ADVANCED,
1099 .label = "null passwords",
1101 .p_class = P_GLOBAL,
1102 .ptr = &Globals.bNullPasswords,
1105 .flags = FLAG_ADVANCED,
1108 .label = "obey pam restrictions",
1110 .p_class = P_GLOBAL,
1111 .ptr = &Globals.bObeyPamRestrictions,
1114 .flags = FLAG_ADVANCED,
1117 .label = "password server",
1119 .p_class = P_GLOBAL,
1120 .ptr = &Globals.szPasswordServer,
1123 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1126 .label = "smb passwd file",
1128 .p_class = P_GLOBAL,
1129 .ptr = &Globals.szSMBPasswdFile,
1132 .flags = FLAG_ADVANCED,
1135 .label = "private dir",
1137 .p_class = P_GLOBAL,
1138 .ptr = &Globals.szPrivateDir,
1141 .flags = FLAG_ADVANCED,
1144 .label = "passdb backend",
1146 .p_class = P_GLOBAL,
1147 .ptr = &Globals.szPassdbBackend,
1150 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1153 .label = "algorithmic rid base",
1155 .p_class = P_GLOBAL,
1156 .ptr = &Globals.AlgorithmicRidBase,
1159 .flags = FLAG_ADVANCED,
1162 .label = "root directory",
1164 .p_class = P_GLOBAL,
1165 .ptr = &Globals.szRootdir,
1168 .flags = FLAG_ADVANCED,
1171 .label = "root dir",
1173 .p_class = P_GLOBAL,
1174 .ptr = &Globals.szRootdir,
1182 .p_class = P_GLOBAL,
1183 .ptr = &Globals.szRootdir,
1189 .label = "guest account",
1191 .p_class = P_GLOBAL,
1192 .ptr = &Globals.szGuestaccount,
1195 .flags = FLAG_BASIC | FLAG_ADVANCED,
1198 .label = "enable privileges",
1200 .p_class = P_GLOBAL,
1201 .ptr = &Globals.bEnablePrivileges,
1204 .flags = FLAG_ADVANCED,
1208 .label = "pam password change",
1210 .p_class = P_GLOBAL,
1211 .ptr = &Globals.bPamPasswordChange,
1214 .flags = FLAG_ADVANCED,
1217 .label = "passwd program",
1219 .p_class = P_GLOBAL,
1220 .ptr = &Globals.szPasswdProgram,
1223 .flags = FLAG_ADVANCED,
1226 .label = "passwd chat",
1228 .p_class = P_GLOBAL,
1229 .ptr = &Globals.szPasswdChat,
1232 .flags = FLAG_ADVANCED,
1235 .label = "passwd chat debug",
1237 .p_class = P_GLOBAL,
1238 .ptr = &Globals.bPasswdChatDebug,
1241 .flags = FLAG_ADVANCED,
1244 .label = "passwd chat timeout",
1246 .p_class = P_GLOBAL,
1247 .ptr = &Globals.iPasswdChatTimeout,
1250 .flags = FLAG_ADVANCED,
1253 .label = "check password script",
1255 .p_class = P_GLOBAL,
1256 .ptr = &Globals.szCheckPasswordScript,
1259 .flags = FLAG_ADVANCED,
1262 .label = "username map",
1264 .p_class = P_GLOBAL,
1265 .ptr = &Globals.szUsernameMap,
1268 .flags = FLAG_ADVANCED,
1271 .label = "password level",
1273 .p_class = P_GLOBAL,
1274 .ptr = &Globals.pwordlevel,
1277 .flags = FLAG_ADVANCED,
1280 .label = "username level",
1282 .p_class = P_GLOBAL,
1283 .ptr = &Globals.unamelevel,
1286 .flags = FLAG_ADVANCED,
1289 .label = "unix password sync",
1291 .p_class = P_GLOBAL,
1292 .ptr = &Globals.bUnixPasswdSync,
1295 .flags = FLAG_ADVANCED,
1298 .label = "restrict anonymous",
1300 .p_class = P_GLOBAL,
1301 .ptr = &Globals.restrict_anonymous,
1304 .flags = FLAG_ADVANCED,
1307 .label = "lanman auth",
1309 .p_class = P_GLOBAL,
1310 .ptr = &Globals.bLanmanAuth,
1313 .flags = FLAG_ADVANCED,
1316 .label = "ntlm auth",
1318 .p_class = P_GLOBAL,
1319 .ptr = &Globals.bNTLMAuth,
1322 .flags = FLAG_ADVANCED,
1325 .label = "client NTLMv2 auth",
1327 .p_class = P_GLOBAL,
1328 .ptr = &Globals.bClientNTLMv2Auth,
1331 .flags = FLAG_ADVANCED,
1334 .label = "client lanman auth",
1336 .p_class = P_GLOBAL,
1337 .ptr = &Globals.bClientLanManAuth,
1340 .flags = FLAG_ADVANCED,
1343 .label = "client plaintext auth",
1345 .p_class = P_GLOBAL,
1346 .ptr = &Globals.bClientPlaintextAuth,
1349 .flags = FLAG_ADVANCED,
1352 .label = "username",
1355 .ptr = &sDefault.szUsername,
1358 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1364 .ptr = &sDefault.szUsername,
1373 .ptr = &sDefault.szUsername,
1379 .label = "invalid users",
1382 .ptr = &sDefault.szInvalidUsers,
1385 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1388 .label = "valid users",
1391 .ptr = &sDefault.szValidUsers,
1394 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1397 .label = "admin users",
1400 .ptr = &sDefault.szAdminUsers,
1403 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1406 .label = "read list",
1409 .ptr = &sDefault.readlist,
1412 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1415 .label = "write list",
1418 .ptr = &sDefault.writelist,
1421 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1424 .label = "printer admin",
1427 .ptr = &sDefault.printer_admin,
1430 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1433 .label = "force user",
1436 .ptr = &sDefault.force_user,
1439 .flags = FLAG_ADVANCED | FLAG_SHARE,
1442 .label = "force group",
1445 .ptr = &sDefault.force_group,
1448 .flags = FLAG_ADVANCED | FLAG_SHARE,
1454 .ptr = &sDefault.force_group,
1457 .flags = FLAG_ADVANCED,
1460 .label = "read only",
1463 .ptr = &sDefault.bRead_only,
1466 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1469 .label = "write ok",
1472 .ptr = &sDefault.bRead_only,
1478 .label = "writeable",
1481 .ptr = &sDefault.bRead_only,
1487 .label = "writable",
1490 .ptr = &sDefault.bRead_only,
1496 .label = "acl check permissions",
1499 .ptr = &sDefault.bAclCheckPermissions,
1502 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1505 .label = "acl group control",
1508 .ptr = &sDefault.bAclGroupControl,
1511 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1514 .label = "acl map full control",
1517 .ptr = &sDefault.bAclMapFullControl,
1520 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1523 .label = "create mask",
1526 .ptr = &sDefault.iCreate_mask,
1529 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1532 .label = "create mode",
1535 .ptr = &sDefault.iCreate_mask,
1541 .label = "force create mode",
1544 .ptr = &sDefault.iCreate_force_mode,
1547 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1550 .label = "security mask",
1553 .ptr = &sDefault.iSecurity_mask,
1556 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1559 .label = "force security mode",
1562 .ptr = &sDefault.iSecurity_force_mode,
1565 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1568 .label = "directory mask",
1571 .ptr = &sDefault.iDir_mask,
1574 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1577 .label = "directory mode",
1580 .ptr = &sDefault.iDir_mask,
1583 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1586 .label = "force directory mode",
1589 .ptr = &sDefault.iDir_force_mode,
1592 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1595 .label = "directory security mask",
1598 .ptr = &sDefault.iDir_Security_mask,
1601 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1604 .label = "force directory security mode",
1607 .ptr = &sDefault.iDir_Security_force_mode,
1610 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1613 .label = "force unknown acl user",
1616 .ptr = &sDefault.bForceUnknownAclUser,
1619 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1622 .label = "inherit permissions",
1625 .ptr = &sDefault.bInheritPerms,
1628 .flags = FLAG_ADVANCED | FLAG_SHARE,
1631 .label = "inherit acls",
1634 .ptr = &sDefault.bInheritACLS,
1637 .flags = FLAG_ADVANCED | FLAG_SHARE,
1640 .label = "inherit owner",
1643 .ptr = &sDefault.bInheritOwner,
1646 .flags = FLAG_ADVANCED | FLAG_SHARE,
1649 .label = "guest only",
1652 .ptr = &sDefault.bGuest_only,
1655 .flags = FLAG_ADVANCED | FLAG_SHARE,
1658 .label = "only guest",
1661 .ptr = &sDefault.bGuest_only,
1667 .label = "administrative share",
1670 .ptr = &sDefault.bAdministrative_share,
1673 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1677 .label = "guest ok",
1680 .ptr = &sDefault.bGuest_ok,
1683 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1689 .ptr = &sDefault.bGuest_ok,
1695 .label = "only user",
1698 .ptr = &sDefault.bOnlyUser,
1701 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1704 .label = "hosts allow",
1707 .ptr = &sDefault.szHostsallow,
1710 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1713 .label = "allow hosts",
1716 .ptr = &sDefault.szHostsallow,
1722 .label = "hosts deny",
1725 .ptr = &sDefault.szHostsdeny,
1728 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1731 .label = "deny hosts",
1734 .ptr = &sDefault.szHostsdeny,
1740 .label = "preload modules",
1742 .p_class = P_GLOBAL,
1743 .ptr = &Globals.szPreloadModules,
1746 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1749 .label = "use kerberos keytab",
1751 .p_class = P_GLOBAL,
1752 .ptr = &Globals.bUseKerberosKeytab,
1755 .flags = FLAG_ADVANCED,
1758 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1761 .label = "log level",
1763 .p_class = P_GLOBAL,
1764 .ptr = &Globals.szLogLevel,
1765 .special = handle_debug_list,
1767 .flags = FLAG_ADVANCED,
1770 .label = "debuglevel",
1772 .p_class = P_GLOBAL,
1773 .ptr = &Globals.szLogLevel,
1774 .special = handle_debug_list,
1781 .p_class = P_GLOBAL,
1782 .ptr = &Globals.syslog,
1785 .flags = FLAG_ADVANCED,
1788 .label = "syslog only",
1790 .p_class = P_GLOBAL,
1791 .ptr = &Globals.bSyslogOnly,
1794 .flags = FLAG_ADVANCED,
1797 .label = "log file",
1799 .p_class = P_GLOBAL,
1800 .ptr = &Globals.szLogFile,
1803 .flags = FLAG_ADVANCED,
1806 .label = "max log size",
1808 .p_class = P_GLOBAL,
1809 .ptr = &Globals.max_log_size,
1812 .flags = FLAG_ADVANCED,
1815 .label = "debug timestamp",
1817 .p_class = P_GLOBAL,
1818 .ptr = &Globals.bTimestampLogs,
1821 .flags = FLAG_ADVANCED,
1824 .label = "timestamp logs",
1826 .p_class = P_GLOBAL,
1827 .ptr = &Globals.bTimestampLogs,
1830 .flags = FLAG_ADVANCED,
1833 .label = "debug prefix timestamp",
1835 .p_class = P_GLOBAL,
1836 .ptr = &Globals.bDebugPrefixTimestamp,
1839 .flags = FLAG_ADVANCED,
1842 .label = "debug hires timestamp",
1844 .p_class = P_GLOBAL,
1845 .ptr = &Globals.bDebugHiresTimestamp,
1848 .flags = FLAG_ADVANCED,
1851 .label = "debug pid",
1853 .p_class = P_GLOBAL,
1854 .ptr = &Globals.bDebugPid,
1857 .flags = FLAG_ADVANCED,
1860 .label = "debug uid",
1862 .p_class = P_GLOBAL,
1863 .ptr = &Globals.bDebugUid,
1866 .flags = FLAG_ADVANCED,
1869 .label = "debug class",
1871 .p_class = P_GLOBAL,
1872 .ptr = &Globals.bDebugClass,
1875 .flags = FLAG_ADVANCED,
1878 .label = "enable core files",
1880 .p_class = P_GLOBAL,
1881 .ptr = &Globals.bEnableCoreFiles,
1884 .flags = FLAG_ADVANCED,
1887 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1890 .label = "allocation roundup size",
1893 .ptr = &sDefault.iallocation_roundup_size,
1896 .flags = FLAG_ADVANCED,
1899 .label = "aio read size",
1902 .ptr = &sDefault.iAioReadSize,
1905 .flags = FLAG_ADVANCED,
1908 .label = "aio write size",
1911 .ptr = &sDefault.iAioWriteSize,
1914 .flags = FLAG_ADVANCED,
1917 .label = "aio write behind",
1920 .ptr = &sDefault.szAioWriteBehind,
1923 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1926 .label = "smb ports",
1928 .p_class = P_GLOBAL,
1929 .ptr = &Globals.smb_ports,
1932 .flags = FLAG_ADVANCED,
1935 .label = "large readwrite",
1937 .p_class = P_GLOBAL,
1938 .ptr = &Globals.bLargeReadwrite,
1941 .flags = FLAG_ADVANCED,
1944 .label = "max protocol",
1946 .p_class = P_GLOBAL,
1947 .ptr = &Globals.maxprotocol,
1949 .enum_list = enum_protocol,
1950 .flags = FLAG_ADVANCED,
1953 .label = "protocol",
1955 .p_class = P_GLOBAL,
1956 .ptr = &Globals.maxprotocol,
1958 .enum_list = enum_protocol,
1959 .flags = FLAG_ADVANCED,
1962 .label = "min protocol",
1964 .p_class = P_GLOBAL,
1965 .ptr = &Globals.minprotocol,
1967 .enum_list = enum_protocol,
1968 .flags = FLAG_ADVANCED,
1971 .label = "min receivefile size",
1973 .p_class = P_GLOBAL,
1974 .ptr = &Globals.iminreceivefile,
1977 .flags = FLAG_ADVANCED,
1980 .label = "read raw",
1982 .p_class = P_GLOBAL,
1983 .ptr = &Globals.bReadRaw,
1986 .flags = FLAG_ADVANCED,
1989 .label = "write raw",
1991 .p_class = P_GLOBAL,
1992 .ptr = &Globals.bWriteRaw,
1995 .flags = FLAG_ADVANCED,
1998 .label = "disable netbios",
2000 .p_class = P_GLOBAL,
2001 .ptr = &Globals.bDisableNetbios,
2004 .flags = FLAG_ADVANCED,
2007 .label = "reset on zero vc",
2009 .p_class = P_GLOBAL,
2010 .ptr = &Globals.bResetOnZeroVC,
2013 .flags = FLAG_ADVANCED,
2016 .label = "acl compatibility",
2018 .p_class = P_GLOBAL,
2019 .ptr = &Globals.iAclCompat,
2021 .enum_list = enum_acl_compat_vals,
2022 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2025 .label = "defer sharing violations",
2027 .p_class = P_GLOBAL,
2028 .ptr = &Globals.bDeferSharingViolations,
2031 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2034 .label = "ea support",
2037 .ptr = &sDefault.bEASupport,
2040 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2043 .label = "nt acl support",
2046 .ptr = &sDefault.bNTAclSupport,
2049 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2052 .label = "nt pipe support",
2054 .p_class = P_GLOBAL,
2055 .ptr = &Globals.bNTPipeSupport,
2058 .flags = FLAG_ADVANCED,
2061 .label = "nt status support",
2063 .p_class = P_GLOBAL,
2064 .ptr = &Globals.bNTStatusSupport,
2067 .flags = FLAG_ADVANCED,
2070 .label = "profile acls",
2073 .ptr = &sDefault.bProfileAcls,
2076 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2079 .label = "announce version",
2081 .p_class = P_GLOBAL,
2082 .ptr = &Globals.szAnnounceVersion,
2085 .flags = FLAG_ADVANCED,
2088 .label = "announce as",
2090 .p_class = P_GLOBAL,
2091 .ptr = &Globals.announce_as,
2093 .enum_list = enum_announce_as,
2094 .flags = FLAG_ADVANCED,
2097 .label = "map acl inherit",
2100 .ptr = &sDefault.bMap_acl_inherit,
2103 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2106 .label = "afs share",
2109 .ptr = &sDefault.bAfs_Share,
2112 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2117 .p_class = P_GLOBAL,
2118 .ptr = &Globals.max_mux,
2121 .flags = FLAG_ADVANCED,
2124 .label = "max xmit",
2126 .p_class = P_GLOBAL,
2127 .ptr = &Globals.max_xmit,
2130 .flags = FLAG_ADVANCED,
2133 .label = "name resolve order",
2135 .p_class = P_GLOBAL,
2136 .ptr = &Globals.szNameResolveOrder,
2139 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2144 .p_class = P_GLOBAL,
2145 .ptr = &Globals.max_ttl,
2148 .flags = FLAG_ADVANCED,
2151 .label = "max wins ttl",
2153 .p_class = P_GLOBAL,
2154 .ptr = &Globals.max_wins_ttl,
2157 .flags = FLAG_ADVANCED,
2160 .label = "min wins ttl",
2162 .p_class = P_GLOBAL,
2163 .ptr = &Globals.min_wins_ttl,
2166 .flags = FLAG_ADVANCED,
2169 .label = "time server",
2171 .p_class = P_GLOBAL,
2172 .ptr = &Globals.bTimeServer,
2175 .flags = FLAG_ADVANCED,
2178 .label = "unix extensions",
2180 .p_class = P_GLOBAL,
2181 .ptr = &Globals.bUnixExtensions,
2184 .flags = FLAG_ADVANCED,
2187 .label = "use spnego",
2189 .p_class = P_GLOBAL,
2190 .ptr = &Globals.bUseSpnego,
2193 .flags = FLAG_ADVANCED,
2196 .label = "client signing",
2198 .p_class = P_GLOBAL,
2199 .ptr = &Globals.client_signing,
2201 .enum_list = enum_smb_signing_vals,
2202 .flags = FLAG_ADVANCED,
2205 .label = "server signing",
2207 .p_class = P_GLOBAL,
2208 .ptr = &Globals.server_signing,
2210 .enum_list = enum_smb_signing_vals,
2211 .flags = FLAG_ADVANCED,
2214 .label = "smb encrypt",
2217 .ptr = &sDefault.ismb_encrypt,
2219 .enum_list = enum_smb_signing_vals,
2220 .flags = FLAG_ADVANCED,
2223 .label = "client use spnego",
2225 .p_class = P_GLOBAL,
2226 .ptr = &Globals.bClientUseSpnego,
2229 .flags = FLAG_ADVANCED,
2232 .label = "client ldap sasl wrapping",
2234 .p_class = P_GLOBAL,
2235 .ptr = &Globals.client_ldap_sasl_wrapping,
2237 .enum_list = enum_ldap_sasl_wrapping,
2238 .flags = FLAG_ADVANCED,
2241 .label = "enable asu support",
2243 .p_class = P_GLOBAL,
2244 .ptr = &Globals.bASUSupport,
2247 .flags = FLAG_ADVANCED,
2250 .label = "svcctl list",
2252 .p_class = P_GLOBAL,
2253 .ptr = &Globals.szServicesList,
2256 .flags = FLAG_ADVANCED,
2259 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2262 .label = "block size",
2265 .ptr = &sDefault.iBlock_size,
2268 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2271 .label = "deadtime",
2273 .p_class = P_GLOBAL,
2274 .ptr = &Globals.deadtime,
2277 .flags = FLAG_ADVANCED,
2280 .label = "getwd cache",
2282 .p_class = P_GLOBAL,
2283 .ptr = &Globals.getwd_cache,
2286 .flags = FLAG_ADVANCED,
2289 .label = "keepalive",
2291 .p_class = P_GLOBAL,
2292 .ptr = &Globals.iKeepalive,
2295 .flags = FLAG_ADVANCED,
2298 .label = "change notify",
2301 .ptr = &sDefault.bChangeNotify,
2304 .flags = FLAG_ADVANCED | FLAG_SHARE,
2307 .label = "directory name cache size",
2310 .ptr = &sDefault.iDirectoryNameCacheSize,
2313 .flags = FLAG_ADVANCED | FLAG_SHARE,
2316 .label = "kernel change notify",
2319 .ptr = &sDefault.bKernelChangeNotify,
2322 .flags = FLAG_ADVANCED | FLAG_SHARE,
2325 .label = "lpq cache time",
2327 .p_class = P_GLOBAL,
2328 .ptr = &Globals.lpqcachetime,
2331 .flags = FLAG_ADVANCED,
2334 .label = "max smbd processes",
2336 .p_class = P_GLOBAL,
2337 .ptr = &Globals.iMaxSmbdProcesses,
2340 .flags = FLAG_ADVANCED,
2343 .label = "max connections",
2346 .ptr = &sDefault.iMaxConnections,
2349 .flags = FLAG_ADVANCED | FLAG_SHARE,
2352 .label = "paranoid server security",
2354 .p_class = P_GLOBAL,
2355 .ptr = &Globals.paranoid_server_security,
2358 .flags = FLAG_ADVANCED,
2361 .label = "max disk size",
2363 .p_class = P_GLOBAL,
2364 .ptr = &Globals.maxdisksize,
2367 .flags = FLAG_ADVANCED,
2370 .label = "max open files",
2372 .p_class = P_GLOBAL,
2373 .ptr = &Globals.max_open_files,
2376 .flags = FLAG_ADVANCED,
2379 .label = "min print space",
2382 .ptr = &sDefault.iMinPrintSpace,
2385 .flags = FLAG_ADVANCED | FLAG_PRINT,
2388 .label = "socket options",
2390 .p_class = P_GLOBAL,
2391 .ptr = &Globals.szSocketOptions,
2394 .flags = FLAG_ADVANCED,
2397 .label = "strict allocate",
2400 .ptr = &sDefault.bStrictAllocate,
2403 .flags = FLAG_ADVANCED | FLAG_SHARE,
2406 .label = "strict sync",
2409 .ptr = &sDefault.bStrictSync,
2412 .flags = FLAG_ADVANCED | FLAG_SHARE,
2415 .label = "sync always",
2418 .ptr = &sDefault.bSyncAlways,
2421 .flags = FLAG_ADVANCED | FLAG_SHARE,
2424 .label = "use mmap",
2426 .p_class = P_GLOBAL,
2427 .ptr = &Globals.bUseMmap,
2430 .flags = FLAG_ADVANCED,
2433 .label = "use sendfile",
2436 .ptr = &sDefault.bUseSendfile,
2439 .flags = FLAG_ADVANCED | FLAG_SHARE,
2442 .label = "hostname lookups",
2444 .p_class = P_GLOBAL,
2445 .ptr = &Globals.bHostnameLookups,
2448 .flags = FLAG_ADVANCED,
2451 .label = "write cache size",
2454 .ptr = &sDefault.iWriteCacheSize,
2457 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2460 .label = "name cache timeout",
2462 .p_class = P_GLOBAL,
2463 .ptr = &Globals.name_cache_timeout,
2466 .flags = FLAG_ADVANCED,
2469 .label = "ctdbd socket",
2471 .p_class = P_GLOBAL,
2472 .ptr = &Globals.ctdbdSocket,
2475 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2478 .label = "cluster addresses",
2480 .p_class = P_GLOBAL,
2481 .ptr = &Globals.szClusterAddresses,
2484 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2487 .label = "clustering",
2489 .p_class = P_GLOBAL,
2490 .ptr = &Globals.clustering,
2493 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2496 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2499 .label = "max reported print jobs",
2502 .ptr = &sDefault.iMaxReportedPrintJobs,
2505 .flags = FLAG_ADVANCED | FLAG_PRINT,
2508 .label = "max print jobs",
2511 .ptr = &sDefault.iMaxPrintJobs,
2514 .flags = FLAG_ADVANCED | FLAG_PRINT,
2517 .label = "load printers",
2519 .p_class = P_GLOBAL,
2520 .ptr = &Globals.bLoadPrinters,
2523 .flags = FLAG_ADVANCED | FLAG_PRINT,
2526 .label = "printcap cache time",
2528 .p_class = P_GLOBAL,
2529 .ptr = &Globals.PrintcapCacheTime,
2532 .flags = FLAG_ADVANCED | FLAG_PRINT,
2535 .label = "printcap name",
2537 .p_class = P_GLOBAL,
2538 .ptr = &Globals.szPrintcapname,
2541 .flags = FLAG_ADVANCED | FLAG_PRINT,
2544 .label = "printcap",
2546 .p_class = P_GLOBAL,
2547 .ptr = &Globals.szPrintcapname,
2553 .label = "printable",
2556 .ptr = &sDefault.bPrint_ok,
2559 .flags = FLAG_ADVANCED | FLAG_PRINT,
2562 .label = "print ok",
2565 .ptr = &sDefault.bPrint_ok,
2571 .label = "printing",
2574 .ptr = &sDefault.iPrinting,
2575 .special = handle_printing,
2576 .enum_list = enum_printing,
2577 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2580 .label = "cups options",
2583 .ptr = &sDefault.szCupsOptions,
2586 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2589 .label = "cups server",
2591 .p_class = P_GLOBAL,
2592 .ptr = &Globals.szCupsServer,
2595 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2598 .label = "iprint server",
2600 .p_class = P_GLOBAL,
2601 .ptr = &Globals.szIPrintServer,
2604 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2607 .label = "print command",
2610 .ptr = &sDefault.szPrintcommand,
2613 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2616 .label = "disable spoolss",
2618 .p_class = P_GLOBAL,
2619 .ptr = &Globals.bDisableSpoolss,
2622 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2625 .label = "enable spoolss",
2627 .p_class = P_GLOBAL,
2628 .ptr = &Globals.bDisableSpoolss,
2634 .label = "lpq command",
2637 .ptr = &sDefault.szLpqcommand,
2640 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2643 .label = "lprm command",
2646 .ptr = &sDefault.szLprmcommand,
2649 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2652 .label = "lppause command",
2655 .ptr = &sDefault.szLppausecommand,
2658 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2661 .label = "lpresume command",
2664 .ptr = &sDefault.szLpresumecommand,
2667 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2670 .label = "queuepause command",
2673 .ptr = &sDefault.szQueuepausecommand,
2676 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2679 .label = "queueresume command",
2682 .ptr = &sDefault.szQueueresumecommand,
2685 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2688 .label = "addport command",
2690 .p_class = P_GLOBAL,
2691 .ptr = &Globals.szAddPortCommand,
2694 .flags = FLAG_ADVANCED,
2697 .label = "enumports command",
2699 .p_class = P_GLOBAL,
2700 .ptr = &Globals.szEnumPortsCommand,
2703 .flags = FLAG_ADVANCED,
2706 .label = "addprinter command",
2708 .p_class = P_GLOBAL,
2709 .ptr = &Globals.szAddPrinterCommand,
2712 .flags = FLAG_ADVANCED,
2715 .label = "deleteprinter command",
2717 .p_class = P_GLOBAL,
2718 .ptr = &Globals.szDeletePrinterCommand,
2721 .flags = FLAG_ADVANCED,
2724 .label = "show add printer wizard",
2726 .p_class = P_GLOBAL,
2727 .ptr = &Globals.bMsAddPrinterWizard,
2730 .flags = FLAG_ADVANCED,
2733 .label = "os2 driver map",
2735 .p_class = P_GLOBAL,
2736 .ptr = &Globals.szOs2DriverMap,
2739 .flags = FLAG_ADVANCED,
2743 .label = "printer name",
2746 .ptr = &sDefault.szPrintername,
2749 .flags = FLAG_ADVANCED | FLAG_PRINT,
2755 .ptr = &sDefault.szPrintername,
2761 .label = "use client driver",
2764 .ptr = &sDefault.bUseClientDriver,
2767 .flags = FLAG_ADVANCED | FLAG_PRINT,
2770 .label = "default devmode",
2773 .ptr = &sDefault.bDefaultDevmode,
2776 .flags = FLAG_ADVANCED | FLAG_PRINT,
2779 .label = "force printername",
2782 .ptr = &sDefault.bForcePrintername,
2785 .flags = FLAG_ADVANCED | FLAG_PRINT,
2788 .label = "printjob username",
2791 .ptr = &sDefault.szPrintjobUsername,
2794 .flags = FLAG_ADVANCED | FLAG_PRINT,
2797 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2800 .label = "mangling method",
2802 .p_class = P_GLOBAL,
2803 .ptr = &Globals.szManglingMethod,
2806 .flags = FLAG_ADVANCED,
2809 .label = "mangle prefix",
2811 .p_class = P_GLOBAL,
2812 .ptr = &Globals.mangle_prefix,
2815 .flags = FLAG_ADVANCED,
2819 .label = "default case",
2822 .ptr = &sDefault.iDefaultCase,
2824 .enum_list = enum_case,
2825 .flags = FLAG_ADVANCED | FLAG_SHARE,
2828 .label = "case sensitive",
2831 .ptr = &sDefault.iCaseSensitive,
2833 .enum_list = enum_bool_auto,
2834 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2837 .label = "casesignames",
2840 .ptr = &sDefault.iCaseSensitive,
2842 .enum_list = enum_bool_auto,
2843 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2846 .label = "preserve case",
2849 .ptr = &sDefault.bCasePreserve,
2852 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2855 .label = "short preserve case",
2858 .ptr = &sDefault.bShortCasePreserve,
2861 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2864 .label = "mangling char",
2867 .ptr = &sDefault.magic_char,
2870 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2873 .label = "hide dot files",
2876 .ptr = &sDefault.bHideDotFiles,
2879 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2882 .label = "hide special files",
2885 .ptr = &sDefault.bHideSpecialFiles,
2888 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2891 .label = "hide unreadable",
2894 .ptr = &sDefault.bHideUnReadable,
2897 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2900 .label = "hide unwriteable files",
2903 .ptr = &sDefault.bHideUnWriteableFiles,
2906 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2909 .label = "delete veto files",
2912 .ptr = &sDefault.bDeleteVetoFiles,
2915 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2918 .label = "veto files",
2921 .ptr = &sDefault.szVetoFiles,
2924 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2927 .label = "hide files",
2930 .ptr = &sDefault.szHideFiles,
2933 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2936 .label = "veto oplock files",
2939 .ptr = &sDefault.szVetoOplockFiles,
2942 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2945 .label = "map archive",
2948 .ptr = &sDefault.bMap_archive,
2951 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2954 .label = "map hidden",
2957 .ptr = &sDefault.bMap_hidden,
2960 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2963 .label = "map system",
2966 .ptr = &sDefault.bMap_system,
2969 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2972 .label = "map readonly",
2975 .ptr = &sDefault.iMap_readonly,
2977 .enum_list = enum_map_readonly,
2978 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2981 .label = "mangled names",
2984 .ptr = &sDefault.bMangledNames,
2987 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2990 .label = "max stat cache size",
2992 .p_class = P_GLOBAL,
2993 .ptr = &Globals.iMaxStatCacheSize,
2996 .flags = FLAG_ADVANCED,
2999 .label = "stat cache",
3001 .p_class = P_GLOBAL,
3002 .ptr = &Globals.bStatCache,
3005 .flags = FLAG_ADVANCED,
3008 .label = "store dos attributes",
3011 .ptr = &sDefault.bStoreDosAttributes,
3014 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3017 .label = "dmapi support",
3020 .ptr = &sDefault.bDmapiSupport,
3023 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3027 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3030 .label = "machine password timeout",
3032 .p_class = P_GLOBAL,
3033 .ptr = &Globals.machine_password_timeout,
3036 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3039 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3042 .label = "add user script",
3044 .p_class = P_GLOBAL,
3045 .ptr = &Globals.szAddUserScript,
3048 .flags = FLAG_ADVANCED,
3051 .label = "rename user script",
3053 .p_class = P_GLOBAL,
3054 .ptr = &Globals.szRenameUserScript,
3057 .flags = FLAG_ADVANCED,
3060 .label = "delete user script",
3062 .p_class = P_GLOBAL,
3063 .ptr = &Globals.szDelUserScript,
3066 .flags = FLAG_ADVANCED,
3069 .label = "add group script",
3071 .p_class = P_GLOBAL,
3072 .ptr = &Globals.szAddGroupScript,
3075 .flags = FLAG_ADVANCED,
3078 .label = "delete group script",
3080 .p_class = P_GLOBAL,
3081 .ptr = &Globals.szDelGroupScript,
3084 .flags = FLAG_ADVANCED,
3087 .label = "add user to group script",
3089 .p_class = P_GLOBAL,
3090 .ptr = &Globals.szAddUserToGroupScript,
3093 .flags = FLAG_ADVANCED,
3096 .label = "delete user from group script",
3098 .p_class = P_GLOBAL,
3099 .ptr = &Globals.szDelUserFromGroupScript,
3102 .flags = FLAG_ADVANCED,
3105 .label = "set primary group script",
3107 .p_class = P_GLOBAL,
3108 .ptr = &Globals.szSetPrimaryGroupScript,
3111 .flags = FLAG_ADVANCED,
3114 .label = "add machine script",
3116 .p_class = P_GLOBAL,
3117 .ptr = &Globals.szAddMachineScript,
3120 .flags = FLAG_ADVANCED,
3123 .label = "shutdown script",
3125 .p_class = P_GLOBAL,
3126 .ptr = &Globals.szShutdownScript,
3129 .flags = FLAG_ADVANCED,
3132 .label = "abort shutdown script",
3134 .p_class = P_GLOBAL,
3135 .ptr = &Globals.szAbortShutdownScript,
3138 .flags = FLAG_ADVANCED,
3141 .label = "username map script",
3143 .p_class = P_GLOBAL,
3144 .ptr = &Globals.szUsernameMapScript,
3147 .flags = FLAG_ADVANCED,
3150 .label = "logon script",
3152 .p_class = P_GLOBAL,
3153 .ptr = &Globals.szLogonScript,
3156 .flags = FLAG_ADVANCED,
3159 .label = "logon path",
3161 .p_class = P_GLOBAL,
3162 .ptr = &Globals.szLogonPath,
3165 .flags = FLAG_ADVANCED,
3168 .label = "logon drive",
3170 .p_class = P_GLOBAL,
3171 .ptr = &Globals.szLogonDrive,
3174 .flags = FLAG_ADVANCED,
3177 .label = "logon home",
3179 .p_class = P_GLOBAL,
3180 .ptr = &Globals.szLogonHome,
3183 .flags = FLAG_ADVANCED,
3186 .label = "domain logons",
3188 .p_class = P_GLOBAL,
3189 .ptr = &Globals.bDomainLogons,
3192 .flags = FLAG_ADVANCED,
3196 .label = "init logon delayed hosts",
3198 .p_class = P_GLOBAL,
3199 .ptr = &Globals.szInitLogonDelayedHosts,
3200 .flags = FLAG_ADVANCED,
3204 .label = "init logon delay",
3206 .p_class = P_GLOBAL,
3207 .ptr = &Globals.InitLogonDelay,
3208 .flags = FLAG_ADVANCED,
3212 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3215 .label = "os level",
3217 .p_class = P_GLOBAL,
3218 .ptr = &Globals.os_level,
3221 .flags = FLAG_BASIC | FLAG_ADVANCED,
3224 .label = "lm announce",
3226 .p_class = P_GLOBAL,
3227 .ptr = &Globals.lm_announce,
3229 .enum_list = enum_bool_auto,
3230 .flags = FLAG_ADVANCED,
3233 .label = "lm interval",
3235 .p_class = P_GLOBAL,
3236 .ptr = &Globals.lm_interval,
3239 .flags = FLAG_ADVANCED,
3242 .label = "preferred master",
3244 .p_class = P_GLOBAL,
3245 .ptr = &Globals.iPreferredMaster,
3247 .enum_list = enum_bool_auto,
3248 .flags = FLAG_BASIC | FLAG_ADVANCED,
3251 .label = "prefered master",
3253 .p_class = P_GLOBAL,
3254 .ptr = &Globals.iPreferredMaster,
3256 .enum_list = enum_bool_auto,
3260 .label = "local master",
3262 .p_class = P_GLOBAL,
3263 .ptr = &Globals.bLocalMaster,
3266 .flags = FLAG_BASIC | FLAG_ADVANCED,
3269 .label = "domain master",
3271 .p_class = P_GLOBAL,
3272 .ptr = &Globals.iDomainMaster,
3274 .enum_list = enum_bool_auto,
3275 .flags = FLAG_BASIC | FLAG_ADVANCED,
3278 .label = "browse list",
3280 .p_class = P_GLOBAL,
3281 .ptr = &Globals.bBrowseList,
3284 .flags = FLAG_ADVANCED,
3287 .label = "browseable",
3290 .ptr = &sDefault.bBrowseable,
3293 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3296 .label = "browsable",
3299 .ptr = &sDefault.bBrowseable,
3305 .label = "enhanced browsing",
3307 .p_class = P_GLOBAL,
3308 .ptr = &Globals.enhanced_browsing,
3311 .flags = FLAG_ADVANCED,
3314 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3317 .label = "dns proxy",
3319 .p_class = P_GLOBAL,
3320 .ptr = &Globals.bDNSproxy,
3323 .flags = FLAG_ADVANCED,
3326 .label = "wins proxy",
3328 .p_class = P_GLOBAL,
3329 .ptr = &Globals.bWINSproxy,
3332 .flags = FLAG_ADVANCED,
3335 .label = "wins server",
3337 .p_class = P_GLOBAL,
3338 .ptr = &Globals.szWINSservers,
3341 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3344 .label = "wins support",
3346 .p_class = P_GLOBAL,
3347 .ptr = &Globals.bWINSsupport,
3350 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3353 .label = "wins hook",
3355 .p_class = P_GLOBAL,
3356 .ptr = &Globals.szWINSHook,
3359 .flags = FLAG_ADVANCED,
3362 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3365 .label = "blocking locks",
3368 .ptr = &sDefault.bBlockingLocks,
3371 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3374 .label = "csc policy",
3377 .ptr = &sDefault.iCSCPolicy,
3379 .enum_list = enum_csc_policy,
3380 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3383 .label = "fake oplocks",
3386 .ptr = &sDefault.bFakeOplocks,
3389 .flags = FLAG_ADVANCED | FLAG_SHARE,
3392 .label = "kernel oplocks",
3394 .p_class = P_GLOBAL,
3395 .ptr = &Globals.bKernelOplocks,
3398 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3404 .ptr = &sDefault.bLocking,
3407 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3410 .label = "lock spin time",
3412 .p_class = P_GLOBAL,
3413 .ptr = &Globals.iLockSpinTime,
3416 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3422 .ptr = &sDefault.bOpLocks,
3425 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3428 .label = "level2 oplocks",
3431 .ptr = &sDefault.bLevel2OpLocks,
3434 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3437 .label = "oplock break wait time",
3439 .p_class = P_GLOBAL,
3440 .ptr = &Globals.oplock_break_wait_time,
3443 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3446 .label = "oplock contention limit",
3449 .ptr = &sDefault.iOplockContentionLimit,
3452 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3455 .label = "posix locking",
3458 .ptr = &sDefault.bPosixLocking,
3461 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3464 .label = "strict locking",
3467 .ptr = &sDefault.iStrictLocking,
3469 .enum_list = enum_bool_auto,
3470 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3473 .label = "share modes",
3476 .ptr = &sDefault.bShareModes,
3479 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3482 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3485 .label = "ldap admin dn",
3487 .p_class = P_GLOBAL,
3488 .ptr = &Globals.szLdapAdminDn,
3491 .flags = FLAG_ADVANCED,
3494 .label = "ldap delete dn",
3496 .p_class = P_GLOBAL,
3497 .ptr = &Globals.ldap_delete_dn,
3500 .flags = FLAG_ADVANCED,
3503 .label = "ldap group suffix",
3505 .p_class = P_GLOBAL,
3506 .ptr = &Globals.szLdapGroupSuffix,
3509 .flags = FLAG_ADVANCED,
3512 .label = "ldap idmap suffix",
3514 .p_class = P_GLOBAL,
3515 .ptr = &Globals.szLdapIdmapSuffix,
3518 .flags = FLAG_ADVANCED,
3521 .label = "ldap machine suffix",
3523 .p_class = P_GLOBAL,
3524 .ptr = &Globals.szLdapMachineSuffix,
3527 .flags = FLAG_ADVANCED,
3530 .label = "ldap passwd sync",
3532 .p_class = P_GLOBAL,
3533 .ptr = &Globals.ldap_passwd_sync,
3535 .enum_list = enum_ldap_passwd_sync,
3536 .flags = FLAG_ADVANCED,
3539 .label = "ldap password sync",
3541 .p_class = P_GLOBAL,
3542 .ptr = &Globals.ldap_passwd_sync,
3544 .enum_list = enum_ldap_passwd_sync,
3548 .label = "ldap replication sleep",
3550 .p_class = P_GLOBAL,
3551 .ptr = &Globals.ldap_replication_sleep,
3554 .flags = FLAG_ADVANCED,
3557 .label = "ldap suffix",
3559 .p_class = P_GLOBAL,
3560 .ptr = &Globals.szLdapSuffix,
3563 .flags = FLAG_ADVANCED,
3566 .label = "ldap ssl",
3568 .p_class = P_GLOBAL,
3569 .ptr = &Globals.ldap_ssl,
3571 .enum_list = enum_ldap_ssl,
3572 .flags = FLAG_ADVANCED,
3575 .label = "ldap timeout",
3577 .p_class = P_GLOBAL,
3578 .ptr = &Globals.ldap_timeout,
3581 .flags = FLAG_ADVANCED,
3584 .label = "ldap connection timeout",
3586 .p_class = P_GLOBAL,
3587 .ptr = &Globals.ldap_connection_timeout,
3590 .flags = FLAG_ADVANCED,
3593 .label = "ldap page size",
3595 .p_class = P_GLOBAL,
3596 .ptr = &Globals.ldap_page_size,
3599 .flags = FLAG_ADVANCED,
3602 .label = "ldap user suffix",
3604 .p_class = P_GLOBAL,
3605 .ptr = &Globals.szLdapUserSuffix,
3608 .flags = FLAG_ADVANCED,
3611 .label = "ldap debug level",
3613 .p_class = P_GLOBAL,
3614 .ptr = &Globals.ldap_debug_level,
3615 .special = handle_ldap_debug_level,
3617 .flags = FLAG_ADVANCED,
3620 .label = "ldap debug threshold",
3622 .p_class = P_GLOBAL,
3623 .ptr = &Globals.ldap_debug_threshold,
3626 .flags = FLAG_ADVANCED,
3629 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3632 .label = "eventlog list",
3634 .p_class = P_GLOBAL,
3635 .ptr = &Globals.szEventLogs,
3638 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3641 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3644 .label = "add share command",
3646 .p_class = P_GLOBAL,
3647 .ptr = &Globals.szAddShareCommand,
3650 .flags = FLAG_ADVANCED,
3653 .label = "change share command",
3655 .p_class = P_GLOBAL,
3656 .ptr = &Globals.szChangeShareCommand,
3659 .flags = FLAG_ADVANCED,
3662 .label = "delete share command",
3664 .p_class = P_GLOBAL,
3665 .ptr = &Globals.szDeleteShareCommand,
3668 .flags = FLAG_ADVANCED,
3671 .label = "config file",
3673 .p_class = P_GLOBAL,
3674 .ptr = &Globals.szConfigFile,
3682 .p_class = P_GLOBAL,
3683 .ptr = &Globals.szAutoServices,
3686 .flags = FLAG_ADVANCED,
3689 .label = "auto services",
3691 .p_class = P_GLOBAL,
3692 .ptr = &Globals.szAutoServices,
3695 .flags = FLAG_ADVANCED,
3698 .label = "lock directory",
3700 .p_class = P_GLOBAL,
3701 .ptr = &Globals.szLockDir,
3704 .flags = FLAG_ADVANCED,
3707 .label = "lock dir",
3709 .p_class = P_GLOBAL,
3710 .ptr = &Globals.szLockDir,
3716 .label = "pid directory",
3718 .p_class = P_GLOBAL,
3719 .ptr = &Globals.szPidDir,
3722 .flags = FLAG_ADVANCED,
3726 .label = "utmp directory",
3728 .p_class = P_GLOBAL,
3729 .ptr = &Globals.szUtmpDir,
3732 .flags = FLAG_ADVANCED,
3735 .label = "wtmp directory",
3737 .p_class = P_GLOBAL,
3738 .ptr = &Globals.szWtmpDir,
3741 .flags = FLAG_ADVANCED,
3746 .p_class = P_GLOBAL,
3747 .ptr = &Globals.bUtmp,
3750 .flags = FLAG_ADVANCED,
3754 .label = "default service",
3756 .p_class = P_GLOBAL,
3757 .ptr = &Globals.szDefaultService,
3760 .flags = FLAG_ADVANCED,
3765 .p_class = P_GLOBAL,
3766 .ptr = &Globals.szDefaultService,
3769 .flags = FLAG_ADVANCED,
3772 .label = "message command",
3774 .p_class = P_GLOBAL,
3775 .ptr = &Globals.szMsgCommand,
3778 .flags = FLAG_ADVANCED,
3781 .label = "dfree cache time",
3784 .ptr = &sDefault.iDfreeCacheTime,
3787 .flags = FLAG_ADVANCED,
3790 .label = "dfree command",
3793 .ptr = &sDefault.szDfree,
3796 .flags = FLAG_ADVANCED,
3799 .label = "get quota command",
3801 .p_class = P_GLOBAL,
3802 .ptr = &Globals.szGetQuota,
3805 .flags = FLAG_ADVANCED,
3808 .label = "set quota command",
3810 .p_class = P_GLOBAL,
3811 .ptr = &Globals.szSetQuota,
3814 .flags = FLAG_ADVANCED,
3817 .label = "remote announce",
3819 .p_class = P_GLOBAL,
3820 .ptr = &Globals.szRemoteAnnounce,
3823 .flags = FLAG_ADVANCED,
3826 .label = "remote browse sync",
3828 .p_class = P_GLOBAL,
3829 .ptr = &Globals.szRemoteBrowseSync,
3832 .flags = FLAG_ADVANCED,
3835 .label = "socket address",
3837 .p_class = P_GLOBAL,
3838 .ptr = &Globals.szSocketAddress,
3841 .flags = FLAG_ADVANCED,
3844 .label = "homedir map",
3846 .p_class = P_GLOBAL,
3847 .ptr = &Globals.szNISHomeMapName,
3850 .flags = FLAG_ADVANCED,
3853 .label = "afs username map",
3855 .p_class = P_GLOBAL,
3856 .ptr = &Globals.szAfsUsernameMap,
3859 .flags = FLAG_ADVANCED,
3862 .label = "afs token lifetime",
3864 .p_class = P_GLOBAL,
3865 .ptr = &Globals.iAfsTokenLifetime,
3868 .flags = FLAG_ADVANCED,
3871 .label = "log nt token command",
3873 .p_class = P_GLOBAL,
3874 .ptr = &Globals.szLogNtTokenCommand,
3877 .flags = FLAG_ADVANCED,
3880 .label = "time offset",
3882 .p_class = P_GLOBAL,
3883 .ptr = &extra_time_offset,
3886 .flags = FLAG_ADVANCED,
3889 .label = "NIS homedir",
3891 .p_class = P_GLOBAL,
3892 .ptr = &Globals.bNISHomeMap,
3895 .flags = FLAG_ADVANCED,
3901 .ptr = &sDefault.valid,
3910 .ptr = &sDefault.szCopy,
3911 .special = handle_copy,
3919 .ptr = &sDefault.szInclude,
3920 .special = handle_include,
3928 .ptr = &sDefault.szPreExec,
3931 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3937 .ptr = &sDefault.szPreExec,
3940 .flags = FLAG_ADVANCED,
3943 .label = "preexec close",
3946 .ptr = &sDefault.bPreexecClose,
3949 .flags = FLAG_ADVANCED | FLAG_SHARE,
3952 .label = "postexec",
3955 .ptr = &sDefault.szPostExec,
3958 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3961 .label = "root preexec",
3964 .ptr = &sDefault.szRootPreExec,
3967 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3970 .label = "root preexec close",
3973 .ptr = &sDefault.bRootpreexecClose,
3976 .flags = FLAG_ADVANCED | FLAG_SHARE,
3979 .label = "root postexec",
3982 .ptr = &sDefault.szRootPostExec,
3985 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3988 .label = "available",
3991 .ptr = &sDefault.bAvailable,
3994 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3997 .label = "registry shares",
3999 .p_class = P_GLOBAL,
4000 .ptr = &Globals.bRegistryShares,
4003 .flags = FLAG_ADVANCED,
4006 .label = "usershare allow guests",
4008 .p_class = P_GLOBAL,
4009 .ptr = &Globals.bUsershareAllowGuests,
4012 .flags = FLAG_ADVANCED,
4015 .label = "usershare max shares",
4017 .p_class = P_GLOBAL,
4018 .ptr = &Globals.iUsershareMaxShares,
4021 .flags = FLAG_ADVANCED,
4024 .label = "usershare owner only",
4026 .p_class = P_GLOBAL,
4027 .ptr = &Globals.bUsershareOwnerOnly,
4030 .flags = FLAG_ADVANCED,
4033 .label = "usershare path",
4035 .p_class = P_GLOBAL,
4036 .ptr = &Globals.szUsersharePath,
4039 .flags = FLAG_ADVANCED,
4042 .label = "usershare prefix allow list",
4044 .p_class = P_GLOBAL,
4045 .ptr = &Globals.szUsersharePrefixAllowList,
4048 .flags = FLAG_ADVANCED,
4051 .label = "usershare prefix deny list",
4053 .p_class = P_GLOBAL,
4054 .ptr = &Globals.szUsersharePrefixDenyList,
4057 .flags = FLAG_ADVANCED,
4060 .label = "usershare template share",
4062 .p_class = P_GLOBAL,
4063 .ptr = &Globals.szUsershareTemplateShare,
4066 .flags = FLAG_ADVANCED,
4072 .ptr = &sDefault.volume,
4075 .flags = FLAG_ADVANCED | FLAG_SHARE,
4081 .ptr = &sDefault.fstype,
4084 .flags = FLAG_ADVANCED | FLAG_SHARE,
4087 .label = "set directory",
4090 .ptr = &sDefault.bNo_set_dir,
4093 .flags = FLAG_ADVANCED | FLAG_SHARE,
4096 .label = "wide links",
4099 .ptr = &sDefault.bWidelinks,
4102 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4105 .label = "follow symlinks",
4108 .ptr = &sDefault.bSymlinks,
4111 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4114 .label = "dont descend",
4117 .ptr = &sDefault.szDontdescend,
4120 .flags = FLAG_ADVANCED | FLAG_SHARE,
4123 .label = "magic script",
4126 .ptr = &sDefault.szMagicScript,
4129 .flags = FLAG_ADVANCED | FLAG_SHARE,
4132 .label = "magic output",
4135 .ptr = &sDefault.szMagicOutput,
4138 .flags = FLAG_ADVANCED | FLAG_SHARE,
4141 .label = "delete readonly",
4144 .ptr = &sDefault.bDeleteReadonly,
4147 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4150 .label = "dos filemode",
4153 .ptr = &sDefault.bDosFilemode,
4156 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4159 .label = "dos filetimes",
4162 .ptr = &sDefault.bDosFiletimes,
4165 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4168 .label = "dos filetime resolution",
4171 .ptr = &sDefault.bDosFiletimeResolution,
4174 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4177 .label = "fake directory create times",
4180 .ptr = &sDefault.bFakeDirCreateTimes,
4183 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4186 .label = "panic action",
4188 .p_class = P_GLOBAL,
4189 .ptr = &Globals.szPanicAction,
4192 .flags = FLAG_ADVANCED,
4195 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4198 .label = "vfs objects",
4201 .ptr = &sDefault.szVfsObjects,
4204 .flags = FLAG_ADVANCED | FLAG_SHARE,
4207 .label = "vfs object",
4210 .ptr = &sDefault.szVfsObjects,
4217 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4220 .label = "msdfs root",
4223 .ptr = &sDefault.bMSDfsRoot,
4226 .flags = FLAG_ADVANCED | FLAG_SHARE,
4229 .label = "msdfs proxy",
4232 .ptr = &sDefault.szMSDfsProxy,
4235 .flags = FLAG_ADVANCED | FLAG_SHARE,
4238 .label = "host msdfs",
4240 .p_class = P_GLOBAL,
4241 .ptr = &Globals.bHostMSDfs,
4244 .flags = FLAG_ADVANCED,
4247 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4250 .label = "passdb expand explicit",
4252 .p_class = P_GLOBAL,
4253 .ptr = &Globals.bPassdbExpandExplicit,
4256 .flags = FLAG_ADVANCED,
4259 .label = "idmap domains",
4261 .p_class = P_GLOBAL,
4262 .ptr = &Globals.szIdmapDomains,
4265 .flags = FLAG_ADVANCED,
4268 .label = "idmap backend",
4270 .p_class = P_GLOBAL,
4271 .ptr = &Globals.szIdmapBackend,
4274 .flags = FLAG_ADVANCED,
4277 .label = "idmap alloc backend",
4279 .p_class = P_GLOBAL,
4280 .ptr = &Globals.szIdmapAllocBackend,
4283 .flags = FLAG_ADVANCED,
4286 .label = "idmap cache time",
4288 .p_class = P_GLOBAL,
4289 .ptr = &Globals.iIdmapCacheTime,
4292 .flags = FLAG_ADVANCED,
4295 .label = "idmap negative cache time",
4297 .p_class = P_GLOBAL,
4298 .ptr = &Globals.iIdmapNegativeCacheTime,
4301 .flags = FLAG_ADVANCED,
4304 .label = "idmap uid",
4306 .p_class = P_GLOBAL,
4307 .ptr = &Globals.szIdmapUID,
4308 .special = handle_idmap_uid,
4310 .flags = FLAG_ADVANCED,
4313 .label = "winbind uid",
4315 .p_class = P_GLOBAL,
4316 .ptr = &Globals.szIdmapUID,
4317 .special = handle_idmap_uid,
4322 .label = "idmap gid",
4324 .p_class = P_GLOBAL,
4325 .ptr = &Globals.szIdmapGID,
4326 .special = handle_idmap_gid,
4328 .flags = FLAG_ADVANCED,
4331 .label = "winbind gid",
4333 .p_class = P_GLOBAL,
4334 .ptr = &Globals.szIdmapGID,
4335 .special = handle_idmap_gid,
4340 .label = "template homedir",
4342 .p_class = P_GLOBAL,
4343 .ptr = &Globals.szTemplateHomedir,
4346 .flags = FLAG_ADVANCED,
4349 .label = "template shell",
4351 .p_class = P_GLOBAL,
4352 .ptr = &Globals.szTemplateShell,
4355 .flags = FLAG_ADVANCED,
4358 .label = "winbind separator",
4360 .p_class = P_GLOBAL,
4361 .ptr = &Globals.szWinbindSeparator,
4364 .flags = FLAG_ADVANCED,
4367 .label = "winbind cache time",
4369 .p_class = P_GLOBAL,
4370 .ptr = &Globals.winbind_cache_time,
4373 .flags = FLAG_ADVANCED,
4376 .label = "winbind enum users",
4378 .p_class = P_GLOBAL,
4379 .ptr = &Globals.bWinbindEnumUsers,
4382 .flags = FLAG_ADVANCED,
4385 .label = "winbind enum groups",
4387 .p_class = P_GLOBAL,
4388 .ptr = &Globals.bWinbindEnumGroups,
4391 .flags = FLAG_ADVANCED,
4394 .label = "winbind use default domain",
4396 .p_class = P_GLOBAL,
4397 .ptr = &Globals.bWinbindUseDefaultDomain,
4400 .flags = FLAG_ADVANCED,
4403 .label = "winbind trusted domains only",
4405 .p_class = P_GLOBAL,
4406 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4409 .flags = FLAG_ADVANCED,
4412 .label = "winbind nested groups",
4414 .p_class = P_GLOBAL,
4415 .ptr = &Globals.bWinbindNestedGroups,
4418 .flags = FLAG_ADVANCED,
4421 .label = "winbind expand groups",
4423 .p_class = P_GLOBAL,
4424 .ptr = &Globals.winbind_expand_groups,
4427 .flags = FLAG_ADVANCED,
4430 .label = "winbind nss info",
4432 .p_class = P_GLOBAL,
4433 .ptr = &Globals.szWinbindNssInfo,
4436 .flags = FLAG_ADVANCED,
4439 .label = "winbind refresh tickets",
4441 .p_class = P_GLOBAL,
4442 .ptr = &Globals.bWinbindRefreshTickets,
4445 .flags = FLAG_ADVANCED,
4448 .label = "winbind offline logon",
4450 .p_class = P_GLOBAL,
4451 .ptr = &Globals.bWinbindOfflineLogon,
4454 .flags = FLAG_ADVANCED,
4457 .label = "winbind normalize names",
4459 .p_class = P_GLOBAL,
4460 .ptr = &Globals.bWinbindNormalizeNames,
4463 .flags = FLAG_ADVANCED,
4466 .label = "winbind rpc only",
4468 .p_class = P_GLOBAL,
4469 .ptr = &Globals.bWinbindRpcOnly,
4472 .flags = FLAG_ADVANCED,
4475 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4478 /***************************************************************************
4479 Initialise the sDefault parameter structure for the printer values.
4480 ***************************************************************************/
4482 static void init_printer_values(struct service *pService)
4484 /* choose defaults depending on the type of printing */
4485 switch (pService->iPrinting) {
4490 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4491 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4492 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4497 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4498 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4499 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4500 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4501 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4502 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4503 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4509 /* set the lpq command to contain the destination printer
4510 name only. This is used by cups_queue_get() */
4511 string_set(&pService->szLpqcommand, "%p");
4512 string_set(&pService->szLprmcommand, "");
4513 string_set(&pService->szPrintcommand, "");
4514 string_set(&pService->szLppausecommand, "");
4515 string_set(&pService->szLpresumecommand, "");
4516 string_set(&pService->szQueuepausecommand, "");
4517 string_set(&pService->szQueueresumecommand, "");
4519 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4520 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4521 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4522 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4523 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4524 string_set(&pService->szQueuepausecommand, "disable '%p'");
4525 string_set(&pService->szQueueresumecommand, "enable '%p'");
4526 #endif /* HAVE_CUPS */
4531 string_set(&pService->szLpqcommand, "lpstat -o%p");
4532 string_set(&pService->szLprmcommand, "cancel %p-%j");
4533 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4534 string_set(&pService->szQueuepausecommand, "disable %p");
4535 string_set(&pService->szQueueresumecommand, "enable %p");
4537 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4538 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4543 string_set(&pService->szLpqcommand, "lpq -P%p");
4544 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4545 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4551 string_set(&pService->szPrintcommand, "vlp print %p %s");
4552 string_set(&pService->szLpqcommand, "vlp lpq %p");
4553 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4554 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4555 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4556 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4557 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4559 #endif /* DEVELOPER */
4564 /***************************************************************************
4565 Initialise the global parameter structure.
4566 ***************************************************************************/
4568 static void init_globals(bool first_time_only)
4570 static bool done_init = False;
4574 /* If requested to initialize only once and we've already done it... */
4575 if (first_time_only && done_init) {
4576 /* ... then we have nothing more to do */
4581 /* The logfile can be set before this is invoked. Free it if so. */
4582 if (Globals.szLogFile != NULL) {
4583 string_free(&Globals.szLogFile);
4584 Globals.szLogFile = NULL;
4588 for (i = 0; parm_table[i].label; i++) {
4589 if ((parm_table[i].type == P_STRING ||
4590 parm_table[i].type == P_USTRING) &&
4593 string_free((char **)parm_table[i].ptr);
4598 memset((void *)&Globals, '\0', sizeof(Globals));
4600 for (i = 0; parm_table[i].label; i++) {
4601 if ((parm_table[i].type == P_STRING ||
4602 parm_table[i].type == P_USTRING) &&
4605 string_set((char **)parm_table[i].ptr, "");
4609 string_set(&sDefault.fstype, FSTYPE_STRING);
4610 string_set(&sDefault.szPrintjobUsername, "%U");
4612 init_printer_values(&sDefault);
4615 DEBUG(3, ("Initialising global parameters\n"));
4617 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4618 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4620 /* use the new 'hash2' method by default, with a prefix of 1 */
4621 string_set(&Globals.szManglingMethod, "hash2");
4622 Globals.mangle_prefix = 1;
4624 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4626 /* using UTF8 by default allows us to support all chars */
4627 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4629 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4630 /* If the system supports nl_langinfo(), try to grab the value
4631 from the user's locale */
4632 string_set(&Globals.display_charset, "LOCALE");
4634 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4637 /* Use codepage 850 as a default for the dos character set */
4638 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4641 * Allow the default PASSWD_CHAT to be overridden in local.h.
4643 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4645 set_global_myname(myhostname());
4646 string_set(&Globals.szNetbiosName,global_myname());
4648 set_global_myworkgroup(WORKGROUP);
4649 string_set(&Globals.szWorkgroup, lp_workgroup());
4651 string_set(&Globals.szPasswdProgram, "");
4652 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4653 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4654 string_set(&Globals.szSocketAddress, "0.0.0.0");
4656 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4657 smb_panic("init_globals: ENOMEM");
4659 string_set(&Globals.szServerString, s);
4661 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4662 DEFAULT_MINOR_VERSION) < 0) {
4663 smb_panic("init_globals: ENOMEM");
4665 string_set(&Globals.szAnnounceVersion, s);
4668 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4671 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4673 string_set(&Globals.szLogonDrive, "");
4674 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4675 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4676 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4678 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4679 string_set(&Globals.szPasswordServer, "*");
4681 Globals.AlgorithmicRidBase = BASE_RID;
4683 Globals.bLoadPrinters = True;
4684 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4686 Globals.ConfigBackend = config_backend;
4688 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4689 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4690 Globals.max_xmit = 0x4104;
4691 Globals.max_mux = 50; /* This is *needed* for profile support. */
4692 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4693 Globals.bDisableSpoolss = False;
4694 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4695 Globals.pwordlevel = 0;
4696 Globals.unamelevel = 0;
4697 Globals.deadtime = 0;
4698 Globals.getwd_cache = true;
4699 Globals.bLargeReadwrite = True;
4700 Globals.max_log_size = 5000;
4701 Globals.max_open_files = MAX_OPEN_FILES;
4702 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4703 Globals.maxprotocol = PROTOCOL_NT1;
4704 Globals.minprotocol = PROTOCOL_CORE;
4705 Globals.security = SEC_USER;
4706 Globals.paranoid_server_security = True;
4707 Globals.bEncryptPasswords = True;
4708 Globals.bUpdateEncrypt = False;
4709 Globals.clientSchannel = Auto;
4710 Globals.serverSchannel = Auto;
4711 Globals.bReadRaw = True;
4712 Globals.bWriteRaw = True;
4713 Globals.bNullPasswords = False;
4714 Globals.bObeyPamRestrictions = False;
4716 Globals.bSyslogOnly = False;
4717 Globals.bTimestampLogs = True;
4718 string_set(&Globals.szLogLevel, "0");
4719 Globals.bDebugPrefixTimestamp = False;
4720 Globals.bDebugHiresTimestamp = False;
4721 Globals.bDebugPid = False;
4722 Globals.bDebugUid = False;
4723 Globals.bDebugClass = False;
4724 Globals.bEnableCoreFiles = True;
4725 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4726 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4727 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4728 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4729 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4730 Globals.lm_interval = 60;
4731 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4732 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4733 Globals.bNISHomeMap = False;
4734 #ifdef WITH_NISPLUS_HOME
4735 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4737 string_set(&Globals.szNISHomeMapName, "auto.home");
4740 Globals.bTimeServer = False;
4741 Globals.bBindInterfacesOnly = False;
4742 Globals.bUnixPasswdSync = False;
4743 Globals.bPamPasswordChange = False;
4744 Globals.bPasswdChatDebug = False;
4745 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4746 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4747 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4748 Globals.bStatCache = True; /* use stat cache by default */
4749 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4750 Globals.restrict_anonymous = 0;
4751 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4752 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4753 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4754 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4755 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4756 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4758 Globals.map_to_guest = 0; /* By Default, "Never" */
4759 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4760 Globals.enhanced_browsing = true;
4761 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4762 #ifdef MMAP_BLACKLIST
4763 Globals.bUseMmap = False;
4765 Globals.bUseMmap = True;
4767 Globals.bUnixExtensions = True;
4768 Globals.bResetOnZeroVC = False;
4770 /* hostname lookups can be very expensive and are broken on
4771 a large number of sites (tridge) */
4772 Globals.bHostnameLookups = False;
4774 string_set(&Globals.szPassdbBackend, "smbpasswd");
4775 string_set(&Globals.szLdapSuffix, "");
4776 string_set(&Globals.szLdapMachineSuffix, "");
4777 string_set(&Globals.szLdapUserSuffix, "");
4778 string_set(&Globals.szLdapGroupSuffix, "");
4779 string_set(&Globals.szLdapIdmapSuffix, "");
4781 string_set(&Globals.szLdapAdminDn, "");
4782 Globals.ldap_ssl = LDAP_SSL_ON;
4783 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4784 Globals.ldap_delete_dn = False;
4785 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4786 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4787 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4788 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4790 Globals.ldap_debug_level = 0;
4791 Globals.ldap_debug_threshold = 10;
4793 /* This is what we tell the afs client. in reality we set the token
4794 * to never expire, though, when this runs out the afs client will
4795 * forget the token. Set to 0 to get NEVERDATE.*/
4796 Globals.iAfsTokenLifetime = 604800;
4798 /* these parameters are set to defaults that are more appropriate
4799 for the increasing samba install base:
4801 as a member of the workgroup, that will possibly become a
4802 _local_ master browser (lm = True). this is opposed to a forced
4803 local master browser startup (pm = True).
4805 doesn't provide WINS server service by default (wsupp = False),
4806 and doesn't provide domain master browser services by default, either.
4810 Globals.bMsAddPrinterWizard = True;
4811 Globals.os_level = 20;
4812 Globals.bLocalMaster = True;
4813 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4814 Globals.bDomainLogons = False;
4815 Globals.bBrowseList = True;
4816 Globals.bWINSsupport = False;
4817 Globals.bWINSproxy = False;
4819 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
4820 Globals.InitLogonDelay = 100; /* 100 ms default delay */
4822 Globals.bDNSproxy = True;
4824 /* this just means to use them if they exist */
4825 Globals.bKernelOplocks = True;
4827 Globals.bAllowTrustedDomains = True;
4829 string_set(&Globals.szTemplateShell, "/bin/false");
4830 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4831 string_set(&Globals.szWinbindSeparator, "\\");
4833 string_set(&Globals.szCupsServer, "");
4834 string_set(&Globals.szIPrintServer, "");
4836 string_set(&Globals.ctdbdSocket, "");
4837 Globals.szClusterAddresses = NULL;
4838 Globals.clustering = False;
4840 Globals.winbind_cache_time = 300; /* 5 minutes */
4841 Globals.bWinbindEnumUsers = False;
4842 Globals.bWinbindEnumGroups = False;
4843 Globals.bWinbindUseDefaultDomain = False;
4844 Globals.bWinbindTrustedDomainsOnly = False;
4845 Globals.bWinbindNestedGroups = True;
4846 Globals.winbind_expand_groups = 1;
4847 Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4848 Globals.bWinbindRefreshTickets = False;
4849 Globals.bWinbindOfflineLogon = False;
4851 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
4852 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4854 Globals.bPassdbExpandExplicit = False;
4856 Globals.name_cache_timeout = 660; /* In seconds */
4858 Globals.bUseSpnego = True;
4859 Globals.bClientUseSpnego = True;
4861 Globals.client_signing = Auto;
4862 Globals.server_signing = False;
4864 Globals.bDeferSharingViolations = True;
4865 string_set(&Globals.smb_ports, SMB_PORTS);
4867 Globals.bEnablePrivileges = True;
4868 Globals.bHostMSDfs = True;
4869 Globals.bASUSupport = False;
4871 /* User defined shares. */
4872 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4873 smb_panic("init_globals: ENOMEM");
4875 string_set(&Globals.szUsersharePath, s);
4877 string_set(&Globals.szUsershareTemplateShare, "");
4878 Globals.iUsershareMaxShares = 0;
4879 /* By default disallow sharing of directories not owned by the sharer. */
4880 Globals.bUsershareOwnerOnly = True;
4881 /* By default disallow guest access to usershares. */
4882 Globals.bUsershareAllowGuests = False;
4884 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4886 /* By default no shares out of the registry */
4887 Globals.bRegistryShares = False;
4889 Globals.iminreceivefile = 0;
4892 /*******************************************************************
4893 Convenience routine to grab string parameters into temporary memory
4894 and run standard_sub_basic on them. The buffers can be written to by
4895 callers without affecting the source string.
4896 ********************************************************************/
4898 static char *lp_string(const char *s)
4901 TALLOC_CTX *ctx = talloc_tos();
4903 /* The follow debug is useful for tracking down memory problems
4904 especially if you have an inner loop that is calling a lp_*()
4905 function that returns a string. Perhaps this debug should be
4906 present all the time? */
4909 DEBUG(10, ("lp_string(%s)\n", s));
4912 ret = talloc_sub_basic(ctx,
4913 get_current_username(),
4914 current_user_info.domain,
4916 if (trim_char(ret, '\"', '\"')) {
4917 if (strchr(ret,'\"') != NULL) {
4919 ret = talloc_sub_basic(ctx,
4920 get_current_username(),
4921 current_user_info.domain,
4929 In this section all the functions that are used to access the
4930 parameters from the rest of the program are defined
4933 #define FN_GLOBAL_STRING(fn_name,ptr) \
4934 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4935 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4936 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4937 #define FN_GLOBAL_LIST(fn_name,ptr) \
4938 const char **fn_name(void) {return(*(const char ***)(ptr));}
4939 #define FN_GLOBAL_BOOL(fn_name,ptr) \
4940 bool fn_name(void) {return(*(bool *)(ptr));}
4941 #define FN_GLOBAL_CHAR(fn_name,ptr) \
4942 char fn_name(void) {return(*(char *)(ptr));}
4943 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
4944 int fn_name(void) {return(*(int *)(ptr));}
4946 #define FN_LOCAL_STRING(fn_name,val) \
4947 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4948 #define FN_LOCAL_CONST_STRING(fn_name,val) \
4949 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4950 #define FN_LOCAL_LIST(fn_name,val) \
4951 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4952 #define FN_LOCAL_BOOL(fn_name,val) \
4953 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4954 #define FN_LOCAL_INTEGER(fn_name,val) \
4955 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4957 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
4958 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4959 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4960 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4961 #define FN_LOCAL_PARM_STRING(fn_name,val) \
4962 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));}
4963 #define FN_LOCAL_CHAR(fn_name,val) \
4964 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4966 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4967 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4968 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4969 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4970 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4971 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4972 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4973 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4974 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4975 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4976 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4977 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4978 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4979 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4980 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4981 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4982 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4983 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4984 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4985 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4986 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4987 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4988 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4989 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4990 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4991 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4992 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
4993 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
4994 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
4995 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
4996 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
4997 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
4998 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
4999 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5000 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5001 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5002 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5003 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5004 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5005 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5006 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5007 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5008 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5009 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5010 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5011 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
5012 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5013 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5014 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5015 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5016 * lp_passdb_backend() should be replace by the this macro again after
5019 const char *lp_passdb_backend(void)
5021 char *delim, *quote;
5023 delim = strchr( Globals.szPassdbBackend, ' ');
5024 /* no space at all */
5025 if (delim == NULL) {
5029 quote = strchr(Globals.szPassdbBackend, '"');
5030 /* no quote char or non in the first part */
5031 if (quote == NULL || quote > delim) {
5036 quote = strchr(quote+1, '"');
5037 if (quote == NULL) {
5038 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5040 } else if (*(quote+1) == '\0') {
5041 /* space, fitting quote char, and one backend only */
5044 /* terminate string after the fitting quote char */
5049 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5050 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5051 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5052 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5055 return Globals.szPassdbBackend;
5057 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5058 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5059 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5060 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5061 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5063 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5064 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5065 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5066 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5067 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5068 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5070 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5072 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5073 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5074 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5076 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5078 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5079 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5080 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5081 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5082 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5083 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5084 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5085 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5086 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5087 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5088 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5089 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5090 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5091 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5092 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5094 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
5095 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
5096 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5097 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5098 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5099 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5100 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5102 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5103 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5104 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5105 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5106 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5107 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5108 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5109 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5110 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5111 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5112 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5113 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5114 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5115 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5116 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5117 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5118 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5120 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5122 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5123 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5124 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5125 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5126 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5127 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5128 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5129 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5130 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5131 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5132 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5133 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5134 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5135 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5136 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5137 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5138 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5139 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5140 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5141 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5142 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5143 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5144 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5145 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5146 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5147 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5148 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5149 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5150 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5151 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5152 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5153 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5154 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5155 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5156 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5157 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5158 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5159 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5160 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5161 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5162 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5163 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5164 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5165 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5166 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5167 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5168 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5169 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5170 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5171 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5172 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5173 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5174 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5175 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5176 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5177 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5178 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5179 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5180 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5181 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5182 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5183 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5184 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5185 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5186 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5187 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5188 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5189 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5190 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5191 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5192 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5193 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5194 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5195 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5196 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5197 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5198 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5199 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5200 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5201 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5202 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5203 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5204 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5205 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5206 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5207 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5208 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5209 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5210 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5211 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5212 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5213 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5214 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5215 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5216 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5217 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5218 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5219 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5221 FN_LOCAL_STRING(lp_preexec, szPreExec)
5222 FN_LOCAL_STRING(lp_postexec, szPostExec)
5223 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5224 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5225 FN_LOCAL_STRING(lp_servicename, szService)
5226 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5227 FN_LOCAL_STRING(lp_pathname, szPath)
5228 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5229 FN_LOCAL_STRING(lp_username, szUsername)
5230 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5231 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5232 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5233 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5234 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5235 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5236 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5237 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5238 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5239 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5240 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5241 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5242 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5243 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5244 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5245 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5246 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5247 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5248 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5249 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5250 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5251 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5252 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5253 FN_LOCAL_STRING(lp_comment, comment)
5254 FN_LOCAL_STRING(lp_force_user, force_user)
5255 FN_LOCAL_STRING(lp_force_group, force_group)
5256 FN_LOCAL_LIST(lp_readlist, readlist)
5257 FN_LOCAL_LIST(lp_writelist, writelist)
5258 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5259 FN_LOCAL_STRING(lp_fstype, fstype)
5260 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5261 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5262 static FN_LOCAL_STRING(lp_volume, volume)
5263 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5264 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5265 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5266 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5267 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5268 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5269 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5270 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5271 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5272 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5273 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5274 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5275 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5276 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5277 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5278 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5279 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5280 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5281 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5282 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5283 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5284 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5285 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5286 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5287 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5288 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5289 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5290 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5291 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5292 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5293 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5294 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5295 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5296 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5297 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5298 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5299 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5300 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5301 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5302 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5303 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5304 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5305 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5306 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5307 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5308 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5309 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5310 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5311 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5312 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5313 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5314 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5315 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5316 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5317 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5318 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5319 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5320 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5321 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5322 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5323 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5324 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5325 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5326 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5327 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5328 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5329 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5330 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5331 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5332 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5333 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5334 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5335 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5336 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5337 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5338 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5339 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5340 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5341 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5342 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5343 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5344 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5345 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5346 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5347 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5348 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5349 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5350 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5351 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5352 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5353 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5354 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5355 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5356 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5357 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5358 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5359 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5361 /* local prototypes */
5363 static int map_parameter(const char *pszParmName);
5364 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5365 static bool set_boolean(bool *pb, const char *pszParmValue);
5366 static const char *get_boolean(bool bool_value);
5367 static int getservicebyname(const char *pszServiceName,
5368 struct service *pserviceDest);
5369 static void copy_service(struct service *pserviceDest,
5370 struct service *pserviceSource,
5371 struct bitmap *pcopymapDest);
5372 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5374 static bool do_section(const char *pszSectionName, void *userdata);
5375 static void init_copymap(struct service *pservice);
5376 static bool hash_a_service(const char *name, int number);
5377 static void free_service_byindex(int iService);
5378 static char * canonicalize_servicename(const char *name);
5379 static void show_parameter(int parmIndex);
5380 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5383 * This is a helper function for parametrical options support. It returns a
5384 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5385 * parametrical functions are quite simple
5387 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5390 bool global_section = False;
5392 struct param_opt_struct *data;
5394 if (snum >= iNumServices) return NULL;
5397 data = Globals.param_opt;
5398 global_section = True;
5400 data = ServicePtrs[snum]->param_opt;
5403 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5404 DEBUG(0,("asprintf failed!\n"));
5409 if (strwicmp(data->key, param_key) == 0) {
5410 string_free(¶m_key);
5416 if (!global_section) {
5417 /* Try to fetch the same option but from globals */
5418 /* but only if we are not already working with Globals */
5419 data = Globals.param_opt;
5421 if (strwicmp(data->key, param_key) == 0) {
5422 string_free(¶m_key);
5429 string_free(¶m_key);
5435 #define MISSING_PARAMETER(name) \
5436 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5438 /*******************************************************************
5439 convenience routine to return int parameters.
5440 ********************************************************************/
5441 static int lp_int(const char *s)
5445 MISSING_PARAMETER(lp_int);
5449 return (int)strtol(s, NULL, 0);
5452 /*******************************************************************
5453 convenience routine to return unsigned long parameters.
5454 ********************************************************************/
5455 static unsigned long lp_ulong(const char *s)
5459 MISSING_PARAMETER(lp_ulong);
5463 return strtoul(s, NULL, 0);
5466 /*******************************************************************
5467 convenience routine to return boolean parameters.
5468 ********************************************************************/
5469 static bool lp_bool(const char *s)
5474 MISSING_PARAMETER(lp_bool);
5478 if (!set_boolean(&ret,s)) {
5479 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5486 /*******************************************************************
5487 convenience routine to return enum parameters.
5488 ********************************************************************/
5489 static int lp_enum(const char *s,const struct enum_list *_enum)
5493 if (!s || !*s || !_enum) {
5494 MISSING_PARAMETER(lp_enum);
5498 for (i=0; _enum[i].name; i++) {
5499 if (strequal(_enum[i].name,s))
5500 return _enum[i].value;
5503 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5507 #undef MISSING_PARAMETER
5509 /* DO NOT USE lp_parm_string ANYMORE!!!!
5510 * use lp_parm_const_string or lp_parm_talloc_string
5512 * lp_parm_string is only used to let old modules find this symbol
5514 #undef lp_parm_string
5515 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5516 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5518 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5521 /* Return parametric option from a given service. Type is a part of option before ':' */
5522 /* Parametric option has following syntax: 'Type: option = value' */
5523 /* the returned value is talloced on the talloc_tos() */
5524 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5526 struct param_opt_struct *data = get_parametrics(snum, type, option);
5528 if (data == NULL||data->value==NULL) {
5530 return lp_string(def);
5536 return lp_string(data->value);
5539 /* Return parametric option from a given service. Type is a part of option before ':' */
5540 /* Parametric option has following syntax: 'Type: option = value' */
5541 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5543 struct param_opt_struct *data = get_parametrics(snum, type, option);
5545 if (data == NULL||data->value==NULL)
5551 /* Return parametric option from a given service. Type is a part of option before ':' */
5552 /* Parametric option has following syntax: 'Type: option = value' */
5554 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5556 struct param_opt_struct *data = get_parametrics(snum, type, option);
5558 if (data == NULL||data->value==NULL)
5559 return (const char **)def;
5561 if (data->list==NULL) {
5562 data->list = str_list_make(NULL, data->value, NULL);
5565 return (const char **)data->list;
5568 /* Return parametric option from a given service. Type is a part of option before ':' */
5569 /* Parametric option has following syntax: 'Type: option = value' */
5571 int lp_parm_int(int snum, const char *type, const char *option, int def)
5573 struct param_opt_struct *data = get_parametrics(snum, type, option);
5575 if (data && data->value && *data->value)
5576 return lp_int(data->value);
5581 /* Return parametric option from a given service. Type is a part of option before ':' */
5582 /* Parametric option has following syntax: 'Type: option = value' */
5584 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5586 struct param_opt_struct *data = get_parametrics(snum, type, option);
5588 if (data && data->value && *data->value)
5589 return lp_ulong(data->value);
5594 /* Return parametric option from a given service. Type is a part of option before ':' */
5595 /* Parametric option has following syntax: 'Type: option = value' */
5597 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5599 struct param_opt_struct *data = get_parametrics(snum, type, option);
5601 if (data && data->value && *data->value)
5602 return lp_bool(data->value);
5607 /* Return parametric option from a given service. Type is a part of option before ':' */
5608 /* Parametric option has following syntax: 'Type: option = value' */
5610 int lp_parm_enum(int snum, const char *type, const char *option,
5611 const struct enum_list *_enum, int def)
5613 struct param_opt_struct *data = get_parametrics(snum, type, option);
5615 if (data && data->value && *data->value && _enum)
5616 return lp_enum(data->value, _enum);
5622 /***************************************************************************
5623 Initialise a service to the defaults.
5624 ***************************************************************************/
5626 static void init_service(struct service *pservice)
5628 memset((char *)pservice, '\0', sizeof(struct service));
5629 copy_service(pservice, &sDefault, NULL);
5632 /***************************************************************************
5633 Free the dynamically allocated parts of a service struct.
5634 ***************************************************************************/
5636 static void free_service(struct service *pservice)
5639 struct param_opt_struct *data, *pdata;
5643 if (pservice->szService)
5644 DEBUG(5, ("free_service: Freeing service %s\n",
5645 pservice->szService));
5647 string_free(&pservice->szService);
5648 bitmap_free(pservice->copymap);
5650 for (i = 0; parm_table[i].label; i++) {
5651 if ((parm_table[i].type == P_STRING ||
5652 parm_table[i].type == P_USTRING) &&
5653 parm_table[i].p_class == P_LOCAL)
5654 string_free((char **)
5655 (((char *)pservice) +
5656 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5657 else if (parm_table[i].type == P_LIST &&
5658 parm_table[i].p_class == P_LOCAL)
5659 TALLOC_FREE(*((char ***)
5660 (((char *)pservice) +
5661 PTR_DIFF(parm_table[i].ptr,
5665 data = pservice->param_opt;
5667 DEBUG(5,("Freeing parametrics:\n"));
5669 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5670 string_free(&data->key);
5671 string_free(&data->value);
5672 TALLOC_FREE(data->list);
5678 ZERO_STRUCTP(pservice);
5682 /***************************************************************************
5683 remove a service indexed in the ServicePtrs array from the ServiceHash
5684 and free the dynamically allocated parts
5685 ***************************************************************************/
5687 static void free_service_byindex(int idx)
5689 if ( !LP_SNUM_OK(idx) )
5692 ServicePtrs[idx]->valid = False;
5693 invalid_services[num_invalid_services++] = idx;
5695 /* we have to cleanup the hash record */
5697 if (ServicePtrs[idx]->szService) {
5698 char *canon_name = canonicalize_servicename(
5699 ServicePtrs[idx]->szService );
5701 dbwrap_delete_bystring(ServiceHash, canon_name );
5702 TALLOC_FREE(canon_name);
5705 free_service(ServicePtrs[idx]);
5708 /***************************************************************************
5709 Add a new service to the services array initialising it with the given
5711 ***************************************************************************/
5713 static int add_a_service(const struct service *pservice, const char *name)
5716 struct service tservice;
5717 int num_to_alloc = iNumServices + 1;
5718 struct param_opt_struct *data, *pdata;
5720 tservice = *pservice;
5722 /* it might already exist */
5724 i = getservicebyname(name, NULL);
5726 /* Clean all parametric options for service */
5727 /* They will be added during parsing again */
5728 data = ServicePtrs[i]->param_opt;
5730 string_free(&data->key);
5731 string_free(&data->value);
5732 TALLOC_FREE(data->list);
5737 ServicePtrs[i]->param_opt = NULL;
5742 /* find an invalid one */
5744 if (num_invalid_services > 0) {
5745 i = invalid_services[--num_invalid_services];
5748 /* if not, then create one */
5749 if (i == iNumServices) {
5750 struct service **tsp;
5753 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5755 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5759 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5760 if (!ServicePtrs[iNumServices]) {
5761 DEBUG(0,("add_a_service: out of memory!\n"));
5766 /* enlarge invalid_services here for now... */
5767 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5769 if (tinvalid == NULL) {
5770 DEBUG(0,("add_a_service: failed to enlarge "
5771 "invalid_services!\n"));
5774 invalid_services = tinvalid;
5776 free_service_byindex(i);
5779 ServicePtrs[i]->valid = True;
5781 init_service(ServicePtrs[i]);
5782 copy_service(ServicePtrs[i], &tservice, NULL);
5784 string_set(&ServicePtrs[i]->szService, name);
5786 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5787 i, ServicePtrs[i]->szService));
5789 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5796 /***************************************************************************
5797 Convert a string to uppercase and remove whitespaces.
5798 ***************************************************************************/
5800 static char *canonicalize_servicename(const char *src)
5805 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5809 result = talloc_strdup(talloc_tos(), src);
5810 SMB_ASSERT(result != NULL);
5816 /***************************************************************************
5817 Add a name/index pair for the services array to the hash table.
5818 ***************************************************************************/
5820 static bool hash_a_service(const char *name, int idx)
5824 if ( !ServiceHash ) {
5825 DEBUG(10,("hash_a_service: creating servicehash\n"));
5826 ServiceHash = db_open_rbt(NULL);
5827 if ( !ServiceHash ) {
5828 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5833 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5836 canon_name = canonicalize_servicename( name );
5838 dbwrap_store_bystring(ServiceHash, canon_name,
5839 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5842 TALLOC_FREE(canon_name);
5847 /***************************************************************************
5848 Add a new home service, with the specified home directory, defaults coming
5850 ***************************************************************************/
5852 bool lp_add_home(const char *pszHomename, int iDefaultService,
5853 const char *user, const char *pszHomedir)
5857 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5862 if (!(*(ServicePtrs[iDefaultService]->szPath))
5863 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5864 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5867 if (!(*(ServicePtrs[i]->comment))) {
5868 char *comment = NULL;
5869 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5872 string_set(&ServicePtrs[i]->comment, comment);
5876 /* set the browseable flag from the global default */
5878 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5880 ServicePtrs[i]->autoloaded = True;
5882 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5883 user, ServicePtrs[i]->szPath ));
5888 /***************************************************************************
5889 Add a new service, based on an old one.
5890 ***************************************************************************/
5892 int lp_add_service(const char *pszService, int iDefaultService)
5894 if (iDefaultService < 0) {
5895 return add_a_service(&sDefault, pszService);
5898 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5901 /***************************************************************************
5902 Add the IPC service.
5903 ***************************************************************************/
5905 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5907 char *comment = NULL;
5908 int i = add_a_service(&sDefault, ipc_name);
5913 if (asprintf(&comment, "IPC Service (%s)",
5914 Globals.szServerString) < 0) {
5918 string_set(&ServicePtrs[i]->szPath, tmpdir());
5919 string_set(&ServicePtrs[i]->szUsername, "");
5920 string_set(&ServicePtrs[i]->comment, comment);
5921 string_set(&ServicePtrs[i]->fstype, "IPC");
5922 ServicePtrs[i]->iMaxConnections = 0;
5923 ServicePtrs[i]->bAvailable = True;
5924 ServicePtrs[i]->bRead_only = True;
5925 ServicePtrs[i]->bGuest_only = False;
5926 ServicePtrs[i]->bAdministrative_share = True;
5927 ServicePtrs[i]->bGuest_ok = guest_ok;
5928 ServicePtrs[i]->bPrint_ok = False;
5929 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5931 DEBUG(3, ("adding IPC service\n"));
5937 /***************************************************************************
5938 Add a new printer service, with defaults coming from service iFrom.
5939 ***************************************************************************/
5941 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5943 const char *comment = "From Printcap";
5944 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5949 /* note that we do NOT default the availability flag to True - */
5950 /* we take it from the default service passed. This allows all */
5951 /* dynamic printers to be disabled by disabling the [printers] */
5952 /* entry (if/when the 'available' keyword is implemented!). */
5954 /* the printer name is set to the service name. */
5955 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5956 string_set(&ServicePtrs[i]->comment, comment);
5958 /* set the browseable flag from the gloabl default */
5959 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5961 /* Printers cannot be read_only. */
5962 ServicePtrs[i]->bRead_only = False;
5963 /* No share modes on printer services. */
5964 ServicePtrs[i]->bShareModes = False;
5965 /* No oplocks on printer services. */
5966 ServicePtrs[i]->bOpLocks = False;
5967 /* Printer services must be printable. */
5968 ServicePtrs[i]->bPrint_ok = True;
5970 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5976 /***************************************************************************
5977 Check whether the given parameter name is valid.
5978 Parametric options (names containing a colon) are considered valid.
5979 ***************************************************************************/
5981 bool lp_parameter_is_valid(const char *pszParmName)
5983 return ((map_parameter(pszParmName) != -1) ||
5984 (strchr(pszParmName, ':') != NULL));
5987 /***************************************************************************
5988 Check whether the given name is the name of a global parameter.
5989 Returns True for strings belonging to parameters of class
5990 P_GLOBAL, False for all other strings, also for parametric options
5991 and strings not belonging to any option.
5992 ***************************************************************************/
5994 bool lp_parameter_is_global(const char *pszParmName)
5996 int num = map_parameter(pszParmName);
5999 return (parm_table[num].p_class == P_GLOBAL);
6005 /**************************************************************************
6006 Check whether the given name is the canonical name of a parameter.
6007 Returns False if it is not a valid parameter Name.
6008 For parametric options, True is returned.
6009 **************************************************************************/
6011 bool lp_parameter_is_canonical(const char *parm_name)
6013 if (!lp_parameter_is_valid(parm_name)) {
6017 return (map_parameter(parm_name) ==
6018 map_parameter_canonical(parm_name, NULL));
6021 /**************************************************************************
6022 Determine the canonical name for a parameter.
6023 Indicate when it is an inverse (boolean) synonym instead of a
6025 **************************************************************************/
6027 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6032 if (!lp_parameter_is_valid(parm_name)) {
6037 num = map_parameter_canonical(parm_name, inverse);
6039 /* parametric option */
6040 *canon_parm = parm_name;
6042 *canon_parm = parm_table[num].label;
6049 /**************************************************************************
6050 Determine the canonical name for a parameter.
6051 Turn the value given into the inverse boolean expression when
6052 the synonym is an invers boolean synonym.
6054 Return True if parm_name is a valid parameter name and
6055 in case it is an invers boolean synonym, if the val string could
6056 successfully be converted to the reverse bool.
6057 Return false in all other cases.
6058 **************************************************************************/
6060 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6062 const char **canon_parm,
6063 const char **canon_val)
6068 if (!lp_parameter_is_valid(parm_name)) {
6074 num = map_parameter_canonical(parm_name, &inverse);
6076 /* parametric option */
6077 *canon_parm = parm_name;
6080 *canon_parm = parm_table[num].label;
6082 if (!lp_invert_boolean(val, canon_val)) {
6094 /***************************************************************************
6095 Map a parameter's string representation to something we can use.
6096 Returns False if the parameter string is not recognised, else TRUE.
6097 ***************************************************************************/
6099 static int map_parameter(const char *pszParmName)
6103 if (*pszParmName == '-')
6106 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6107 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6110 /* Warn only if it isn't parametric option */
6111 if (strchr(pszParmName, ':') == NULL)
6112 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6113 /* We do return 'fail' for parametric options as well because they are
6114 stored in different storage
6119 /***************************************************************************
6120 Map a parameter's string representation to the index of the canonical
6121 form of the parameter (it might be a synonym).
6122 Returns -1 if the parameter string is not recognised.
6123 ***************************************************************************/
6125 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6127 int parm_num, canon_num;
6128 bool loc_inverse = False;
6130 parm_num = map_parameter(pszParmName);
6131 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6132 /* invalid, parametric or no canidate for synonyms ... */
6136 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6137 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6138 parm_num = canon_num;
6144 if (inverse != NULL) {
6145 *inverse = loc_inverse;
6150 /***************************************************************************
6151 return true if parameter number parm1 is a synonym of parameter
6152 number parm2 (parm2 being the principal name).
6153 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6155 ***************************************************************************/
6157 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6159 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6160 (parm_table[parm1].flags & FLAG_HIDE) &&
6161 !(parm_table[parm2].flags & FLAG_HIDE))
6163 if (inverse != NULL) {
6164 if ((parm_table[parm1].type == P_BOOLREV) &&
6165 (parm_table[parm2].type == P_BOOL))
6177 /***************************************************************************
6178 Show one parameter's name, type, [values,] and flags.
6179 (helper functions for show_parameter_list)
6180 ***************************************************************************/
6182 static void show_parameter(int parmIndex)
6184 int enumIndex, flagIndex;
6189 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6190 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6192 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6193 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6194 FLAG_HIDE, FLAG_DOS_STRING};
6195 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6196 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6197 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6199 printf("%s=%s", parm_table[parmIndex].label,
6200 type[parm_table[parmIndex].type]);
6201 if (parm_table[parmIndex].type == P_ENUM) {
6204 parm_table[parmIndex].enum_list[enumIndex].name;
6208 enumIndex ? "|" : "",
6209 parm_table[parmIndex].enum_list[enumIndex].name);
6214 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6215 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6218 flag_names[flagIndex]);
6223 /* output synonyms */
6225 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6226 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6227 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6228 parm_table[parmIndex2].label);
6229 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6231 printf(" (synonyms: ");
6236 printf("%s%s", parm_table[parmIndex2].label,
6237 inverse ? "[i]" : "");
6247 /***************************************************************************
6248 Show all parameter's name, type, [values,] and flags.
6249 ***************************************************************************/
6251 void show_parameter_list(void)
6253 int classIndex, parmIndex;
6254 const char *section_names[] = { "local", "global", NULL};
6256 for (classIndex=0; section_names[classIndex]; classIndex++) {
6257 printf("[%s]\n", section_names[classIndex]);
6258 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6259 if (parm_table[parmIndex].p_class == classIndex) {
6260 show_parameter(parmIndex);
6266 /***************************************************************************
6267 Set a boolean variable from the text value stored in the passed string.
6268 Returns True in success, False if the passed string does not correctly
6269 represent a boolean.
6270 ***************************************************************************/
6272 static bool set_boolean(bool *pb, const char *pszParmValue)
6279 if (strwicmp(pszParmValue, "yes") == 0 ||
6280 strwicmp(pszParmValue, "true") == 0 ||
6281 strwicmp(pszParmValue, "1") == 0)
6283 else if (strwicmp(pszParmValue, "no") == 0 ||
6284 strwicmp(pszParmValue, "False") == 0 ||
6285 strwicmp(pszParmValue, "0") == 0)
6289 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6294 if ((pb != NULL) && (bRetval != False)) {
6302 /***************************************************************************
6303 Check if a given string correctly represents a boolean value.
6304 ***************************************************************************/
6306 bool lp_string_is_valid_boolean(const char *parm_value)
6308 return set_boolean(NULL, parm_value);
6311 /***************************************************************************
6312 Get the standard string representation of a boolean value ("yes" or "no")
6313 ***************************************************************************/
6315 static const char *get_boolean(bool bool_value)
6317 static const char *yes_str = "yes";
6318 static const char *no_str = "no";
6320 return (bool_value ? yes_str : no_str);
6323 /***************************************************************************
6324 Provide the string of the negated boolean value associated to the boolean
6325 given as a string. Returns False if the passed string does not correctly
6326 represent a boolean.
6327 ***************************************************************************/
6329 bool lp_invert_boolean(const char *str, const char **inverse_str)
6333 if (!set_boolean(&val, str)) {
6337 *inverse_str = get_boolean(!val);
6341 /***************************************************************************
6342 Provide the canonical string representation of a boolean value given
6343 as a string. Return True on success, False if the string given does
6344 not correctly represent a boolean.
6345 ***************************************************************************/
6347 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6351 if (!set_boolean(&val, str)) {
6355 *canon_str = get_boolean(val);
6359 /***************************************************************************
6360 Find a service by name. Otherwise works like get_service.
6361 ***************************************************************************/
6363 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6369 if (ServiceHash == NULL) {
6373 canon_name = canonicalize_servicename(pszServiceName);
6375 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6377 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6378 iService = *(int *)data.dptr;
6381 TALLOC_FREE(canon_name);
6383 if ((iService != -1) && (LP_SNUM_OK(iService))
6384 && (pserviceDest != NULL)) {
6385 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6391 /***************************************************************************
6392 Copy a service structure to another.
6393 If pcopymapDest is NULL then copy all fields
6394 ***************************************************************************/
6396 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6397 struct bitmap *pcopymapDest)
6400 bool bcopyall = (pcopymapDest == NULL);
6401 struct param_opt_struct *data, *pdata, *paramo;
6404 for (i = 0; parm_table[i].label; i++)
6405 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6406 (bcopyall || bitmap_query(pcopymapDest,i))) {
6407 void *def_ptr = parm_table[i].ptr;
6409 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6412 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6415 switch (parm_table[i].type) {
6418 *(bool *)dest_ptr = *(bool *)src_ptr;
6424 *(int *)dest_ptr = *(int *)src_ptr;
6428 *(char *)dest_ptr = *(char *)src_ptr;
6432 string_set((char **)dest_ptr,
6437 string_set((char **)dest_ptr,
6439 strupper_m(*(char **)dest_ptr);
6442 TALLOC_FREE(*((char ***)dest_ptr));
6443 str_list_copy(NULL, (char ***)dest_ptr,
6444 *(const char ***)src_ptr);
6452 init_copymap(pserviceDest);
6453 if (pserviceSource->copymap)
6454 bitmap_copy(pserviceDest->copymap,
6455 pserviceSource->copymap);
6458 data = pserviceSource->param_opt;
6461 pdata = pserviceDest->param_opt;
6462 /* Traverse destination */
6464 /* If we already have same option, override it */
6465 if (strwicmp(pdata->key, data->key) == 0) {
6466 string_free(&pdata->value);
6467 TALLOC_FREE(data->list);
6468 pdata->value = SMB_STRDUP(data->value);
6472 pdata = pdata->next;
6475 paramo = SMB_XMALLOC_P(struct param_opt_struct);
6476 paramo->key = SMB_STRDUP(data->key);
6477 paramo->value = SMB_STRDUP(data->value);
6478 paramo->list = NULL;
6479 DLIST_ADD(pserviceDest->param_opt, paramo);
6485 /***************************************************************************
6486 Check a service for consistency. Return False if the service is in any way
6487 incomplete or faulty, else True.
6488 ***************************************************************************/
6490 bool service_ok(int iService)
6495 if (ServicePtrs[iService]->szService[0] == '\0') {
6496 DEBUG(0, ("The following message indicates an internal error:\n"));
6497 DEBUG(0, ("No service name in service entry.\n"));
6501 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6502 /* I can't see why you'd want a non-printable printer service... */
6503 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6504 if (!ServicePtrs[iService]->bPrint_ok) {
6505 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6506 ServicePtrs[iService]->szService));
6507 ServicePtrs[iService]->bPrint_ok = True;
6509 /* [printers] service must also be non-browsable. */
6510 if (ServicePtrs[iService]->bBrowseable)
6511 ServicePtrs[iService]->bBrowseable = False;
6514 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6515 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6516 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6518 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6519 ServicePtrs[iService]->szService));
6520 ServicePtrs[iService]->bAvailable = False;
6523 /* If a service is flagged unavailable, log the fact at level 1. */
6524 if (!ServicePtrs[iService]->bAvailable)
6525 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6526 ServicePtrs[iService]->szService));
6531 static struct smbconf_ctx *lp_smbconf_ctx(void)
6534 static struct smbconf_ctx *conf_ctx = NULL;
6536 if (conf_ctx == NULL) {
6537 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6538 if (!W_ERROR_IS_OK(werr)) {
6539 DEBUG(1, ("error initializing registry configuration: "
6540 "%s\n", dos_errstr(werr)));
6548 static bool process_registry_service(struct smbconf_service *service)
6553 if (service == NULL) {
6557 ret = do_section(service->name, NULL);
6561 for (count = 0; count < service->num_params; count++) {
6562 ret = do_parameter(service->param_names[count],
6563 service->param_values[count],
6573 * process_registry_globals
6575 static bool process_registry_globals(void)
6578 struct smbconf_service *service = NULL;
6579 TALLOC_CTX *mem_ctx = talloc_stackframe();
6580 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6583 if (conf_ctx == NULL) {
6587 ret = do_parameter("registry shares", "yes", NULL);
6592 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6593 /* nothing to read from the registry yet but make sure lp_load
6594 * doesn't return false */
6599 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6600 if (!W_ERROR_IS_OK(werr)) {
6604 ret = process_registry_service(service);
6610 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6613 TALLOC_FREE(mem_ctx);
6617 static bool process_registry_shares(void)
6621 struct smbconf_service **service = NULL;
6622 uint32_t num_shares = 0;
6623 TALLOC_CTX *mem_ctx = talloc_stackframe();
6624 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6627 if (conf_ctx == NULL) {
6631 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6632 if (!W_ERROR_IS_OK(werr)) {
6638 for (count = 0; count < num_shares; count++) {
6639 if (strequal(service[count]->name, GLOBAL_NAME)) {
6642 ret = process_registry_service(service[count]);
6649 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6652 TALLOC_FREE(mem_ctx);
6656 static struct file_lists {
6657 struct file_lists *next;
6661 } *file_lists = NULL;
6663 /*******************************************************************
6664 Keep a linked list of all config files so we know when one has changed
6665 it's date and needs to be reloaded.
6666 ********************************************************************/
6668 static void add_to_file_list(const char *fname, const char *subfname)
6670 struct file_lists *f = file_lists;
6673 if (f->name && !strcmp(f->name, fname))
6679 f = SMB_MALLOC_P(struct file_lists);
6682 f->next = file_lists;
6683 f->name = SMB_STRDUP(fname);
6688 f->subfname = SMB_STRDUP(subfname);
6694 f->modtime = file_modtime(subfname);
6696 time_t t = file_modtime(subfname);
6703 * Utility function for outsiders to check if we're running on registry.
6705 bool lp_config_backend_is_registry(void)
6707 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6711 * Utility function to check if the config backend is FILE.
6713 bool lp_config_backend_is_file(void)
6715 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6718 /*******************************************************************
6719 Check if a config file has changed date.
6720 ********************************************************************/
6722 bool lp_file_list_changed(void)
6724 struct file_lists *f = file_lists;
6726 DEBUG(6, ("lp_file_list_changed()\n"));
6728 if (lp_config_backend_is_registry()) {
6729 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6731 if (conf_ctx == NULL) {
6734 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6735 DEBUGADD(6, ("registry config changed\n"));
6744 n2 = alloc_sub_basic(get_current_username(),
6745 current_user_info.domain,
6750 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6751 f->name, n2, ctime(&f->modtime)));
6753 mod_time = file_modtime(n2);
6755 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6757 ("file %s modified: %s\n", n2,
6759 f->modtime = mod_time;
6760 SAFE_FREE(f->subfname);
6761 f->subfname = n2; /* Passing ownership of
6762 return from alloc_sub_basic
6773 /***************************************************************************
6774 Run standard_sub_basic on netbios name... needed because global_myname
6775 is not accessed through any lp_ macro.
6776 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6777 ***************************************************************************/
6779 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6782 char *netbios_name = alloc_sub_basic(get_current_username(),
6783 current_user_info.domain,
6786 ret = set_global_myname(netbios_name);
6787 SAFE_FREE(netbios_name);
6788 string_set(&Globals.szNetbiosName,global_myname());
6790 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6796 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6798 if (strcmp(*ptr, pszParmValue) != 0) {
6799 string_set(ptr, pszParmValue);
6807 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6811 ret = set_global_myworkgroup(pszParmValue);
6812 string_set(&Globals.szWorkgroup,lp_workgroup());
6817 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6821 ret = set_global_scope(pszParmValue);
6822 string_set(&Globals.szNetbiosScope,global_scope());
6827 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6829 TALLOC_FREE(Globals.szNetbiosAliases);
6830 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6831 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6834 /***************************************************************************
6835 Handle the include operation.
6836 ***************************************************************************/
6837 static bool bAllowIncludeRegistry = true;
6839 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6843 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6844 if (!bAllowIncludeRegistry) {
6847 if (bInGlobalSection) {
6848 return process_registry_globals();
6850 DEBUG(1, ("\"include = registry\" only effective "
6851 "in %s section\n", GLOBAL_NAME));
6856 fname = alloc_sub_basic(get_current_username(),
6857 current_user_info.domain,
6860 add_to_file_list(pszParmValue, fname);
6862 string_set(ptr, fname);
6864 if (file_exist(fname, NULL)) {
6865 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6870 DEBUG(2, ("Can't find include file %s\n", fname));
6875 /***************************************************************************
6876 Handle the interpretation of the copy parameter.
6877 ***************************************************************************/
6879 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6883 struct service serviceTemp;
6885 string_set(ptr, pszParmValue);
6887 init_service(&serviceTemp);
6891 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6893 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6894 if (iTemp == iServiceIndex) {
6895 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6897 copy_service(ServicePtrs[iServiceIndex],
6899 ServicePtrs[iServiceIndex]->copymap);
6903 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6907 free_service(&serviceTemp);
6911 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6913 Globals.ldap_debug_level = lp_int(pszParmValue);
6914 init_ldap_debugging();
6918 /***************************************************************************
6919 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6924 idmap uid = 1000-1999
6927 We only do simple parsing checks here. The strings are parsed into useful
6928 structures in the idmap daemon code.
6930 ***************************************************************************/
6932 /* Some lp_ routines to return idmap [ug]id information */
6934 static uid_t idmap_uid_low, idmap_uid_high;
6935 static gid_t idmap_gid_low, idmap_gid_high;
6937 bool lp_idmap_uid(uid_t *low, uid_t *high)
6939 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6943 *low = idmap_uid_low;
6946 *high = idmap_uid_high;
6951 bool lp_idmap_gid(gid_t *low, gid_t *high)
6953 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6957 *low = idmap_gid_low;
6960 *high = idmap_gid_high;
6965 /* Do some simple checks on "idmap [ug]id" parameter values */
6967 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6971 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6976 string_set(ptr, pszParmValue);
6978 idmap_uid_low = low;
6979 idmap_uid_high = high;
6984 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6988 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6993 string_set(ptr, pszParmValue);
6995 idmap_gid_low = low;
6996 idmap_gid_high = high;
7001 /***************************************************************************
7002 Handle the DEBUG level list.
7003 ***************************************************************************/
7005 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7007 string_set(ptr, pszParmValueIn);
7008 return debug_parse_levels(pszParmValueIn);
7011 /***************************************************************************
7012 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7013 ***************************************************************************/
7015 static const char *append_ldap_suffix( const char *str )
7017 const char *suffix_string;
7020 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7021 Globals.szLdapSuffix );
7022 if ( !suffix_string ) {
7023 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7027 return suffix_string;
7030 const char *lp_ldap_machine_suffix(void)
7032 if (Globals.szLdapMachineSuffix[0])
7033 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7035 return lp_string(Globals.szLdapSuffix);
7038 const char *lp_ldap_user_suffix(void)
7040 if (Globals.szLdapUserSuffix[0])
7041 return append_ldap_suffix(Globals.szLdapUserSuffix);
7043 return lp_string(Globals.szLdapSuffix);
7046 const char *lp_ldap_group_suffix(void)
7048 if (Globals.szLdapGroupSuffix[0])
7049 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7051 return lp_string(Globals.szLdapSuffix);
7054 const char *lp_ldap_idmap_suffix(void)
7056 if (Globals.szLdapIdmapSuffix[0])
7057 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7059 return lp_string(Globals.szLdapSuffix);
7062 /****************************************************************************
7063 set the value for a P_ENUM
7064 ***************************************************************************/
7066 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7071 for (i = 0; parm->enum_list[i].name; i++) {
7072 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7073 *ptr = parm->enum_list[i].value;
7077 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7078 pszParmValue, parm->label));
7081 /***************************************************************************
7082 ***************************************************************************/
7084 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7086 static int parm_num = -1;
7089 if ( parm_num == -1 )
7090 parm_num = map_parameter( "printing" );
7092 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7097 s = ServicePtrs[snum];
7099 init_printer_values( s );
7105 /***************************************************************************
7106 Initialise a copymap.
7107 ***************************************************************************/
7109 static void init_copymap(struct service *pservice)
7112 if (pservice->copymap) {
7113 bitmap_free(pservice->copymap);
7115 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7116 if (!pservice->copymap)
7118 ("Couldn't allocate copymap!! (size %d)\n",
7119 (int)NUMPARAMETERS));
7121 for (i = 0; i < NUMPARAMETERS; i++)
7122 bitmap_set(pservice->copymap, i);
7125 /***************************************************************************
7126 Return the local pointer to a parameter given the service number and the
7127 pointer into the default structure.
7128 ***************************************************************************/
7130 void *lp_local_ptr(int snum, void *ptr)
7132 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7135 /***************************************************************************
7136 Process a parameter for a particular service number. If snum < 0
7137 then assume we are in the globals.
7138 ***************************************************************************/
7140 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7143 void *parm_ptr = NULL; /* where we are going to store the result */
7144 void *def_ptr = NULL;
7145 struct param_opt_struct *paramo, *data;
7148 parmnum = map_parameter(pszParmName);
7153 if (strchr(pszParmName, ':') == NULL) {
7154 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7160 * We've got a parametric option
7163 frame = talloc_stackframe();
7167 ? Globals.param_opt : ServicePtrs[snum]->param_opt;
7168 /* Traverse destination */
7170 /* If we already have same option, override it */
7171 if (strwicmp(data->key, pszParmName) == 0) {
7172 string_free(&data->value);
7173 TALLOC_FREE(data->list);
7174 data->value = SMB_STRDUP(pszParmValue);
7181 paramo = SMB_XMALLOC_P(struct param_opt_struct);
7182 paramo->key = SMB_STRDUP(pszParmName);
7183 paramo->value = SMB_STRDUP(pszParmValue);
7184 paramo->list = NULL;
7186 DLIST_ADD(Globals.param_opt, paramo);
7188 DLIST_ADD(ServicePtrs[snum]->param_opt,
7197 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7198 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7202 def_ptr = parm_table[parmnum].ptr;
7204 /* we might point at a service, the default service or a global */
7208 if (parm_table[parmnum].p_class == P_GLOBAL) {
7210 ("Global parameter %s found in service section!\n",
7215 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7220 if (!ServicePtrs[snum]->copymap)
7221 init_copymap(ServicePtrs[snum]);
7223 /* this handles the aliases - set the copymap for other entries with
7224 the same data pointer */
7225 for (i = 0; parm_table[i].label; i++)
7226 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7227 bitmap_clear(ServicePtrs[snum]->copymap, i);
7230 /* if it is a special case then go ahead */
7231 if (parm_table[parmnum].special) {
7232 return parm_table[parmnum].special(snum, pszParmValue,
7236 /* now switch on the type of variable it is */
7237 switch (parm_table[parmnum].type)
7240 *(bool *)parm_ptr = lp_bool(pszParmValue);
7244 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7248 *(int *)parm_ptr = lp_int(pszParmValue);
7252 *(char *)parm_ptr = *pszParmValue;
7256 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7258 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7263 TALLOC_FREE(*((char ***)parm_ptr));
7264 *(char ***)parm_ptr = str_list_make(
7265 NULL, pszParmValue, NULL);
7269 string_set((char **)parm_ptr, pszParmValue);
7273 string_set((char **)parm_ptr, pszParmValue);
7274 strupper_m(*(char **)parm_ptr);
7278 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7287 /***************************************************************************
7288 Process a parameter.
7289 ***************************************************************************/
7291 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7294 if (!bInGlobalSection && bGlobalOnly)
7297 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7299 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7300 pszParmName, pszParmValue));
7303 /***************************************************************************
7304 Print a parameter of the specified type.
7305 ***************************************************************************/
7307 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7313 for (i = 0; p->enum_list[i].name; i++) {
7314 if (*(int *)ptr == p->enum_list[i].value) {
7316 p->enum_list[i].name);
7323 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7327 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7331 fprintf(f, "%d", *(int *)ptr);
7335 fprintf(f, "%c", *(char *)ptr);
7339 char *o = octal_string(*(int *)ptr);
7340 fprintf(f, "%s", o);
7346 if ((char ***)ptr && *(char ***)ptr) {
7347 char **list = *(char ***)ptr;
7348 for (; *list; list++) {
7349 /* surround strings with whitespace in double quotes */
7350 if ( strchr_m( *list, ' ' ) )
7351 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7353 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7360 if (*(char **)ptr) {
7361 fprintf(f, "%s", *(char **)ptr);
7369 /***************************************************************************
7370 Check if two parameters are equal.
7371 ***************************************************************************/
7373 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7378 return (*((bool *)ptr1) == *((bool *)ptr2));
7383 return (*((int *)ptr1) == *((int *)ptr2));
7386 return (*((char *)ptr1) == *((char *)ptr2));
7389 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7394 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7399 return (p1 == p2 || strequal(p1, p2));
7407 /***************************************************************************
7408 Initialize any local varients in the sDefault table.
7409 ***************************************************************************/
7411 void init_locals(void)
7416 /***************************************************************************
7417 Process a new section (service). At this stage all sections are services.
7418 Later we'll have special sections that permit server parameters to be set.
7419 Returns True on success, False on failure.
7420 ***************************************************************************/
7422 static bool do_section(const char *pszSectionName, void *userdata)
7425 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7426 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7429 /* if we were in a global section then do the local inits */
7430 if (bInGlobalSection && !isglobal)
7433 /* if we've just struck a global section, note the fact. */
7434 bInGlobalSection = isglobal;
7436 /* check for multiple global sections */
7437 if (bInGlobalSection) {
7438 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7442 if (!bInGlobalSection && bGlobalOnly)
7445 /* if we have a current service, tidy it up before moving on */
7448 if (iServiceIndex >= 0)
7449 bRetval = service_ok(iServiceIndex);
7451 /* if all is still well, move to the next record in the services array */
7453 /* We put this here to avoid an odd message order if messages are */
7454 /* issued by the post-processing of a previous section. */
7455 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7457 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7459 DEBUG(0, ("Failed to add a new service\n"));
7468 /***************************************************************************
7469 Determine if a partcular base parameter is currentl set to the default value.
7470 ***************************************************************************/
7472 static bool is_default(int i)
7474 if (!defaults_saved)
7476 switch (parm_table[i].type) {
7478 return str_list_compare (parm_table[i].def.lvalue,
7479 *(char ***)parm_table[i].ptr);
7482 return strequal(parm_table[i].def.svalue,
7483 *(char **)parm_table[i].ptr);
7486 return parm_table[i].def.bvalue ==
7487 *(bool *)parm_table[i].ptr;
7489 return parm_table[i].def.cvalue ==
7490 *(char *)parm_table[i].ptr;
7494 return parm_table[i].def.ivalue ==
7495 *(int *)parm_table[i].ptr;
7502 /***************************************************************************
7503 Display the contents of the global structure.
7504 ***************************************************************************/
7506 static void dump_globals(FILE *f)
7509 struct param_opt_struct *data;
7511 fprintf(f, "[global]\n");
7513 for (i = 0; parm_table[i].label; i++)
7514 if (parm_table[i].p_class == P_GLOBAL &&
7515 parm_table[i].ptr &&
7516 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7517 if (defaults_saved && is_default(i))
7519 fprintf(f, "\t%s = ", parm_table[i].label);
7520 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7523 if (Globals.param_opt != NULL) {
7524 data = Globals.param_opt;
7526 fprintf(f, "\t%s = %s\n", data->key, data->value);
7533 /***************************************************************************
7534 Return True if a local parameter is currently set to the global default.
7535 ***************************************************************************/
7537 bool lp_is_default(int snum, struct parm_struct *parm)
7539 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7541 return equal_parameter(parm->type,
7542 ((char *)ServicePtrs[snum]) + pdiff,
7543 ((char *)&sDefault) + pdiff);
7546 /***************************************************************************
7547 Display the contents of a single services record.
7548 ***************************************************************************/
7550 static void dump_a_service(struct service *pService, FILE * f)
7553 struct param_opt_struct *data;
7555 if (pService != &sDefault)
7556 fprintf(f, "[%s]\n", pService->szService);
7558 for (i = 0; parm_table[i].label; i++) {
7560 if (parm_table[i].p_class == P_LOCAL &&
7561 parm_table[i].ptr &&
7562 (*parm_table[i].label != '-') &&
7563 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7566 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7568 if (pService == &sDefault) {
7569 if (defaults_saved && is_default(i))
7572 if (equal_parameter(parm_table[i].type,
7573 ((char *)pService) +
7575 ((char *)&sDefault) +
7580 fprintf(f, "\t%s = ", parm_table[i].label);
7581 print_parameter(&parm_table[i],
7582 ((char *)pService) + pdiff, f);
7587 if (pService->param_opt != NULL) {
7588 data = pService->param_opt;
7590 fprintf(f, "\t%s = %s\n", data->key, data->value);
7596 /***************************************************************************
7597 Display the contents of a parameter of a single services record.
7598 ***************************************************************************/
7600 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7603 bool result = False;
7606 fstring local_parm_name;
7608 const char *parm_opt_value;
7610 /* check for parametrical option */
7611 fstrcpy( local_parm_name, parm_name);
7612 parm_opt = strchr( local_parm_name, ':');
7617 if (strlen(parm_opt)) {
7618 parm_opt_value = lp_parm_const_string( snum,
7619 local_parm_name, parm_opt, NULL);
7620 if (parm_opt_value) {
7621 printf( "%s\n", parm_opt_value);
7628 /* check for a key and print the value */
7635 for (i = 0; parm_table[i].label; i++) {
7636 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7637 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7638 parm_table[i].ptr &&
7639 (*parm_table[i].label != '-') &&
7640 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7645 ptr = parm_table[i].ptr;
7647 struct service *pService = ServicePtrs[snum];
7648 ptr = ((char *)pService) +
7649 PTR_DIFF(parm_table[i].ptr, &sDefault);
7652 print_parameter(&parm_table[i],
7663 /***************************************************************************
7664 Return info about the requested parameter (given as a string).
7665 Return NULL when the string is not a valid parameter name.
7666 ***************************************************************************/
7668 struct parm_struct *lp_get_parameter(const char *param_name)
7670 int num = map_parameter(param_name);
7676 return &parm_table[num];
7679 /***************************************************************************
7680 Return info about the next parameter in a service.
7681 snum==GLOBAL_SECTION_SNUM gives the globals.
7682 Return NULL when out of parameters.
7683 ***************************************************************************/
7685 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7688 /* do the globals */
7689 for (; parm_table[*i].label; (*i)++) {
7690 if (parm_table[*i].p_class == P_SEPARATOR)
7691 return &parm_table[(*i)++];
7693 if (!parm_table[*i].ptr
7694 || (*parm_table[*i].label == '-'))
7698 && (parm_table[*i].ptr ==
7699 parm_table[(*i) - 1].ptr))
7702 if (is_default(*i) && !allparameters)
7705 return &parm_table[(*i)++];
7708 struct service *pService = ServicePtrs[snum];
7710 for (; parm_table[*i].label; (*i)++) {
7711 if (parm_table[*i].p_class == P_SEPARATOR)
7712 return &parm_table[(*i)++];
7714 if (parm_table[*i].p_class == P_LOCAL &&
7715 parm_table[*i].ptr &&
7716 (*parm_table[*i].label != '-') &&
7718 (parm_table[*i].ptr !=
7719 parm_table[(*i) - 1].ptr)))
7722 PTR_DIFF(parm_table[*i].ptr,
7725 if (allparameters ||
7726 !equal_parameter(parm_table[*i].type,
7727 ((char *)pService) +
7729 ((char *)&sDefault) +
7732 return &parm_table[(*i)++];
7743 /***************************************************************************
7744 Display the contents of a single copy structure.
7745 ***************************************************************************/
7746 static void dump_copy_map(bool *pcopymap)
7752 printf("\n\tNon-Copied parameters:\n");
7754 for (i = 0; parm_table[i].label; i++)
7755 if (parm_table[i].p_class == P_LOCAL &&
7756 parm_table[i].ptr && !pcopymap[i] &&
7757 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7759 printf("\t\t%s\n", parm_table[i].label);
7764 /***************************************************************************
7765 Return TRUE if the passed service number is within range.
7766 ***************************************************************************/
7768 bool lp_snum_ok(int iService)
7770 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7773 /***************************************************************************
7774 Auto-load some home services.
7775 ***************************************************************************/
7777 static void lp_add_auto_services(char *str)
7787 s = SMB_STRDUP(str);
7791 homes = lp_servicenumber(HOMES_NAME);
7793 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7794 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7797 if (lp_servicenumber(p) >= 0)
7800 home = get_user_home_dir(talloc_tos(), p);
7802 if (home && homes >= 0)
7803 lp_add_home(p, homes, p, home);
7810 /***************************************************************************
7811 Auto-load one printer.
7812 ***************************************************************************/
7814 void lp_add_one_printer(char *name, char *comment)
7816 int printers = lp_servicenumber(PRINTERS_NAME);
7819 if (lp_servicenumber(name) < 0) {
7820 lp_add_printer(name, printers);
7821 if ((i = lp_servicenumber(name)) >= 0) {
7822 string_set(&ServicePtrs[i]->comment, comment);
7823 ServicePtrs[i]->autoloaded = True;
7828 /***************************************************************************
7829 Have we loaded a services file yet?
7830 ***************************************************************************/
7832 bool lp_loaded(void)
7837 /***************************************************************************
7838 Unload unused services.
7839 ***************************************************************************/
7841 void lp_killunused(bool (*snumused) (int))
7844 for (i = 0; i < iNumServices; i++) {
7848 /* don't kill autoloaded or usershare services */
7849 if ( ServicePtrs[i]->autoloaded ||
7850 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7854 if (!snumused || !snumused(i)) {
7855 free_service_byindex(i);
7861 * Kill all except autoloaded and usershare services - convenience wrapper
7863 void lp_kill_all_services(void)
7865 lp_killunused(NULL);
7868 /***************************************************************************
7870 ***************************************************************************/
7872 void lp_killservice(int iServiceIn)
7874 if (VALID(iServiceIn)) {
7875 free_service_byindex(iServiceIn);
7879 /***************************************************************************
7880 Save the curent values of all global and sDefault parameters into the
7881 defaults union. This allows swat and testparm to show only the
7882 changed (ie. non-default) parameters.
7883 ***************************************************************************/
7885 static void lp_save_defaults(void)
7888 for (i = 0; parm_table[i].label; i++) {
7889 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7891 switch (parm_table[i].type) {
7894 NULL, &(parm_table[i].def.lvalue),
7895 *(const char ***)parm_table[i].ptr);
7899 if (parm_table[i].ptr) {
7900 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7902 parm_table[i].def.svalue = NULL;
7907 parm_table[i].def.bvalue =
7908 *(bool *)parm_table[i].ptr;
7911 parm_table[i].def.cvalue =
7912 *(char *)parm_table[i].ptr;
7917 parm_table[i].def.ivalue =
7918 *(int *)parm_table[i].ptr;
7924 defaults_saved = True;
7927 /*******************************************************************
7928 Set the server type we will announce as via nmbd.
7929 ********************************************************************/
7931 static const struct srv_role_tab {
7933 const char *role_str;
7934 } srv_role_tab [] = {
7935 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7936 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7937 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7938 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7942 const char* server_role_str(uint32 role)
7945 for (i=0; srv_role_tab[i].role_str; i++) {
7946 if (role == srv_role_tab[i].role) {
7947 return srv_role_tab[i].role_str;
7953 static void set_server_role(void)
7955 server_role = ROLE_STANDALONE;
7957 switch (lp_security()) {
7959 if (lp_domain_logons())
7960 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7963 if (lp_domain_logons())
7964 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7965 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7966 server_role = ROLE_STANDALONE;
7969 if (lp_domain_logons()) {
7970 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7971 server_role = ROLE_DOMAIN_BDC;
7974 server_role = ROLE_DOMAIN_MEMBER;
7977 if (lp_domain_logons()) {
7978 server_role = ROLE_DOMAIN_PDC;
7981 server_role = ROLE_DOMAIN_MEMBER;
7984 if (lp_domain_logons()) {
7986 if (Globals.iDomainMaster) /* auto or yes */
7987 server_role = ROLE_DOMAIN_PDC;
7989 server_role = ROLE_DOMAIN_BDC;
7993 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7997 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8000 /***********************************************************
8001 If we should send plaintext/LANMAN passwords in the clinet
8002 ************************************************************/
8004 static void set_allowed_client_auth(void)
8006 if (Globals.bClientNTLMv2Auth) {
8007 Globals.bClientLanManAuth = False;
8009 if (!Globals.bClientLanManAuth) {
8010 Globals.bClientPlaintextAuth = False;
8014 /***************************************************************************
8016 The following code allows smbd to read a user defined share file.
8017 Yes, this is my intent. Yes, I'm comfortable with that...
8019 THE FOLLOWING IS SECURITY CRITICAL CODE.
8021 It washes your clothes, it cleans your house, it guards you while you sleep...
8022 Do not f%^k with it....
8023 ***************************************************************************/
8025 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8027 /***************************************************************************
8028 Check allowed stat state of a usershare file.
8029 Ensure we print out who is dicking with us so the admin can
8030 get their sorry ass fired.
8031 ***************************************************************************/
8033 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8035 if (!S_ISREG(psbuf->st_mode)) {
8036 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8037 "not a regular file\n",
8038 fname, (unsigned int)psbuf->st_uid ));
8042 /* Ensure this doesn't have the other write bit set. */
8043 if (psbuf->st_mode & S_IWOTH) {
8044 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8045 "public write. Refusing to allow as a usershare file.\n",
8046 fname, (unsigned int)psbuf->st_uid ));
8050 /* Should be 10k or less. */
8051 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8052 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8053 "too large (%u) to be a user share file.\n",
8054 fname, (unsigned int)psbuf->st_uid,
8055 (unsigned int)psbuf->st_size ));
8062 /***************************************************************************
8063 Parse the contents of a usershare file.
8064 ***************************************************************************/
8066 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8067 SMB_STRUCT_STAT *psbuf,
8068 const char *servicename,
8072 char **pp_sharepath,
8077 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8078 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8081 SMB_STRUCT_STAT sbuf;
8082 char *sharepath = NULL;
8083 char *comment = NULL;
8085 *pp_sharepath = NULL;
8088 *pallow_guest = False;
8091 return USERSHARE_MALFORMED_FILE;
8094 if (strcmp(lines[0], "#VERSION 1") == 0) {
8096 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8099 return USERSHARE_MALFORMED_FILE;
8102 return USERSHARE_BAD_VERSION;
8105 if (strncmp(lines[1], "path=", 5) != 0) {
8106 return USERSHARE_MALFORMED_PATH;
8109 sharepath = talloc_strdup(ctx, &lines[1][5]);
8111 return USERSHARE_POSIX_ERR;
8113 trim_string(sharepath, " ", " ");
8115 if (strncmp(lines[2], "comment=", 8) != 0) {
8116 return USERSHARE_MALFORMED_COMMENT_DEF;
8119 comment = talloc_strdup(ctx, &lines[2][8]);
8121 return USERSHARE_POSIX_ERR;
8123 trim_string(comment, " ", " ");
8124 trim_char(comment, '"', '"');
8126 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8127 return USERSHARE_MALFORMED_ACL_DEF;
8130 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8131 return USERSHARE_ACL_ERR;
8135 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8136 return USERSHARE_MALFORMED_ACL_DEF;
8138 if (lines[4][9] == 'y') {
8139 *pallow_guest = True;
8143 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8144 /* Path didn't change, no checks needed. */
8145 *pp_sharepath = sharepath;
8146 *pp_comment = comment;
8147 return USERSHARE_OK;
8150 /* The path *must* be absolute. */
8151 if (sharepath[0] != '/') {
8152 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8153 servicename, sharepath));
8154 return USERSHARE_PATH_NOT_ABSOLUTE;
8157 /* If there is a usershare prefix deny list ensure one of these paths
8158 doesn't match the start of the user given path. */
8159 if (prefixdenylist) {
8161 for ( i=0; prefixdenylist[i]; i++ ) {
8162 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8163 servicename, i, prefixdenylist[i], sharepath ));
8164 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8165 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8166 "usershare prefix deny list entries.\n",
8167 servicename, sharepath));
8168 return USERSHARE_PATH_IS_DENIED;
8173 /* If there is a usershare prefix allow list ensure one of these paths
8174 does match the start of the user given path. */
8176 if (prefixallowlist) {
8178 for ( i=0; prefixallowlist[i]; i++ ) {
8179 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8180 servicename, i, prefixallowlist[i], sharepath ));
8181 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8185 if (prefixallowlist[i] == NULL) {
8186 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8187 "usershare prefix allow list entries.\n",
8188 servicename, sharepath));
8189 return USERSHARE_PATH_NOT_ALLOWED;
8193 /* Ensure this is pointing to a directory. */
8194 dp = sys_opendir(sharepath);
8197 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8198 servicename, sharepath));
8199 return USERSHARE_PATH_NOT_DIRECTORY;
8202 /* Ensure the owner of the usershare file has permission to share
8205 if (sys_stat(sharepath, &sbuf) == -1) {
8206 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8207 servicename, sharepath, strerror(errno) ));
8209 return USERSHARE_POSIX_ERR;
8214 if (!S_ISDIR(sbuf.st_mode)) {
8215 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8216 servicename, sharepath ));
8217 return USERSHARE_PATH_NOT_DIRECTORY;
8220 /* Check if sharing is restricted to owner-only. */
8221 /* psbuf is the stat of the usershare definition file,
8222 sbuf is the stat of the target directory to be shared. */
8224 if (lp_usershare_owner_only()) {
8225 /* root can share anything. */
8226 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8227 return USERSHARE_PATH_NOT_ALLOWED;
8231 *pp_sharepath = sharepath;
8232 *pp_comment = comment;
8233 return USERSHARE_OK;
8236 /***************************************************************************
8237 Deal with a usershare file.
8240 -1 - Bad name, invalid contents.
8241 - service name already existed and not a usershare, problem
8242 with permissions to share directory etc.
8243 ***************************************************************************/
8245 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8247 SMB_STRUCT_STAT sbuf;
8248 SMB_STRUCT_STAT lsbuf;
8250 char *sharepath = NULL;
8251 char *comment = NULL;
8252 fstring service_name;
8253 char **lines = NULL;
8257 TALLOC_CTX *ctx = NULL;
8258 SEC_DESC *psd = NULL;
8259 bool guest_ok = False;
8261 /* Ensure share name doesn't contain invalid characters. */
8262 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8263 DEBUG(0,("process_usershare_file: share name %s contains "
8264 "invalid characters (any of %s)\n",
8265 file_name, INVALID_SHARENAME_CHARS ));
8269 fstrcpy(service_name, file_name);
8271 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8274 /* Minimize the race condition by doing an lstat before we
8275 open and fstat. Ensure this isn't a symlink link. */
8277 if (sys_lstat(fname, &lsbuf) != 0) {
8278 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8279 fname, strerror(errno) ));
8284 /* This must be a regular file, not a symlink, directory or
8285 other strange filetype. */
8286 if (!check_usershare_stat(fname, &lsbuf)) {
8292 char *canon_name = canonicalize_servicename(service_name);
8293 TDB_DATA data = dbwrap_fetch_bystring(
8294 ServiceHash, canon_name, canon_name);
8298 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8299 iService = *(int *)data.dptr;
8301 TALLOC_FREE(canon_name);
8304 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8305 /* Nothing changed - Mark valid and return. */
8306 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8308 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8313 /* Try and open the file read only - no symlinks allowed. */
8315 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8317 fd = sys_open(fname, O_RDONLY, 0);
8321 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8322 fname, strerror(errno) ));
8327 /* Now fstat to be *SURE* it's a regular file. */
8328 if (sys_fstat(fd, &sbuf) != 0) {
8330 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8331 fname, strerror(errno) ));
8336 /* Is it the same dev/inode as was lstated ? */
8337 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8339 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8340 "Symlink spoofing going on ?\n", fname ));
8345 /* This must be a regular file, not a symlink, directory or
8346 other strange filetype. */
8347 if (!check_usershare_stat(fname, &sbuf)) {
8352 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8355 if (lines == NULL) {
8356 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8357 fname, (unsigned int)sbuf.st_uid ));
8364 /* Should we allow printers to be shared... ? */
8365 ctx = talloc_init("usershare_sd_xctx");
8367 file_lines_free(lines);
8371 if (parse_usershare_file(ctx, &sbuf, service_name,
8372 iService, lines, numlines, &sharepath,
8373 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8374 talloc_destroy(ctx);
8375 file_lines_free(lines);
8379 file_lines_free(lines);
8381 /* Everything ok - add the service possibly using a template. */
8383 const struct service *sp = &sDefault;
8384 if (snum_template != -1) {
8385 sp = ServicePtrs[snum_template];
8388 if ((iService = add_a_service(sp, service_name)) < 0) {
8389 DEBUG(0, ("process_usershare_file: Failed to add "
8390 "new service %s\n", service_name));
8391 talloc_destroy(ctx);
8395 /* Read only is controlled by usershare ACL below. */
8396 ServicePtrs[iService]->bRead_only = False;
8399 /* Write the ACL of the new/modified share. */
8400 if (!set_share_security(service_name, psd)) {
8401 DEBUG(0, ("process_usershare_file: Failed to set share "
8402 "security for user share %s\n",
8404 lp_remove_service(iService);
8405 talloc_destroy(ctx);
8409 /* If from a template it may be marked invalid. */
8410 ServicePtrs[iService]->valid = True;
8412 /* Set the service as a valid usershare. */
8413 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8415 /* Set guest access. */
8416 if (lp_usershare_allow_guests()) {
8417 ServicePtrs[iService]->bGuest_ok = guest_ok;
8420 /* And note when it was loaded. */
8421 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8422 string_set(&ServicePtrs[iService]->szPath, sharepath);
8423 string_set(&ServicePtrs[iService]->comment, comment);
8425 talloc_destroy(ctx);
8430 /***************************************************************************
8431 Checks if a usershare entry has been modified since last load.
8432 ***************************************************************************/
8434 static bool usershare_exists(int iService, time_t *last_mod)
8436 SMB_STRUCT_STAT lsbuf;
8437 const char *usersharepath = Globals.szUsersharePath;
8440 if (asprintf(&fname, "%s/%s",
8442 ServicePtrs[iService]->szService) < 0) {
8446 if (sys_lstat(fname, &lsbuf) != 0) {
8451 if (!S_ISREG(lsbuf.st_mode)) {
8457 *last_mod = lsbuf.st_mtime;
8461 /***************************************************************************
8462 Load a usershare service by name. Returns a valid servicenumber or -1.
8463 ***************************************************************************/
8465 int load_usershare_service(const char *servicename)
8467 SMB_STRUCT_STAT sbuf;
8468 const char *usersharepath = Globals.szUsersharePath;
8469 int max_user_shares = Globals.iUsershareMaxShares;
8470 int snum_template = -1;
8472 if (*usersharepath == 0 || max_user_shares == 0) {
8476 if (sys_stat(usersharepath, &sbuf) != 0) {
8477 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8478 usersharepath, strerror(errno) ));
8482 if (!S_ISDIR(sbuf.st_mode)) {
8483 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8489 * This directory must be owned by root, and have the 't' bit set.
8490 * It also must not be writable by "other".
8494 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8496 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8498 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8499 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8504 /* Ensure the template share exists if it's set. */
8505 if (Globals.szUsershareTemplateShare[0]) {
8506 /* We can't use lp_servicenumber here as we are recommending that
8507 template shares have -valid=False set. */
8508 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8509 if (ServicePtrs[snum_template]->szService &&
8510 strequal(ServicePtrs[snum_template]->szService,
8511 Globals.szUsershareTemplateShare)) {
8516 if (snum_template == -1) {
8517 DEBUG(0,("load_usershare_service: usershare template share %s "
8518 "does not exist.\n",
8519 Globals.szUsershareTemplateShare ));
8524 return process_usershare_file(usersharepath, servicename, snum_template);
8527 /***************************************************************************
8528 Load all user defined shares from the user share directory.
8529 We only do this if we're enumerating the share list.
8530 This is the function that can delete usershares that have
8532 ***************************************************************************/
8534 int load_usershare_shares(void)
8537 SMB_STRUCT_STAT sbuf;
8538 SMB_STRUCT_DIRENT *de;
8539 int num_usershares = 0;
8540 int max_user_shares = Globals.iUsershareMaxShares;
8541 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8542 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8543 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8545 int snum_template = -1;
8546 const char *usersharepath = Globals.szUsersharePath;
8547 int ret = lp_numservices();
8549 if (max_user_shares == 0 || *usersharepath == '\0') {
8550 return lp_numservices();
8553 if (sys_stat(usersharepath, &sbuf) != 0) {
8554 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8555 usersharepath, strerror(errno) ));
8560 * This directory must be owned by root, and have the 't' bit set.
8561 * It also must not be writable by "other".
8565 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8567 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8569 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8570 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8575 /* Ensure the template share exists if it's set. */
8576 if (Globals.szUsershareTemplateShare[0]) {
8577 /* We can't use lp_servicenumber here as we are recommending that
8578 template shares have -valid=False set. */
8579 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8580 if (ServicePtrs[snum_template]->szService &&
8581 strequal(ServicePtrs[snum_template]->szService,
8582 Globals.szUsershareTemplateShare)) {
8587 if (snum_template == -1) {
8588 DEBUG(0,("load_usershare_shares: usershare template share %s "
8589 "does not exist.\n",
8590 Globals.szUsershareTemplateShare ));
8595 /* Mark all existing usershares as pending delete. */
8596 for (iService = iNumServices - 1; iService >= 0; iService--) {
8597 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8598 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8602 dp = sys_opendir(usersharepath);
8604 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8605 usersharepath, strerror(errno) ));
8609 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8610 (de = sys_readdir(dp));
8611 num_dir_entries++ ) {
8613 const char *n = de->d_name;
8615 /* Ignore . and .. */
8617 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8623 /* Temporary file used when creating a share. */
8624 num_tmp_dir_entries++;
8627 /* Allow 20% tmp entries. */
8628 if (num_tmp_dir_entries > allowed_tmp_entries) {
8629 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8630 "in directory %s\n",
8631 num_tmp_dir_entries, usersharepath));
8635 r = process_usershare_file(usersharepath, n, snum_template);
8637 /* Update the services count. */
8639 if (num_usershares >= max_user_shares) {
8640 DEBUG(0,("load_usershare_shares: max user shares reached "
8641 "on file %s in directory %s\n",
8642 n, usersharepath ));
8645 } else if (r == -1) {
8646 num_bad_dir_entries++;
8649 /* Allow 20% bad entries. */
8650 if (num_bad_dir_entries > allowed_bad_entries) {
8651 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8652 "in directory %s\n",
8653 num_bad_dir_entries, usersharepath));
8657 /* Allow 20% bad entries. */
8658 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8659 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8660 "in directory %s\n",
8661 num_dir_entries, usersharepath));
8668 /* Sweep through and delete any non-refreshed usershares that are
8669 not currently in use. */
8670 for (iService = iNumServices - 1; iService >= 0; iService--) {
8671 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8672 if (conn_snum_used(iService)) {
8675 /* Remove from the share ACL db. */
8676 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8677 lp_servicename(iService) ));
8678 delete_share_security(lp_servicename(iService));
8679 free_service_byindex(iService);
8683 return lp_numservices();
8686 /********************************************************
8687 Destroy global resources allocated in this file
8688 ********************************************************/
8690 void gfree_loadparm(void)
8692 struct file_lists *f;
8693 struct file_lists *next;
8696 /* Free the file lists */
8701 SAFE_FREE( f->name );
8702 SAFE_FREE( f->subfname );
8707 /* Free resources allocated to services */
8709 for ( i = 0; i < iNumServices; i++ ) {
8711 free_service_byindex(i);
8715 SAFE_FREE( ServicePtrs );
8718 /* Now release all resources allocated to global
8719 parameters and the default service */
8721 for (i = 0; parm_table[i].label; i++)
8723 if ( parm_table[i].type == P_STRING
8724 || parm_table[i].type == P_USTRING )
8726 string_free( (char**)parm_table[i].ptr );
8728 else if (parm_table[i].type == P_LIST) {
8729 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8735 /***************************************************************************
8736 Allow client apps to specify that they are a client
8737 ***************************************************************************/
8738 void lp_set_in_client(bool b)
8744 /***************************************************************************
8745 Determine if we're running in a client app
8746 ***************************************************************************/
8747 bool lp_is_in_client(void)
8755 /***************************************************************************
8756 Load the services array from the services file. Return True on success,
8758 ***************************************************************************/
8760 bool lp_load_ex(const char *pszFname,
8764 bool initialize_globals,
8765 bool allow_include_registry,
8766 bool allow_registry_shares)
8770 struct param_opt_struct *data, *pdata;
8774 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8776 bInGlobalSection = True;
8777 bGlobalOnly = global_only;
8778 bAllowIncludeRegistry = allow_include_registry;
8780 init_globals(! initialize_globals);
8783 if (save_defaults) {
8788 /* We get sections first, so have to start 'behind' to make up */
8791 if (Globals.param_opt != NULL) {
8792 data = Globals.param_opt;
8794 string_free(&data->key);
8795 string_free(&data->value);
8796 TALLOC_FREE(data->list);
8801 Globals.param_opt = NULL;
8804 if (lp_config_backend_is_file()) {
8805 n2 = alloc_sub_basic(get_current_username(),
8806 current_user_info.domain,
8809 smb_panic("lp_load_ex: out of memory");
8812 add_to_file_list(pszFname, n2);
8814 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8817 /* finish up the last section */
8818 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8820 if (iServiceIndex >= 0) {
8821 bRetval = service_ok(iServiceIndex);
8825 if (lp_config_backend_is_registry()) {
8826 /* config backend changed to registry in config file */
8828 * We need to use this extra global variable here to
8829 * survive restart: init_globals uses this as a default
8830 * for ConfigBackend. Otherwise, init_globals would
8831 * send us into an endless loop here.
8833 config_backend = CONFIG_BACKEND_REGISTRY;
8835 DEBUG(1, ("lp_load_ex: changing to config backend "
8837 init_globals(false);
8838 lp_kill_all_services();
8839 return lp_load_ex(pszFname, global_only, save_defaults,
8840 add_ipc, initialize_globals,
8841 allow_include_registry,
8842 allow_registry_shares);
8844 } else if (lp_config_backend_is_registry()) {
8845 bRetval = process_registry_globals();
8847 DEBUG(0, ("Illegal config backend given: %d\n",
8848 lp_config_backend()));
8852 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8853 bRetval = process_registry_shares();
8856 lp_add_auto_services(lp_auto_services());
8859 /* When 'restrict anonymous = 2' guest connections to ipc$
8861 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8862 if ( lp_enable_asu_support() ) {
8863 lp_add_ipc("ADMIN$", false);
8868 set_default_server_announce_type();
8869 set_allowed_client_auth();
8873 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8874 /* if bWINSsupport is true and we are in the client */
8875 if (lp_is_in_client() && Globals.bWINSsupport) {
8876 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8881 bAllowIncludeRegistry = true;
8886 bool lp_load(const char *pszFname,
8890 bool initialize_globals)
8892 return lp_load_ex(pszFname,
8900 bool lp_load_initial_only(const char *pszFname)
8902 return lp_load_ex(pszFname,
8911 bool lp_load_with_registry_shares(const char *pszFname,
8915 bool initialize_globals)
8917 return lp_load_ex(pszFname,
8926 /***************************************************************************
8927 Return the max number of services.
8928 ***************************************************************************/
8930 int lp_numservices(void)
8932 return (iNumServices);
8935 /***************************************************************************
8936 Display the contents of the services array in human-readable form.
8937 ***************************************************************************/
8939 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8944 defaults_saved = False;
8948 dump_a_service(&sDefault, f);
8950 for (iService = 0; iService < maxtoprint; iService++) {
8952 lp_dump_one(f, show_defaults, iService);
8956 /***************************************************************************
8957 Display the contents of one service in human-readable form.
8958 ***************************************************************************/
8960 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8963 if (ServicePtrs[snum]->szService[0] == '\0')
8965 dump_a_service(ServicePtrs[snum], f);
8969 /***************************************************************************
8970 Return the number of the service with the given name, or -1 if it doesn't
8971 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8972 getservicebyname()! This works ONLY if all services have been loaded, and
8973 does not copy the found service.
8974 ***************************************************************************/
8976 int lp_servicenumber(const char *pszServiceName)
8979 fstring serviceName;
8981 if (!pszServiceName) {
8982 return GLOBAL_SECTION_SNUM;
8985 for (iService = iNumServices - 1; iService >= 0; iService--) {
8986 if (VALID(iService) && ServicePtrs[iService]->szService) {
8988 * The substitution here is used to support %U is
8991 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8992 standard_sub_basic(get_current_username(),
8993 current_user_info.domain,
8994 serviceName,sizeof(serviceName));
8995 if (strequal(serviceName, pszServiceName)) {
9001 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9004 if (!usershare_exists(iService, &last_mod)) {
9005 /* Remove the share security tdb entry for it. */
9006 delete_share_security(lp_servicename(iService));
9007 /* Remove it from the array. */
9008 free_service_byindex(iService);
9009 /* Doesn't exist anymore. */
9010 return GLOBAL_SECTION_SNUM;
9013 /* Has it been modified ? If so delete and reload. */
9014 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9015 /* Remove it from the array. */
9016 free_service_byindex(iService);
9017 /* and now reload it. */
9018 iService = load_usershare_service(pszServiceName);
9023 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9024 return GLOBAL_SECTION_SNUM;
9030 bool share_defined(const char *service_name)
9032 return (lp_servicenumber(service_name) != -1);
9035 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9036 const char *sharename)
9038 struct share_params *result;
9042 if (!(sname = SMB_STRDUP(sharename))) {
9046 snum = find_service(sname);
9053 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9054 DEBUG(0, ("talloc failed\n"));
9058 result->service = snum;
9062 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9064 struct share_iterator *result;
9066 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9067 DEBUG(0, ("talloc failed\n"));
9071 result->next_id = 0;
9075 struct share_params *next_share(struct share_iterator *list)
9077 struct share_params *result;
9079 while (!lp_snum_ok(list->next_id) &&
9080 (list->next_id < lp_numservices())) {
9084 if (list->next_id >= lp_numservices()) {
9088 if (!(result = TALLOC_P(list, struct share_params))) {
9089 DEBUG(0, ("talloc failed\n"));
9093 result->service = list->next_id;
9098 struct share_params *next_printer(struct share_iterator *list)
9100 struct share_params *result;
9102 while ((result = next_share(list)) != NULL) {
9103 if (lp_print_ok(result->service)) {
9111 * This is a hack for a transition period until we transformed all code from
9112 * service numbers to struct share_params.
9115 struct share_params *snum2params_static(int snum)
9117 static struct share_params result;
9118 result.service = snum;
9122 /*******************************************************************
9123 A useful volume label function.
9124 ********************************************************************/
9126 const char *volume_label(int snum)
9129 const char *label = lp_volume(snum);
9131 label = lp_servicename(snum);
9134 /* This returns a 33 byte guarenteed null terminated string. */
9135 ret = talloc_strndup(talloc_tos(), label, 32);
9142 /*******************************************************************
9143 Set the server type we will announce as via nmbd.
9144 ********************************************************************/
9146 static void set_default_server_announce_type(void)
9148 default_server_announce = 0;
9149 default_server_announce |= SV_TYPE_WORKSTATION;
9150 default_server_announce |= SV_TYPE_SERVER;
9151 default_server_announce |= SV_TYPE_SERVER_UNIX;
9153 /* note that the flag should be set only if we have a
9154 printer service but nmbd doesn't actually load the
9155 services so we can't tell --jerry */
9157 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9159 switch (lp_announce_as()) {
9160 case ANNOUNCE_AS_NT_SERVER:
9161 default_server_announce |= SV_TYPE_SERVER_NT;
9162 /* fall through... */
9163 case ANNOUNCE_AS_NT_WORKSTATION:
9164 default_server_announce |= SV_TYPE_NT;
9166 case ANNOUNCE_AS_WIN95:
9167 default_server_announce |= SV_TYPE_WIN95_PLUS;
9169 case ANNOUNCE_AS_WFW:
9170 default_server_announce |= SV_TYPE_WFW;
9176 switch (lp_server_role()) {
9177 case ROLE_DOMAIN_MEMBER:
9178 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9180 case ROLE_DOMAIN_PDC:
9181 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9183 case ROLE_DOMAIN_BDC:
9184 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9186 case ROLE_STANDALONE:
9190 if (lp_time_server())
9191 default_server_announce |= SV_TYPE_TIME_SOURCE;
9193 if (lp_host_msdfs())
9194 default_server_announce |= SV_TYPE_DFS_SERVER;
9197 /***********************************************************
9198 returns role of Samba server
9199 ************************************************************/
9201 int lp_server_role(void)
9206 /***********************************************************
9207 If we are PDC then prefer us as DMB
9208 ************************************************************/
9210 bool lp_domain_master(void)
9212 if (Globals.iDomainMaster == Auto)
9213 return (lp_server_role() == ROLE_DOMAIN_PDC);
9215 return (bool)Globals.iDomainMaster;
9218 /***********************************************************
9219 If we are DMB then prefer us as LMB
9220 ************************************************************/
9222 bool lp_preferred_master(void)
9224 if (Globals.iPreferredMaster == Auto)
9225 return (lp_local_master() && lp_domain_master());
9227 return (bool)Globals.iPreferredMaster;
9230 /*******************************************************************
9232 ********************************************************************/
9234 void lp_remove_service(int snum)
9236 ServicePtrs[snum]->valid = False;
9237 invalid_services[num_invalid_services++] = snum;
9240 /*******************************************************************
9242 ********************************************************************/
9244 void lp_copy_service(int snum, const char *new_name)
9246 do_section(new_name, NULL);
9248 snum = lp_servicenumber(new_name);
9250 lp_do_parameter(snum, "copy", lp_servicename(snum));
9255 /*******************************************************************
9256 Get the default server type we will announce as via nmbd.
9257 ********************************************************************/
9259 int lp_default_server_announce(void)
9261 return default_server_announce;
9264 /*******************************************************************
9265 Split the announce version into major and minor numbers.
9266 ********************************************************************/
9268 int lp_major_announce_version(void)
9270 static bool got_major = False;
9271 static int major_version = DEFAULT_MAJOR_VERSION;
9276 return major_version;
9279 if ((vers = lp_announce_version()) == NULL)
9280 return major_version;
9282 if ((p = strchr_m(vers, '.')) == 0)
9283 return major_version;
9286 major_version = atoi(vers);
9287 return major_version;
9290 int lp_minor_announce_version(void)
9292 static bool got_minor = False;
9293 static int minor_version = DEFAULT_MINOR_VERSION;
9298 return minor_version;
9301 if ((vers = lp_announce_version()) == NULL)
9302 return minor_version;
9304 if ((p = strchr_m(vers, '.')) == 0)
9305 return minor_version;
9308 minor_version = atoi(p);
9309 return minor_version;
9312 /***********************************************************
9313 Set the global name resolution order (used in smbclient).
9314 ************************************************************/
9316 void lp_set_name_resolve_order(const char *new_order)
9318 string_set(&Globals.szNameResolveOrder, new_order);
9321 const char *lp_printername(int snum)
9323 const char *ret = _lp_printername(snum);
9324 if (ret == NULL || (ret != NULL && *ret == '\0'))
9325 ret = lp_const_servicename(snum);
9331 /***********************************************************
9332 Allow daemons such as winbindd to fix their logfile name.
9333 ************************************************************/
9335 void lp_set_logfile(const char *name)
9337 string_set(&Globals.szLogFile, name);
9338 debug_set_logfile(name);
9341 /*******************************************************************
9342 Return the max print jobs per queue.
9343 ********************************************************************/
9345 int lp_maxprintjobs(int snum)
9347 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9348 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9349 maxjobs = PRINT_MAX_JOBID - 1;
9354 const char *lp_printcapname(void)
9356 if ((Globals.szPrintcapname != NULL) &&
9357 (Globals.szPrintcapname[0] != '\0'))
9358 return Globals.szPrintcapname;
9360 if (sDefault.iPrinting == PRINT_CUPS) {
9368 if (sDefault.iPrinting == PRINT_BSD)
9369 return "/etc/printcap";
9371 return PRINTCAP_NAME;
9374 /*******************************************************************
9375 Ensure we don't use sendfile if server smb signing is active.
9376 ********************************************************************/
9378 static uint32 spoolss_state;
9380 bool lp_disable_spoolss( void )
9382 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9383 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9385 return spoolss_state == SVCCTL_STOPPED ? True : False;
9388 void lp_set_spoolss_state( uint32 state )
9390 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9392 spoolss_state = state;
9395 uint32 lp_get_spoolss_state( void )
9397 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9400 /*******************************************************************
9401 Ensure we don't use sendfile if server smb signing is active.
9402 ********************************************************************/
9404 bool lp_use_sendfile(int snum)
9406 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9407 if (Protocol < PROTOCOL_NT1) {
9410 return (_lp_use_sendfile(snum) &&
9411 (get_remote_arch() != RA_WIN95) &&
9412 !srv_is_signing_active());
9415 /*******************************************************************
9416 Turn off sendfile if we find the underlying OS doesn't support it.
9417 ********************************************************************/
9419 void set_use_sendfile(int snum, bool val)
9421 if (LP_SNUM_OK(snum))
9422 ServicePtrs[snum]->bUseSendfile = val;
9424 sDefault.bUseSendfile = val;
9427 /*******************************************************************
9428 Turn off storing DOS attributes if this share doesn't support it.
9429 ********************************************************************/
9431 void set_store_dos_attributes(int snum, bool val)
9433 if (!LP_SNUM_OK(snum))
9435 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9438 void lp_set_mangling_method(const char *new_method)
9440 string_set(&Globals.szManglingMethod, new_method);
9443 /*******************************************************************
9444 Global state for POSIX pathname processing.
9445 ********************************************************************/
9447 static bool posix_pathnames;
9449 bool lp_posix_pathnames(void)
9451 return posix_pathnames;
9454 /*******************************************************************
9455 Change everything needed to ensure POSIX pathname processing (currently
9457 ********************************************************************/
9459 void lp_set_posix_pathnames(void)
9461 posix_pathnames = True;
9464 /*******************************************************************
9465 Global state for POSIX lock processing - CIFS unix extensions.
9466 ********************************************************************/
9468 bool posix_default_lock_was_set;
9469 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9471 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9473 if (posix_default_lock_was_set) {
9474 return posix_cifsx_locktype;
9476 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9480 /*******************************************************************
9481 ********************************************************************/
9483 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9485 posix_default_lock_was_set = True;
9486 posix_cifsx_locktype = val;
9489 int lp_min_receive_file_size(void)
9491 if (Globals.iminreceivefile < 0) {
9494 return MIN(Globals.iminreceivefile, BUFFER_SIZE);