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 *szIdmapBackend;
198 char *szIdmapAllocBackend;
199 char *szAddShareCommand;
200 char *szChangeShareCommand;
201 char *szDeleteShareCommand;
203 char *szGuestaccount;
204 char *szManglingMethod;
205 char **szServicesList;
206 char *szUsersharePath;
207 char *szUsershareTemplateShare;
208 char **szUsersharePrefixAllowList;
209 char **szUsersharePrefixDenyList;
216 int open_files_db_hash_size;
225 bool paranoid_server_security;
228 int iMaxSmbdProcesses;
229 bool bDisableSpoolss;
232 bool enhanced_browsing;
238 int announce_as; /* This is initialised in init_globals */
239 int machine_password_timeout;
241 int oplock_break_wait_time;
242 int winbind_cache_time;
243 int winbind_reconnect_delay;
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 backend",
4261 .p_class = P_GLOBAL,
4262 .ptr = &Globals.szIdmapBackend,
4265 .flags = FLAG_ADVANCED,
4268 .label = "idmap alloc backend",
4270 .p_class = P_GLOBAL,
4271 .ptr = &Globals.szIdmapAllocBackend,
4274 .flags = FLAG_ADVANCED,
4277 .label = "idmap cache time",
4279 .p_class = P_GLOBAL,
4280 .ptr = &Globals.iIdmapCacheTime,
4283 .flags = FLAG_ADVANCED,
4286 .label = "idmap negative cache time",
4288 .p_class = P_GLOBAL,
4289 .ptr = &Globals.iIdmapNegativeCacheTime,
4292 .flags = FLAG_ADVANCED,
4295 .label = "idmap uid",
4297 .p_class = P_GLOBAL,
4298 .ptr = &Globals.szIdmapUID,
4299 .special = handle_idmap_uid,
4301 .flags = FLAG_ADVANCED,
4304 .label = "winbind uid",
4306 .p_class = P_GLOBAL,
4307 .ptr = &Globals.szIdmapUID,
4308 .special = handle_idmap_uid,
4313 .label = "idmap gid",
4315 .p_class = P_GLOBAL,
4316 .ptr = &Globals.szIdmapGID,
4317 .special = handle_idmap_gid,
4319 .flags = FLAG_ADVANCED,
4322 .label = "winbind gid",
4324 .p_class = P_GLOBAL,
4325 .ptr = &Globals.szIdmapGID,
4326 .special = handle_idmap_gid,
4331 .label = "template homedir",
4333 .p_class = P_GLOBAL,
4334 .ptr = &Globals.szTemplateHomedir,
4337 .flags = FLAG_ADVANCED,
4340 .label = "template shell",
4342 .p_class = P_GLOBAL,
4343 .ptr = &Globals.szTemplateShell,
4346 .flags = FLAG_ADVANCED,
4349 .label = "winbind separator",
4351 .p_class = P_GLOBAL,
4352 .ptr = &Globals.szWinbindSeparator,
4355 .flags = FLAG_ADVANCED,
4358 .label = "winbind cache time",
4360 .p_class = P_GLOBAL,
4361 .ptr = &Globals.winbind_cache_time,
4364 .flags = FLAG_ADVANCED,
4367 .label = "winbind reconnect delay",
4369 .p_class = P_GLOBAL,
4370 .ptr = &Globals.winbind_reconnect_delay,
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;
4828 string_set(&Globals.szIdmapBackend, "tdb");
4830 string_set(&Globals.szTemplateShell, "/bin/false");
4831 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4832 string_set(&Globals.szWinbindSeparator, "\\");
4834 string_set(&Globals.szCupsServer, "");
4835 string_set(&Globals.szIPrintServer, "");
4837 string_set(&Globals.ctdbdSocket, "");
4838 Globals.szClusterAddresses = NULL;
4839 Globals.clustering = False;
4841 Globals.winbind_cache_time = 300; /* 5 minutes */
4842 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
4843 Globals.bWinbindEnumUsers = False;
4844 Globals.bWinbindEnumGroups = False;
4845 Globals.bWinbindUseDefaultDomain = False;
4846 Globals.bWinbindTrustedDomainsOnly = False;
4847 Globals.bWinbindNestedGroups = True;
4848 Globals.winbind_expand_groups = 1;
4849 Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4850 Globals.bWinbindRefreshTickets = False;
4851 Globals.bWinbindOfflineLogon = False;
4853 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
4854 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4856 Globals.bPassdbExpandExplicit = False;
4858 Globals.name_cache_timeout = 660; /* In seconds */
4860 Globals.bUseSpnego = True;
4861 Globals.bClientUseSpnego = True;
4863 Globals.client_signing = Auto;
4864 Globals.server_signing = False;
4866 Globals.bDeferSharingViolations = True;
4867 string_set(&Globals.smb_ports, SMB_PORTS);
4869 Globals.bEnablePrivileges = True;
4870 Globals.bHostMSDfs = True;
4871 Globals.bASUSupport = False;
4873 /* User defined shares. */
4874 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4875 smb_panic("init_globals: ENOMEM");
4877 string_set(&Globals.szUsersharePath, s);
4879 string_set(&Globals.szUsershareTemplateShare, "");
4880 Globals.iUsershareMaxShares = 0;
4881 /* By default disallow sharing of directories not owned by the sharer. */
4882 Globals.bUsershareOwnerOnly = True;
4883 /* By default disallow guest access to usershares. */
4884 Globals.bUsershareAllowGuests = False;
4886 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4888 /* By default no shares out of the registry */
4889 Globals.bRegistryShares = False;
4891 Globals.iminreceivefile = 0;
4894 /*******************************************************************
4895 Convenience routine to grab string parameters into temporary memory
4896 and run standard_sub_basic on them. The buffers can be written to by
4897 callers without affecting the source string.
4898 ********************************************************************/
4900 static char *lp_string(const char *s)
4903 TALLOC_CTX *ctx = talloc_tos();
4905 /* The follow debug is useful for tracking down memory problems
4906 especially if you have an inner loop that is calling a lp_*()
4907 function that returns a string. Perhaps this debug should be
4908 present all the time? */
4911 DEBUG(10, ("lp_string(%s)\n", s));
4914 ret = talloc_sub_basic(ctx,
4915 get_current_username(),
4916 current_user_info.domain,
4918 if (trim_char(ret, '\"', '\"')) {
4919 if (strchr(ret,'\"') != NULL) {
4921 ret = talloc_sub_basic(ctx,
4922 get_current_username(),
4923 current_user_info.domain,
4931 In this section all the functions that are used to access the
4932 parameters from the rest of the program are defined
4935 #define FN_GLOBAL_STRING(fn_name,ptr) \
4936 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4937 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4938 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4939 #define FN_GLOBAL_LIST(fn_name,ptr) \
4940 const char **fn_name(void) {return(*(const char ***)(ptr));}
4941 #define FN_GLOBAL_BOOL(fn_name,ptr) \
4942 bool fn_name(void) {return(*(bool *)(ptr));}
4943 #define FN_GLOBAL_CHAR(fn_name,ptr) \
4944 char fn_name(void) {return(*(char *)(ptr));}
4945 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
4946 int fn_name(void) {return(*(int *)(ptr));}
4948 #define FN_LOCAL_STRING(fn_name,val) \
4949 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4950 #define FN_LOCAL_CONST_STRING(fn_name,val) \
4951 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4952 #define FN_LOCAL_LIST(fn_name,val) \
4953 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4954 #define FN_LOCAL_BOOL(fn_name,val) \
4955 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4956 #define FN_LOCAL_INTEGER(fn_name,val) \
4957 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4959 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
4960 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4961 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4962 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4963 #define FN_LOCAL_PARM_STRING(fn_name,val) \
4964 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));}
4965 #define FN_LOCAL_CHAR(fn_name,val) \
4966 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4968 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4969 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4970 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4971 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4972 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4973 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4974 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4975 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4976 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4977 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4978 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4979 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4980 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4981 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4982 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4983 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4984 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4985 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4986 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4987 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4988 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4989 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4990 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4991 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4992 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4993 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4994 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
4995 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
4996 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
4997 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
4998 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
4999 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5000 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5001 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5002 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5003 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5004 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5005 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5006 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5007 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5008 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5009 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5010 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5011 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5012 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5013 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
5014 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5015 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5016 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5017 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5018 * lp_passdb_backend() should be replace by the this macro again after
5021 const char *lp_passdb_backend(void)
5023 char *delim, *quote;
5025 delim = strchr( Globals.szPassdbBackend, ' ');
5026 /* no space at all */
5027 if (delim == NULL) {
5031 quote = strchr(Globals.szPassdbBackend, '"');
5032 /* no quote char or non in the first part */
5033 if (quote == NULL || quote > delim) {
5038 quote = strchr(quote+1, '"');
5039 if (quote == NULL) {
5040 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5042 } else if (*(quote+1) == '\0') {
5043 /* space, fitting quote char, and one backend only */
5046 /* terminate string after the fitting quote char */
5051 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5052 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5053 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5054 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5057 return Globals.szPassdbBackend;
5059 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5060 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5061 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5062 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5063 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5065 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5066 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5067 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5068 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5069 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5070 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5072 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5074 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5075 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5076 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5078 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5080 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5081 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5082 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5083 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5084 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5085 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5086 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5087 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5088 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5089 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5090 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5091 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5092 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5093 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5094 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5096 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5097 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5098 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5099 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5100 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5101 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5103 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5104 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5105 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5106 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5107 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5108 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5109 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5110 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5111 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5112 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5113 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5114 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5115 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5116 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5117 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5118 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5119 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5121 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5123 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5124 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5125 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5126 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5127 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5128 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5129 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5130 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5131 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5132 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5133 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5134 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5135 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5136 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5137 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5138 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5139 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5140 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5141 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5142 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5143 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5144 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5145 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5146 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5147 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5148 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5149 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5150 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5151 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5152 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5153 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5154 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5155 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5156 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5157 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5158 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5159 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5160 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5161 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5162 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5163 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5164 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5165 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5166 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5167 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5168 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5169 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5170 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5171 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5172 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5173 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5174 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5175 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5176 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5177 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5178 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5179 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5180 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5181 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5182 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5183 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5184 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5185 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5186 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5187 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5188 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5189 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5190 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5191 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5192 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5193 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5194 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5195 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5196 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5197 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5198 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5199 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5200 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5201 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5202 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5203 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5204 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5205 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5206 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5207 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5208 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5209 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5210 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5211 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5212 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5213 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5214 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5215 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5216 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5217 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5218 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5219 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5220 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5222 FN_LOCAL_STRING(lp_preexec, szPreExec)
5223 FN_LOCAL_STRING(lp_postexec, szPostExec)
5224 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5225 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5226 FN_LOCAL_STRING(lp_servicename, szService)
5227 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5228 FN_LOCAL_STRING(lp_pathname, szPath)
5229 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5230 FN_LOCAL_STRING(lp_username, szUsername)
5231 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5232 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5233 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5234 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5235 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5236 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5237 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5238 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5239 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5240 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5241 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5242 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5243 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5244 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5245 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5246 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5247 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5248 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5249 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5250 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5251 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5252 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5253 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5254 FN_LOCAL_STRING(lp_comment, comment)
5255 FN_LOCAL_STRING(lp_force_user, force_user)
5256 FN_LOCAL_STRING(lp_force_group, force_group)
5257 FN_LOCAL_LIST(lp_readlist, readlist)
5258 FN_LOCAL_LIST(lp_writelist, writelist)
5259 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5260 FN_LOCAL_STRING(lp_fstype, fstype)
5261 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5262 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5263 static FN_LOCAL_STRING(lp_volume, volume)
5264 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5265 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5266 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5267 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5268 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5269 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5270 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5271 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5272 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5273 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5274 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5275 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5276 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5277 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5278 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5279 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5280 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5281 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5282 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5283 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5284 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5285 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5286 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5287 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5288 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5289 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5290 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5291 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5292 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5293 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5294 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5295 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5296 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5297 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5298 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5299 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5300 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5301 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5302 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5303 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5304 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5305 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5306 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5307 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5308 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5309 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5310 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5311 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5312 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5313 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5314 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5315 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5316 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5317 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5318 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5319 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5320 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5321 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5322 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5323 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5324 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5325 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5326 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5327 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5328 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5329 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5330 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5331 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5332 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5333 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5334 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5335 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5336 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5337 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5338 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5339 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5340 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5341 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5342 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5343 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5344 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5345 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5346 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5347 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5348 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5349 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5350 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5351 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5352 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5353 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5354 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5355 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5356 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5357 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5358 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5359 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5360 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5361 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5363 /* local prototypes */
5365 static int map_parameter(const char *pszParmName);
5366 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5367 static bool set_boolean(bool *pb, const char *pszParmValue);
5368 static const char *get_boolean(bool bool_value);
5369 static int getservicebyname(const char *pszServiceName,
5370 struct service *pserviceDest);
5371 static void copy_service(struct service *pserviceDest,
5372 struct service *pserviceSource,
5373 struct bitmap *pcopymapDest);
5374 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5376 static bool do_section(const char *pszSectionName, void *userdata);
5377 static void init_copymap(struct service *pservice);
5378 static bool hash_a_service(const char *name, int number);
5379 static void free_service_byindex(int iService);
5380 static char * canonicalize_servicename(const char *name);
5381 static void show_parameter(int parmIndex);
5382 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5385 * This is a helper function for parametrical options support. It returns a
5386 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5387 * parametrical functions are quite simple
5389 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5392 bool global_section = False;
5394 struct param_opt_struct *data;
5396 if (snum >= iNumServices) return NULL;
5399 data = Globals.param_opt;
5400 global_section = True;
5402 data = ServicePtrs[snum]->param_opt;
5405 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5406 DEBUG(0,("asprintf failed!\n"));
5411 if (strwicmp(data->key, param_key) == 0) {
5412 string_free(¶m_key);
5418 if (!global_section) {
5419 /* Try to fetch the same option but from globals */
5420 /* but only if we are not already working with Globals */
5421 data = Globals.param_opt;
5423 if (strwicmp(data->key, param_key) == 0) {
5424 string_free(¶m_key);
5431 string_free(¶m_key);
5437 #define MISSING_PARAMETER(name) \
5438 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5440 /*******************************************************************
5441 convenience routine to return int parameters.
5442 ********************************************************************/
5443 static int lp_int(const char *s)
5447 MISSING_PARAMETER(lp_int);
5451 return (int)strtol(s, NULL, 0);
5454 /*******************************************************************
5455 convenience routine to return unsigned long parameters.
5456 ********************************************************************/
5457 static unsigned long lp_ulong(const char *s)
5461 MISSING_PARAMETER(lp_ulong);
5465 return strtoul(s, NULL, 0);
5468 /*******************************************************************
5469 convenience routine to return boolean parameters.
5470 ********************************************************************/
5471 static bool lp_bool(const char *s)
5476 MISSING_PARAMETER(lp_bool);
5480 if (!set_boolean(&ret,s)) {
5481 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5488 /*******************************************************************
5489 convenience routine to return enum parameters.
5490 ********************************************************************/
5491 static int lp_enum(const char *s,const struct enum_list *_enum)
5495 if (!s || !*s || !_enum) {
5496 MISSING_PARAMETER(lp_enum);
5500 for (i=0; _enum[i].name; i++) {
5501 if (strequal(_enum[i].name,s))
5502 return _enum[i].value;
5505 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5509 #undef MISSING_PARAMETER
5511 /* DO NOT USE lp_parm_string ANYMORE!!!!
5512 * use lp_parm_const_string or lp_parm_talloc_string
5514 * lp_parm_string is only used to let old modules find this symbol
5516 #undef lp_parm_string
5517 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5518 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5520 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5523 /* Return parametric option from a given service. Type is a part of option before ':' */
5524 /* Parametric option has following syntax: 'Type: option = value' */
5525 /* the returned value is talloced on the talloc_tos() */
5526 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5528 struct param_opt_struct *data = get_parametrics(snum, type, option);
5530 if (data == NULL||data->value==NULL) {
5532 return lp_string(def);
5538 return lp_string(data->value);
5541 /* Return parametric option from a given service. Type is a part of option before ':' */
5542 /* Parametric option has following syntax: 'Type: option = value' */
5543 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5545 struct param_opt_struct *data = get_parametrics(snum, type, option);
5547 if (data == NULL||data->value==NULL)
5553 /* Return parametric option from a given service. Type is a part of option before ':' */
5554 /* Parametric option has following syntax: 'Type: option = value' */
5556 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5558 struct param_opt_struct *data = get_parametrics(snum, type, option);
5560 if (data == NULL||data->value==NULL)
5561 return (const char **)def;
5563 if (data->list==NULL) {
5564 data->list = str_list_make(NULL, data->value, NULL);
5567 return (const char **)data->list;
5570 /* Return parametric option from a given service. Type is a part of option before ':' */
5571 /* Parametric option has following syntax: 'Type: option = value' */
5573 int lp_parm_int(int snum, const char *type, const char *option, int def)
5575 struct param_opt_struct *data = get_parametrics(snum, type, option);
5577 if (data && data->value && *data->value)
5578 return lp_int(data->value);
5583 /* Return parametric option from a given service. Type is a part of option before ':' */
5584 /* Parametric option has following syntax: 'Type: option = value' */
5586 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5588 struct param_opt_struct *data = get_parametrics(snum, type, option);
5590 if (data && data->value && *data->value)
5591 return lp_ulong(data->value);
5596 /* Return parametric option from a given service. Type is a part of option before ':' */
5597 /* Parametric option has following syntax: 'Type: option = value' */
5599 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5601 struct param_opt_struct *data = get_parametrics(snum, type, option);
5603 if (data && data->value && *data->value)
5604 return lp_bool(data->value);
5609 /* Return parametric option from a given service. Type is a part of option before ':' */
5610 /* Parametric option has following syntax: 'Type: option = value' */
5612 int lp_parm_enum(int snum, const char *type, const char *option,
5613 const struct enum_list *_enum, int def)
5615 struct param_opt_struct *data = get_parametrics(snum, type, option);
5617 if (data && data->value && *data->value && _enum)
5618 return lp_enum(data->value, _enum);
5624 /***************************************************************************
5625 Initialise a service to the defaults.
5626 ***************************************************************************/
5628 static void init_service(struct service *pservice)
5630 memset((char *)pservice, '\0', sizeof(struct service));
5631 copy_service(pservice, &sDefault, NULL);
5634 /***************************************************************************
5635 Free the dynamically allocated parts of a service struct.
5636 ***************************************************************************/
5638 static void free_service(struct service *pservice)
5641 struct param_opt_struct *data, *pdata;
5645 if (pservice->szService)
5646 DEBUG(5, ("free_service: Freeing service %s\n",
5647 pservice->szService));
5649 string_free(&pservice->szService);
5650 bitmap_free(pservice->copymap);
5652 for (i = 0; parm_table[i].label; i++) {
5653 if ((parm_table[i].type == P_STRING ||
5654 parm_table[i].type == P_USTRING) &&
5655 parm_table[i].p_class == P_LOCAL)
5656 string_free((char **)
5657 (((char *)pservice) +
5658 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5659 else if (parm_table[i].type == P_LIST &&
5660 parm_table[i].p_class == P_LOCAL)
5661 TALLOC_FREE(*((char ***)
5662 (((char *)pservice) +
5663 PTR_DIFF(parm_table[i].ptr,
5667 data = pservice->param_opt;
5669 DEBUG(5,("Freeing parametrics:\n"));
5671 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5672 string_free(&data->key);
5673 string_free(&data->value);
5674 TALLOC_FREE(data->list);
5680 ZERO_STRUCTP(pservice);
5684 /***************************************************************************
5685 remove a service indexed in the ServicePtrs array from the ServiceHash
5686 and free the dynamically allocated parts
5687 ***************************************************************************/
5689 static void free_service_byindex(int idx)
5691 if ( !LP_SNUM_OK(idx) )
5694 ServicePtrs[idx]->valid = False;
5695 invalid_services[num_invalid_services++] = idx;
5697 /* we have to cleanup the hash record */
5699 if (ServicePtrs[idx]->szService) {
5700 char *canon_name = canonicalize_servicename(
5701 ServicePtrs[idx]->szService );
5703 dbwrap_delete_bystring(ServiceHash, canon_name );
5704 TALLOC_FREE(canon_name);
5707 free_service(ServicePtrs[idx]);
5710 /***************************************************************************
5711 Add a new service to the services array initialising it with the given
5713 ***************************************************************************/
5715 static int add_a_service(const struct service *pservice, const char *name)
5718 struct service tservice;
5719 int num_to_alloc = iNumServices + 1;
5720 struct param_opt_struct *data, *pdata;
5722 tservice = *pservice;
5724 /* it might already exist */
5726 i = getservicebyname(name, NULL);
5728 /* Clean all parametric options for service */
5729 /* They will be added during parsing again */
5730 data = ServicePtrs[i]->param_opt;
5732 string_free(&data->key);
5733 string_free(&data->value);
5734 TALLOC_FREE(data->list);
5739 ServicePtrs[i]->param_opt = NULL;
5744 /* find an invalid one */
5746 if (num_invalid_services > 0) {
5747 i = invalid_services[--num_invalid_services];
5750 /* if not, then create one */
5751 if (i == iNumServices) {
5752 struct service **tsp;
5755 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5757 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5761 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5762 if (!ServicePtrs[iNumServices]) {
5763 DEBUG(0,("add_a_service: out of memory!\n"));
5768 /* enlarge invalid_services here for now... */
5769 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5771 if (tinvalid == NULL) {
5772 DEBUG(0,("add_a_service: failed to enlarge "
5773 "invalid_services!\n"));
5776 invalid_services = tinvalid;
5778 free_service_byindex(i);
5781 ServicePtrs[i]->valid = True;
5783 init_service(ServicePtrs[i]);
5784 copy_service(ServicePtrs[i], &tservice, NULL);
5786 string_set(&ServicePtrs[i]->szService, name);
5788 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5789 i, ServicePtrs[i]->szService));
5791 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5798 /***************************************************************************
5799 Convert a string to uppercase and remove whitespaces.
5800 ***************************************************************************/
5802 static char *canonicalize_servicename(const char *src)
5807 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5811 result = talloc_strdup(talloc_tos(), src);
5812 SMB_ASSERT(result != NULL);
5818 /***************************************************************************
5819 Add a name/index pair for the services array to the hash table.
5820 ***************************************************************************/
5822 static bool hash_a_service(const char *name, int idx)
5826 if ( !ServiceHash ) {
5827 DEBUG(10,("hash_a_service: creating servicehash\n"));
5828 ServiceHash = db_open_rbt(NULL);
5829 if ( !ServiceHash ) {
5830 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5835 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5838 canon_name = canonicalize_servicename( name );
5840 dbwrap_store_bystring(ServiceHash, canon_name,
5841 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5844 TALLOC_FREE(canon_name);
5849 /***************************************************************************
5850 Add a new home service, with the specified home directory, defaults coming
5852 ***************************************************************************/
5854 bool lp_add_home(const char *pszHomename, int iDefaultService,
5855 const char *user, const char *pszHomedir)
5859 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5864 if (!(*(ServicePtrs[iDefaultService]->szPath))
5865 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5866 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5869 if (!(*(ServicePtrs[i]->comment))) {
5870 char *comment = NULL;
5871 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5874 string_set(&ServicePtrs[i]->comment, comment);
5878 /* set the browseable flag from the global default */
5880 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5882 ServicePtrs[i]->autoloaded = True;
5884 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5885 user, ServicePtrs[i]->szPath ));
5890 /***************************************************************************
5891 Add a new service, based on an old one.
5892 ***************************************************************************/
5894 int lp_add_service(const char *pszService, int iDefaultService)
5896 if (iDefaultService < 0) {
5897 return add_a_service(&sDefault, pszService);
5900 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5903 /***************************************************************************
5904 Add the IPC service.
5905 ***************************************************************************/
5907 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5909 char *comment = NULL;
5910 int i = add_a_service(&sDefault, ipc_name);
5915 if (asprintf(&comment, "IPC Service (%s)",
5916 Globals.szServerString) < 0) {
5920 string_set(&ServicePtrs[i]->szPath, tmpdir());
5921 string_set(&ServicePtrs[i]->szUsername, "");
5922 string_set(&ServicePtrs[i]->comment, comment);
5923 string_set(&ServicePtrs[i]->fstype, "IPC");
5924 ServicePtrs[i]->iMaxConnections = 0;
5925 ServicePtrs[i]->bAvailable = True;
5926 ServicePtrs[i]->bRead_only = True;
5927 ServicePtrs[i]->bGuest_only = False;
5928 ServicePtrs[i]->bAdministrative_share = True;
5929 ServicePtrs[i]->bGuest_ok = guest_ok;
5930 ServicePtrs[i]->bPrint_ok = False;
5931 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5933 DEBUG(3, ("adding IPC service\n"));
5939 /***************************************************************************
5940 Add a new printer service, with defaults coming from service iFrom.
5941 ***************************************************************************/
5943 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5945 const char *comment = "From Printcap";
5946 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5951 /* note that we do NOT default the availability flag to True - */
5952 /* we take it from the default service passed. This allows all */
5953 /* dynamic printers to be disabled by disabling the [printers] */
5954 /* entry (if/when the 'available' keyword is implemented!). */
5956 /* the printer name is set to the service name. */
5957 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5958 string_set(&ServicePtrs[i]->comment, comment);
5960 /* set the browseable flag from the gloabl default */
5961 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5963 /* Printers cannot be read_only. */
5964 ServicePtrs[i]->bRead_only = False;
5965 /* No share modes on printer services. */
5966 ServicePtrs[i]->bShareModes = False;
5967 /* No oplocks on printer services. */
5968 ServicePtrs[i]->bOpLocks = False;
5969 /* Printer services must be printable. */
5970 ServicePtrs[i]->bPrint_ok = True;
5972 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5978 /***************************************************************************
5979 Check whether the given parameter name is valid.
5980 Parametric options (names containing a colon) are considered valid.
5981 ***************************************************************************/
5983 bool lp_parameter_is_valid(const char *pszParmName)
5985 return ((map_parameter(pszParmName) != -1) ||
5986 (strchr(pszParmName, ':') != NULL));
5989 /***************************************************************************
5990 Check whether the given name is the name of a global parameter.
5991 Returns True for strings belonging to parameters of class
5992 P_GLOBAL, False for all other strings, also for parametric options
5993 and strings not belonging to any option.
5994 ***************************************************************************/
5996 bool lp_parameter_is_global(const char *pszParmName)
5998 int num = map_parameter(pszParmName);
6001 return (parm_table[num].p_class == P_GLOBAL);
6007 /**************************************************************************
6008 Check whether the given name is the canonical name of a parameter.
6009 Returns False if it is not a valid parameter Name.
6010 For parametric options, True is returned.
6011 **************************************************************************/
6013 bool lp_parameter_is_canonical(const char *parm_name)
6015 if (!lp_parameter_is_valid(parm_name)) {
6019 return (map_parameter(parm_name) ==
6020 map_parameter_canonical(parm_name, NULL));
6023 /**************************************************************************
6024 Determine the canonical name for a parameter.
6025 Indicate when it is an inverse (boolean) synonym instead of a
6027 **************************************************************************/
6029 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6034 if (!lp_parameter_is_valid(parm_name)) {
6039 num = map_parameter_canonical(parm_name, inverse);
6041 /* parametric option */
6042 *canon_parm = parm_name;
6044 *canon_parm = parm_table[num].label;
6051 /**************************************************************************
6052 Determine the canonical name for a parameter.
6053 Turn the value given into the inverse boolean expression when
6054 the synonym is an invers boolean synonym.
6056 Return True if parm_name is a valid parameter name and
6057 in case it is an invers boolean synonym, if the val string could
6058 successfully be converted to the reverse bool.
6059 Return false in all other cases.
6060 **************************************************************************/
6062 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6064 const char **canon_parm,
6065 const char **canon_val)
6070 if (!lp_parameter_is_valid(parm_name)) {
6076 num = map_parameter_canonical(parm_name, &inverse);
6078 /* parametric option */
6079 *canon_parm = parm_name;
6082 *canon_parm = parm_table[num].label;
6084 if (!lp_invert_boolean(val, canon_val)) {
6096 /***************************************************************************
6097 Map a parameter's string representation to something we can use.
6098 Returns False if the parameter string is not recognised, else TRUE.
6099 ***************************************************************************/
6101 static int map_parameter(const char *pszParmName)
6105 if (*pszParmName == '-')
6108 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6109 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6112 /* Warn only if it isn't parametric option */
6113 if (strchr(pszParmName, ':') == NULL)
6114 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6115 /* We do return 'fail' for parametric options as well because they are
6116 stored in different storage
6121 /***************************************************************************
6122 Map a parameter's string representation to the index of the canonical
6123 form of the parameter (it might be a synonym).
6124 Returns -1 if the parameter string is not recognised.
6125 ***************************************************************************/
6127 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6129 int parm_num, canon_num;
6130 bool loc_inverse = False;
6132 parm_num = map_parameter(pszParmName);
6133 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6134 /* invalid, parametric or no canidate for synonyms ... */
6138 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6139 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6140 parm_num = canon_num;
6146 if (inverse != NULL) {
6147 *inverse = loc_inverse;
6152 /***************************************************************************
6153 return true if parameter number parm1 is a synonym of parameter
6154 number parm2 (parm2 being the principal name).
6155 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6157 ***************************************************************************/
6159 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6161 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6162 (parm_table[parm1].flags & FLAG_HIDE) &&
6163 !(parm_table[parm2].flags & FLAG_HIDE))
6165 if (inverse != NULL) {
6166 if ((parm_table[parm1].type == P_BOOLREV) &&
6167 (parm_table[parm2].type == P_BOOL))
6179 /***************************************************************************
6180 Show one parameter's name, type, [values,] and flags.
6181 (helper functions for show_parameter_list)
6182 ***************************************************************************/
6184 static void show_parameter(int parmIndex)
6186 int enumIndex, flagIndex;
6191 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6192 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6194 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6195 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6196 FLAG_HIDE, FLAG_DOS_STRING};
6197 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6198 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6199 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6201 printf("%s=%s", parm_table[parmIndex].label,
6202 type[parm_table[parmIndex].type]);
6203 if (parm_table[parmIndex].type == P_ENUM) {
6206 parm_table[parmIndex].enum_list[enumIndex].name;
6210 enumIndex ? "|" : "",
6211 parm_table[parmIndex].enum_list[enumIndex].name);
6216 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6217 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6220 flag_names[flagIndex]);
6225 /* output synonyms */
6227 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6228 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6229 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6230 parm_table[parmIndex2].label);
6231 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6233 printf(" (synonyms: ");
6238 printf("%s%s", parm_table[parmIndex2].label,
6239 inverse ? "[i]" : "");
6249 /***************************************************************************
6250 Show all parameter's name, type, [values,] and flags.
6251 ***************************************************************************/
6253 void show_parameter_list(void)
6255 int classIndex, parmIndex;
6256 const char *section_names[] = { "local", "global", NULL};
6258 for (classIndex=0; section_names[classIndex]; classIndex++) {
6259 printf("[%s]\n", section_names[classIndex]);
6260 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6261 if (parm_table[parmIndex].p_class == classIndex) {
6262 show_parameter(parmIndex);
6268 /***************************************************************************
6269 Set a boolean variable from the text value stored in the passed string.
6270 Returns True in success, False if the passed string does not correctly
6271 represent a boolean.
6272 ***************************************************************************/
6274 static bool set_boolean(bool *pb, const char *pszParmValue)
6281 if (strwicmp(pszParmValue, "yes") == 0 ||
6282 strwicmp(pszParmValue, "true") == 0 ||
6283 strwicmp(pszParmValue, "1") == 0)
6285 else if (strwicmp(pszParmValue, "no") == 0 ||
6286 strwicmp(pszParmValue, "False") == 0 ||
6287 strwicmp(pszParmValue, "0") == 0)
6291 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6296 if ((pb != NULL) && (bRetval != False)) {
6304 /***************************************************************************
6305 Check if a given string correctly represents a boolean value.
6306 ***************************************************************************/
6308 bool lp_string_is_valid_boolean(const char *parm_value)
6310 return set_boolean(NULL, parm_value);
6313 /***************************************************************************
6314 Get the standard string representation of a boolean value ("yes" or "no")
6315 ***************************************************************************/
6317 static const char *get_boolean(bool bool_value)
6319 static const char *yes_str = "yes";
6320 static const char *no_str = "no";
6322 return (bool_value ? yes_str : no_str);
6325 /***************************************************************************
6326 Provide the string of the negated boolean value associated to the boolean
6327 given as a string. Returns False if the passed string does not correctly
6328 represent a boolean.
6329 ***************************************************************************/
6331 bool lp_invert_boolean(const char *str, const char **inverse_str)
6335 if (!set_boolean(&val, str)) {
6339 *inverse_str = get_boolean(!val);
6343 /***************************************************************************
6344 Provide the canonical string representation of a boolean value given
6345 as a string. Return True on success, False if the string given does
6346 not correctly represent a boolean.
6347 ***************************************************************************/
6349 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6353 if (!set_boolean(&val, str)) {
6357 *canon_str = get_boolean(val);
6361 /***************************************************************************
6362 Find a service by name. Otherwise works like get_service.
6363 ***************************************************************************/
6365 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6371 if (ServiceHash == NULL) {
6375 canon_name = canonicalize_servicename(pszServiceName);
6377 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6379 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6380 iService = *(int *)data.dptr;
6383 TALLOC_FREE(canon_name);
6385 if ((iService != -1) && (LP_SNUM_OK(iService))
6386 && (pserviceDest != NULL)) {
6387 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6393 /***************************************************************************
6394 Copy a service structure to another.
6395 If pcopymapDest is NULL then copy all fields
6396 ***************************************************************************/
6398 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6399 struct bitmap *pcopymapDest)
6402 bool bcopyall = (pcopymapDest == NULL);
6403 struct param_opt_struct *data, *pdata, *paramo;
6406 for (i = 0; parm_table[i].label; i++)
6407 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6408 (bcopyall || bitmap_query(pcopymapDest,i))) {
6409 void *def_ptr = parm_table[i].ptr;
6411 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6414 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6417 switch (parm_table[i].type) {
6420 *(bool *)dest_ptr = *(bool *)src_ptr;
6426 *(int *)dest_ptr = *(int *)src_ptr;
6430 *(char *)dest_ptr = *(char *)src_ptr;
6434 string_set((char **)dest_ptr,
6439 string_set((char **)dest_ptr,
6441 strupper_m(*(char **)dest_ptr);
6444 TALLOC_FREE(*((char ***)dest_ptr));
6445 str_list_copy(NULL, (char ***)dest_ptr,
6446 *(const char ***)src_ptr);
6454 init_copymap(pserviceDest);
6455 if (pserviceSource->copymap)
6456 bitmap_copy(pserviceDest->copymap,
6457 pserviceSource->copymap);
6460 data = pserviceSource->param_opt;
6463 pdata = pserviceDest->param_opt;
6464 /* Traverse destination */
6466 /* If we already have same option, override it */
6467 if (strwicmp(pdata->key, data->key) == 0) {
6468 string_free(&pdata->value);
6469 TALLOC_FREE(data->list);
6470 pdata->value = SMB_STRDUP(data->value);
6474 pdata = pdata->next;
6477 paramo = SMB_XMALLOC_P(struct param_opt_struct);
6478 paramo->key = SMB_STRDUP(data->key);
6479 paramo->value = SMB_STRDUP(data->value);
6480 paramo->list = NULL;
6481 DLIST_ADD(pserviceDest->param_opt, paramo);
6487 /***************************************************************************
6488 Check a service for consistency. Return False if the service is in any way
6489 incomplete or faulty, else True.
6490 ***************************************************************************/
6492 bool service_ok(int iService)
6497 if (ServicePtrs[iService]->szService[0] == '\0') {
6498 DEBUG(0, ("The following message indicates an internal error:\n"));
6499 DEBUG(0, ("No service name in service entry.\n"));
6503 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6504 /* I can't see why you'd want a non-printable printer service... */
6505 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6506 if (!ServicePtrs[iService]->bPrint_ok) {
6507 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6508 ServicePtrs[iService]->szService));
6509 ServicePtrs[iService]->bPrint_ok = True;
6511 /* [printers] service must also be non-browsable. */
6512 if (ServicePtrs[iService]->bBrowseable)
6513 ServicePtrs[iService]->bBrowseable = False;
6516 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6517 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6518 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6520 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6521 ServicePtrs[iService]->szService));
6522 ServicePtrs[iService]->bAvailable = False;
6525 /* If a service is flagged unavailable, log the fact at level 1. */
6526 if (!ServicePtrs[iService]->bAvailable)
6527 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6528 ServicePtrs[iService]->szService));
6533 static struct smbconf_ctx *lp_smbconf_ctx(void)
6536 static struct smbconf_ctx *conf_ctx = NULL;
6538 if (conf_ctx == NULL) {
6539 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6540 if (!W_ERROR_IS_OK(werr)) {
6541 DEBUG(1, ("error initializing registry configuration: "
6542 "%s\n", dos_errstr(werr)));
6550 static bool process_registry_service(struct smbconf_service *service)
6555 if (service == NULL) {
6559 ret = do_section(service->name, NULL);
6563 for (count = 0; count < service->num_params; count++) {
6564 ret = do_parameter(service->param_names[count],
6565 service->param_values[count],
6575 * process_registry_globals
6577 static bool process_registry_globals(void)
6580 struct smbconf_service *service = NULL;
6581 TALLOC_CTX *mem_ctx = talloc_stackframe();
6582 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6585 if (conf_ctx == NULL) {
6589 ret = do_parameter("registry shares", "yes", NULL);
6594 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6595 /* nothing to read from the registry yet but make sure lp_load
6596 * doesn't return false */
6601 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6602 if (!W_ERROR_IS_OK(werr)) {
6606 ret = process_registry_service(service);
6612 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6615 TALLOC_FREE(mem_ctx);
6619 static bool process_registry_shares(void)
6623 struct smbconf_service **service = NULL;
6624 uint32_t num_shares = 0;
6625 TALLOC_CTX *mem_ctx = talloc_stackframe();
6626 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6629 if (conf_ctx == NULL) {
6633 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6634 if (!W_ERROR_IS_OK(werr)) {
6640 for (count = 0; count < num_shares; count++) {
6641 if (strequal(service[count]->name, GLOBAL_NAME)) {
6644 ret = process_registry_service(service[count]);
6651 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6654 TALLOC_FREE(mem_ctx);
6658 static struct file_lists {
6659 struct file_lists *next;
6663 } *file_lists = NULL;
6665 /*******************************************************************
6666 Keep a linked list of all config files so we know when one has changed
6667 it's date and needs to be reloaded.
6668 ********************************************************************/
6670 static void add_to_file_list(const char *fname, const char *subfname)
6672 struct file_lists *f = file_lists;
6675 if (f->name && !strcmp(f->name, fname))
6681 f = SMB_MALLOC_P(struct file_lists);
6684 f->next = file_lists;
6685 f->name = SMB_STRDUP(fname);
6690 f->subfname = SMB_STRDUP(subfname);
6696 f->modtime = file_modtime(subfname);
6698 time_t t = file_modtime(subfname);
6705 * Utility function for outsiders to check if we're running on registry.
6707 bool lp_config_backend_is_registry(void)
6709 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6713 * Utility function to check if the config backend is FILE.
6715 bool lp_config_backend_is_file(void)
6717 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6720 /*******************************************************************
6721 Check if a config file has changed date.
6722 ********************************************************************/
6724 bool lp_file_list_changed(void)
6726 struct file_lists *f = file_lists;
6728 DEBUG(6, ("lp_file_list_changed()\n"));
6730 if (lp_config_backend_is_registry()) {
6731 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6733 if (conf_ctx == NULL) {
6736 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6737 DEBUGADD(6, ("registry config changed\n"));
6746 n2 = alloc_sub_basic(get_current_username(),
6747 current_user_info.domain,
6752 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6753 f->name, n2, ctime(&f->modtime)));
6755 mod_time = file_modtime(n2);
6757 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6759 ("file %s modified: %s\n", n2,
6761 f->modtime = mod_time;
6762 SAFE_FREE(f->subfname);
6763 f->subfname = n2; /* Passing ownership of
6764 return from alloc_sub_basic
6775 /***************************************************************************
6776 Run standard_sub_basic on netbios name... needed because global_myname
6777 is not accessed through any lp_ macro.
6778 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6779 ***************************************************************************/
6781 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6784 char *netbios_name = alloc_sub_basic(get_current_username(),
6785 current_user_info.domain,
6788 ret = set_global_myname(netbios_name);
6789 SAFE_FREE(netbios_name);
6790 string_set(&Globals.szNetbiosName,global_myname());
6792 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6798 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6800 if (strcmp(*ptr, pszParmValue) != 0) {
6801 string_set(ptr, pszParmValue);
6809 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6813 ret = set_global_myworkgroup(pszParmValue);
6814 string_set(&Globals.szWorkgroup,lp_workgroup());
6819 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6823 ret = set_global_scope(pszParmValue);
6824 string_set(&Globals.szNetbiosScope,global_scope());
6829 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6831 TALLOC_FREE(Globals.szNetbiosAliases);
6832 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6833 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6836 /***************************************************************************
6837 Handle the include operation.
6838 ***************************************************************************/
6839 static bool bAllowIncludeRegistry = true;
6841 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6845 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6846 if (!bAllowIncludeRegistry) {
6849 if (bInGlobalSection) {
6850 return process_registry_globals();
6852 DEBUG(1, ("\"include = registry\" only effective "
6853 "in %s section\n", GLOBAL_NAME));
6858 fname = alloc_sub_basic(get_current_username(),
6859 current_user_info.domain,
6862 add_to_file_list(pszParmValue, fname);
6864 string_set(ptr, fname);
6866 if (file_exist(fname, NULL)) {
6867 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6872 DEBUG(2, ("Can't find include file %s\n", fname));
6877 /***************************************************************************
6878 Handle the interpretation of the copy parameter.
6879 ***************************************************************************/
6881 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6885 struct service serviceTemp;
6887 string_set(ptr, pszParmValue);
6889 init_service(&serviceTemp);
6893 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6895 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6896 if (iTemp == iServiceIndex) {
6897 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6899 copy_service(ServicePtrs[iServiceIndex],
6901 ServicePtrs[iServiceIndex]->copymap);
6905 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6909 free_service(&serviceTemp);
6913 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6915 Globals.ldap_debug_level = lp_int(pszParmValue);
6916 init_ldap_debugging();
6920 /***************************************************************************
6921 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6926 idmap uid = 1000-1999
6929 We only do simple parsing checks here. The strings are parsed into useful
6930 structures in the idmap daemon code.
6932 ***************************************************************************/
6934 /* Some lp_ routines to return idmap [ug]id information */
6936 static uid_t idmap_uid_low, idmap_uid_high;
6937 static gid_t idmap_gid_low, idmap_gid_high;
6939 bool lp_idmap_uid(uid_t *low, uid_t *high)
6941 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6945 *low = idmap_uid_low;
6948 *high = idmap_uid_high;
6953 bool lp_idmap_gid(gid_t *low, gid_t *high)
6955 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6959 *low = idmap_gid_low;
6962 *high = idmap_gid_high;
6967 /* Do some simple checks on "idmap [ug]id" parameter values */
6969 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6973 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6978 string_set(ptr, pszParmValue);
6980 idmap_uid_low = low;
6981 idmap_uid_high = high;
6986 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6990 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6995 string_set(ptr, pszParmValue);
6997 idmap_gid_low = low;
6998 idmap_gid_high = high;
7003 /***************************************************************************
7004 Handle the DEBUG level list.
7005 ***************************************************************************/
7007 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7009 string_set(ptr, pszParmValueIn);
7010 return debug_parse_levels(pszParmValueIn);
7013 /***************************************************************************
7014 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7015 ***************************************************************************/
7017 static const char *append_ldap_suffix( const char *str )
7019 const char *suffix_string;
7022 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7023 Globals.szLdapSuffix );
7024 if ( !suffix_string ) {
7025 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7029 return suffix_string;
7032 const char *lp_ldap_machine_suffix(void)
7034 if (Globals.szLdapMachineSuffix[0])
7035 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7037 return lp_string(Globals.szLdapSuffix);
7040 const char *lp_ldap_user_suffix(void)
7042 if (Globals.szLdapUserSuffix[0])
7043 return append_ldap_suffix(Globals.szLdapUserSuffix);
7045 return lp_string(Globals.szLdapSuffix);
7048 const char *lp_ldap_group_suffix(void)
7050 if (Globals.szLdapGroupSuffix[0])
7051 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7053 return lp_string(Globals.szLdapSuffix);
7056 const char *lp_ldap_idmap_suffix(void)
7058 if (Globals.szLdapIdmapSuffix[0])
7059 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7061 return lp_string(Globals.szLdapSuffix);
7064 /****************************************************************************
7065 set the value for a P_ENUM
7066 ***************************************************************************/
7068 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7073 for (i = 0; parm->enum_list[i].name; i++) {
7074 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7075 *ptr = parm->enum_list[i].value;
7079 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7080 pszParmValue, parm->label));
7083 /***************************************************************************
7084 ***************************************************************************/
7086 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7088 static int parm_num = -1;
7091 if ( parm_num == -1 )
7092 parm_num = map_parameter( "printing" );
7094 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7099 s = ServicePtrs[snum];
7101 init_printer_values( s );
7107 /***************************************************************************
7108 Initialise a copymap.
7109 ***************************************************************************/
7111 static void init_copymap(struct service *pservice)
7114 if (pservice->copymap) {
7115 bitmap_free(pservice->copymap);
7117 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7118 if (!pservice->copymap)
7120 ("Couldn't allocate copymap!! (size %d)\n",
7121 (int)NUMPARAMETERS));
7123 for (i = 0; i < NUMPARAMETERS; i++)
7124 bitmap_set(pservice->copymap, i);
7127 /***************************************************************************
7128 Return the local pointer to a parameter given the service number and the
7129 pointer into the default structure.
7130 ***************************************************************************/
7132 void *lp_local_ptr(int snum, void *ptr)
7134 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7137 /***************************************************************************
7138 Process a parameter for a particular service number. If snum < 0
7139 then assume we are in the globals.
7140 ***************************************************************************/
7142 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7145 void *parm_ptr = NULL; /* where we are going to store the result */
7146 void *def_ptr = NULL;
7147 struct param_opt_struct *paramo, *data;
7150 parmnum = map_parameter(pszParmName);
7155 if (strchr(pszParmName, ':') == NULL) {
7156 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7162 * We've got a parametric option
7165 frame = talloc_stackframe();
7169 ? Globals.param_opt : ServicePtrs[snum]->param_opt;
7170 /* Traverse destination */
7172 /* If we already have same option, override it */
7173 if (strwicmp(data->key, pszParmName) == 0) {
7174 string_free(&data->value);
7175 TALLOC_FREE(data->list);
7176 data->value = SMB_STRDUP(pszParmValue);
7183 paramo = SMB_XMALLOC_P(struct param_opt_struct);
7184 paramo->key = SMB_STRDUP(pszParmName);
7185 paramo->value = SMB_STRDUP(pszParmValue);
7186 paramo->list = NULL;
7188 DLIST_ADD(Globals.param_opt, paramo);
7190 DLIST_ADD(ServicePtrs[snum]->param_opt,
7199 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7200 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7204 def_ptr = parm_table[parmnum].ptr;
7206 /* we might point at a service, the default service or a global */
7210 if (parm_table[parmnum].p_class == P_GLOBAL) {
7212 ("Global parameter %s found in service section!\n",
7217 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7222 if (!ServicePtrs[snum]->copymap)
7223 init_copymap(ServicePtrs[snum]);
7225 /* this handles the aliases - set the copymap for other entries with
7226 the same data pointer */
7227 for (i = 0; parm_table[i].label; i++)
7228 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7229 bitmap_clear(ServicePtrs[snum]->copymap, i);
7232 /* if it is a special case then go ahead */
7233 if (parm_table[parmnum].special) {
7234 return parm_table[parmnum].special(snum, pszParmValue,
7238 /* now switch on the type of variable it is */
7239 switch (parm_table[parmnum].type)
7242 *(bool *)parm_ptr = lp_bool(pszParmValue);
7246 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7250 *(int *)parm_ptr = lp_int(pszParmValue);
7254 *(char *)parm_ptr = *pszParmValue;
7258 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7260 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7265 TALLOC_FREE(*((char ***)parm_ptr));
7266 *(char ***)parm_ptr = str_list_make(
7267 NULL, pszParmValue, NULL);
7271 string_set((char **)parm_ptr, pszParmValue);
7275 string_set((char **)parm_ptr, pszParmValue);
7276 strupper_m(*(char **)parm_ptr);
7280 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7289 /***************************************************************************
7290 Process a parameter.
7291 ***************************************************************************/
7293 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7296 if (!bInGlobalSection && bGlobalOnly)
7299 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7301 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7302 pszParmName, pszParmValue));
7305 /***************************************************************************
7306 Print a parameter of the specified type.
7307 ***************************************************************************/
7309 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7315 for (i = 0; p->enum_list[i].name; i++) {
7316 if (*(int *)ptr == p->enum_list[i].value) {
7318 p->enum_list[i].name);
7325 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7329 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7333 fprintf(f, "%d", *(int *)ptr);
7337 fprintf(f, "%c", *(char *)ptr);
7341 char *o = octal_string(*(int *)ptr);
7342 fprintf(f, "%s", o);
7348 if ((char ***)ptr && *(char ***)ptr) {
7349 char **list = *(char ***)ptr;
7350 for (; *list; list++) {
7351 /* surround strings with whitespace in double quotes */
7352 if ( strchr_m( *list, ' ' ) )
7353 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7355 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7362 if (*(char **)ptr) {
7363 fprintf(f, "%s", *(char **)ptr);
7371 /***************************************************************************
7372 Check if two parameters are equal.
7373 ***************************************************************************/
7375 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7380 return (*((bool *)ptr1) == *((bool *)ptr2));
7385 return (*((int *)ptr1) == *((int *)ptr2));
7388 return (*((char *)ptr1) == *((char *)ptr2));
7391 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7396 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7401 return (p1 == p2 || strequal(p1, p2));
7409 /***************************************************************************
7410 Initialize any local varients in the sDefault table.
7411 ***************************************************************************/
7413 void init_locals(void)
7418 /***************************************************************************
7419 Process a new section (service). At this stage all sections are services.
7420 Later we'll have special sections that permit server parameters to be set.
7421 Returns True on success, False on failure.
7422 ***************************************************************************/
7424 static bool do_section(const char *pszSectionName, void *userdata)
7427 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7428 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7431 /* if we were in a global section then do the local inits */
7432 if (bInGlobalSection && !isglobal)
7435 /* if we've just struck a global section, note the fact. */
7436 bInGlobalSection = isglobal;
7438 /* check for multiple global sections */
7439 if (bInGlobalSection) {
7440 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7444 if (!bInGlobalSection && bGlobalOnly)
7447 /* if we have a current service, tidy it up before moving on */
7450 if (iServiceIndex >= 0)
7451 bRetval = service_ok(iServiceIndex);
7453 /* if all is still well, move to the next record in the services array */
7455 /* We put this here to avoid an odd message order if messages are */
7456 /* issued by the post-processing of a previous section. */
7457 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7459 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7461 DEBUG(0, ("Failed to add a new service\n"));
7470 /***************************************************************************
7471 Determine if a partcular base parameter is currentl set to the default value.
7472 ***************************************************************************/
7474 static bool is_default(int i)
7476 if (!defaults_saved)
7478 switch (parm_table[i].type) {
7480 return str_list_compare (parm_table[i].def.lvalue,
7481 *(char ***)parm_table[i].ptr);
7484 return strequal(parm_table[i].def.svalue,
7485 *(char **)parm_table[i].ptr);
7488 return parm_table[i].def.bvalue ==
7489 *(bool *)parm_table[i].ptr;
7491 return parm_table[i].def.cvalue ==
7492 *(char *)parm_table[i].ptr;
7496 return parm_table[i].def.ivalue ==
7497 *(int *)parm_table[i].ptr;
7504 /***************************************************************************
7505 Display the contents of the global structure.
7506 ***************************************************************************/
7508 static void dump_globals(FILE *f)
7511 struct param_opt_struct *data;
7513 fprintf(f, "[global]\n");
7515 for (i = 0; parm_table[i].label; i++)
7516 if (parm_table[i].p_class == P_GLOBAL &&
7517 parm_table[i].ptr &&
7518 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7519 if (defaults_saved && is_default(i))
7521 fprintf(f, "\t%s = ", parm_table[i].label);
7522 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7525 if (Globals.param_opt != NULL) {
7526 data = Globals.param_opt;
7528 fprintf(f, "\t%s = %s\n", data->key, data->value);
7535 /***************************************************************************
7536 Return True if a local parameter is currently set to the global default.
7537 ***************************************************************************/
7539 bool lp_is_default(int snum, struct parm_struct *parm)
7541 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7543 return equal_parameter(parm->type,
7544 ((char *)ServicePtrs[snum]) + pdiff,
7545 ((char *)&sDefault) + pdiff);
7548 /***************************************************************************
7549 Display the contents of a single services record.
7550 ***************************************************************************/
7552 static void dump_a_service(struct service *pService, FILE * f)
7555 struct param_opt_struct *data;
7557 if (pService != &sDefault)
7558 fprintf(f, "[%s]\n", pService->szService);
7560 for (i = 0; parm_table[i].label; i++) {
7562 if (parm_table[i].p_class == P_LOCAL &&
7563 parm_table[i].ptr &&
7564 (*parm_table[i].label != '-') &&
7565 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7568 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7570 if (pService == &sDefault) {
7571 if (defaults_saved && is_default(i))
7574 if (equal_parameter(parm_table[i].type,
7575 ((char *)pService) +
7577 ((char *)&sDefault) +
7582 fprintf(f, "\t%s = ", parm_table[i].label);
7583 print_parameter(&parm_table[i],
7584 ((char *)pService) + pdiff, f);
7589 if (pService->param_opt != NULL) {
7590 data = pService->param_opt;
7592 fprintf(f, "\t%s = %s\n", data->key, data->value);
7598 /***************************************************************************
7599 Display the contents of a parameter of a single services record.
7600 ***************************************************************************/
7602 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7605 bool result = False;
7608 fstring local_parm_name;
7610 const char *parm_opt_value;
7612 /* check for parametrical option */
7613 fstrcpy( local_parm_name, parm_name);
7614 parm_opt = strchr( local_parm_name, ':');
7619 if (strlen(parm_opt)) {
7620 parm_opt_value = lp_parm_const_string( snum,
7621 local_parm_name, parm_opt, NULL);
7622 if (parm_opt_value) {
7623 printf( "%s\n", parm_opt_value);
7630 /* check for a key and print the value */
7637 for (i = 0; parm_table[i].label; i++) {
7638 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7639 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7640 parm_table[i].ptr &&
7641 (*parm_table[i].label != '-') &&
7642 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7647 ptr = parm_table[i].ptr;
7649 struct service *pService = ServicePtrs[snum];
7650 ptr = ((char *)pService) +
7651 PTR_DIFF(parm_table[i].ptr, &sDefault);
7654 print_parameter(&parm_table[i],
7665 /***************************************************************************
7666 Return info about the requested parameter (given as a string).
7667 Return NULL when the string is not a valid parameter name.
7668 ***************************************************************************/
7670 struct parm_struct *lp_get_parameter(const char *param_name)
7672 int num = map_parameter(param_name);
7678 return &parm_table[num];
7681 /***************************************************************************
7682 Return info about the next parameter in a service.
7683 snum==GLOBAL_SECTION_SNUM gives the globals.
7684 Return NULL when out of parameters.
7685 ***************************************************************************/
7687 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7690 /* do the globals */
7691 for (; parm_table[*i].label; (*i)++) {
7692 if (parm_table[*i].p_class == P_SEPARATOR)
7693 return &parm_table[(*i)++];
7695 if (!parm_table[*i].ptr
7696 || (*parm_table[*i].label == '-'))
7700 && (parm_table[*i].ptr ==
7701 parm_table[(*i) - 1].ptr))
7704 if (is_default(*i) && !allparameters)
7707 return &parm_table[(*i)++];
7710 struct service *pService = ServicePtrs[snum];
7712 for (; parm_table[*i].label; (*i)++) {
7713 if (parm_table[*i].p_class == P_SEPARATOR)
7714 return &parm_table[(*i)++];
7716 if (parm_table[*i].p_class == P_LOCAL &&
7717 parm_table[*i].ptr &&
7718 (*parm_table[*i].label != '-') &&
7720 (parm_table[*i].ptr !=
7721 parm_table[(*i) - 1].ptr)))
7724 PTR_DIFF(parm_table[*i].ptr,
7727 if (allparameters ||
7728 !equal_parameter(parm_table[*i].type,
7729 ((char *)pService) +
7731 ((char *)&sDefault) +
7734 return &parm_table[(*i)++];
7745 /***************************************************************************
7746 Display the contents of a single copy structure.
7747 ***************************************************************************/
7748 static void dump_copy_map(bool *pcopymap)
7754 printf("\n\tNon-Copied parameters:\n");
7756 for (i = 0; parm_table[i].label; i++)
7757 if (parm_table[i].p_class == P_LOCAL &&
7758 parm_table[i].ptr && !pcopymap[i] &&
7759 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7761 printf("\t\t%s\n", parm_table[i].label);
7766 /***************************************************************************
7767 Return TRUE if the passed service number is within range.
7768 ***************************************************************************/
7770 bool lp_snum_ok(int iService)
7772 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7775 /***************************************************************************
7776 Auto-load some home services.
7777 ***************************************************************************/
7779 static void lp_add_auto_services(char *str)
7789 s = SMB_STRDUP(str);
7793 homes = lp_servicenumber(HOMES_NAME);
7795 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7796 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7799 if (lp_servicenumber(p) >= 0)
7802 home = get_user_home_dir(talloc_tos(), p);
7804 if (home && homes >= 0)
7805 lp_add_home(p, homes, p, home);
7812 /***************************************************************************
7813 Auto-load one printer.
7814 ***************************************************************************/
7816 void lp_add_one_printer(char *name, char *comment)
7818 int printers = lp_servicenumber(PRINTERS_NAME);
7821 if (lp_servicenumber(name) < 0) {
7822 lp_add_printer(name, printers);
7823 if ((i = lp_servicenumber(name)) >= 0) {
7824 string_set(&ServicePtrs[i]->comment, comment);
7825 ServicePtrs[i]->autoloaded = True;
7830 /***************************************************************************
7831 Have we loaded a services file yet?
7832 ***************************************************************************/
7834 bool lp_loaded(void)
7839 /***************************************************************************
7840 Unload unused services.
7841 ***************************************************************************/
7843 void lp_killunused(bool (*snumused) (int))
7846 for (i = 0; i < iNumServices; i++) {
7850 /* don't kill autoloaded or usershare services */
7851 if ( ServicePtrs[i]->autoloaded ||
7852 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7856 if (!snumused || !snumused(i)) {
7857 free_service_byindex(i);
7863 * Kill all except autoloaded and usershare services - convenience wrapper
7865 void lp_kill_all_services(void)
7867 lp_killunused(NULL);
7870 /***************************************************************************
7872 ***************************************************************************/
7874 void lp_killservice(int iServiceIn)
7876 if (VALID(iServiceIn)) {
7877 free_service_byindex(iServiceIn);
7881 /***************************************************************************
7882 Save the curent values of all global and sDefault parameters into the
7883 defaults union. This allows swat and testparm to show only the
7884 changed (ie. non-default) parameters.
7885 ***************************************************************************/
7887 static void lp_save_defaults(void)
7890 for (i = 0; parm_table[i].label; i++) {
7891 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7893 switch (parm_table[i].type) {
7896 NULL, &(parm_table[i].def.lvalue),
7897 *(const char ***)parm_table[i].ptr);
7901 if (parm_table[i].ptr) {
7902 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7904 parm_table[i].def.svalue = NULL;
7909 parm_table[i].def.bvalue =
7910 *(bool *)parm_table[i].ptr;
7913 parm_table[i].def.cvalue =
7914 *(char *)parm_table[i].ptr;
7919 parm_table[i].def.ivalue =
7920 *(int *)parm_table[i].ptr;
7926 defaults_saved = True;
7929 /*******************************************************************
7930 Set the server type we will announce as via nmbd.
7931 ********************************************************************/
7933 static const struct srv_role_tab {
7935 const char *role_str;
7936 } srv_role_tab [] = {
7937 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7938 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7939 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7940 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7944 const char* server_role_str(uint32 role)
7947 for (i=0; srv_role_tab[i].role_str; i++) {
7948 if (role == srv_role_tab[i].role) {
7949 return srv_role_tab[i].role_str;
7955 static void set_server_role(void)
7957 server_role = ROLE_STANDALONE;
7959 switch (lp_security()) {
7961 if (lp_domain_logons())
7962 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7965 if (lp_domain_logons())
7966 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7967 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7968 server_role = ROLE_STANDALONE;
7971 if (lp_domain_logons()) {
7972 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7973 server_role = ROLE_DOMAIN_BDC;
7976 server_role = ROLE_DOMAIN_MEMBER;
7979 if (lp_domain_logons()) {
7980 server_role = ROLE_DOMAIN_PDC;
7983 server_role = ROLE_DOMAIN_MEMBER;
7986 if (lp_domain_logons()) {
7988 if (Globals.iDomainMaster) /* auto or yes */
7989 server_role = ROLE_DOMAIN_PDC;
7991 server_role = ROLE_DOMAIN_BDC;
7995 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7999 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8002 /***********************************************************
8003 If we should send plaintext/LANMAN passwords in the clinet
8004 ************************************************************/
8006 static void set_allowed_client_auth(void)
8008 if (Globals.bClientNTLMv2Auth) {
8009 Globals.bClientLanManAuth = False;
8011 if (!Globals.bClientLanManAuth) {
8012 Globals.bClientPlaintextAuth = False;
8016 /***************************************************************************
8018 The following code allows smbd to read a user defined share file.
8019 Yes, this is my intent. Yes, I'm comfortable with that...
8021 THE FOLLOWING IS SECURITY CRITICAL CODE.
8023 It washes your clothes, it cleans your house, it guards you while you sleep...
8024 Do not f%^k with it....
8025 ***************************************************************************/
8027 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8029 /***************************************************************************
8030 Check allowed stat state of a usershare file.
8031 Ensure we print out who is dicking with us so the admin can
8032 get their sorry ass fired.
8033 ***************************************************************************/
8035 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8037 if (!S_ISREG(psbuf->st_mode)) {
8038 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8039 "not a regular file\n",
8040 fname, (unsigned int)psbuf->st_uid ));
8044 /* Ensure this doesn't have the other write bit set. */
8045 if (psbuf->st_mode & S_IWOTH) {
8046 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8047 "public write. Refusing to allow as a usershare file.\n",
8048 fname, (unsigned int)psbuf->st_uid ));
8052 /* Should be 10k or less. */
8053 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8054 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8055 "too large (%u) to be a user share file.\n",
8056 fname, (unsigned int)psbuf->st_uid,
8057 (unsigned int)psbuf->st_size ));
8064 /***************************************************************************
8065 Parse the contents of a usershare file.
8066 ***************************************************************************/
8068 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8069 SMB_STRUCT_STAT *psbuf,
8070 const char *servicename,
8074 char **pp_sharepath,
8079 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8080 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8083 SMB_STRUCT_STAT sbuf;
8084 char *sharepath = NULL;
8085 char *comment = NULL;
8087 *pp_sharepath = NULL;
8090 *pallow_guest = False;
8093 return USERSHARE_MALFORMED_FILE;
8096 if (strcmp(lines[0], "#VERSION 1") == 0) {
8098 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8101 return USERSHARE_MALFORMED_FILE;
8104 return USERSHARE_BAD_VERSION;
8107 if (strncmp(lines[1], "path=", 5) != 0) {
8108 return USERSHARE_MALFORMED_PATH;
8111 sharepath = talloc_strdup(ctx, &lines[1][5]);
8113 return USERSHARE_POSIX_ERR;
8115 trim_string(sharepath, " ", " ");
8117 if (strncmp(lines[2], "comment=", 8) != 0) {
8118 return USERSHARE_MALFORMED_COMMENT_DEF;
8121 comment = talloc_strdup(ctx, &lines[2][8]);
8123 return USERSHARE_POSIX_ERR;
8125 trim_string(comment, " ", " ");
8126 trim_char(comment, '"', '"');
8128 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8129 return USERSHARE_MALFORMED_ACL_DEF;
8132 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8133 return USERSHARE_ACL_ERR;
8137 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8138 return USERSHARE_MALFORMED_ACL_DEF;
8140 if (lines[4][9] == 'y') {
8141 *pallow_guest = True;
8145 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8146 /* Path didn't change, no checks needed. */
8147 *pp_sharepath = sharepath;
8148 *pp_comment = comment;
8149 return USERSHARE_OK;
8152 /* The path *must* be absolute. */
8153 if (sharepath[0] != '/') {
8154 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8155 servicename, sharepath));
8156 return USERSHARE_PATH_NOT_ABSOLUTE;
8159 /* If there is a usershare prefix deny list ensure one of these paths
8160 doesn't match the start of the user given path. */
8161 if (prefixdenylist) {
8163 for ( i=0; prefixdenylist[i]; i++ ) {
8164 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8165 servicename, i, prefixdenylist[i], sharepath ));
8166 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8167 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8168 "usershare prefix deny list entries.\n",
8169 servicename, sharepath));
8170 return USERSHARE_PATH_IS_DENIED;
8175 /* If there is a usershare prefix allow list ensure one of these paths
8176 does match the start of the user given path. */
8178 if (prefixallowlist) {
8180 for ( i=0; prefixallowlist[i]; i++ ) {
8181 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8182 servicename, i, prefixallowlist[i], sharepath ));
8183 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8187 if (prefixallowlist[i] == NULL) {
8188 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8189 "usershare prefix allow list entries.\n",
8190 servicename, sharepath));
8191 return USERSHARE_PATH_NOT_ALLOWED;
8195 /* Ensure this is pointing to a directory. */
8196 dp = sys_opendir(sharepath);
8199 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8200 servicename, sharepath));
8201 return USERSHARE_PATH_NOT_DIRECTORY;
8204 /* Ensure the owner of the usershare file has permission to share
8207 if (sys_stat(sharepath, &sbuf) == -1) {
8208 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8209 servicename, sharepath, strerror(errno) ));
8211 return USERSHARE_POSIX_ERR;
8216 if (!S_ISDIR(sbuf.st_mode)) {
8217 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8218 servicename, sharepath ));
8219 return USERSHARE_PATH_NOT_DIRECTORY;
8222 /* Check if sharing is restricted to owner-only. */
8223 /* psbuf is the stat of the usershare definition file,
8224 sbuf is the stat of the target directory to be shared. */
8226 if (lp_usershare_owner_only()) {
8227 /* root can share anything. */
8228 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8229 return USERSHARE_PATH_NOT_ALLOWED;
8233 *pp_sharepath = sharepath;
8234 *pp_comment = comment;
8235 return USERSHARE_OK;
8238 /***************************************************************************
8239 Deal with a usershare file.
8242 -1 - Bad name, invalid contents.
8243 - service name already existed and not a usershare, problem
8244 with permissions to share directory etc.
8245 ***************************************************************************/
8247 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8249 SMB_STRUCT_STAT sbuf;
8250 SMB_STRUCT_STAT lsbuf;
8252 char *sharepath = NULL;
8253 char *comment = NULL;
8254 fstring service_name;
8255 char **lines = NULL;
8259 TALLOC_CTX *ctx = NULL;
8260 SEC_DESC *psd = NULL;
8261 bool guest_ok = False;
8263 /* Ensure share name doesn't contain invalid characters. */
8264 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8265 DEBUG(0,("process_usershare_file: share name %s contains "
8266 "invalid characters (any of %s)\n",
8267 file_name, INVALID_SHARENAME_CHARS ));
8271 fstrcpy(service_name, file_name);
8273 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8276 /* Minimize the race condition by doing an lstat before we
8277 open and fstat. Ensure this isn't a symlink link. */
8279 if (sys_lstat(fname, &lsbuf) != 0) {
8280 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8281 fname, strerror(errno) ));
8286 /* This must be a regular file, not a symlink, directory or
8287 other strange filetype. */
8288 if (!check_usershare_stat(fname, &lsbuf)) {
8294 char *canon_name = canonicalize_servicename(service_name);
8295 TDB_DATA data = dbwrap_fetch_bystring(
8296 ServiceHash, canon_name, canon_name);
8300 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8301 iService = *(int *)data.dptr;
8303 TALLOC_FREE(canon_name);
8306 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8307 /* Nothing changed - Mark valid and return. */
8308 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8310 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8315 /* Try and open the file read only - no symlinks allowed. */
8317 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8319 fd = sys_open(fname, O_RDONLY, 0);
8323 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8324 fname, strerror(errno) ));
8329 /* Now fstat to be *SURE* it's a regular file. */
8330 if (sys_fstat(fd, &sbuf) != 0) {
8332 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8333 fname, strerror(errno) ));
8338 /* Is it the same dev/inode as was lstated ? */
8339 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8341 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8342 "Symlink spoofing going on ?\n", fname ));
8347 /* This must be a regular file, not a symlink, directory or
8348 other strange filetype. */
8349 if (!check_usershare_stat(fname, &sbuf)) {
8354 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8357 if (lines == NULL) {
8358 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8359 fname, (unsigned int)sbuf.st_uid ));
8366 /* Should we allow printers to be shared... ? */
8367 ctx = talloc_init("usershare_sd_xctx");
8369 file_lines_free(lines);
8373 if (parse_usershare_file(ctx, &sbuf, service_name,
8374 iService, lines, numlines, &sharepath,
8375 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8376 talloc_destroy(ctx);
8377 file_lines_free(lines);
8381 file_lines_free(lines);
8383 /* Everything ok - add the service possibly using a template. */
8385 const struct service *sp = &sDefault;
8386 if (snum_template != -1) {
8387 sp = ServicePtrs[snum_template];
8390 if ((iService = add_a_service(sp, service_name)) < 0) {
8391 DEBUG(0, ("process_usershare_file: Failed to add "
8392 "new service %s\n", service_name));
8393 talloc_destroy(ctx);
8397 /* Read only is controlled by usershare ACL below. */
8398 ServicePtrs[iService]->bRead_only = False;
8401 /* Write the ACL of the new/modified share. */
8402 if (!set_share_security(service_name, psd)) {
8403 DEBUG(0, ("process_usershare_file: Failed to set share "
8404 "security for user share %s\n",
8406 lp_remove_service(iService);
8407 talloc_destroy(ctx);
8411 /* If from a template it may be marked invalid. */
8412 ServicePtrs[iService]->valid = True;
8414 /* Set the service as a valid usershare. */
8415 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8417 /* Set guest access. */
8418 if (lp_usershare_allow_guests()) {
8419 ServicePtrs[iService]->bGuest_ok = guest_ok;
8422 /* And note when it was loaded. */
8423 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8424 string_set(&ServicePtrs[iService]->szPath, sharepath);
8425 string_set(&ServicePtrs[iService]->comment, comment);
8427 talloc_destroy(ctx);
8432 /***************************************************************************
8433 Checks if a usershare entry has been modified since last load.
8434 ***************************************************************************/
8436 static bool usershare_exists(int iService, time_t *last_mod)
8438 SMB_STRUCT_STAT lsbuf;
8439 const char *usersharepath = Globals.szUsersharePath;
8442 if (asprintf(&fname, "%s/%s",
8444 ServicePtrs[iService]->szService) < 0) {
8448 if (sys_lstat(fname, &lsbuf) != 0) {
8453 if (!S_ISREG(lsbuf.st_mode)) {
8459 *last_mod = lsbuf.st_mtime;
8463 /***************************************************************************
8464 Load a usershare service by name. Returns a valid servicenumber or -1.
8465 ***************************************************************************/
8467 int load_usershare_service(const char *servicename)
8469 SMB_STRUCT_STAT sbuf;
8470 const char *usersharepath = Globals.szUsersharePath;
8471 int max_user_shares = Globals.iUsershareMaxShares;
8472 int snum_template = -1;
8474 if (*usersharepath == 0 || max_user_shares == 0) {
8478 if (sys_stat(usersharepath, &sbuf) != 0) {
8479 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8480 usersharepath, strerror(errno) ));
8484 if (!S_ISDIR(sbuf.st_mode)) {
8485 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8491 * This directory must be owned by root, and have the 't' bit set.
8492 * It also must not be writable by "other".
8496 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8498 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8500 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8501 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8506 /* Ensure the template share exists if it's set. */
8507 if (Globals.szUsershareTemplateShare[0]) {
8508 /* We can't use lp_servicenumber here as we are recommending that
8509 template shares have -valid=False set. */
8510 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8511 if (ServicePtrs[snum_template]->szService &&
8512 strequal(ServicePtrs[snum_template]->szService,
8513 Globals.szUsershareTemplateShare)) {
8518 if (snum_template == -1) {
8519 DEBUG(0,("load_usershare_service: usershare template share %s "
8520 "does not exist.\n",
8521 Globals.szUsershareTemplateShare ));
8526 return process_usershare_file(usersharepath, servicename, snum_template);
8529 /***************************************************************************
8530 Load all user defined shares from the user share directory.
8531 We only do this if we're enumerating the share list.
8532 This is the function that can delete usershares that have
8534 ***************************************************************************/
8536 int load_usershare_shares(void)
8539 SMB_STRUCT_STAT sbuf;
8540 SMB_STRUCT_DIRENT *de;
8541 int num_usershares = 0;
8542 int max_user_shares = Globals.iUsershareMaxShares;
8543 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8544 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8545 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8547 int snum_template = -1;
8548 const char *usersharepath = Globals.szUsersharePath;
8549 int ret = lp_numservices();
8551 if (max_user_shares == 0 || *usersharepath == '\0') {
8552 return lp_numservices();
8555 if (sys_stat(usersharepath, &sbuf) != 0) {
8556 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8557 usersharepath, strerror(errno) ));
8562 * This directory must be owned by root, and have the 't' bit set.
8563 * It also must not be writable by "other".
8567 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8569 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8571 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8572 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8577 /* Ensure the template share exists if it's set. */
8578 if (Globals.szUsershareTemplateShare[0]) {
8579 /* We can't use lp_servicenumber here as we are recommending that
8580 template shares have -valid=False set. */
8581 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8582 if (ServicePtrs[snum_template]->szService &&
8583 strequal(ServicePtrs[snum_template]->szService,
8584 Globals.szUsershareTemplateShare)) {
8589 if (snum_template == -1) {
8590 DEBUG(0,("load_usershare_shares: usershare template share %s "
8591 "does not exist.\n",
8592 Globals.szUsershareTemplateShare ));
8597 /* Mark all existing usershares as pending delete. */
8598 for (iService = iNumServices - 1; iService >= 0; iService--) {
8599 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8600 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8604 dp = sys_opendir(usersharepath);
8606 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8607 usersharepath, strerror(errno) ));
8611 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8612 (de = sys_readdir(dp));
8613 num_dir_entries++ ) {
8615 const char *n = de->d_name;
8617 /* Ignore . and .. */
8619 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8625 /* Temporary file used when creating a share. */
8626 num_tmp_dir_entries++;
8629 /* Allow 20% tmp entries. */
8630 if (num_tmp_dir_entries > allowed_tmp_entries) {
8631 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8632 "in directory %s\n",
8633 num_tmp_dir_entries, usersharepath));
8637 r = process_usershare_file(usersharepath, n, snum_template);
8639 /* Update the services count. */
8641 if (num_usershares >= max_user_shares) {
8642 DEBUG(0,("load_usershare_shares: max user shares reached "
8643 "on file %s in directory %s\n",
8644 n, usersharepath ));
8647 } else if (r == -1) {
8648 num_bad_dir_entries++;
8651 /* Allow 20% bad entries. */
8652 if (num_bad_dir_entries > allowed_bad_entries) {
8653 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8654 "in directory %s\n",
8655 num_bad_dir_entries, usersharepath));
8659 /* Allow 20% bad entries. */
8660 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8661 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8662 "in directory %s\n",
8663 num_dir_entries, usersharepath));
8670 /* Sweep through and delete any non-refreshed usershares that are
8671 not currently in use. */
8672 for (iService = iNumServices - 1; iService >= 0; iService--) {
8673 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8674 if (conn_snum_used(iService)) {
8677 /* Remove from the share ACL db. */
8678 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8679 lp_servicename(iService) ));
8680 delete_share_security(lp_servicename(iService));
8681 free_service_byindex(iService);
8685 return lp_numservices();
8688 /********************************************************
8689 Destroy global resources allocated in this file
8690 ********************************************************/
8692 void gfree_loadparm(void)
8694 struct file_lists *f;
8695 struct file_lists *next;
8698 /* Free the file lists */
8703 SAFE_FREE( f->name );
8704 SAFE_FREE( f->subfname );
8710 /* Free resources allocated to services */
8712 for ( i = 0; i < iNumServices; i++ ) {
8714 free_service_byindex(i);
8718 SAFE_FREE( ServicePtrs );
8721 /* Now release all resources allocated to global
8722 parameters and the default service */
8724 for (i = 0; parm_table[i].label; i++)
8726 if ( parm_table[i].type == P_STRING
8727 || parm_table[i].type == P_USTRING )
8729 string_free( (char**)parm_table[i].ptr );
8731 else if (parm_table[i].type == P_LIST) {
8732 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8738 /***************************************************************************
8739 Allow client apps to specify that they are a client
8740 ***************************************************************************/
8741 void lp_set_in_client(bool b)
8747 /***************************************************************************
8748 Determine if we're running in a client app
8749 ***************************************************************************/
8750 bool lp_is_in_client(void)
8758 /***************************************************************************
8759 Load the services array from the services file. Return True on success,
8761 ***************************************************************************/
8763 bool lp_load_ex(const char *pszFname,
8767 bool initialize_globals,
8768 bool allow_include_registry,
8769 bool allow_registry_shares)
8773 struct param_opt_struct *data, *pdata;
8777 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8779 bInGlobalSection = True;
8780 bGlobalOnly = global_only;
8781 bAllowIncludeRegistry = allow_include_registry;
8783 init_globals(! initialize_globals);
8786 if (save_defaults) {
8791 /* We get sections first, so have to start 'behind' to make up */
8794 if (Globals.param_opt != NULL) {
8795 data = Globals.param_opt;
8797 string_free(&data->key);
8798 string_free(&data->value);
8799 TALLOC_FREE(data->list);
8804 Globals.param_opt = NULL;
8807 if (lp_config_backend_is_file()) {
8808 n2 = alloc_sub_basic(get_current_username(),
8809 current_user_info.domain,
8812 smb_panic("lp_load_ex: out of memory");
8815 add_to_file_list(pszFname, n2);
8817 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8820 /* finish up the last section */
8821 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8823 if (iServiceIndex >= 0) {
8824 bRetval = service_ok(iServiceIndex);
8828 if (lp_config_backend_is_registry()) {
8829 /* config backend changed to registry in config file */
8831 * We need to use this extra global variable here to
8832 * survive restart: init_globals uses this as a default
8833 * for ConfigBackend. Otherwise, init_globals would
8834 * send us into an endless loop here.
8836 config_backend = CONFIG_BACKEND_REGISTRY;
8838 DEBUG(1, ("lp_load_ex: changing to config backend "
8840 init_globals(false);
8841 lp_kill_all_services();
8842 return lp_load_ex(pszFname, global_only, save_defaults,
8843 add_ipc, initialize_globals,
8844 allow_include_registry,
8845 allow_registry_shares);
8847 } else if (lp_config_backend_is_registry()) {
8848 bRetval = process_registry_globals();
8850 DEBUG(0, ("Illegal config backend given: %d\n",
8851 lp_config_backend()));
8855 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8856 bRetval = process_registry_shares();
8859 lp_add_auto_services(lp_auto_services());
8862 /* When 'restrict anonymous = 2' guest connections to ipc$
8864 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8865 if ( lp_enable_asu_support() ) {
8866 lp_add_ipc("ADMIN$", false);
8871 set_default_server_announce_type();
8872 set_allowed_client_auth();
8876 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8877 /* if bWINSsupport is true and we are in the client */
8878 if (lp_is_in_client() && Globals.bWINSsupport) {
8879 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8884 bAllowIncludeRegistry = true;
8889 bool lp_load(const char *pszFname,
8893 bool initialize_globals)
8895 return lp_load_ex(pszFname,
8903 bool lp_load_initial_only(const char *pszFname)
8905 return lp_load_ex(pszFname,
8914 bool lp_load_with_registry_shares(const char *pszFname,
8918 bool initialize_globals)
8920 return lp_load_ex(pszFname,
8929 /***************************************************************************
8930 Return the max number of services.
8931 ***************************************************************************/
8933 int lp_numservices(void)
8935 return (iNumServices);
8938 /***************************************************************************
8939 Display the contents of the services array in human-readable form.
8940 ***************************************************************************/
8942 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8947 defaults_saved = False;
8951 dump_a_service(&sDefault, f);
8953 for (iService = 0; iService < maxtoprint; iService++) {
8955 lp_dump_one(f, show_defaults, iService);
8959 /***************************************************************************
8960 Display the contents of one service in human-readable form.
8961 ***************************************************************************/
8963 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8966 if (ServicePtrs[snum]->szService[0] == '\0')
8968 dump_a_service(ServicePtrs[snum], f);
8972 /***************************************************************************
8973 Return the number of the service with the given name, or -1 if it doesn't
8974 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8975 getservicebyname()! This works ONLY if all services have been loaded, and
8976 does not copy the found service.
8977 ***************************************************************************/
8979 int lp_servicenumber(const char *pszServiceName)
8982 fstring serviceName;
8984 if (!pszServiceName) {
8985 return GLOBAL_SECTION_SNUM;
8988 for (iService = iNumServices - 1; iService >= 0; iService--) {
8989 if (VALID(iService) && ServicePtrs[iService]->szService) {
8991 * The substitution here is used to support %U is
8994 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8995 standard_sub_basic(get_current_username(),
8996 current_user_info.domain,
8997 serviceName,sizeof(serviceName));
8998 if (strequal(serviceName, pszServiceName)) {
9004 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9007 if (!usershare_exists(iService, &last_mod)) {
9008 /* Remove the share security tdb entry for it. */
9009 delete_share_security(lp_servicename(iService));
9010 /* Remove it from the array. */
9011 free_service_byindex(iService);
9012 /* Doesn't exist anymore. */
9013 return GLOBAL_SECTION_SNUM;
9016 /* Has it been modified ? If so delete and reload. */
9017 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9018 /* Remove it from the array. */
9019 free_service_byindex(iService);
9020 /* and now reload it. */
9021 iService = load_usershare_service(pszServiceName);
9026 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9027 return GLOBAL_SECTION_SNUM;
9033 bool share_defined(const char *service_name)
9035 return (lp_servicenumber(service_name) != -1);
9038 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9039 const char *sharename)
9041 struct share_params *result;
9045 if (!(sname = SMB_STRDUP(sharename))) {
9049 snum = find_service(sname);
9056 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9057 DEBUG(0, ("talloc failed\n"));
9061 result->service = snum;
9065 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9067 struct share_iterator *result;
9069 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9070 DEBUG(0, ("talloc failed\n"));
9074 result->next_id = 0;
9078 struct share_params *next_share(struct share_iterator *list)
9080 struct share_params *result;
9082 while (!lp_snum_ok(list->next_id) &&
9083 (list->next_id < lp_numservices())) {
9087 if (list->next_id >= lp_numservices()) {
9091 if (!(result = TALLOC_P(list, struct share_params))) {
9092 DEBUG(0, ("talloc failed\n"));
9096 result->service = list->next_id;
9101 struct share_params *next_printer(struct share_iterator *list)
9103 struct share_params *result;
9105 while ((result = next_share(list)) != NULL) {
9106 if (lp_print_ok(result->service)) {
9114 * This is a hack for a transition period until we transformed all code from
9115 * service numbers to struct share_params.
9118 struct share_params *snum2params_static(int snum)
9120 static struct share_params result;
9121 result.service = snum;
9125 /*******************************************************************
9126 A useful volume label function.
9127 ********************************************************************/
9129 const char *volume_label(int snum)
9132 const char *label = lp_volume(snum);
9134 label = lp_servicename(snum);
9137 /* This returns a 33 byte guarenteed null terminated string. */
9138 ret = talloc_strndup(talloc_tos(), label, 32);
9145 /*******************************************************************
9146 Set the server type we will announce as via nmbd.
9147 ********************************************************************/
9149 static void set_default_server_announce_type(void)
9151 default_server_announce = 0;
9152 default_server_announce |= SV_TYPE_WORKSTATION;
9153 default_server_announce |= SV_TYPE_SERVER;
9154 default_server_announce |= SV_TYPE_SERVER_UNIX;
9156 /* note that the flag should be set only if we have a
9157 printer service but nmbd doesn't actually load the
9158 services so we can't tell --jerry */
9160 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9162 switch (lp_announce_as()) {
9163 case ANNOUNCE_AS_NT_SERVER:
9164 default_server_announce |= SV_TYPE_SERVER_NT;
9165 /* fall through... */
9166 case ANNOUNCE_AS_NT_WORKSTATION:
9167 default_server_announce |= SV_TYPE_NT;
9169 case ANNOUNCE_AS_WIN95:
9170 default_server_announce |= SV_TYPE_WIN95_PLUS;
9172 case ANNOUNCE_AS_WFW:
9173 default_server_announce |= SV_TYPE_WFW;
9179 switch (lp_server_role()) {
9180 case ROLE_DOMAIN_MEMBER:
9181 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9183 case ROLE_DOMAIN_PDC:
9184 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9186 case ROLE_DOMAIN_BDC:
9187 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9189 case ROLE_STANDALONE:
9193 if (lp_time_server())
9194 default_server_announce |= SV_TYPE_TIME_SOURCE;
9196 if (lp_host_msdfs())
9197 default_server_announce |= SV_TYPE_DFS_SERVER;
9200 /***********************************************************
9201 returns role of Samba server
9202 ************************************************************/
9204 int lp_server_role(void)
9209 /***********************************************************
9210 If we are PDC then prefer us as DMB
9211 ************************************************************/
9213 bool lp_domain_master(void)
9215 if (Globals.iDomainMaster == Auto)
9216 return (lp_server_role() == ROLE_DOMAIN_PDC);
9218 return (bool)Globals.iDomainMaster;
9221 /***********************************************************
9222 If we are DMB then prefer us as LMB
9223 ************************************************************/
9225 bool lp_preferred_master(void)
9227 if (Globals.iPreferredMaster == Auto)
9228 return (lp_local_master() && lp_domain_master());
9230 return (bool)Globals.iPreferredMaster;
9233 /*******************************************************************
9235 ********************************************************************/
9237 void lp_remove_service(int snum)
9239 ServicePtrs[snum]->valid = False;
9240 invalid_services[num_invalid_services++] = snum;
9243 /*******************************************************************
9245 ********************************************************************/
9247 void lp_copy_service(int snum, const char *new_name)
9249 do_section(new_name, NULL);
9251 snum = lp_servicenumber(new_name);
9253 lp_do_parameter(snum, "copy", lp_servicename(snum));
9258 /*******************************************************************
9259 Get the default server type we will announce as via nmbd.
9260 ********************************************************************/
9262 int lp_default_server_announce(void)
9264 return default_server_announce;
9267 /*******************************************************************
9268 Split the announce version into major and minor numbers.
9269 ********************************************************************/
9271 int lp_major_announce_version(void)
9273 static bool got_major = False;
9274 static int major_version = DEFAULT_MAJOR_VERSION;
9279 return major_version;
9282 if ((vers = lp_announce_version()) == NULL)
9283 return major_version;
9285 if ((p = strchr_m(vers, '.')) == 0)
9286 return major_version;
9289 major_version = atoi(vers);
9290 return major_version;
9293 int lp_minor_announce_version(void)
9295 static bool got_minor = False;
9296 static int minor_version = DEFAULT_MINOR_VERSION;
9301 return minor_version;
9304 if ((vers = lp_announce_version()) == NULL)
9305 return minor_version;
9307 if ((p = strchr_m(vers, '.')) == 0)
9308 return minor_version;
9311 minor_version = atoi(p);
9312 return minor_version;
9315 /***********************************************************
9316 Set the global name resolution order (used in smbclient).
9317 ************************************************************/
9319 void lp_set_name_resolve_order(const char *new_order)
9321 string_set(&Globals.szNameResolveOrder, new_order);
9324 const char *lp_printername(int snum)
9326 const char *ret = _lp_printername(snum);
9327 if (ret == NULL || (ret != NULL && *ret == '\0'))
9328 ret = lp_const_servicename(snum);
9334 /***********************************************************
9335 Allow daemons such as winbindd to fix their logfile name.
9336 ************************************************************/
9338 void lp_set_logfile(const char *name)
9340 string_set(&Globals.szLogFile, name);
9341 debug_set_logfile(name);
9344 /*******************************************************************
9345 Return the max print jobs per queue.
9346 ********************************************************************/
9348 int lp_maxprintjobs(int snum)
9350 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9351 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9352 maxjobs = PRINT_MAX_JOBID - 1;
9357 const char *lp_printcapname(void)
9359 if ((Globals.szPrintcapname != NULL) &&
9360 (Globals.szPrintcapname[0] != '\0'))
9361 return Globals.szPrintcapname;
9363 if (sDefault.iPrinting == PRINT_CUPS) {
9371 if (sDefault.iPrinting == PRINT_BSD)
9372 return "/etc/printcap";
9374 return PRINTCAP_NAME;
9377 /*******************************************************************
9378 Ensure we don't use sendfile if server smb signing is active.
9379 ********************************************************************/
9381 static uint32 spoolss_state;
9383 bool lp_disable_spoolss( void )
9385 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9386 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9388 return spoolss_state == SVCCTL_STOPPED ? True : False;
9391 void lp_set_spoolss_state( uint32 state )
9393 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9395 spoolss_state = state;
9398 uint32 lp_get_spoolss_state( void )
9400 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9403 /*******************************************************************
9404 Ensure we don't use sendfile if server smb signing is active.
9405 ********************************************************************/
9407 bool lp_use_sendfile(int snum)
9409 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9410 if (Protocol < PROTOCOL_NT1) {
9413 return (_lp_use_sendfile(snum) &&
9414 (get_remote_arch() != RA_WIN95) &&
9415 !srv_is_signing_active());
9418 /*******************************************************************
9419 Turn off sendfile if we find the underlying OS doesn't support it.
9420 ********************************************************************/
9422 void set_use_sendfile(int snum, bool val)
9424 if (LP_SNUM_OK(snum))
9425 ServicePtrs[snum]->bUseSendfile = val;
9427 sDefault.bUseSendfile = val;
9430 /*******************************************************************
9431 Turn off storing DOS attributes if this share doesn't support it.
9432 ********************************************************************/
9434 void set_store_dos_attributes(int snum, bool val)
9436 if (!LP_SNUM_OK(snum))
9438 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9441 void lp_set_mangling_method(const char *new_method)
9443 string_set(&Globals.szManglingMethod, new_method);
9446 /*******************************************************************
9447 Global state for POSIX pathname processing.
9448 ********************************************************************/
9450 static bool posix_pathnames;
9452 bool lp_posix_pathnames(void)
9454 return posix_pathnames;
9457 /*******************************************************************
9458 Change everything needed to ensure POSIX pathname processing (currently
9460 ********************************************************************/
9462 void lp_set_posix_pathnames(void)
9464 posix_pathnames = True;
9467 /*******************************************************************
9468 Global state for POSIX lock processing - CIFS unix extensions.
9469 ********************************************************************/
9471 bool posix_default_lock_was_set;
9472 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9474 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9476 if (posix_default_lock_was_set) {
9477 return posix_cifsx_locktype;
9479 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9483 /*******************************************************************
9484 ********************************************************************/
9486 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9488 posix_default_lock_was_set = True;
9489 posix_cifsx_locktype = val;
9492 int lp_min_receive_file_size(void)
9494 if (Globals.iminreceivefile < 0) {
9497 return MIN(Globals.iminreceivefile, BUFFER_SIZE);