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 typedef struct _param_opt_struct param_opt_struct;
101 struct _param_opt_struct {
102 param_opt_struct *prev, *next;
109 * This structure describes global (ie., server-wide) parameters.
116 char *display_charset;
117 char *szPrintcapname;
118 char *szAddPortCommand;
119 char *szEnumPortsCommand;
120 char *szAddPrinterCommand;
121 char *szDeletePrinterCommand;
122 char *szOs2DriverMap;
126 char *szDefaultService;
130 char *szServerString;
131 char *szAutoServices;
132 char *szPasswdProgram;
136 char *szSMBPasswdFile;
138 char *szPassdbBackend;
139 char **szPreloadModules;
140 char *szPasswordServer;
141 char *szSocketOptions;
143 char *szAfsUsernameMap;
144 int iAfsTokenLifetime;
145 char *szLogNtTokenCommand;
151 char **szWINSservers;
153 char *szRemoteAnnounce;
154 char *szRemoteBrowseSync;
155 char *szSocketAddress;
156 char *szNISHomeMapName;
157 char *szAnnounceVersion; /* This is initialised in init_globals */
160 char **szNetbiosAliases;
161 char *szNetbiosScope;
162 char *szNameResolveOrder;
164 char *szAddUserScript;
165 char *szRenameUserScript;
166 char *szDelUserScript;
167 char *szAddGroupScript;
168 char *szDelGroupScript;
169 char *szAddUserToGroupScript;
170 char *szDelUserFromGroupScript;
171 char *szSetPrimaryGroupScript;
172 char *szAddMachineScript;
173 char *szShutdownScript;
174 char *szAbortShutdownScript;
175 char *szUsernameMapScript;
176 char *szCheckPasswordScript;
183 bool bPassdbExpandExplicit;
184 int AlgorithmicRidBase;
185 char *szTemplateHomedir;
186 char *szTemplateShell;
187 char *szWinbindSeparator;
188 bool bWinbindEnumUsers;
189 bool bWinbindEnumGroups;
190 bool bWinbindUseDefaultDomain;
191 bool bWinbindTrustedDomainsOnly;
192 bool bWinbindNestedGroups;
193 int winbind_expand_groups;
194 bool bWinbindRefreshTickets;
195 bool bWinbindOfflineLogon;
196 bool bWinbindNormalizeNames;
197 bool bWinbindRpcOnly;
198 char *szIdmapBackend;
199 char *szIdmapAllocBackend;
200 char *szAddShareCommand;
201 char *szChangeShareCommand;
202 char *szDeleteShareCommand;
204 char *szGuestaccount;
205 char *szManglingMethod;
206 char **szServicesList;
207 char *szUsersharePath;
208 char *szUsershareTemplateShare;
209 char **szUsersharePrefixAllowList;
210 char **szUsersharePrefixDenyList;
217 int open_files_db_hash_size;
226 bool paranoid_server_security;
229 int iMaxSmbdProcesses;
230 bool bDisableSpoolss;
233 bool enhanced_browsing;
239 int announce_as; /* This is initialised in init_globals */
240 int machine_password_timeout;
242 int oplock_break_wait_time;
243 int winbind_cache_time;
244 int winbind_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 bool bEncryptPasswords;
281 bool bObeyPamRestrictions;
283 int PrintcapCacheTime;
284 bool bLargeReadwrite;
291 bool bBindInterfacesOnly;
292 bool bPamPasswordChange;
293 bool bUnixPasswdSync;
294 bool bPasswdChatDebug;
295 int iPasswdChatTimeout;
299 bool bNTStatusSupport;
301 int iMaxStatCacheSize;
303 bool bAllowTrustedDomains;
307 bool bClientLanManAuth;
308 bool bClientNTLMv2Auth;
309 bool bClientPlaintextAuth;
310 bool bClientUseSpnego;
311 bool bDebugPrefixTimestamp;
312 bool bDebugHiresTimestamp;
316 bool bEnableCoreFiles;
319 bool bHostnameLookups;
320 bool bUnixExtensions;
321 bool bDisableNetbios;
322 bool bUseKerberosKeytab;
323 bool bDeferSharingViolations;
324 bool bEnablePrivileges;
326 bool bUsershareOwnerOnly;
327 bool bUsershareAllowGuests;
328 bool bRegistryShares;
329 int restrict_anonymous;
330 int name_cache_timeout;
333 int client_ldap_sasl_wrapping;
334 int iUsershareMaxShares;
336 int iIdmapNegativeCacheTime;
340 param_opt_struct *param_opt;
343 static struct global Globals;
346 * This structure describes a single service.
352 time_t usershare_last_mod;
356 char **szInvalidUsers;
364 char *szRootPostExec;
366 char *szPrintcommand;
369 char *szLppausecommand;
370 char *szLpresumecommand;
371 char *szQueuepausecommand;
372 char *szQueueresumecommand;
374 char *szPrintjobUsername;
382 char *szVetoOplockFiles;
388 char **printer_admin;
393 char *szAioWriteBehind;
397 int iMaxReportedPrintJobs;
400 int iCreate_force_mode;
402 int iSecurity_force_mode;
405 int iDir_Security_mask;
406 int iDir_Security_force_mode;
410 int iOplockContentionLimit;
415 bool bRootpreexecClose;
418 bool bShortCasePreserve;
420 bool bHideSpecialFiles;
421 bool bHideUnReadable;
422 bool bHideUnWriteableFiles;
428 bool bAdministrative_share;
434 bool bStoreDosAttributes;
447 bool bStrictAllocate;
450 struct bitmap *copymap;
451 bool bDeleteReadonly;
453 bool bDeleteVetoFiles;
456 bool bDosFiletimeResolution;
457 bool bFakeDirCreateTimes;
463 bool bUseClientDriver;
464 bool bDefaultDevmode;
465 bool bForcePrintername;
467 bool bForceUnknownAclUser;
470 bool bMap_acl_inherit;
473 bool bAclCheckPermissions;
474 bool bAclMapFullControl;
475 bool bAclGroupControl;
477 bool bKernelChangeNotify;
478 int iallocation_roundup_size;
482 int iDirectoryNameCacheSize;
484 param_opt_struct *param_opt;
486 char dummy[3]; /* for alignment */
490 /* This is a default service used to prime a services structure */
491 static struct service sDefault = {
493 False, /* not autoloaded */
494 0, /* not a usershare */
495 (time_t)0, /* No last mod time */
496 NULL, /* szService */
498 NULL, /* szUsername */
499 NULL, /* szInvalidUsers */
500 NULL, /* szValidUsers */
501 NULL, /* szAdminUsers */
503 NULL, /* szInclude */
504 NULL, /* szPreExec */
505 NULL, /* szPostExec */
506 NULL, /* szRootPreExec */
507 NULL, /* szRootPostExec */
508 NULL, /* szCupsOptions */
509 NULL, /* szPrintcommand */
510 NULL, /* szLpqcommand */
511 NULL, /* szLprmcommand */
512 NULL, /* szLppausecommand */
513 NULL, /* szLpresumecommand */
514 NULL, /* szQueuepausecommand */
515 NULL, /* szQueueresumecommand */
516 NULL, /* szPrintername */
517 NULL, /* szPrintjobUsername */
518 NULL, /* szDontdescend */
519 NULL, /* szHostsallow */
520 NULL, /* szHostsdeny */
521 NULL, /* szMagicScript */
522 NULL, /* szMagicOutput */
523 NULL, /* szVetoFiles */
524 NULL, /* szHideFiles */
525 NULL, /* szVetoOplockFiles */
527 NULL, /* force user */
528 NULL, /* force group */
530 NULL, /* writelist */
531 NULL, /* printer admin */
534 NULL, /* vfs objects */
535 NULL, /* szMSDfsProxy */
536 NULL, /* szAioWriteBehind */
538 0, /* iMinPrintSpace */
539 1000, /* iMaxPrintJobs */
540 0, /* iMaxReportedPrintJobs */
541 0, /* iWriteCacheSize */
542 0744, /* iCreate_mask */
543 0000, /* iCreate_force_mode */
544 0777, /* iSecurity_mask */
545 0, /* iSecurity_force_mode */
546 0755, /* iDir_mask */
547 0000, /* iDir_force_mode */
548 0777, /* iDir_Security_mask */
549 0, /* iDir_Security_force_mode */
550 0, /* iMaxConnections */
551 CASE_LOWER, /* iDefaultCase */
552 DEFAULT_PRINTING, /* iPrinting */
553 2, /* iOplockContentionLimit */
555 1024, /* iBlock_size */
556 0, /* iDfreeCacheTime */
557 False, /* bPreexecClose */
558 False, /* bRootpreexecClose */
559 Auto, /* case sensitive */
560 True, /* case preserve */
561 True, /* short case preserve */
562 True, /* bHideDotFiles */
563 False, /* bHideSpecialFiles */
564 False, /* bHideUnReadable */
565 False, /* bHideUnWriteableFiles */
566 True, /* bBrowseable */
567 True, /* bAvailable */
568 True, /* bRead_only */
569 True, /* bNo_set_dir */
570 False, /* bGuest_only */
571 False, /* bAdministrative_share */
572 False, /* bGuest_ok */
573 False, /* bPrint_ok */
574 False, /* bMap_system */
575 False, /* bMap_hidden */
576 True, /* bMap_archive */
577 False, /* bStoreDosAttributes */
578 False, /* bDmapiSupport */
580 Auto, /* iStrictLocking */
581 True, /* bPosixLocking */
582 True, /* bShareModes */
584 True, /* bLevel2OpLocks */
585 False, /* bOnlyUser */
586 True, /* bMangledNames */
587 True, /* bWidelinks */
588 True, /* bSymlinks */
589 False, /* bSyncAlways */
590 False, /* bStrictAllocate */
591 False, /* bStrictSync */
592 '~', /* magic char */
594 False, /* bDeleteReadonly */
595 False, /* bFakeOplocks */
596 False, /* bDeleteVetoFiles */
597 False, /* bDosFilemode */
598 True, /* bDosFiletimes */
599 False, /* bDosFiletimeResolution */
600 False, /* bFakeDirCreateTimes */
601 True, /* bBlockingLocks */
602 False, /* bInheritPerms */
603 False, /* bInheritACLS */
604 False, /* bInheritOwner */
605 False, /* bMSDfsRoot */
606 False, /* bUseClientDriver */
607 True, /* bDefaultDevmode */
608 False, /* bForcePrintername */
609 True, /* bNTAclSupport */
610 False, /* bForceUnknownAclUser */
611 False, /* bUseSendfile */
612 False, /* bProfileAcls */
613 False, /* bMap_acl_inherit */
614 False, /* bAfs_Share */
615 False, /* bEASupport */
616 True, /* bAclCheckPermissions */
617 True, /* bAclMapFullControl */
618 False, /* bAclGroupControl */
619 True, /* bChangeNotify */
620 True, /* bKernelChangeNotify */
621 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
622 0, /* iAioReadSize */
623 0, /* iAioWriteSize */
624 MAP_READONLY_YES, /* iMap_readonly */
625 #ifdef BROKEN_DIRECTORY_HANDLING
626 0, /* iDirectoryNameCacheSize */
628 100, /* iDirectoryNameCacheSize */
630 Auto, /* ismb_encrypt */
631 NULL, /* Parametric options */
636 /* local variables */
637 static struct service **ServicePtrs = NULL;
638 static int iNumServices = 0;
639 static int iServiceIndex = 0;
640 static struct db_context *ServiceHash;
641 static int *invalid_services = NULL;
642 static int num_invalid_services = 0;
643 static bool bInGlobalSection = True;
644 static bool bGlobalOnly = False;
645 static int server_role;
646 static int default_server_announce;
648 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
650 /* prototypes for the special type handlers */
651 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
652 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
653 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
654 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
655 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
656 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
657 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
658 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
659 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
660 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
661 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
662 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
664 static void set_server_role(void);
665 static void set_default_server_announce_type(void);
666 static void set_allowed_client_auth(void);
668 static void add_to_file_list(const char *fname, const char *subfname);
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. Parameters 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) parameters:
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,
3195 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3198 .label = "os level",
3200 .p_class = P_GLOBAL,
3201 .ptr = &Globals.os_level,
3204 .flags = FLAG_BASIC | FLAG_ADVANCED,
3207 .label = "lm announce",
3209 .p_class = P_GLOBAL,
3210 .ptr = &Globals.lm_announce,
3212 .enum_list = enum_bool_auto,
3213 .flags = FLAG_ADVANCED,
3216 .label = "lm interval",
3218 .p_class = P_GLOBAL,
3219 .ptr = &Globals.lm_interval,
3222 .flags = FLAG_ADVANCED,
3225 .label = "preferred master",
3227 .p_class = P_GLOBAL,
3228 .ptr = &Globals.iPreferredMaster,
3230 .enum_list = enum_bool_auto,
3231 .flags = FLAG_BASIC | FLAG_ADVANCED,
3234 .label = "prefered master",
3236 .p_class = P_GLOBAL,
3237 .ptr = &Globals.iPreferredMaster,
3239 .enum_list = enum_bool_auto,
3243 .label = "local master",
3245 .p_class = P_GLOBAL,
3246 .ptr = &Globals.bLocalMaster,
3249 .flags = FLAG_BASIC | FLAG_ADVANCED,
3252 .label = "domain master",
3254 .p_class = P_GLOBAL,
3255 .ptr = &Globals.iDomainMaster,
3257 .enum_list = enum_bool_auto,
3258 .flags = FLAG_BASIC | FLAG_ADVANCED,
3261 .label = "browse list",
3263 .p_class = P_GLOBAL,
3264 .ptr = &Globals.bBrowseList,
3267 .flags = FLAG_ADVANCED,
3270 .label = "browseable",
3273 .ptr = &sDefault.bBrowseable,
3276 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3279 .label = "browsable",
3282 .ptr = &sDefault.bBrowseable,
3288 .label = "enhanced browsing",
3290 .p_class = P_GLOBAL,
3291 .ptr = &Globals.enhanced_browsing,
3294 .flags = FLAG_ADVANCED,
3297 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3300 .label = "dns proxy",
3302 .p_class = P_GLOBAL,
3303 .ptr = &Globals.bDNSproxy,
3306 .flags = FLAG_ADVANCED,
3309 .label = "wins proxy",
3311 .p_class = P_GLOBAL,
3312 .ptr = &Globals.bWINSproxy,
3315 .flags = FLAG_ADVANCED,
3318 .label = "wins server",
3320 .p_class = P_GLOBAL,
3321 .ptr = &Globals.szWINSservers,
3324 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3327 .label = "wins support",
3329 .p_class = P_GLOBAL,
3330 .ptr = &Globals.bWINSsupport,
3333 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3336 .label = "wins hook",
3338 .p_class = P_GLOBAL,
3339 .ptr = &Globals.szWINSHook,
3342 .flags = FLAG_ADVANCED,
3345 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3348 .label = "blocking locks",
3351 .ptr = &sDefault.bBlockingLocks,
3354 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3357 .label = "csc policy",
3360 .ptr = &sDefault.iCSCPolicy,
3362 .enum_list = enum_csc_policy,
3363 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3366 .label = "fake oplocks",
3369 .ptr = &sDefault.bFakeOplocks,
3372 .flags = FLAG_ADVANCED | FLAG_SHARE,
3375 .label = "kernel oplocks",
3377 .p_class = P_GLOBAL,
3378 .ptr = &Globals.bKernelOplocks,
3381 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3387 .ptr = &sDefault.bLocking,
3390 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3393 .label = "lock spin time",
3395 .p_class = P_GLOBAL,
3396 .ptr = &Globals.iLockSpinTime,
3399 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3405 .ptr = &sDefault.bOpLocks,
3408 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3411 .label = "level2 oplocks",
3414 .ptr = &sDefault.bLevel2OpLocks,
3417 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3420 .label = "oplock break wait time",
3422 .p_class = P_GLOBAL,
3423 .ptr = &Globals.oplock_break_wait_time,
3426 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3429 .label = "oplock contention limit",
3432 .ptr = &sDefault.iOplockContentionLimit,
3435 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3438 .label = "posix locking",
3441 .ptr = &sDefault.bPosixLocking,
3444 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3447 .label = "strict locking",
3450 .ptr = &sDefault.iStrictLocking,
3452 .enum_list = enum_bool_auto,
3453 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3456 .label = "share modes",
3459 .ptr = &sDefault.bShareModes,
3462 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3465 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3468 .label = "ldap admin dn",
3470 .p_class = P_GLOBAL,
3471 .ptr = &Globals.szLdapAdminDn,
3474 .flags = FLAG_ADVANCED,
3477 .label = "ldap delete dn",
3479 .p_class = P_GLOBAL,
3480 .ptr = &Globals.ldap_delete_dn,
3483 .flags = FLAG_ADVANCED,
3486 .label = "ldap group suffix",
3488 .p_class = P_GLOBAL,
3489 .ptr = &Globals.szLdapGroupSuffix,
3492 .flags = FLAG_ADVANCED,
3495 .label = "ldap idmap suffix",
3497 .p_class = P_GLOBAL,
3498 .ptr = &Globals.szLdapIdmapSuffix,
3501 .flags = FLAG_ADVANCED,
3504 .label = "ldap machine suffix",
3506 .p_class = P_GLOBAL,
3507 .ptr = &Globals.szLdapMachineSuffix,
3510 .flags = FLAG_ADVANCED,
3513 .label = "ldap passwd sync",
3515 .p_class = P_GLOBAL,
3516 .ptr = &Globals.ldap_passwd_sync,
3518 .enum_list = enum_ldap_passwd_sync,
3519 .flags = FLAG_ADVANCED,
3522 .label = "ldap password sync",
3524 .p_class = P_GLOBAL,
3525 .ptr = &Globals.ldap_passwd_sync,
3527 .enum_list = enum_ldap_passwd_sync,
3531 .label = "ldap replication sleep",
3533 .p_class = P_GLOBAL,
3534 .ptr = &Globals.ldap_replication_sleep,
3537 .flags = FLAG_ADVANCED,
3540 .label = "ldap suffix",
3542 .p_class = P_GLOBAL,
3543 .ptr = &Globals.szLdapSuffix,
3546 .flags = FLAG_ADVANCED,
3549 .label = "ldap ssl",
3551 .p_class = P_GLOBAL,
3552 .ptr = &Globals.ldap_ssl,
3554 .enum_list = enum_ldap_ssl,
3555 .flags = FLAG_ADVANCED,
3558 .label = "ldap timeout",
3560 .p_class = P_GLOBAL,
3561 .ptr = &Globals.ldap_timeout,
3564 .flags = FLAG_ADVANCED,
3567 .label = "ldap connection timeout",
3569 .p_class = P_GLOBAL,
3570 .ptr = &Globals.ldap_connection_timeout,
3573 .flags = FLAG_ADVANCED,
3576 .label = "ldap page size",
3578 .p_class = P_GLOBAL,
3579 .ptr = &Globals.ldap_page_size,
3582 .flags = FLAG_ADVANCED,
3585 .label = "ldap user suffix",
3587 .p_class = P_GLOBAL,
3588 .ptr = &Globals.szLdapUserSuffix,
3591 .flags = FLAG_ADVANCED,
3594 .label = "ldap debug level",
3596 .p_class = P_GLOBAL,
3597 .ptr = &Globals.ldap_debug_level,
3598 .special = handle_ldap_debug_level,
3600 .flags = FLAG_ADVANCED,
3603 .label = "ldap debug threshold",
3605 .p_class = P_GLOBAL,
3606 .ptr = &Globals.ldap_debug_threshold,
3609 .flags = FLAG_ADVANCED,
3612 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3615 .label = "eventlog list",
3617 .p_class = P_GLOBAL,
3618 .ptr = &Globals.szEventLogs,
3621 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3624 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3627 .label = "add share command",
3629 .p_class = P_GLOBAL,
3630 .ptr = &Globals.szAddShareCommand,
3633 .flags = FLAG_ADVANCED,
3636 .label = "change share command",
3638 .p_class = P_GLOBAL,
3639 .ptr = &Globals.szChangeShareCommand,
3642 .flags = FLAG_ADVANCED,
3645 .label = "delete share command",
3647 .p_class = P_GLOBAL,
3648 .ptr = &Globals.szDeleteShareCommand,
3651 .flags = FLAG_ADVANCED,
3654 .label = "config file",
3656 .p_class = P_GLOBAL,
3657 .ptr = &Globals.szConfigFile,
3665 .p_class = P_GLOBAL,
3666 .ptr = &Globals.szAutoServices,
3669 .flags = FLAG_ADVANCED,
3672 .label = "auto services",
3674 .p_class = P_GLOBAL,
3675 .ptr = &Globals.szAutoServices,
3678 .flags = FLAG_ADVANCED,
3681 .label = "lock directory",
3683 .p_class = P_GLOBAL,
3684 .ptr = &Globals.szLockDir,
3687 .flags = FLAG_ADVANCED,
3690 .label = "lock dir",
3692 .p_class = P_GLOBAL,
3693 .ptr = &Globals.szLockDir,
3699 .label = "pid directory",
3701 .p_class = P_GLOBAL,
3702 .ptr = &Globals.szPidDir,
3705 .flags = FLAG_ADVANCED,
3709 .label = "utmp directory",
3711 .p_class = P_GLOBAL,
3712 .ptr = &Globals.szUtmpDir,
3715 .flags = FLAG_ADVANCED,
3718 .label = "wtmp directory",
3720 .p_class = P_GLOBAL,
3721 .ptr = &Globals.szWtmpDir,
3724 .flags = FLAG_ADVANCED,
3729 .p_class = P_GLOBAL,
3730 .ptr = &Globals.bUtmp,
3733 .flags = FLAG_ADVANCED,
3737 .label = "default service",
3739 .p_class = P_GLOBAL,
3740 .ptr = &Globals.szDefaultService,
3743 .flags = FLAG_ADVANCED,
3748 .p_class = P_GLOBAL,
3749 .ptr = &Globals.szDefaultService,
3752 .flags = FLAG_ADVANCED,
3755 .label = "message command",
3757 .p_class = P_GLOBAL,
3758 .ptr = &Globals.szMsgCommand,
3761 .flags = FLAG_ADVANCED,
3764 .label = "dfree cache time",
3767 .ptr = &sDefault.iDfreeCacheTime,
3770 .flags = FLAG_ADVANCED,
3773 .label = "dfree command",
3776 .ptr = &sDefault.szDfree,
3779 .flags = FLAG_ADVANCED,
3782 .label = "get quota command",
3784 .p_class = P_GLOBAL,
3785 .ptr = &Globals.szGetQuota,
3788 .flags = FLAG_ADVANCED,
3791 .label = "set quota command",
3793 .p_class = P_GLOBAL,
3794 .ptr = &Globals.szSetQuota,
3797 .flags = FLAG_ADVANCED,
3800 .label = "remote announce",
3802 .p_class = P_GLOBAL,
3803 .ptr = &Globals.szRemoteAnnounce,
3806 .flags = FLAG_ADVANCED,
3809 .label = "remote browse sync",
3811 .p_class = P_GLOBAL,
3812 .ptr = &Globals.szRemoteBrowseSync,
3815 .flags = FLAG_ADVANCED,
3818 .label = "socket address",
3820 .p_class = P_GLOBAL,
3821 .ptr = &Globals.szSocketAddress,
3824 .flags = FLAG_ADVANCED,
3827 .label = "homedir map",
3829 .p_class = P_GLOBAL,
3830 .ptr = &Globals.szNISHomeMapName,
3833 .flags = FLAG_ADVANCED,
3836 .label = "afs username map",
3838 .p_class = P_GLOBAL,
3839 .ptr = &Globals.szAfsUsernameMap,
3842 .flags = FLAG_ADVANCED,
3845 .label = "afs token lifetime",
3847 .p_class = P_GLOBAL,
3848 .ptr = &Globals.iAfsTokenLifetime,
3851 .flags = FLAG_ADVANCED,
3854 .label = "log nt token command",
3856 .p_class = P_GLOBAL,
3857 .ptr = &Globals.szLogNtTokenCommand,
3860 .flags = FLAG_ADVANCED,
3863 .label = "time offset",
3865 .p_class = P_GLOBAL,
3866 .ptr = &extra_time_offset,
3869 .flags = FLAG_ADVANCED,
3872 .label = "NIS homedir",
3874 .p_class = P_GLOBAL,
3875 .ptr = &Globals.bNISHomeMap,
3878 .flags = FLAG_ADVANCED,
3884 .ptr = &sDefault.valid,
3893 .ptr = &sDefault.szCopy,
3894 .special = handle_copy,
3902 .ptr = &sDefault.szInclude,
3903 .special = handle_include,
3911 .ptr = &sDefault.szPreExec,
3914 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3920 .ptr = &sDefault.szPreExec,
3923 .flags = FLAG_ADVANCED,
3926 .label = "preexec close",
3929 .ptr = &sDefault.bPreexecClose,
3932 .flags = FLAG_ADVANCED | FLAG_SHARE,
3935 .label = "postexec",
3938 .ptr = &sDefault.szPostExec,
3941 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3944 .label = "root preexec",
3947 .ptr = &sDefault.szRootPreExec,
3950 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3953 .label = "root preexec close",
3956 .ptr = &sDefault.bRootpreexecClose,
3959 .flags = FLAG_ADVANCED | FLAG_SHARE,
3962 .label = "root postexec",
3965 .ptr = &sDefault.szRootPostExec,
3968 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3971 .label = "available",
3974 .ptr = &sDefault.bAvailable,
3977 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3980 .label = "registry shares",
3982 .p_class = P_GLOBAL,
3983 .ptr = &Globals.bRegistryShares,
3986 .flags = FLAG_ADVANCED,
3989 .label = "usershare allow guests",
3991 .p_class = P_GLOBAL,
3992 .ptr = &Globals.bUsershareAllowGuests,
3995 .flags = FLAG_ADVANCED,
3998 .label = "usershare max shares",
4000 .p_class = P_GLOBAL,
4001 .ptr = &Globals.iUsershareMaxShares,
4004 .flags = FLAG_ADVANCED,
4007 .label = "usershare owner only",
4009 .p_class = P_GLOBAL,
4010 .ptr = &Globals.bUsershareOwnerOnly,
4013 .flags = FLAG_ADVANCED,
4016 .label = "usershare path",
4018 .p_class = P_GLOBAL,
4019 .ptr = &Globals.szUsersharePath,
4022 .flags = FLAG_ADVANCED,
4025 .label = "usershare prefix allow list",
4027 .p_class = P_GLOBAL,
4028 .ptr = &Globals.szUsersharePrefixAllowList,
4031 .flags = FLAG_ADVANCED,
4034 .label = "usershare prefix deny list",
4036 .p_class = P_GLOBAL,
4037 .ptr = &Globals.szUsersharePrefixDenyList,
4040 .flags = FLAG_ADVANCED,
4043 .label = "usershare template share",
4045 .p_class = P_GLOBAL,
4046 .ptr = &Globals.szUsershareTemplateShare,
4049 .flags = FLAG_ADVANCED,
4055 .ptr = &sDefault.volume,
4058 .flags = FLAG_ADVANCED | FLAG_SHARE,
4064 .ptr = &sDefault.fstype,
4067 .flags = FLAG_ADVANCED | FLAG_SHARE,
4070 .label = "set directory",
4073 .ptr = &sDefault.bNo_set_dir,
4076 .flags = FLAG_ADVANCED | FLAG_SHARE,
4079 .label = "wide links",
4082 .ptr = &sDefault.bWidelinks,
4085 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4088 .label = "follow symlinks",
4091 .ptr = &sDefault.bSymlinks,
4094 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4097 .label = "dont descend",
4100 .ptr = &sDefault.szDontdescend,
4103 .flags = FLAG_ADVANCED | FLAG_SHARE,
4106 .label = "magic script",
4109 .ptr = &sDefault.szMagicScript,
4112 .flags = FLAG_ADVANCED | FLAG_SHARE,
4115 .label = "magic output",
4118 .ptr = &sDefault.szMagicOutput,
4121 .flags = FLAG_ADVANCED | FLAG_SHARE,
4124 .label = "delete readonly",
4127 .ptr = &sDefault.bDeleteReadonly,
4130 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4133 .label = "dos filemode",
4136 .ptr = &sDefault.bDosFilemode,
4139 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4142 .label = "dos filetimes",
4145 .ptr = &sDefault.bDosFiletimes,
4148 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4151 .label = "dos filetime resolution",
4154 .ptr = &sDefault.bDosFiletimeResolution,
4157 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4160 .label = "fake directory create times",
4163 .ptr = &sDefault.bFakeDirCreateTimes,
4166 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4169 .label = "panic action",
4171 .p_class = P_GLOBAL,
4172 .ptr = &Globals.szPanicAction,
4175 .flags = FLAG_ADVANCED,
4178 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4181 .label = "vfs objects",
4184 .ptr = &sDefault.szVfsObjects,
4187 .flags = FLAG_ADVANCED | FLAG_SHARE,
4190 .label = "vfs object",
4193 .ptr = &sDefault.szVfsObjects,
4200 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4203 .label = "msdfs root",
4206 .ptr = &sDefault.bMSDfsRoot,
4209 .flags = FLAG_ADVANCED | FLAG_SHARE,
4212 .label = "msdfs proxy",
4215 .ptr = &sDefault.szMSDfsProxy,
4218 .flags = FLAG_ADVANCED | FLAG_SHARE,
4221 .label = "host msdfs",
4223 .p_class = P_GLOBAL,
4224 .ptr = &Globals.bHostMSDfs,
4227 .flags = FLAG_ADVANCED,
4230 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4233 .label = "passdb expand explicit",
4235 .p_class = P_GLOBAL,
4236 .ptr = &Globals.bPassdbExpandExplicit,
4239 .flags = FLAG_ADVANCED,
4242 .label = "idmap backend",
4244 .p_class = P_GLOBAL,
4245 .ptr = &Globals.szIdmapBackend,
4248 .flags = FLAG_ADVANCED,
4251 .label = "idmap alloc backend",
4253 .p_class = P_GLOBAL,
4254 .ptr = &Globals.szIdmapAllocBackend,
4257 .flags = FLAG_ADVANCED,
4260 .label = "idmap cache time",
4262 .p_class = P_GLOBAL,
4263 .ptr = &Globals.iIdmapCacheTime,
4266 .flags = FLAG_ADVANCED,
4269 .label = "idmap negative cache time",
4271 .p_class = P_GLOBAL,
4272 .ptr = &Globals.iIdmapNegativeCacheTime,
4275 .flags = FLAG_ADVANCED,
4278 .label = "idmap uid",
4280 .p_class = P_GLOBAL,
4281 .ptr = &Globals.szIdmapUID,
4282 .special = handle_idmap_uid,
4284 .flags = FLAG_ADVANCED,
4287 .label = "winbind uid",
4289 .p_class = P_GLOBAL,
4290 .ptr = &Globals.szIdmapUID,
4291 .special = handle_idmap_uid,
4296 .label = "idmap gid",
4298 .p_class = P_GLOBAL,
4299 .ptr = &Globals.szIdmapGID,
4300 .special = handle_idmap_gid,
4302 .flags = FLAG_ADVANCED,
4305 .label = "winbind gid",
4307 .p_class = P_GLOBAL,
4308 .ptr = &Globals.szIdmapGID,
4309 .special = handle_idmap_gid,
4314 .label = "template homedir",
4316 .p_class = P_GLOBAL,
4317 .ptr = &Globals.szTemplateHomedir,
4320 .flags = FLAG_ADVANCED,
4323 .label = "template shell",
4325 .p_class = P_GLOBAL,
4326 .ptr = &Globals.szTemplateShell,
4329 .flags = FLAG_ADVANCED,
4332 .label = "winbind separator",
4334 .p_class = P_GLOBAL,
4335 .ptr = &Globals.szWinbindSeparator,
4338 .flags = FLAG_ADVANCED,
4341 .label = "winbind cache time",
4343 .p_class = P_GLOBAL,
4344 .ptr = &Globals.winbind_cache_time,
4347 .flags = FLAG_ADVANCED,
4350 .label = "winbind enum users",
4352 .p_class = P_GLOBAL,
4353 .ptr = &Globals.bWinbindEnumUsers,
4356 .flags = FLAG_ADVANCED,
4359 .label = "winbind enum groups",
4361 .p_class = P_GLOBAL,
4362 .ptr = &Globals.bWinbindEnumGroups,
4365 .flags = FLAG_ADVANCED,
4368 .label = "winbind use default domain",
4370 .p_class = P_GLOBAL,
4371 .ptr = &Globals.bWinbindUseDefaultDomain,
4374 .flags = FLAG_ADVANCED,
4377 .label = "winbind trusted domains only",
4379 .p_class = P_GLOBAL,
4380 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4383 .flags = FLAG_ADVANCED,
4386 .label = "winbind nested groups",
4388 .p_class = P_GLOBAL,
4389 .ptr = &Globals.bWinbindNestedGroups,
4392 .flags = FLAG_ADVANCED,
4395 .label = "winbind expand groups",
4397 .p_class = P_GLOBAL,
4398 .ptr = &Globals.winbind_expand_groups,
4401 .flags = FLAG_ADVANCED,
4404 .label = "winbind nss info",
4406 .p_class = P_GLOBAL,
4407 .ptr = &Globals.szWinbindNssInfo,
4410 .flags = FLAG_ADVANCED,
4413 .label = "winbind refresh tickets",
4415 .p_class = P_GLOBAL,
4416 .ptr = &Globals.bWinbindRefreshTickets,
4419 .flags = FLAG_ADVANCED,
4422 .label = "winbind offline logon",
4424 .p_class = P_GLOBAL,
4425 .ptr = &Globals.bWinbindOfflineLogon,
4428 .flags = FLAG_ADVANCED,
4431 .label = "winbind normalize names",
4433 .p_class = P_GLOBAL,
4434 .ptr = &Globals.bWinbindNormalizeNames,
4437 .flags = FLAG_ADVANCED,
4440 .label = "winbind rpc only",
4442 .p_class = P_GLOBAL,
4443 .ptr = &Globals.bWinbindRpcOnly,
4446 .flags = FLAG_ADVANCED,
4449 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4452 /***************************************************************************
4453 Initialise the sDefault parameter structure for the printer values.
4454 ***************************************************************************/
4456 static void init_printer_values(struct service *pService)
4458 /* choose defaults depending on the type of printing */
4459 switch (pService->iPrinting) {
4464 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4465 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4466 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4471 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4472 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4473 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4474 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4475 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4476 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4477 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4483 /* set the lpq command to contain the destination printer
4484 name only. This is used by cups_queue_get() */
4485 string_set(&pService->szLpqcommand, "%p");
4486 string_set(&pService->szLprmcommand, "");
4487 string_set(&pService->szPrintcommand, "");
4488 string_set(&pService->szLppausecommand, "");
4489 string_set(&pService->szLpresumecommand, "");
4490 string_set(&pService->szQueuepausecommand, "");
4491 string_set(&pService->szQueueresumecommand, "");
4493 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4494 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4495 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4496 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4497 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4498 string_set(&pService->szQueuepausecommand, "disable '%p'");
4499 string_set(&pService->szQueueresumecommand, "enable '%p'");
4500 #endif /* HAVE_CUPS */
4505 string_set(&pService->szLpqcommand, "lpstat -o%p");
4506 string_set(&pService->szLprmcommand, "cancel %p-%j");
4507 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4508 string_set(&pService->szQueuepausecommand, "disable %p");
4509 string_set(&pService->szQueueresumecommand, "enable %p");
4511 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4512 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4517 string_set(&pService->szLpqcommand, "lpq -P%p");
4518 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4519 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4525 string_set(&pService->szPrintcommand, "vlp print %p %s");
4526 string_set(&pService->szLpqcommand, "vlp lpq %p");
4527 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4528 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4529 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4530 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4531 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4533 #endif /* DEVELOPER */
4538 /***************************************************************************
4539 Initialise the global parameter structure.
4540 ***************************************************************************/
4542 static void init_globals(bool first_time_only)
4544 static bool done_init = False;
4548 /* If requested to initialize only once and we've already done it... */
4549 if (first_time_only && done_init) {
4550 /* ... then we have nothing more to do */
4555 /* The logfile can be set before this is invoked. Free it if so. */
4556 if (Globals.szLogFile != NULL) {
4557 string_free(&Globals.szLogFile);
4558 Globals.szLogFile = NULL;
4562 for (i = 0; parm_table[i].label; i++) {
4563 if ((parm_table[i].type == P_STRING ||
4564 parm_table[i].type == P_USTRING) &&
4567 string_free((char **)parm_table[i].ptr);
4572 memset((void *)&Globals, '\0', sizeof(Globals));
4574 for (i = 0; parm_table[i].label; i++) {
4575 if ((parm_table[i].type == P_STRING ||
4576 parm_table[i].type == P_USTRING) &&
4579 string_set((char **)parm_table[i].ptr, "");
4583 string_set(&sDefault.fstype, FSTYPE_STRING);
4584 string_set(&sDefault.szPrintjobUsername, "%U");
4586 init_printer_values(&sDefault);
4589 DEBUG(3, ("Initialising global parameters\n"));
4591 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4592 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4594 /* use the new 'hash2' method by default, with a prefix of 1 */
4595 string_set(&Globals.szManglingMethod, "hash2");
4596 Globals.mangle_prefix = 1;
4598 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4600 /* using UTF8 by default allows us to support all chars */
4601 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4603 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4604 /* If the system supports nl_langinfo(), try to grab the value
4605 from the user's locale */
4606 string_set(&Globals.display_charset, "LOCALE");
4608 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4611 /* Use codepage 850 as a default for the dos character set */
4612 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4615 * Allow the default PASSWD_CHAT to be overridden in local.h.
4617 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4619 set_global_myname(myhostname());
4620 string_set(&Globals.szNetbiosName,global_myname());
4622 set_global_myworkgroup(WORKGROUP);
4623 string_set(&Globals.szWorkgroup, lp_workgroup());
4625 string_set(&Globals.szPasswdProgram, "");
4626 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4627 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4628 string_set(&Globals.szSocketAddress, "0.0.0.0");
4630 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4631 smb_panic("init_globals: ENOMEM");
4633 string_set(&Globals.szServerString, s);
4635 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4636 DEFAULT_MINOR_VERSION) < 0) {
4637 smb_panic("init_globals: ENOMEM");
4639 string_set(&Globals.szAnnounceVersion, s);
4642 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4645 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4647 string_set(&Globals.szLogonDrive, "");
4648 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4649 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4650 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4652 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4653 string_set(&Globals.szPasswordServer, "*");
4655 Globals.AlgorithmicRidBase = BASE_RID;
4657 Globals.bLoadPrinters = True;
4658 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4660 Globals.ConfigBackend = config_backend;
4662 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4663 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4664 Globals.max_xmit = 0x4104;
4665 Globals.max_mux = 50; /* This is *needed* for profile support. */
4666 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4667 Globals.bDisableSpoolss = False;
4668 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4669 Globals.pwordlevel = 0;
4670 Globals.unamelevel = 0;
4671 Globals.deadtime = 0;
4672 Globals.getwd_cache = true;
4673 Globals.bLargeReadwrite = True;
4674 Globals.max_log_size = 5000;
4675 Globals.max_open_files = MAX_OPEN_FILES;
4676 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4677 Globals.maxprotocol = PROTOCOL_NT1;
4678 Globals.minprotocol = PROTOCOL_CORE;
4679 Globals.security = SEC_USER;
4680 Globals.paranoid_server_security = True;
4681 Globals.bEncryptPasswords = True;
4682 Globals.bUpdateEncrypt = False;
4683 Globals.clientSchannel = Auto;
4684 Globals.serverSchannel = Auto;
4685 Globals.bReadRaw = True;
4686 Globals.bWriteRaw = True;
4687 Globals.bNullPasswords = False;
4688 Globals.bObeyPamRestrictions = False;
4690 Globals.bSyslogOnly = False;
4691 Globals.bTimestampLogs = True;
4692 string_set(&Globals.szLogLevel, "0");
4693 Globals.bDebugPrefixTimestamp = False;
4694 Globals.bDebugHiresTimestamp = False;
4695 Globals.bDebugPid = False;
4696 Globals.bDebugUid = False;
4697 Globals.bDebugClass = False;
4698 Globals.bEnableCoreFiles = True;
4699 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4700 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4701 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4702 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4703 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4704 Globals.lm_interval = 60;
4705 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4706 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4707 Globals.bNISHomeMap = False;
4708 #ifdef WITH_NISPLUS_HOME
4709 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4711 string_set(&Globals.szNISHomeMapName, "auto.home");
4714 Globals.bTimeServer = False;
4715 Globals.bBindInterfacesOnly = False;
4716 Globals.bUnixPasswdSync = False;
4717 Globals.bPamPasswordChange = False;
4718 Globals.bPasswdChatDebug = False;
4719 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4720 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4721 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4722 Globals.bStatCache = True; /* use stat cache by default */
4723 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4724 Globals.restrict_anonymous = 0;
4725 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4726 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4727 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4728 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4729 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4730 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4732 Globals.map_to_guest = 0; /* By Default, "Never" */
4733 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4734 Globals.enhanced_browsing = true;
4735 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4736 #ifdef MMAP_BLACKLIST
4737 Globals.bUseMmap = False;
4739 Globals.bUseMmap = True;
4741 Globals.bUnixExtensions = True;
4742 Globals.bResetOnZeroVC = False;
4744 /* hostname lookups can be very expensive and are broken on
4745 a large number of sites (tridge) */
4746 Globals.bHostnameLookups = False;
4748 string_set(&Globals.szPassdbBackend, "smbpasswd");
4749 string_set(&Globals.szLdapSuffix, "");
4750 string_set(&Globals.szLdapMachineSuffix, "");
4751 string_set(&Globals.szLdapUserSuffix, "");
4752 string_set(&Globals.szLdapGroupSuffix, "");
4753 string_set(&Globals.szLdapIdmapSuffix, "");
4755 string_set(&Globals.szLdapAdminDn, "");
4756 Globals.ldap_ssl = LDAP_SSL_OFF;
4757 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4758 Globals.ldap_delete_dn = False;
4759 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4760 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4761 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4762 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4764 Globals.ldap_debug_level = 0;
4765 Globals.ldap_debug_threshold = 10;
4767 /* This is what we tell the afs client. in reality we set the token
4768 * to never expire, though, when this runs out the afs client will
4769 * forget the token. Set to 0 to get NEVERDATE.*/
4770 Globals.iAfsTokenLifetime = 604800;
4772 /* these parameters are set to defaults that are more appropriate
4773 for the increasing samba install base:
4775 as a member of the workgroup, that will possibly become a
4776 _local_ master browser (lm = True). this is opposed to a forced
4777 local master browser startup (pm = True).
4779 doesn't provide WINS server service by default (wsupp = False),
4780 and doesn't provide domain master browser services by default, either.
4784 Globals.bMsAddPrinterWizard = True;
4785 Globals.os_level = 20;
4786 Globals.bLocalMaster = True;
4787 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4788 Globals.bDomainLogons = False;
4789 Globals.bBrowseList = True;
4790 Globals.bWINSsupport = False;
4791 Globals.bWINSproxy = False;
4793 Globals.bDNSproxy = True;
4795 /* this just means to use them if they exist */
4796 Globals.bKernelOplocks = True;
4798 Globals.bAllowTrustedDomains = True;
4799 string_set(&Globals.szIdmapBackend, "tdb");
4801 string_set(&Globals.szTemplateShell, "/bin/false");
4802 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4803 string_set(&Globals.szWinbindSeparator, "\\");
4805 string_set(&Globals.szCupsServer, "");
4806 string_set(&Globals.szIPrintServer, "");
4808 string_set(&Globals.ctdbdSocket, "");
4809 Globals.szClusterAddresses = NULL;
4810 Globals.clustering = False;
4812 Globals.winbind_cache_time = 300; /* 5 minutes */
4813 Globals.bWinbindEnumUsers = False;
4814 Globals.bWinbindEnumGroups = False;
4815 Globals.bWinbindUseDefaultDomain = False;
4816 Globals.bWinbindTrustedDomainsOnly = False;
4817 Globals.bWinbindNestedGroups = True;
4818 Globals.winbind_expand_groups = 1;
4819 Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4820 Globals.bWinbindRefreshTickets = False;
4821 Globals.bWinbindOfflineLogon = False;
4823 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
4824 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4826 Globals.bPassdbExpandExplicit = False;
4828 Globals.name_cache_timeout = 660; /* In seconds */
4830 Globals.bUseSpnego = True;
4831 Globals.bClientUseSpnego = True;
4833 Globals.client_signing = Auto;
4834 Globals.server_signing = False;
4836 Globals.bDeferSharingViolations = True;
4837 string_set(&Globals.smb_ports, SMB_PORTS);
4839 Globals.bEnablePrivileges = True;
4840 Globals.bHostMSDfs = True;
4841 Globals.bASUSupport = False;
4843 /* User defined shares. */
4844 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4845 smb_panic("init_globals: ENOMEM");
4847 string_set(&Globals.szUsersharePath, s);
4849 string_set(&Globals.szUsershareTemplateShare, "");
4850 Globals.iUsershareMaxShares = 0;
4851 /* By default disallow sharing of directories not owned by the sharer. */
4852 Globals.bUsershareOwnerOnly = True;
4853 /* By default disallow guest access to usershares. */
4854 Globals.bUsershareAllowGuests = False;
4856 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4858 /* By default no shares out of the registry */
4859 Globals.bRegistryShares = False;
4861 Globals.iminreceivefile = 0;
4864 /*******************************************************************
4865 Convenience routine to grab string parameters into temporary memory
4866 and run standard_sub_basic on them. The buffers can be written to by
4867 callers without affecting the source string.
4868 ********************************************************************/
4870 static char *lp_string(const char *s)
4873 TALLOC_CTX *ctx = talloc_tos();
4875 /* The follow debug is useful for tracking down memory problems
4876 especially if you have an inner loop that is calling a lp_*()
4877 function that returns a string. Perhaps this debug should be
4878 present all the time? */
4881 DEBUG(10, ("lp_string(%s)\n", s));
4884 ret = talloc_sub_basic(ctx,
4885 get_current_username(),
4886 current_user_info.domain,
4888 if (trim_char(ret, '\"', '\"')) {
4889 if (strchr(ret,'\"') != NULL) {
4891 ret = talloc_sub_basic(ctx,
4892 get_current_username(),
4893 current_user_info.domain,
4901 In this section all the functions that are used to access the
4902 parameters from the rest of the program are defined
4905 #define FN_GLOBAL_STRING(fn_name,ptr) \
4906 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4907 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4908 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4909 #define FN_GLOBAL_LIST(fn_name,ptr) \
4910 const char **fn_name(void) {return(*(const char ***)(ptr));}
4911 #define FN_GLOBAL_BOOL(fn_name,ptr) \
4912 bool fn_name(void) {return(*(bool *)(ptr));}
4913 #define FN_GLOBAL_CHAR(fn_name,ptr) \
4914 char fn_name(void) {return(*(char *)(ptr));}
4915 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
4916 int fn_name(void) {return(*(int *)(ptr));}
4918 #define FN_LOCAL_STRING(fn_name,val) \
4919 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4920 #define FN_LOCAL_CONST_STRING(fn_name,val) \
4921 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4922 #define FN_LOCAL_LIST(fn_name,val) \
4923 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4924 #define FN_LOCAL_BOOL(fn_name,val) \
4925 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4926 #define FN_LOCAL_INTEGER(fn_name,val) \
4927 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4929 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
4930 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4931 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4932 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4933 #define FN_LOCAL_PARM_STRING(fn_name,val) \
4934 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));}
4935 #define FN_LOCAL_CHAR(fn_name,val) \
4936 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4938 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4939 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4940 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4941 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4942 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4943 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4944 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4945 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4946 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4947 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4948 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4949 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4950 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4951 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4952 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4953 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4954 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4955 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4956 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4957 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4958 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4959 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4960 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4961 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4962 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4963 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4964 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
4965 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
4966 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
4967 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
4968 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
4969 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
4970 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
4971 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
4972 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
4973 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
4974 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
4975 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
4976 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
4977 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
4978 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
4979 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
4980 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
4981 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
4982 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
4983 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
4984 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
4985 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
4986 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
4987 * lp_passdb_backend() should be replace by the this macro again after
4990 const char *lp_passdb_backend(void)
4992 char *delim, *quote;
4994 delim = strchr( Globals.szPassdbBackend, ' ');
4995 /* no space at all */
4996 if (delim == NULL) {
5000 quote = strchr(Globals.szPassdbBackend, '"');
5001 /* no quote char or non in the first part */
5002 if (quote == NULL || quote > delim) {
5007 quote = strchr(quote+1, '"');
5008 if (quote == NULL) {
5009 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5011 } else if (*(quote+1) == '\0') {
5012 /* space, fitting quote char, and one backend only */
5015 /* terminate string after the fitting quote char */
5020 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5021 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5022 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5023 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5026 return Globals.szPassdbBackend;
5028 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5029 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5030 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5031 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5032 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5034 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5035 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5036 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5037 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5038 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5039 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5041 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5043 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5044 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5045 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5047 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5049 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5050 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5051 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5052 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5053 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5054 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5055 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5056 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5057 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5058 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5059 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5060 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5061 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5062 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5063 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5065 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5066 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5067 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5068 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5069 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5070 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5072 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5073 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5074 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5075 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5076 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5077 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5078 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5079 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5080 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5081 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5082 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5083 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5084 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5085 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5086 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5087 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5088 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5090 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5092 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5093 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5094 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5095 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5096 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5097 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5098 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5099 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5100 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5101 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5102 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5103 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5104 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5105 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5106 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5107 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5108 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5109 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5110 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5111 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5112 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5113 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5114 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5115 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5116 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5117 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5118 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5119 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5120 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5121 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5122 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5123 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5124 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5125 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5126 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5127 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5128 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5129 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5130 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5131 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5132 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5133 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5134 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5135 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5136 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5137 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5138 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5139 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5140 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5141 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5142 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5143 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5144 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5145 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5146 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5147 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5148 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5149 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5150 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5151 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5152 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5153 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5154 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5155 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5156 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5157 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5158 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5159 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5160 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5161 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5162 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5163 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5164 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5165 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5166 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5167 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5168 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5169 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5170 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5171 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5172 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5173 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5174 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5175 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5176 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5177 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5178 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5179 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5180 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5181 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5182 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5183 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5184 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5185 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5186 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5187 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5189 FN_LOCAL_STRING(lp_preexec, szPreExec)
5190 FN_LOCAL_STRING(lp_postexec, szPostExec)
5191 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5192 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5193 FN_LOCAL_STRING(lp_servicename, szService)
5194 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5195 FN_LOCAL_STRING(lp_pathname, szPath)
5196 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5197 FN_LOCAL_STRING(lp_username, szUsername)
5198 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5199 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5200 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5201 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5202 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5203 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5204 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5205 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5206 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5207 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5208 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5209 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5210 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5211 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5212 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5213 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5214 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5215 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5216 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5217 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5218 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5219 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5220 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5221 FN_LOCAL_STRING(lp_comment, comment)
5222 FN_LOCAL_STRING(lp_force_user, force_user)
5223 FN_LOCAL_STRING(lp_force_group, force_group)
5224 FN_LOCAL_LIST(lp_readlist, readlist)
5225 FN_LOCAL_LIST(lp_writelist, writelist)
5226 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5227 FN_LOCAL_STRING(lp_fstype, fstype)
5228 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5229 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5230 static FN_LOCAL_STRING(lp_volume, volume)
5231 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5232 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5233 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5234 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5235 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5236 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5237 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5238 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5239 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5240 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5241 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5242 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5243 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5244 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5245 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5246 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5247 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5248 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5249 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5250 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5251 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5252 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5253 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5254 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5255 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5256 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5257 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5258 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5259 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5260 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5261 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5262 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5263 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5264 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5265 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5266 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5267 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5268 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5269 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5270 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5271 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5272 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5273 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5274 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5275 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5276 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5277 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5278 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5279 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5280 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5281 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5282 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5283 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5284 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5285 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5286 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5287 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5288 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5289 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5290 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5291 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5292 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5293 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5294 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5295 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5296 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5297 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5298 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5299 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5300 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5301 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5302 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5303 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5304 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5305 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5306 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5307 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5308 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5309 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5310 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5311 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5312 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5313 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5314 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5315 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5316 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5317 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5318 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5319 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5320 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5321 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5322 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5323 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5324 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5325 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5326 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5327 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5329 /* local prototypes */
5331 static int map_parameter(const char *pszParmName);
5332 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5333 static bool set_boolean(bool *pb, const char *pszParmValue);
5334 static const char *get_boolean(bool bool_value);
5335 static int getservicebyname(const char *pszServiceName,
5336 struct service *pserviceDest);
5337 static void copy_service(struct service *pserviceDest,
5338 struct service *pserviceSource,
5339 struct bitmap *pcopymapDest);
5340 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5342 static bool do_section(const char *pszSectionName, void *userdata);
5343 static void init_copymap(struct service *pservice);
5344 static bool hash_a_service(const char *name, int number);
5345 static void free_service_byindex(int iService);
5346 static char * canonicalize_servicename(const char *name);
5347 static void show_parameter(int parmIndex);
5348 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5350 /* This is a helper function for parametrical options support. */
5351 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
5352 /* Actual parametrical functions are quite simple */
5353 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
5355 bool global_section = False;
5357 param_opt_struct *data;
5359 if (snum >= iNumServices) return NULL;
5362 data = Globals.param_opt;
5363 global_section = True;
5365 data = ServicePtrs[snum]->param_opt;
5368 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5369 DEBUG(0,("asprintf failed!\n"));
5374 if (strwicmp(data->key, param_key) == 0) {
5375 string_free(¶m_key);
5381 if (!global_section) {
5382 /* Try to fetch the same option but from globals */
5383 /* but only if we are not already working with Globals */
5384 data = Globals.param_opt;
5386 if (strwicmp(data->key, param_key) == 0) {
5387 string_free(¶m_key);
5394 string_free(¶m_key);
5400 #define MISSING_PARAMETER(name) \
5401 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5403 /*******************************************************************
5404 convenience routine to return int parameters.
5405 ********************************************************************/
5406 static int lp_int(const char *s)
5410 MISSING_PARAMETER(lp_int);
5414 return (int)strtol(s, NULL, 0);
5417 /*******************************************************************
5418 convenience routine to return unsigned long parameters.
5419 ********************************************************************/
5420 static unsigned long lp_ulong(const char *s)
5424 MISSING_PARAMETER(lp_ulong);
5428 return strtoul(s, NULL, 0);
5431 /*******************************************************************
5432 convenience routine to return boolean parameters.
5433 ********************************************************************/
5434 static bool lp_bool(const char *s)
5439 MISSING_PARAMETER(lp_bool);
5443 if (!set_boolean(&ret,s)) {
5444 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5451 /*******************************************************************
5452 convenience routine to return enum parameters.
5453 ********************************************************************/
5454 static int lp_enum(const char *s,const struct enum_list *_enum)
5458 if (!s || !*s || !_enum) {
5459 MISSING_PARAMETER(lp_enum);
5463 for (i=0; _enum[i].name; i++) {
5464 if (strequal(_enum[i].name,s))
5465 return _enum[i].value;
5468 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5472 #undef MISSING_PARAMETER
5474 /* DO NOT USE lp_parm_string ANYMORE!!!!
5475 * use lp_parm_const_string or lp_parm_talloc_string
5477 * lp_parm_string is only used to let old modules find this symbol
5479 #undef lp_parm_string
5480 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5481 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5483 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5486 /* Return parametric option from a given service. Type is a part of option before ':' */
5487 /* Parametric option has following syntax: 'Type: option = value' */
5488 /* the returned value is talloced on the talloc_tos() */
5489 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5491 param_opt_struct *data = get_parametrics(snum, type, option);
5493 if (data == NULL||data->value==NULL) {
5495 return lp_string(def);
5501 return lp_string(data->value);
5504 /* Return parametric option from a given service. Type is a part of option before ':' */
5505 /* Parametric option has following syntax: 'Type: option = value' */
5506 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5508 param_opt_struct *data = get_parametrics(snum, type, option);
5510 if (data == NULL||data->value==NULL)
5516 /* Return parametric option from a given service. Type is a part of option before ':' */
5517 /* Parametric option has following syntax: 'Type: option = value' */
5519 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5521 param_opt_struct *data = get_parametrics(snum, type, option);
5523 if (data == NULL||data->value==NULL)
5524 return (const char **)def;
5526 if (data->list==NULL) {
5527 data->list = str_list_make(NULL, data->value, NULL);
5530 return (const char **)data->list;
5533 /* Return parametric option from a given service. Type is a part of option before ':' */
5534 /* Parametric option has following syntax: 'Type: option = value' */
5536 int lp_parm_int(int snum, const char *type, const char *option, int def)
5538 param_opt_struct *data = get_parametrics(snum, type, option);
5540 if (data && data->value && *data->value)
5541 return lp_int(data->value);
5546 /* Return parametric option from a given service. Type is a part of option before ':' */
5547 /* Parametric option has following syntax: 'Type: option = value' */
5549 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5551 param_opt_struct *data = get_parametrics(snum, type, option);
5553 if (data && data->value && *data->value)
5554 return lp_ulong(data->value);
5559 /* Return parametric option from a given service. Type is a part of option before ':' */
5560 /* Parametric option has following syntax: 'Type: option = value' */
5562 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5564 param_opt_struct *data = get_parametrics(snum, type, option);
5566 if (data && data->value && *data->value)
5567 return lp_bool(data->value);
5572 /* Return parametric option from a given service. Type is a part of option before ':' */
5573 /* Parametric option has following syntax: 'Type: option = value' */
5575 int lp_parm_enum(int snum, const char *type, const char *option,
5576 const struct enum_list *_enum, int def)
5578 param_opt_struct *data = get_parametrics(snum, type, option);
5580 if (data && data->value && *data->value && _enum)
5581 return lp_enum(data->value, _enum);
5587 /***************************************************************************
5588 Initialise a service to the defaults.
5589 ***************************************************************************/
5591 static void init_service(struct service *pservice)
5593 memset((char *)pservice, '\0', sizeof(struct service));
5594 copy_service(pservice, &sDefault, NULL);
5597 /***************************************************************************
5598 Free the dynamically allocated parts of a service struct.
5599 ***************************************************************************/
5601 static void free_service(struct service *pservice)
5604 param_opt_struct *data, *pdata;
5608 if (pservice->szService)
5609 DEBUG(5, ("free_service: Freeing service %s\n",
5610 pservice->szService));
5612 string_free(&pservice->szService);
5613 bitmap_free(pservice->copymap);
5615 for (i = 0; parm_table[i].label; i++) {
5616 if ((parm_table[i].type == P_STRING ||
5617 parm_table[i].type == P_USTRING) &&
5618 parm_table[i].p_class == P_LOCAL)
5619 string_free((char **)
5620 (((char *)pservice) +
5621 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5622 else if (parm_table[i].type == P_LIST &&
5623 parm_table[i].p_class == P_LOCAL)
5624 TALLOC_FREE(*((char ***)
5625 (((char *)pservice) +
5626 PTR_DIFF(parm_table[i].ptr,
5630 data = pservice->param_opt;
5632 DEBUG(5,("Freeing parametrics:\n"));
5634 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5635 string_free(&data->key);
5636 string_free(&data->value);
5637 TALLOC_FREE(data->list);
5643 ZERO_STRUCTP(pservice);
5647 /***************************************************************************
5648 remove a service indexed in the ServicePtrs array from the ServiceHash
5649 and free the dynamically allocated parts
5650 ***************************************************************************/
5652 static void free_service_byindex(int idx)
5654 if ( !LP_SNUM_OK(idx) )
5657 ServicePtrs[idx]->valid = False;
5658 invalid_services[num_invalid_services++] = idx;
5660 /* we have to cleanup the hash record */
5662 if (ServicePtrs[idx]->szService) {
5663 char *canon_name = canonicalize_servicename(
5664 ServicePtrs[idx]->szService );
5666 dbwrap_delete_bystring(ServiceHash, canon_name );
5667 TALLOC_FREE(canon_name);
5670 free_service(ServicePtrs[idx]);
5673 /***************************************************************************
5674 Add a new service to the services array initialising it with the given
5676 ***************************************************************************/
5678 static int add_a_service(const struct service *pservice, const char *name)
5681 struct service tservice;
5682 int num_to_alloc = iNumServices + 1;
5683 param_opt_struct *data, *pdata;
5685 tservice = *pservice;
5687 /* it might already exist */
5689 i = getservicebyname(name, NULL);
5691 /* Clean all parametric options for service */
5692 /* They will be added during parsing again */
5693 data = ServicePtrs[i]->param_opt;
5695 string_free(&data->key);
5696 string_free(&data->value);
5697 TALLOC_FREE(data->list);
5702 ServicePtrs[i]->param_opt = NULL;
5707 /* find an invalid one */
5709 if (num_invalid_services > 0) {
5710 i = invalid_services[--num_invalid_services];
5713 /* if not, then create one */
5714 if (i == iNumServices) {
5715 struct service **tsp;
5718 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5720 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5724 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5725 if (!ServicePtrs[iNumServices]) {
5726 DEBUG(0,("add_a_service: out of memory!\n"));
5731 /* enlarge invalid_services here for now... */
5732 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5734 if (tinvalid == NULL) {
5735 DEBUG(0,("add_a_service: failed to enlarge "
5736 "invalid_services!\n"));
5739 invalid_services = tinvalid;
5741 free_service_byindex(i);
5744 ServicePtrs[i]->valid = True;
5746 init_service(ServicePtrs[i]);
5747 copy_service(ServicePtrs[i], &tservice, NULL);
5749 string_set(&ServicePtrs[i]->szService, name);
5751 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5752 i, ServicePtrs[i]->szService));
5754 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5761 /***************************************************************************
5762 Convert a string to uppercase and remove whitespaces.
5763 ***************************************************************************/
5765 static char *canonicalize_servicename(const char *src)
5770 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5774 result = talloc_strdup(talloc_tos(), src);
5775 SMB_ASSERT(result != NULL);
5781 /***************************************************************************
5782 Add a name/index pair for the services array to the hash table.
5783 ***************************************************************************/
5785 static bool hash_a_service(const char *name, int idx)
5789 if ( !ServiceHash ) {
5790 DEBUG(10,("hash_a_service: creating servicehash\n"));
5791 ServiceHash = db_open_rbt(NULL);
5792 if ( !ServiceHash ) {
5793 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5798 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5801 canon_name = canonicalize_servicename( name );
5803 dbwrap_store_bystring(ServiceHash, canon_name,
5804 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5807 TALLOC_FREE(canon_name);
5812 /***************************************************************************
5813 Add a new home service, with the specified home directory, defaults coming
5815 ***************************************************************************/
5817 bool lp_add_home(const char *pszHomename, int iDefaultService,
5818 const char *user, const char *pszHomedir)
5822 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5827 if (!(*(ServicePtrs[iDefaultService]->szPath))
5828 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5829 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5832 if (!(*(ServicePtrs[i]->comment))) {
5833 char *comment = NULL;
5834 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5837 string_set(&ServicePtrs[i]->comment, comment);
5841 /* set the browseable flag from the global default */
5843 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5845 ServicePtrs[i]->autoloaded = True;
5847 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5848 user, ServicePtrs[i]->szPath ));
5853 /***************************************************************************
5854 Add a new service, based on an old one.
5855 ***************************************************************************/
5857 int lp_add_service(const char *pszService, int iDefaultService)
5859 if (iDefaultService < 0) {
5860 return add_a_service(&sDefault, pszService);
5863 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5866 /***************************************************************************
5867 Add the IPC service.
5868 ***************************************************************************/
5870 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5872 char *comment = NULL;
5873 int i = add_a_service(&sDefault, ipc_name);
5878 if (asprintf(&comment, "IPC Service (%s)",
5879 Globals.szServerString) < 0) {
5883 string_set(&ServicePtrs[i]->szPath, tmpdir());
5884 string_set(&ServicePtrs[i]->szUsername, "");
5885 string_set(&ServicePtrs[i]->comment, comment);
5886 string_set(&ServicePtrs[i]->fstype, "IPC");
5887 ServicePtrs[i]->iMaxConnections = 0;
5888 ServicePtrs[i]->bAvailable = True;
5889 ServicePtrs[i]->bRead_only = True;
5890 ServicePtrs[i]->bGuest_only = False;
5891 ServicePtrs[i]->bAdministrative_share = True;
5892 ServicePtrs[i]->bGuest_ok = guest_ok;
5893 ServicePtrs[i]->bPrint_ok = False;
5894 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5896 DEBUG(3, ("adding IPC service\n"));
5902 /***************************************************************************
5903 Add a new printer service, with defaults coming from service iFrom.
5904 ***************************************************************************/
5906 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5908 const char *comment = "From Printcap";
5909 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5914 /* note that we do NOT default the availability flag to True - */
5915 /* we take it from the default service passed. This allows all */
5916 /* dynamic printers to be disabled by disabling the [printers] */
5917 /* entry (if/when the 'available' keyword is implemented!). */
5919 /* the printer name is set to the service name. */
5920 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5921 string_set(&ServicePtrs[i]->comment, comment);
5923 /* set the browseable flag from the gloabl default */
5924 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5926 /* Printers cannot be read_only. */
5927 ServicePtrs[i]->bRead_only = False;
5928 /* No share modes on printer services. */
5929 ServicePtrs[i]->bShareModes = False;
5930 /* No oplocks on printer services. */
5931 ServicePtrs[i]->bOpLocks = False;
5932 /* Printer services must be printable. */
5933 ServicePtrs[i]->bPrint_ok = True;
5935 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5941 /***************************************************************************
5942 Check whether the given parameter name is valid.
5943 Parametric options (names containing a colon) are considered valid.
5944 ***************************************************************************/
5946 bool lp_parameter_is_valid(const char *pszParmName)
5948 return ((map_parameter(pszParmName) != -1) ||
5949 (strchr(pszParmName, ':') != NULL));
5952 /***************************************************************************
5953 Check whether the given name is the name of a global parameter.
5954 Returns True for strings belonging to parameters of class
5955 P_GLOBAL, False for all other strings, also for parametric options
5956 and strings not belonging to any option.
5957 ***************************************************************************/
5959 bool lp_parameter_is_global(const char *pszParmName)
5961 int num = map_parameter(pszParmName);
5964 return (parm_table[num].p_class == P_GLOBAL);
5970 /**************************************************************************
5971 Check whether the given name is the canonical name of a parameter.
5972 Returns False if it is not a valid parameter Name.
5973 For parametric options, True is returned.
5974 **************************************************************************/
5976 bool lp_parameter_is_canonical(const char *parm_name)
5978 if (!lp_parameter_is_valid(parm_name)) {
5982 return (map_parameter(parm_name) ==
5983 map_parameter_canonical(parm_name, NULL));
5986 /**************************************************************************
5987 Determine the canonical name for a parameter.
5988 Indicate when it is an inverse (boolean) synonym instead of a
5990 **************************************************************************/
5992 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
5997 if (!lp_parameter_is_valid(parm_name)) {
6002 num = map_parameter_canonical(parm_name, inverse);
6004 /* parametric option */
6005 *canon_parm = parm_name;
6007 *canon_parm = parm_table[num].label;
6014 /**************************************************************************
6015 Determine the canonical name for a parameter.
6016 Turn the value given into the inverse boolean expression when
6017 the synonym is an invers boolean synonym.
6019 Return True if parm_name is a valid parameter name and
6020 in case it is an invers boolean synonym, if the val string could
6021 successfully be converted to the reverse bool.
6022 Return false in all other cases.
6023 **************************************************************************/
6025 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6027 const char **canon_parm,
6028 const char **canon_val)
6033 if (!lp_parameter_is_valid(parm_name)) {
6039 num = map_parameter_canonical(parm_name, &inverse);
6041 /* parametric option */
6042 *canon_parm = parm_name;
6045 *canon_parm = parm_table[num].label;
6047 if (!lp_invert_boolean(val, canon_val)) {
6059 /***************************************************************************
6060 Map a parameter's string representation to something we can use.
6061 Returns False if the parameter string is not recognised, else TRUE.
6062 ***************************************************************************/
6064 static int map_parameter(const char *pszParmName)
6068 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6071 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6072 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6075 /* Warn only if it isn't parametric option */
6076 if (strchr(pszParmName, ':') == NULL)
6077 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6078 /* We do return 'fail' for parametric options as well because they are
6079 stored in different storage
6084 /***************************************************************************
6085 Map a parameter's string representation to the index of the canonical
6086 form of the parameter (it might be a synonym).
6087 Returns -1 if the parameter string is not recognised.
6088 ***************************************************************************/
6090 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6092 int parm_num, canon_num;
6093 bool loc_inverse = False;
6095 parm_num = map_parameter(pszParmName);
6096 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6097 /* invalid, parametric or no canidate for synonyms ... */
6101 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6102 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6103 parm_num = canon_num;
6109 if (inverse != NULL) {
6110 *inverse = loc_inverse;
6115 /***************************************************************************
6116 return true if parameter number parm1 is a synonym of parameter
6117 number parm2 (parm2 being the principal name).
6118 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6120 ***************************************************************************/
6122 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6124 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6125 (parm_table[parm1].flags & FLAG_HIDE) &&
6126 !(parm_table[parm2].flags & FLAG_HIDE))
6128 if (inverse != NULL) {
6129 if ((parm_table[parm1].type == P_BOOLREV) &&
6130 (parm_table[parm2].type == P_BOOL))
6142 /***************************************************************************
6143 Show one parameter's name, type, [values,] and flags.
6144 (helper functions for show_parameter_list)
6145 ***************************************************************************/
6147 static void show_parameter(int parmIndex)
6149 int enumIndex, flagIndex;
6154 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6155 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6157 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6158 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6159 FLAG_HIDE, FLAG_DOS_STRING};
6160 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6161 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6162 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6164 printf("%s=%s", parm_table[parmIndex].label,
6165 type[parm_table[parmIndex].type]);
6166 if (parm_table[parmIndex].type == P_ENUM) {
6169 parm_table[parmIndex].enum_list[enumIndex].name;
6173 enumIndex ? "|" : "",
6174 parm_table[parmIndex].enum_list[enumIndex].name);
6179 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6180 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6183 flag_names[flagIndex]);
6188 /* output synonyms */
6190 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6191 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6192 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6193 parm_table[parmIndex2].label);
6194 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6196 printf(" (synonyms: ");
6201 printf("%s%s", parm_table[parmIndex2].label,
6202 inverse ? "[i]" : "");
6212 /***************************************************************************
6213 Show all parameter's name, type, [values,] and flags.
6214 ***************************************************************************/
6216 void show_parameter_list(void)
6218 int classIndex, parmIndex;
6219 const char *section_names[] = { "local", "global", NULL};
6221 for (classIndex=0; section_names[classIndex]; classIndex++) {
6222 printf("[%s]\n", section_names[classIndex]);
6223 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6224 if (parm_table[parmIndex].p_class == classIndex) {
6225 show_parameter(parmIndex);
6231 /***************************************************************************
6232 Set a boolean variable from the text value stored in the passed string.
6233 Returns True in success, False if the passed string does not correctly
6234 represent a boolean.
6235 ***************************************************************************/
6237 static bool set_boolean(bool *pb, const char *pszParmValue)
6244 if (strwicmp(pszParmValue, "yes") == 0 ||
6245 strwicmp(pszParmValue, "true") == 0 ||
6246 strwicmp(pszParmValue, "1") == 0)
6248 else if (strwicmp(pszParmValue, "no") == 0 ||
6249 strwicmp(pszParmValue, "False") == 0 ||
6250 strwicmp(pszParmValue, "0") == 0)
6254 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6259 if ((pb != NULL) && (bRetval != False)) {
6267 /***************************************************************************
6268 Check if a given string correctly represents a boolean value.
6269 ***************************************************************************/
6271 bool lp_string_is_valid_boolean(const char *parm_value)
6273 return set_boolean(NULL, parm_value);
6276 /***************************************************************************
6277 Get the standard string representation of a boolean value ("yes" or "no")
6278 ***************************************************************************/
6280 static const char *get_boolean(bool bool_value)
6282 static const char *yes_str = "yes";
6283 static const char *no_str = "no";
6285 return (bool_value ? yes_str : no_str);
6288 /***************************************************************************
6289 Provide the string of the negated boolean value associated to the boolean
6290 given as a string. Returns False if the passed string does not correctly
6291 represent a boolean.
6292 ***************************************************************************/
6294 bool lp_invert_boolean(const char *str, const char **inverse_str)
6298 if (!set_boolean(&val, str)) {
6302 *inverse_str = get_boolean(!val);
6306 /***************************************************************************
6307 Provide the canonical string representation of a boolean value given
6308 as a string. Return True on success, False if the string given does
6309 not correctly represent a boolean.
6310 ***************************************************************************/
6312 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6316 if (!set_boolean(&val, str)) {
6320 *canon_str = get_boolean(val);
6324 /***************************************************************************
6325 Find a service by name. Otherwise works like get_service.
6326 ***************************************************************************/
6328 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6334 if (ServiceHash == NULL) {
6338 canon_name = canonicalize_servicename(pszServiceName);
6340 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6342 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6343 iService = *(int *)data.dptr;
6346 TALLOC_FREE(canon_name);
6348 if ((iService != -1) && (LP_SNUM_OK(iService))
6349 && (pserviceDest != NULL)) {
6350 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6356 /***************************************************************************
6357 Copy a service structure to another.
6358 If pcopymapDest is NULL then copy all fields
6359 ***************************************************************************/
6361 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6362 struct bitmap *pcopymapDest)
6365 bool bcopyall = (pcopymapDest == NULL);
6366 param_opt_struct *data, *pdata, *paramo;
6369 for (i = 0; parm_table[i].label; i++)
6370 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6371 (bcopyall || bitmap_query(pcopymapDest,i))) {
6372 void *def_ptr = parm_table[i].ptr;
6374 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6377 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6380 switch (parm_table[i].type) {
6383 *(bool *)dest_ptr = *(bool *)src_ptr;
6389 *(int *)dest_ptr = *(int *)src_ptr;
6393 *(char *)dest_ptr = *(char *)src_ptr;
6397 string_set((char **)dest_ptr,
6402 string_set((char **)dest_ptr,
6404 strupper_m(*(char **)dest_ptr);
6407 TALLOC_FREE(*((char ***)dest_ptr));
6408 str_list_copy(NULL, (char ***)dest_ptr,
6409 *(const char ***)src_ptr);
6417 init_copymap(pserviceDest);
6418 if (pserviceSource->copymap)
6419 bitmap_copy(pserviceDest->copymap,
6420 pserviceSource->copymap);
6423 data = pserviceSource->param_opt;
6426 pdata = pserviceDest->param_opt;
6427 /* Traverse destination */
6429 /* If we already have same option, override it */
6430 if (strwicmp(pdata->key, data->key) == 0) {
6431 string_free(&pdata->value);
6432 TALLOC_FREE(data->list);
6433 pdata->value = SMB_STRDUP(data->value);
6437 pdata = pdata->next;
6440 paramo = SMB_XMALLOC_P(param_opt_struct);
6441 paramo->key = SMB_STRDUP(data->key);
6442 paramo->value = SMB_STRDUP(data->value);
6443 paramo->list = NULL;
6444 DLIST_ADD(pserviceDest->param_opt, paramo);
6450 /***************************************************************************
6451 Check a service for consistency. Return False if the service is in any way
6452 incomplete or faulty, else True.
6453 ***************************************************************************/
6455 bool service_ok(int iService)
6460 if (ServicePtrs[iService]->szService[0] == '\0') {
6461 DEBUG(0, ("The following message indicates an internal error:\n"));
6462 DEBUG(0, ("No service name in service entry.\n"));
6466 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6467 /* I can't see why you'd want a non-printable printer service... */
6468 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6469 if (!ServicePtrs[iService]->bPrint_ok) {
6470 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6471 ServicePtrs[iService]->szService));
6472 ServicePtrs[iService]->bPrint_ok = True;
6474 /* [printers] service must also be non-browsable. */
6475 if (ServicePtrs[iService]->bBrowseable)
6476 ServicePtrs[iService]->bBrowseable = False;
6479 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6480 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6481 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6483 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6484 ServicePtrs[iService]->szService));
6485 ServicePtrs[iService]->bAvailable = False;
6488 /* If a service is flagged unavailable, log the fact at level 1. */
6489 if (!ServicePtrs[iService]->bAvailable)
6490 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6491 ServicePtrs[iService]->szService));
6496 static struct smbconf_ctx *lp_smbconf_ctx(void)
6499 static struct smbconf_ctx *conf_ctx = NULL;
6501 if (conf_ctx == NULL) {
6502 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6503 if (!W_ERROR_IS_OK(werr)) {
6504 DEBUG(1, ("error initializing registry configuration: "
6505 "%s\n", dos_errstr(werr)));
6513 static bool process_smbconf_service(struct smbconf_service *service)
6518 if (service == NULL) {
6522 ret = do_section(service->name, NULL);
6526 for (count = 0; count < service->num_params; count++) {
6527 ret = do_parameter(service->param_names[count],
6528 service->param_values[count],
6534 if (iServiceIndex >= 0) {
6535 ret = service_ok(iServiceIndex);
6541 * load a service from registry and activate it
6543 bool process_registry_service(const char *service_name)
6546 struct smbconf_service *service = NULL;
6547 TALLOC_CTX *mem_ctx = talloc_stackframe();
6548 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6551 if (conf_ctx == NULL) {
6555 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6557 if (!smbconf_share_exists(conf_ctx, service_name)) {
6559 * Registry does not contain data for this service (yet),
6560 * but make sure lp_load doesn't return false.
6566 werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6567 if (!W_ERROR_IS_OK(werr)) {
6571 ret = process_smbconf_service(service);
6577 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6580 TALLOC_FREE(mem_ctx);
6585 * process_registry_globals
6587 static bool process_registry_globals(void)
6591 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6593 ret = do_parameter("registry shares", "yes", NULL);
6598 return process_registry_service(GLOBAL_NAME);
6601 bool process_registry_shares(void)
6605 struct smbconf_service **service = NULL;
6606 uint32_t num_shares = 0;
6607 TALLOC_CTX *mem_ctx = talloc_stackframe();
6608 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6611 if (conf_ctx == NULL) {
6615 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6616 if (!W_ERROR_IS_OK(werr)) {
6622 for (count = 0; count < num_shares; count++) {
6623 if (strequal(service[count]->name, GLOBAL_NAME)) {
6626 ret = process_smbconf_service(service[count]);
6633 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6636 TALLOC_FREE(mem_ctx);
6640 #define MAX_INCLUDE_DEPTH 100
6642 static uint8_t include_depth;
6644 static struct file_lists {
6645 struct file_lists *next;
6649 } *file_lists = NULL;
6651 /*******************************************************************
6652 Keep a linked list of all config files so we know when one has changed
6653 it's date and needs to be reloaded.
6654 ********************************************************************/
6656 static void add_to_file_list(const char *fname, const char *subfname)
6658 struct file_lists *f = file_lists;
6661 if (f->name && !strcmp(f->name, fname))
6667 f = SMB_MALLOC_P(struct file_lists);
6670 f->next = file_lists;
6671 f->name = SMB_STRDUP(fname);
6676 f->subfname = SMB_STRDUP(subfname);
6682 f->modtime = file_modtime(subfname);
6684 time_t t = file_modtime(subfname);
6691 * Utility function for outsiders to check if we're running on registry.
6693 bool lp_config_backend_is_registry(void)
6695 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6699 * Utility function to check if the config backend is FILE.
6701 bool lp_config_backend_is_file(void)
6703 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6706 /*******************************************************************
6707 Check if a config file has changed date.
6708 ********************************************************************/
6710 bool lp_file_list_changed(void)
6712 struct file_lists *f = file_lists;
6714 DEBUG(6, ("lp_file_list_changed()\n"));
6720 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
6721 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6723 if (conf_ctx == NULL) {
6726 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
6729 DEBUGADD(6, ("registry config changed\n"));
6733 n2 = alloc_sub_basic(get_current_username(),
6734 current_user_info.domain,
6739 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6740 f->name, n2, ctime(&f->modtime)));
6742 mod_time = file_modtime(n2);
6745 ((f->modtime != mod_time) ||
6746 (f->subfname == NULL) ||
6747 (strcmp(n2, f->subfname) != 0)))
6750 ("file %s modified: %s\n", n2,
6752 f->modtime = mod_time;
6753 SAFE_FREE(f->subfname);
6754 f->subfname = n2; /* Passing ownership of
6755 return from alloc_sub_basic
6767 /***************************************************************************
6768 Run standard_sub_basic on netbios name... needed because global_myname
6769 is not accessed through any lp_ macro.
6770 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6771 ***************************************************************************/
6773 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6776 char *netbios_name = alloc_sub_basic(get_current_username(),
6777 current_user_info.domain,
6780 ret = set_global_myname(netbios_name);
6781 SAFE_FREE(netbios_name);
6782 string_set(&Globals.szNetbiosName,global_myname());
6784 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6790 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6792 if (strcmp(*ptr, pszParmValue) != 0) {
6793 string_set(ptr, pszParmValue);
6801 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6805 ret = set_global_myworkgroup(pszParmValue);
6806 string_set(&Globals.szWorkgroup,lp_workgroup());
6811 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6815 ret = set_global_scope(pszParmValue);
6816 string_set(&Globals.szNetbiosScope,global_scope());
6821 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6823 TALLOC_FREE(Globals.szNetbiosAliases);
6824 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6825 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6828 /***************************************************************************
6829 Handle the include operation.
6830 ***************************************************************************/
6831 static bool bAllowIncludeRegistry = true;
6833 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6837 if (include_depth >= MAX_INCLUDE_DEPTH) {
6838 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
6843 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6844 if (!bAllowIncludeRegistry) {
6847 if (bInGlobalSection) {
6850 ret = process_registry_globals();
6854 DEBUG(1, ("\"include = registry\" only effective "
6855 "in %s section\n", GLOBAL_NAME));
6860 fname = alloc_sub_basic(get_current_username(),
6861 current_user_info.domain,
6864 add_to_file_list(pszParmValue, fname);
6866 string_set(ptr, fname);
6868 if (file_exist(fname, NULL)) {
6871 ret = pm_process(fname, do_section, do_parameter, NULL);
6877 DEBUG(2, ("Can't find include file %s\n", fname));
6882 /***************************************************************************
6883 Handle the interpretation of the copy parameter.
6884 ***************************************************************************/
6886 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6890 struct service serviceTemp;
6892 string_set(ptr, pszParmValue);
6894 init_service(&serviceTemp);
6898 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6900 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6901 if (iTemp == iServiceIndex) {
6902 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6904 copy_service(ServicePtrs[iServiceIndex],
6906 ServicePtrs[iServiceIndex]->copymap);
6910 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6914 free_service(&serviceTemp);
6918 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6920 Globals.ldap_debug_level = lp_int(pszParmValue);
6921 init_ldap_debugging();
6925 /***************************************************************************
6926 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6931 idmap uid = 1000-1999
6934 We only do simple parsing checks here. The strings are parsed into useful
6935 structures in the idmap daemon code.
6937 ***************************************************************************/
6939 /* Some lp_ routines to return idmap [ug]id information */
6941 static uid_t idmap_uid_low, idmap_uid_high;
6942 static gid_t idmap_gid_low, idmap_gid_high;
6944 bool lp_idmap_uid(uid_t *low, uid_t *high)
6946 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6950 *low = idmap_uid_low;
6953 *high = idmap_uid_high;
6958 bool lp_idmap_gid(gid_t *low, gid_t *high)
6960 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6964 *low = idmap_gid_low;
6967 *high = idmap_gid_high;
6972 /* Do some simple checks on "idmap [ug]id" parameter values */
6974 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6978 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6983 string_set(ptr, pszParmValue);
6985 idmap_uid_low = low;
6986 idmap_uid_high = high;
6991 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6995 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7000 string_set(ptr, pszParmValue);
7002 idmap_gid_low = low;
7003 idmap_gid_high = high;
7008 /***************************************************************************
7009 Handle the DEBUG level list.
7010 ***************************************************************************/
7012 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7014 string_set(ptr, pszParmValueIn);
7015 return debug_parse_levels(pszParmValueIn);
7018 /***************************************************************************
7019 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7020 ***************************************************************************/
7022 static const char *append_ldap_suffix( const char *str )
7024 const char *suffix_string;
7027 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7028 Globals.szLdapSuffix );
7029 if ( !suffix_string ) {
7030 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7034 return suffix_string;
7037 const char *lp_ldap_machine_suffix(void)
7039 if (Globals.szLdapMachineSuffix[0])
7040 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7042 return lp_string(Globals.szLdapSuffix);
7045 const char *lp_ldap_user_suffix(void)
7047 if (Globals.szLdapUserSuffix[0])
7048 return append_ldap_suffix(Globals.szLdapUserSuffix);
7050 return lp_string(Globals.szLdapSuffix);
7053 const char *lp_ldap_group_suffix(void)
7055 if (Globals.szLdapGroupSuffix[0])
7056 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7058 return lp_string(Globals.szLdapSuffix);
7061 const char *lp_ldap_idmap_suffix(void)
7063 if (Globals.szLdapIdmapSuffix[0])
7064 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7066 return lp_string(Globals.szLdapSuffix);
7069 /****************************************************************************
7070 set the value for a P_ENUM
7071 ***************************************************************************/
7073 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7078 for (i = 0; parm->enum_list[i].name; i++) {
7079 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7080 *ptr = parm->enum_list[i].value;
7086 /***************************************************************************
7087 ***************************************************************************/
7089 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7091 static int parm_num = -1;
7094 if ( parm_num == -1 )
7095 parm_num = map_parameter( "printing" );
7097 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7102 s = ServicePtrs[snum];
7104 init_printer_values( s );
7110 /***************************************************************************
7111 Initialise a copymap.
7112 ***************************************************************************/
7114 static void init_copymap(struct service *pservice)
7117 if (pservice->copymap) {
7118 bitmap_free(pservice->copymap);
7120 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7121 if (!pservice->copymap)
7123 ("Couldn't allocate copymap!! (size %d)\n",
7124 (int)NUMPARAMETERS));
7126 for (i = 0; i < NUMPARAMETERS; i++)
7127 bitmap_set(pservice->copymap, i);
7130 /***************************************************************************
7131 Return the local pointer to a parameter given the service number and the
7132 pointer into the default structure.
7133 ***************************************************************************/
7135 void *lp_local_ptr(int snum, void *ptr)
7137 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7140 /***************************************************************************
7141 Process a parameter for a particular service number. If snum < 0
7142 then assume we are in the globals.
7143 ***************************************************************************/
7145 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7147 int parmnum, i, slen;
7148 void *parm_ptr = NULL; /* where we are going to store the result */
7149 void *def_ptr = NULL;
7150 char *param_key = NULL;
7152 param_opt_struct *paramo, *data;
7155 parmnum = map_parameter(pszParmName);
7158 if ((sep=strchr(pszParmName, ':')) != NULL) {
7159 TALLOC_CTX *frame = talloc_stackframe();
7162 param_key = talloc_asprintf(frame, "%s:", pszParmName);
7167 slen = strlen(param_key);
7168 param_key = talloc_asprintf_append(param_key, sep+1);
7173 trim_char(param_key+slen, ' ', ' ');
7175 data = (snum < 0) ? Globals.param_opt :
7176 ServicePtrs[snum]->param_opt;
7177 /* Traverse destination */
7179 /* If we already have same option, override it */
7180 if (strwicmp(data->key, param_key) == 0) {
7181 string_free(&data->value);
7182 TALLOC_FREE(data->list);
7183 data->value = SMB_STRDUP(pszParmValue);
7190 paramo = SMB_XMALLOC_P(param_opt_struct);
7191 paramo->key = SMB_STRDUP(param_key);
7192 paramo->value = SMB_STRDUP(pszParmValue);
7193 paramo->list = NULL;
7195 DLIST_ADD(Globals.param_opt, paramo);
7197 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
7205 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7209 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7210 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7214 def_ptr = parm_table[parmnum].ptr;
7216 /* we might point at a service, the default service or a global */
7220 if (parm_table[parmnum].p_class == P_GLOBAL) {
7222 ("Global parameter %s found in service section!\n",
7227 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7232 if (!ServicePtrs[snum]->copymap)
7233 init_copymap(ServicePtrs[snum]);
7235 /* this handles the aliases - set the copymap for other entries with
7236 the same data pointer */
7237 for (i = 0; parm_table[i].label; i++)
7238 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7239 bitmap_clear(ServicePtrs[snum]->copymap, i);
7242 /* if it is a special case then go ahead */
7243 if (parm_table[parmnum].special) {
7244 return parm_table[parmnum].special(snum, pszParmValue,
7248 /* now switch on the type of variable it is */
7249 switch (parm_table[parmnum].type)
7252 *(bool *)parm_ptr = lp_bool(pszParmValue);
7256 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7260 *(int *)parm_ptr = lp_int(pszParmValue);
7264 *(char *)parm_ptr = *pszParmValue;
7268 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7270 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7275 TALLOC_FREE(*((char ***)parm_ptr));
7276 *(char ***)parm_ptr = str_list_make(
7277 NULL, pszParmValue, NULL);
7281 string_set((char **)parm_ptr, pszParmValue);
7285 string_set((char **)parm_ptr, pszParmValue);
7286 strupper_m(*(char **)parm_ptr);
7290 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7299 /***************************************************************************
7300 Process a parameter.
7301 ***************************************************************************/
7303 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7306 if (!bInGlobalSection && bGlobalOnly)
7309 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7311 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7312 pszParmName, pszParmValue));
7315 /***************************************************************************
7316 Print a parameter of the specified type.
7317 ***************************************************************************/
7319 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7325 for (i = 0; p->enum_list[i].name; i++) {
7326 if (*(int *)ptr == p->enum_list[i].value) {
7328 p->enum_list[i].name);
7335 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7339 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7343 fprintf(f, "%d", *(int *)ptr);
7347 fprintf(f, "%c", *(char *)ptr);
7351 char *o = octal_string(*(int *)ptr);
7352 fprintf(f, "%s", o);
7358 if ((char ***)ptr && *(char ***)ptr) {
7359 char **list = *(char ***)ptr;
7360 for (; *list; list++) {
7361 /* surround strings with whitespace in double quotes */
7362 if ( strchr_m( *list, ' ' ) )
7363 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7365 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7372 if (*(char **)ptr) {
7373 fprintf(f, "%s", *(char **)ptr);
7381 /***************************************************************************
7382 Check if two parameters are equal.
7383 ***************************************************************************/
7385 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7390 return (*((bool *)ptr1) == *((bool *)ptr2));
7395 return (*((int *)ptr1) == *((int *)ptr2));
7398 return (*((char *)ptr1) == *((char *)ptr2));
7401 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7406 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7411 return (p1 == p2 || strequal(p1, p2));
7419 /***************************************************************************
7420 Initialize any local varients in the sDefault table.
7421 ***************************************************************************/
7423 void init_locals(void)
7428 /***************************************************************************
7429 Process a new section (service). At this stage all sections are services.
7430 Later we'll have special sections that permit server parameters to be set.
7431 Returns True on success, False on failure.
7432 ***************************************************************************/
7434 static bool do_section(const char *pszSectionName, void *userdata)
7437 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7438 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7441 /* if we were in a global section then do the local inits */
7442 if (bInGlobalSection && !isglobal)
7445 /* if we've just struck a global section, note the fact. */
7446 bInGlobalSection = isglobal;
7448 /* check for multiple global sections */
7449 if (bInGlobalSection) {
7450 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7454 if (!bInGlobalSection && bGlobalOnly)
7457 /* if we have a current service, tidy it up before moving on */
7460 if (iServiceIndex >= 0)
7461 bRetval = service_ok(iServiceIndex);
7463 /* if all is still well, move to the next record in the services array */
7465 /* We put this here to avoid an odd message order if messages are */
7466 /* issued by the post-processing of a previous section. */
7467 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7469 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7471 DEBUG(0, ("Failed to add a new service\n"));
7480 /***************************************************************************
7481 Determine if a partcular base parameter is currentl set to the default value.
7482 ***************************************************************************/
7484 static bool is_default(int i)
7486 if (!defaults_saved)
7488 switch (parm_table[i].type) {
7490 return str_list_compare (parm_table[i].def.lvalue,
7491 *(char ***)parm_table[i].ptr);
7494 return strequal(parm_table[i].def.svalue,
7495 *(char **)parm_table[i].ptr);
7498 return parm_table[i].def.bvalue ==
7499 *(bool *)parm_table[i].ptr;
7501 return parm_table[i].def.cvalue ==
7502 *(char *)parm_table[i].ptr;
7506 return parm_table[i].def.ivalue ==
7507 *(int *)parm_table[i].ptr;
7514 /***************************************************************************
7515 Display the contents of the global structure.
7516 ***************************************************************************/
7518 static void dump_globals(FILE *f)
7521 param_opt_struct *data;
7523 fprintf(f, "[global]\n");
7525 for (i = 0; parm_table[i].label; i++)
7526 if (parm_table[i].p_class == P_GLOBAL &&
7527 parm_table[i].ptr &&
7528 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7529 if (defaults_saved && is_default(i))
7531 fprintf(f, "\t%s = ", parm_table[i].label);
7532 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7535 if (Globals.param_opt != NULL) {
7536 data = Globals.param_opt;
7538 fprintf(f, "\t%s = %s\n", data->key, data->value);
7545 /***************************************************************************
7546 Return True if a local parameter is currently set to the global default.
7547 ***************************************************************************/
7549 bool lp_is_default(int snum, struct parm_struct *parm)
7551 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7553 return equal_parameter(parm->type,
7554 ((char *)ServicePtrs[snum]) + pdiff,
7555 ((char *)&sDefault) + pdiff);
7558 /***************************************************************************
7559 Display the contents of a single services record.
7560 ***************************************************************************/
7562 static void dump_a_service(struct service *pService, FILE * f)
7565 param_opt_struct *data;
7567 if (pService != &sDefault)
7568 fprintf(f, "[%s]\n", pService->szService);
7570 for (i = 0; parm_table[i].label; i++) {
7572 if (parm_table[i].p_class == P_LOCAL &&
7573 parm_table[i].ptr &&
7574 (*parm_table[i].label != '-') &&
7575 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7578 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7580 if (pService == &sDefault) {
7581 if (defaults_saved && is_default(i))
7584 if (equal_parameter(parm_table[i].type,
7585 ((char *)pService) +
7587 ((char *)&sDefault) +
7592 fprintf(f, "\t%s = ", parm_table[i].label);
7593 print_parameter(&parm_table[i],
7594 ((char *)pService) + pdiff, f);
7599 if (pService->param_opt != NULL) {
7600 data = pService->param_opt;
7602 fprintf(f, "\t%s = %s\n", data->key, data->value);
7608 /***************************************************************************
7609 Display the contents of a parameter of a single services record.
7610 ***************************************************************************/
7612 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7615 bool result = False;
7618 fstring local_parm_name;
7620 const char *parm_opt_value;
7622 /* check for parametrical option */
7623 fstrcpy( local_parm_name, parm_name);
7624 parm_opt = strchr( local_parm_name, ':');
7629 if (strlen(parm_opt)) {
7630 parm_opt_value = lp_parm_const_string( snum,
7631 local_parm_name, parm_opt, NULL);
7632 if (parm_opt_value) {
7633 printf( "%s\n", parm_opt_value);
7640 /* check for a key and print the value */
7647 for (i = 0; parm_table[i].label; i++) {
7648 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7649 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7650 parm_table[i].ptr &&
7651 (*parm_table[i].label != '-') &&
7652 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7657 ptr = parm_table[i].ptr;
7659 struct service *pService = ServicePtrs[snum];
7660 ptr = ((char *)pService) +
7661 PTR_DIFF(parm_table[i].ptr, &sDefault);
7664 print_parameter(&parm_table[i],
7675 /***************************************************************************
7676 Return info about the requested parameter (given as a string).
7677 Return NULL when the string is not a valid parameter name.
7678 ***************************************************************************/
7680 struct parm_struct *lp_get_parameter(const char *param_name)
7682 int num = map_parameter(param_name);
7688 return &parm_table[num];
7691 /***************************************************************************
7692 Return info about the next parameter in a service.
7693 snum==GLOBAL_SECTION_SNUM gives the globals.
7694 Return NULL when out of parameters.
7695 ***************************************************************************/
7697 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7700 /* do the globals */
7701 for (; parm_table[*i].label; (*i)++) {
7702 if (parm_table[*i].p_class == P_SEPARATOR)
7703 return &parm_table[(*i)++];
7705 if (!parm_table[*i].ptr
7706 || (*parm_table[*i].label == '-'))
7710 && (parm_table[*i].ptr ==
7711 parm_table[(*i) - 1].ptr))
7714 if (is_default(*i) && !allparameters)
7717 return &parm_table[(*i)++];
7720 struct service *pService = ServicePtrs[snum];
7722 for (; parm_table[*i].label; (*i)++) {
7723 if (parm_table[*i].p_class == P_SEPARATOR)
7724 return &parm_table[(*i)++];
7726 if (parm_table[*i].p_class == P_LOCAL &&
7727 parm_table[*i].ptr &&
7728 (*parm_table[*i].label != '-') &&
7730 (parm_table[*i].ptr !=
7731 parm_table[(*i) - 1].ptr)))
7734 PTR_DIFF(parm_table[*i].ptr,
7737 if (allparameters ||
7738 !equal_parameter(parm_table[*i].type,
7739 ((char *)pService) +
7741 ((char *)&sDefault) +
7744 return &parm_table[(*i)++];
7755 /***************************************************************************
7756 Display the contents of a single copy structure.
7757 ***************************************************************************/
7758 static void dump_copy_map(bool *pcopymap)
7764 printf("\n\tNon-Copied parameters:\n");
7766 for (i = 0; parm_table[i].label; i++)
7767 if (parm_table[i].p_class == P_LOCAL &&
7768 parm_table[i].ptr && !pcopymap[i] &&
7769 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7771 printf("\t\t%s\n", parm_table[i].label);
7776 /***************************************************************************
7777 Return TRUE if the passed service number is within range.
7778 ***************************************************************************/
7780 bool lp_snum_ok(int iService)
7782 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7785 /***************************************************************************
7786 Auto-load some home services.
7787 ***************************************************************************/
7789 static void lp_add_auto_services(char *str)
7799 s = SMB_STRDUP(str);
7803 homes = lp_servicenumber(HOMES_NAME);
7805 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7806 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7809 if (lp_servicenumber(p) >= 0)
7812 home = get_user_home_dir(talloc_tos(), p);
7814 if (home && homes >= 0)
7815 lp_add_home(p, homes, p, home);
7822 /***************************************************************************
7823 Auto-load one printer.
7824 ***************************************************************************/
7826 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7828 int printers = lp_servicenumber(PRINTERS_NAME);
7831 if (lp_servicenumber(name) < 0) {
7832 lp_add_printer(name, printers);
7833 if ((i = lp_servicenumber(name)) >= 0) {
7834 string_set(&ServicePtrs[i]->comment, comment);
7835 ServicePtrs[i]->autoloaded = True;
7840 /***************************************************************************
7841 Have we loaded a services file yet?
7842 ***************************************************************************/
7844 bool lp_loaded(void)
7849 /***************************************************************************
7850 Unload unused services.
7851 ***************************************************************************/
7853 void lp_killunused(bool (*snumused) (int))
7856 for (i = 0; i < iNumServices; i++) {
7860 /* don't kill autoloaded or usershare services */
7861 if ( ServicePtrs[i]->autoloaded ||
7862 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7866 if (!snumused || !snumused(i)) {
7867 free_service_byindex(i);
7873 * Kill all except autoloaded and usershare services - convenience wrapper
7875 void lp_kill_all_services(void)
7877 lp_killunused(NULL);
7880 /***************************************************************************
7882 ***************************************************************************/
7884 void lp_killservice(int iServiceIn)
7886 if (VALID(iServiceIn)) {
7887 free_service_byindex(iServiceIn);
7891 /***************************************************************************
7892 Save the curent values of all global and sDefault parameters into the
7893 defaults union. This allows swat and testparm to show only the
7894 changed (ie. non-default) parameters.
7895 ***************************************************************************/
7897 static void lp_save_defaults(void)
7900 for (i = 0; parm_table[i].label; i++) {
7901 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7903 switch (parm_table[i].type) {
7906 NULL, &(parm_table[i].def.lvalue),
7907 *(const char ***)parm_table[i].ptr);
7911 if (parm_table[i].ptr) {
7912 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7914 parm_table[i].def.svalue = NULL;
7919 parm_table[i].def.bvalue =
7920 *(bool *)parm_table[i].ptr;
7923 parm_table[i].def.cvalue =
7924 *(char *)parm_table[i].ptr;
7929 parm_table[i].def.ivalue =
7930 *(int *)parm_table[i].ptr;
7936 defaults_saved = True;
7939 /*******************************************************************
7940 Set the server type we will announce as via nmbd.
7941 ********************************************************************/
7943 static const struct srv_role_tab {
7945 const char *role_str;
7946 } srv_role_tab [] = {
7947 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7948 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7949 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7950 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7954 const char* server_role_str(uint32 role)
7957 for (i=0; srv_role_tab[i].role_str; i++) {
7958 if (role == srv_role_tab[i].role) {
7959 return srv_role_tab[i].role_str;
7965 static void set_server_role(void)
7967 server_role = ROLE_STANDALONE;
7969 switch (lp_security()) {
7971 if (lp_domain_logons())
7972 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7975 if (lp_domain_logons())
7976 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7977 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7978 server_role = ROLE_STANDALONE;
7981 if (lp_domain_logons()) {
7982 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7983 server_role = ROLE_DOMAIN_BDC;
7986 server_role = ROLE_DOMAIN_MEMBER;
7989 if (lp_domain_logons()) {
7990 server_role = ROLE_DOMAIN_PDC;
7993 server_role = ROLE_DOMAIN_MEMBER;
7996 if (lp_domain_logons()) {
7998 if (Globals.iDomainMaster) /* auto or yes */
7999 server_role = ROLE_DOMAIN_PDC;
8001 server_role = ROLE_DOMAIN_BDC;
8005 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8009 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8012 /***********************************************************
8013 If we should send plaintext/LANMAN passwords in the clinet
8014 ************************************************************/
8016 static void set_allowed_client_auth(void)
8018 if (Globals.bClientNTLMv2Auth) {
8019 Globals.bClientLanManAuth = False;
8021 if (!Globals.bClientLanManAuth) {
8022 Globals.bClientPlaintextAuth = False;
8026 /***************************************************************************
8028 The following code allows smbd to read a user defined share file.
8029 Yes, this is my intent. Yes, I'm comfortable with that...
8031 THE FOLLOWING IS SECURITY CRITICAL CODE.
8033 It washes your clothes, it cleans your house, it guards you while you sleep...
8034 Do not f%^k with it....
8035 ***************************************************************************/
8037 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8039 /***************************************************************************
8040 Check allowed stat state of a usershare file.
8041 Ensure we print out who is dicking with us so the admin can
8042 get their sorry ass fired.
8043 ***************************************************************************/
8045 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8047 if (!S_ISREG(psbuf->st_mode)) {
8048 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8049 "not a regular file\n",
8050 fname, (unsigned int)psbuf->st_uid ));
8054 /* Ensure this doesn't have the other write bit set. */
8055 if (psbuf->st_mode & S_IWOTH) {
8056 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8057 "public write. Refusing to allow as a usershare file.\n",
8058 fname, (unsigned int)psbuf->st_uid ));
8062 /* Should be 10k or less. */
8063 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8064 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8065 "too large (%u) to be a user share file.\n",
8066 fname, (unsigned int)psbuf->st_uid,
8067 (unsigned int)psbuf->st_size ));
8074 /***************************************************************************
8075 Parse the contents of a usershare file.
8076 ***************************************************************************/
8078 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8079 SMB_STRUCT_STAT *psbuf,
8080 const char *servicename,
8084 char **pp_sharepath,
8089 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8090 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8093 SMB_STRUCT_STAT sbuf;
8094 char *sharepath = NULL;
8095 char *comment = NULL;
8097 *pp_sharepath = NULL;
8100 *pallow_guest = False;
8103 return USERSHARE_MALFORMED_FILE;
8106 if (strcmp(lines[0], "#VERSION 1") == 0) {
8108 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8111 return USERSHARE_MALFORMED_FILE;
8114 return USERSHARE_BAD_VERSION;
8117 if (strncmp(lines[1], "path=", 5) != 0) {
8118 return USERSHARE_MALFORMED_PATH;
8121 sharepath = talloc_strdup(ctx, &lines[1][5]);
8123 return USERSHARE_POSIX_ERR;
8125 trim_string(sharepath, " ", " ");
8127 if (strncmp(lines[2], "comment=", 8) != 0) {
8128 return USERSHARE_MALFORMED_COMMENT_DEF;
8131 comment = talloc_strdup(ctx, &lines[2][8]);
8133 return USERSHARE_POSIX_ERR;
8135 trim_string(comment, " ", " ");
8136 trim_char(comment, '"', '"');
8138 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8139 return USERSHARE_MALFORMED_ACL_DEF;
8142 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8143 return USERSHARE_ACL_ERR;
8147 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8148 return USERSHARE_MALFORMED_ACL_DEF;
8150 if (lines[4][9] == 'y') {
8151 *pallow_guest = True;
8155 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8156 /* Path didn't change, no checks needed. */
8157 *pp_sharepath = sharepath;
8158 *pp_comment = comment;
8159 return USERSHARE_OK;
8162 /* The path *must* be absolute. */
8163 if (sharepath[0] != '/') {
8164 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8165 servicename, sharepath));
8166 return USERSHARE_PATH_NOT_ABSOLUTE;
8169 /* If there is a usershare prefix deny list ensure one of these paths
8170 doesn't match the start of the user given path. */
8171 if (prefixdenylist) {
8173 for ( i=0; prefixdenylist[i]; i++ ) {
8174 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8175 servicename, i, prefixdenylist[i], sharepath ));
8176 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8177 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8178 "usershare prefix deny list entries.\n",
8179 servicename, sharepath));
8180 return USERSHARE_PATH_IS_DENIED;
8185 /* If there is a usershare prefix allow list ensure one of these paths
8186 does match the start of the user given path. */
8188 if (prefixallowlist) {
8190 for ( i=0; prefixallowlist[i]; i++ ) {
8191 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8192 servicename, i, prefixallowlist[i], sharepath ));
8193 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8197 if (prefixallowlist[i] == NULL) {
8198 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8199 "usershare prefix allow list entries.\n",
8200 servicename, sharepath));
8201 return USERSHARE_PATH_NOT_ALLOWED;
8205 /* Ensure this is pointing to a directory. */
8206 dp = sys_opendir(sharepath);
8209 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8210 servicename, sharepath));
8211 return USERSHARE_PATH_NOT_DIRECTORY;
8214 /* Ensure the owner of the usershare file has permission to share
8217 if (sys_stat(sharepath, &sbuf) == -1) {
8218 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8219 servicename, sharepath, strerror(errno) ));
8221 return USERSHARE_POSIX_ERR;
8226 if (!S_ISDIR(sbuf.st_mode)) {
8227 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8228 servicename, sharepath ));
8229 return USERSHARE_PATH_NOT_DIRECTORY;
8232 /* Check if sharing is restricted to owner-only. */
8233 /* psbuf is the stat of the usershare definition file,
8234 sbuf is the stat of the target directory to be shared. */
8236 if (lp_usershare_owner_only()) {
8237 /* root can share anything. */
8238 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8239 return USERSHARE_PATH_NOT_ALLOWED;
8243 *pp_sharepath = sharepath;
8244 *pp_comment = comment;
8245 return USERSHARE_OK;
8248 /***************************************************************************
8249 Deal with a usershare file.
8252 -1 - Bad name, invalid contents.
8253 - service name already existed and not a usershare, problem
8254 with permissions to share directory etc.
8255 ***************************************************************************/
8257 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8259 SMB_STRUCT_STAT sbuf;
8260 SMB_STRUCT_STAT lsbuf;
8262 char *sharepath = NULL;
8263 char *comment = NULL;
8264 fstring service_name;
8265 char **lines = NULL;
8269 TALLOC_CTX *ctx = NULL;
8270 SEC_DESC *psd = NULL;
8271 bool guest_ok = False;
8273 /* Ensure share name doesn't contain invalid characters. */
8274 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8275 DEBUG(0,("process_usershare_file: share name %s contains "
8276 "invalid characters (any of %s)\n",
8277 file_name, INVALID_SHARENAME_CHARS ));
8281 fstrcpy(service_name, file_name);
8283 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8286 /* Minimize the race condition by doing an lstat before we
8287 open and fstat. Ensure this isn't a symlink link. */
8289 if (sys_lstat(fname, &lsbuf) != 0) {
8290 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8291 fname, strerror(errno) ));
8296 /* This must be a regular file, not a symlink, directory or
8297 other strange filetype. */
8298 if (!check_usershare_stat(fname, &lsbuf)) {
8304 char *canon_name = canonicalize_servicename(service_name);
8305 TDB_DATA data = dbwrap_fetch_bystring(
8306 ServiceHash, canon_name, canon_name);
8310 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8311 iService = *(int *)data.dptr;
8313 TALLOC_FREE(canon_name);
8316 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8317 /* Nothing changed - Mark valid and return. */
8318 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8320 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8325 /* Try and open the file read only - no symlinks allowed. */
8327 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8329 fd = sys_open(fname, O_RDONLY, 0);
8333 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8334 fname, strerror(errno) ));
8339 /* Now fstat to be *SURE* it's a regular file. */
8340 if (sys_fstat(fd, &sbuf) != 0) {
8342 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8343 fname, strerror(errno) ));
8348 /* Is it the same dev/inode as was lstated ? */
8349 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8351 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8352 "Symlink spoofing going on ?\n", fname ));
8357 /* This must be a regular file, not a symlink, directory or
8358 other strange filetype. */
8359 if (!check_usershare_stat(fname, &sbuf)) {
8364 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8367 if (lines == NULL) {
8368 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8369 fname, (unsigned int)sbuf.st_uid ));
8376 /* Should we allow printers to be shared... ? */
8377 ctx = talloc_init("usershare_sd_xctx");
8379 file_lines_free(lines);
8383 if (parse_usershare_file(ctx, &sbuf, service_name,
8384 iService, lines, numlines, &sharepath,
8385 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8386 talloc_destroy(ctx);
8387 file_lines_free(lines);
8391 file_lines_free(lines);
8393 /* Everything ok - add the service possibly using a template. */
8395 const struct service *sp = &sDefault;
8396 if (snum_template != -1) {
8397 sp = ServicePtrs[snum_template];
8400 if ((iService = add_a_service(sp, service_name)) < 0) {
8401 DEBUG(0, ("process_usershare_file: Failed to add "
8402 "new service %s\n", service_name));
8403 talloc_destroy(ctx);
8407 /* Read only is controlled by usershare ACL below. */
8408 ServicePtrs[iService]->bRead_only = False;
8411 /* Write the ACL of the new/modified share. */
8412 if (!set_share_security(service_name, psd)) {
8413 DEBUG(0, ("process_usershare_file: Failed to set share "
8414 "security for user share %s\n",
8416 lp_remove_service(iService);
8417 talloc_destroy(ctx);
8421 /* If from a template it may be marked invalid. */
8422 ServicePtrs[iService]->valid = True;
8424 /* Set the service as a valid usershare. */
8425 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8427 /* Set guest access. */
8428 if (lp_usershare_allow_guests()) {
8429 ServicePtrs[iService]->bGuest_ok = guest_ok;
8432 /* And note when it was loaded. */
8433 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8434 string_set(&ServicePtrs[iService]->szPath, sharepath);
8435 string_set(&ServicePtrs[iService]->comment, comment);
8437 talloc_destroy(ctx);
8442 /***************************************************************************
8443 Checks if a usershare entry has been modified since last load.
8444 ***************************************************************************/
8446 static bool usershare_exists(int iService, time_t *last_mod)
8448 SMB_STRUCT_STAT lsbuf;
8449 const char *usersharepath = Globals.szUsersharePath;
8452 if (asprintf(&fname, "%s/%s",
8454 ServicePtrs[iService]->szService) < 0) {
8458 if (sys_lstat(fname, &lsbuf) != 0) {
8463 if (!S_ISREG(lsbuf.st_mode)) {
8469 *last_mod = lsbuf.st_mtime;
8473 /***************************************************************************
8474 Load a usershare service by name. Returns a valid servicenumber or -1.
8475 ***************************************************************************/
8477 int load_usershare_service(const char *servicename)
8479 SMB_STRUCT_STAT sbuf;
8480 const char *usersharepath = Globals.szUsersharePath;
8481 int max_user_shares = Globals.iUsershareMaxShares;
8482 int snum_template = -1;
8484 if (*usersharepath == 0 || max_user_shares == 0) {
8488 if (sys_stat(usersharepath, &sbuf) != 0) {
8489 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8490 usersharepath, strerror(errno) ));
8494 if (!S_ISDIR(sbuf.st_mode)) {
8495 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8501 * This directory must be owned by root, and have the 't' bit set.
8502 * It also must not be writable by "other".
8506 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8508 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8510 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8511 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8516 /* Ensure the template share exists if it's set. */
8517 if (Globals.szUsershareTemplateShare[0]) {
8518 /* We can't use lp_servicenumber here as we are recommending that
8519 template shares have -valid=False set. */
8520 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8521 if (ServicePtrs[snum_template]->szService &&
8522 strequal(ServicePtrs[snum_template]->szService,
8523 Globals.szUsershareTemplateShare)) {
8528 if (snum_template == -1) {
8529 DEBUG(0,("load_usershare_service: usershare template share %s "
8530 "does not exist.\n",
8531 Globals.szUsershareTemplateShare ));
8536 return process_usershare_file(usersharepath, servicename, snum_template);
8539 /***************************************************************************
8540 Load all user defined shares from the user share directory.
8541 We only do this if we're enumerating the share list.
8542 This is the function that can delete usershares that have
8544 ***************************************************************************/
8546 int load_usershare_shares(void)
8549 SMB_STRUCT_STAT sbuf;
8550 SMB_STRUCT_DIRENT *de;
8551 int num_usershares = 0;
8552 int max_user_shares = Globals.iUsershareMaxShares;
8553 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8554 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8555 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8557 int snum_template = -1;
8558 const char *usersharepath = Globals.szUsersharePath;
8559 int ret = lp_numservices();
8561 if (max_user_shares == 0 || *usersharepath == '\0') {
8562 return lp_numservices();
8565 if (sys_stat(usersharepath, &sbuf) != 0) {
8566 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8567 usersharepath, strerror(errno) ));
8572 * This directory must be owned by root, and have the 't' bit set.
8573 * It also must not be writable by "other".
8577 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8579 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8581 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8582 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8587 /* Ensure the template share exists if it's set. */
8588 if (Globals.szUsershareTemplateShare[0]) {
8589 /* We can't use lp_servicenumber here as we are recommending that
8590 template shares have -valid=False set. */
8591 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8592 if (ServicePtrs[snum_template]->szService &&
8593 strequal(ServicePtrs[snum_template]->szService,
8594 Globals.szUsershareTemplateShare)) {
8599 if (snum_template == -1) {
8600 DEBUG(0,("load_usershare_shares: usershare template share %s "
8601 "does not exist.\n",
8602 Globals.szUsershareTemplateShare ));
8607 /* Mark all existing usershares as pending delete. */
8608 for (iService = iNumServices - 1; iService >= 0; iService--) {
8609 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8610 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8614 dp = sys_opendir(usersharepath);
8616 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8617 usersharepath, strerror(errno) ));
8621 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8622 (de = sys_readdir(dp));
8623 num_dir_entries++ ) {
8625 const char *n = de->d_name;
8627 /* Ignore . and .. */
8629 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8635 /* Temporary file used when creating a share. */
8636 num_tmp_dir_entries++;
8639 /* Allow 20% tmp entries. */
8640 if (num_tmp_dir_entries > allowed_tmp_entries) {
8641 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8642 "in directory %s\n",
8643 num_tmp_dir_entries, usersharepath));
8647 r = process_usershare_file(usersharepath, n, snum_template);
8649 /* Update the services count. */
8651 if (num_usershares >= max_user_shares) {
8652 DEBUG(0,("load_usershare_shares: max user shares reached "
8653 "on file %s in directory %s\n",
8654 n, usersharepath ));
8657 } else if (r == -1) {
8658 num_bad_dir_entries++;
8661 /* Allow 20% bad entries. */
8662 if (num_bad_dir_entries > allowed_bad_entries) {
8663 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8664 "in directory %s\n",
8665 num_bad_dir_entries, usersharepath));
8669 /* Allow 20% bad entries. */
8670 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8671 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8672 "in directory %s\n",
8673 num_dir_entries, usersharepath));
8680 /* Sweep through and delete any non-refreshed usershares that are
8681 not currently in use. */
8682 for (iService = iNumServices - 1; iService >= 0; iService--) {
8683 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8684 if (conn_snum_used(iService)) {
8687 /* Remove from the share ACL db. */
8688 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8689 lp_servicename(iService) ));
8690 delete_share_security(lp_servicename(iService));
8691 free_service_byindex(iService);
8695 return lp_numservices();
8698 /********************************************************
8699 Destroy global resources allocated in this file
8700 ********************************************************/
8702 void gfree_loadparm(void)
8704 struct file_lists *f;
8705 struct file_lists *next;
8708 /* Free the file lists */
8713 SAFE_FREE( f->name );
8714 SAFE_FREE( f->subfname );
8720 /* Free resources allocated to services */
8722 for ( i = 0; i < iNumServices; i++ ) {
8724 free_service_byindex(i);
8728 SAFE_FREE( ServicePtrs );
8731 /* Now release all resources allocated to global
8732 parameters and the default service */
8734 for (i = 0; parm_table[i].label; i++)
8736 if ( parm_table[i].type == P_STRING
8737 || parm_table[i].type == P_USTRING )
8739 string_free( (char**)parm_table[i].ptr );
8741 else if (parm_table[i].type == P_LIST) {
8742 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8748 /***************************************************************************
8749 Allow client apps to specify that they are a client
8750 ***************************************************************************/
8751 void lp_set_in_client(bool b)
8757 /***************************************************************************
8758 Determine if we're running in a client app
8759 ***************************************************************************/
8760 bool lp_is_in_client(void)
8768 /***************************************************************************
8769 Load the services array from the services file. Return True on success,
8771 ***************************************************************************/
8773 bool lp_load_ex(const char *pszFname,
8777 bool initialize_globals,
8778 bool allow_include_registry,
8779 bool allow_registry_shares)
8783 param_opt_struct *data, *pdata;
8787 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8789 bInGlobalSection = True;
8790 bGlobalOnly = global_only;
8791 bAllowIncludeRegistry = allow_include_registry;
8793 init_globals(! initialize_globals);
8796 if (save_defaults) {
8801 /* We get sections first, so have to start 'behind' to make up */
8804 if (Globals.param_opt != NULL) {
8805 data = Globals.param_opt;
8807 string_free(&data->key);
8808 string_free(&data->value);
8809 TALLOC_FREE(data->list);
8814 Globals.param_opt = NULL;
8817 if (lp_config_backend_is_file()) {
8818 n2 = alloc_sub_basic(get_current_username(),
8819 current_user_info.domain,
8822 smb_panic("lp_load_ex: out of memory");
8825 add_to_file_list(pszFname, n2);
8827 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8830 /* finish up the last section */
8831 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8833 if (iServiceIndex >= 0) {
8834 bRetval = service_ok(iServiceIndex);
8838 if (lp_config_backend_is_registry()) {
8839 /* config backend changed to registry in config file */
8841 * We need to use this extra global variable here to
8842 * survive restart: init_globals uses this as a default
8843 * for ConfigBackend. Otherwise, init_globals would
8844 * send us into an endless loop here.
8846 config_backend = CONFIG_BACKEND_REGISTRY;
8848 DEBUG(1, ("lp_load_ex: changing to config backend "
8850 init_globals(false);
8851 lp_kill_all_services();
8852 return lp_load_ex(pszFname, global_only, save_defaults,
8853 add_ipc, initialize_globals,
8854 allow_include_registry,
8855 allow_registry_shares);
8857 } else if (lp_config_backend_is_registry()) {
8858 bRetval = process_registry_globals();
8860 DEBUG(0, ("Illegal config backend given: %d\n",
8861 lp_config_backend()));
8865 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8866 bRetval = process_registry_shares();
8869 lp_add_auto_services(lp_auto_services());
8872 /* When 'restrict anonymous = 2' guest connections to ipc$
8874 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8875 if ( lp_enable_asu_support() ) {
8876 lp_add_ipc("ADMIN$", false);
8881 set_default_server_announce_type();
8882 set_allowed_client_auth();
8886 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8887 /* if bWINSsupport is true and we are in the client */
8888 if (lp_is_in_client() && Globals.bWINSsupport) {
8889 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8894 bAllowIncludeRegistry = true;
8899 bool lp_load(const char *pszFname,
8903 bool initialize_globals)
8905 return lp_load_ex(pszFname,
8913 bool lp_load_initial_only(const char *pszFname)
8915 return lp_load_ex(pszFname,
8924 bool lp_load_with_registry_shares(const char *pszFname,
8928 bool initialize_globals)
8930 return lp_load_ex(pszFname,
8939 /***************************************************************************
8940 Return the max number of services.
8941 ***************************************************************************/
8943 int lp_numservices(void)
8945 return (iNumServices);
8948 /***************************************************************************
8949 Display the contents of the services array in human-readable form.
8950 ***************************************************************************/
8952 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8957 defaults_saved = False;
8961 dump_a_service(&sDefault, f);
8963 for (iService = 0; iService < maxtoprint; iService++) {
8965 lp_dump_one(f, show_defaults, iService);
8969 /***************************************************************************
8970 Display the contents of one service in human-readable form.
8971 ***************************************************************************/
8973 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8976 if (ServicePtrs[snum]->szService[0] == '\0')
8978 dump_a_service(ServicePtrs[snum], f);
8982 /***************************************************************************
8983 Return the number of the service with the given name, or -1 if it doesn't
8984 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8985 getservicebyname()! This works ONLY if all services have been loaded, and
8986 does not copy the found service.
8987 ***************************************************************************/
8989 int lp_servicenumber(const char *pszServiceName)
8992 fstring serviceName;
8994 if (!pszServiceName) {
8995 return GLOBAL_SECTION_SNUM;
8998 for (iService = iNumServices - 1; iService >= 0; iService--) {
8999 if (VALID(iService) && ServicePtrs[iService]->szService) {
9001 * The substitution here is used to support %U is
9004 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9005 standard_sub_basic(get_current_username(),
9006 current_user_info.domain,
9007 serviceName,sizeof(serviceName));
9008 if (strequal(serviceName, pszServiceName)) {
9014 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9017 if (!usershare_exists(iService, &last_mod)) {
9018 /* Remove the share security tdb entry for it. */
9019 delete_share_security(lp_servicename(iService));
9020 /* Remove it from the array. */
9021 free_service_byindex(iService);
9022 /* Doesn't exist anymore. */
9023 return GLOBAL_SECTION_SNUM;
9026 /* Has it been modified ? If so delete and reload. */
9027 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9028 /* Remove it from the array. */
9029 free_service_byindex(iService);
9030 /* and now reload it. */
9031 iService = load_usershare_service(pszServiceName);
9036 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9037 return GLOBAL_SECTION_SNUM;
9043 bool share_defined(const char *service_name)
9045 return (lp_servicenumber(service_name) != -1);
9048 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9049 const char *sharename)
9051 struct share_params *result;
9055 if (!(sname = SMB_STRDUP(sharename))) {
9059 snum = find_service(sname);
9066 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9067 DEBUG(0, ("talloc failed\n"));
9071 result->service = snum;
9075 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9077 struct share_iterator *result;
9079 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9080 DEBUG(0, ("talloc failed\n"));
9084 result->next_id = 0;
9088 struct share_params *next_share(struct share_iterator *list)
9090 struct share_params *result;
9092 while (!lp_snum_ok(list->next_id) &&
9093 (list->next_id < lp_numservices())) {
9097 if (list->next_id >= lp_numservices()) {
9101 if (!(result = TALLOC_P(list, struct share_params))) {
9102 DEBUG(0, ("talloc failed\n"));
9106 result->service = list->next_id;
9111 struct share_params *next_printer(struct share_iterator *list)
9113 struct share_params *result;
9115 while ((result = next_share(list)) != NULL) {
9116 if (lp_print_ok(result->service)) {
9124 * This is a hack for a transition period until we transformed all code from
9125 * service numbers to struct share_params.
9128 struct share_params *snum2params_static(int snum)
9130 static struct share_params result;
9131 result.service = snum;
9135 /*******************************************************************
9136 A useful volume label function.
9137 ********************************************************************/
9139 const char *volume_label(int snum)
9142 const char *label = lp_volume(snum);
9144 label = lp_servicename(snum);
9147 /* This returns a 33 byte guarenteed null terminated string. */
9148 ret = talloc_strndup(talloc_tos(), label, 32);
9155 /*******************************************************************
9156 Set the server type we will announce as via nmbd.
9157 ********************************************************************/
9159 static void set_default_server_announce_type(void)
9161 default_server_announce = 0;
9162 default_server_announce |= SV_TYPE_WORKSTATION;
9163 default_server_announce |= SV_TYPE_SERVER;
9164 default_server_announce |= SV_TYPE_SERVER_UNIX;
9166 /* note that the flag should be set only if we have a
9167 printer service but nmbd doesn't actually load the
9168 services so we can't tell --jerry */
9170 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9172 switch (lp_announce_as()) {
9173 case ANNOUNCE_AS_NT_SERVER:
9174 default_server_announce |= SV_TYPE_SERVER_NT;
9175 /* fall through... */
9176 case ANNOUNCE_AS_NT_WORKSTATION:
9177 default_server_announce |= SV_TYPE_NT;
9179 case ANNOUNCE_AS_WIN95:
9180 default_server_announce |= SV_TYPE_WIN95_PLUS;
9182 case ANNOUNCE_AS_WFW:
9183 default_server_announce |= SV_TYPE_WFW;
9189 switch (lp_server_role()) {
9190 case ROLE_DOMAIN_MEMBER:
9191 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9193 case ROLE_DOMAIN_PDC:
9194 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9196 case ROLE_DOMAIN_BDC:
9197 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9199 case ROLE_STANDALONE:
9203 if (lp_time_server())
9204 default_server_announce |= SV_TYPE_TIME_SOURCE;
9206 if (lp_host_msdfs())
9207 default_server_announce |= SV_TYPE_DFS_SERVER;
9210 /***********************************************************
9211 returns role of Samba server
9212 ************************************************************/
9214 int lp_server_role(void)
9219 /***********************************************************
9220 If we are PDC then prefer us as DMB
9221 ************************************************************/
9223 bool lp_domain_master(void)
9225 if (Globals.iDomainMaster == Auto)
9226 return (lp_server_role() == ROLE_DOMAIN_PDC);
9228 return (bool)Globals.iDomainMaster;
9231 /***********************************************************
9232 If we are DMB then prefer us as LMB
9233 ************************************************************/
9235 bool lp_preferred_master(void)
9237 if (Globals.iPreferredMaster == Auto)
9238 return (lp_local_master() && lp_domain_master());
9240 return (bool)Globals.iPreferredMaster;
9243 /*******************************************************************
9245 ********************************************************************/
9247 void lp_remove_service(int snum)
9249 ServicePtrs[snum]->valid = False;
9250 invalid_services[num_invalid_services++] = snum;
9253 /*******************************************************************
9255 ********************************************************************/
9257 void lp_copy_service(int snum, const char *new_name)
9259 do_section(new_name, NULL);
9261 snum = lp_servicenumber(new_name);
9263 lp_do_parameter(snum, "copy", lp_servicename(snum));
9268 /*******************************************************************
9269 Get the default server type we will announce as via nmbd.
9270 ********************************************************************/
9272 int lp_default_server_announce(void)
9274 return default_server_announce;
9277 /*******************************************************************
9278 Split the announce version into major and minor numbers.
9279 ********************************************************************/
9281 int lp_major_announce_version(void)
9283 static bool got_major = False;
9284 static int major_version = DEFAULT_MAJOR_VERSION;
9289 return major_version;
9292 if ((vers = lp_announce_version()) == NULL)
9293 return major_version;
9295 if ((p = strchr_m(vers, '.')) == 0)
9296 return major_version;
9299 major_version = atoi(vers);
9300 return major_version;
9303 int lp_minor_announce_version(void)
9305 static bool got_minor = False;
9306 static int minor_version = DEFAULT_MINOR_VERSION;
9311 return minor_version;
9314 if ((vers = lp_announce_version()) == NULL)
9315 return minor_version;
9317 if ((p = strchr_m(vers, '.')) == 0)
9318 return minor_version;
9321 minor_version = atoi(p);
9322 return minor_version;
9325 /***********************************************************
9326 Set the global name resolution order (used in smbclient).
9327 ************************************************************/
9329 void lp_set_name_resolve_order(const char *new_order)
9331 string_set(&Globals.szNameResolveOrder, new_order);
9334 const char *lp_printername(int snum)
9336 const char *ret = _lp_printername(snum);
9337 if (ret == NULL || (ret != NULL && *ret == '\0'))
9338 ret = lp_const_servicename(snum);
9344 /***********************************************************
9345 Allow daemons such as winbindd to fix their logfile name.
9346 ************************************************************/
9348 void lp_set_logfile(const char *name)
9350 string_set(&Globals.szLogFile, name);
9351 debug_set_logfile(name);
9354 /*******************************************************************
9355 Return the max print jobs per queue.
9356 ********************************************************************/
9358 int lp_maxprintjobs(int snum)
9360 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9361 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9362 maxjobs = PRINT_MAX_JOBID - 1;
9367 const char *lp_printcapname(void)
9369 if ((Globals.szPrintcapname != NULL) &&
9370 (Globals.szPrintcapname[0] != '\0'))
9371 return Globals.szPrintcapname;
9373 if (sDefault.iPrinting == PRINT_CUPS) {
9381 if (sDefault.iPrinting == PRINT_BSD)
9382 return "/etc/printcap";
9384 return PRINTCAP_NAME;
9387 /*******************************************************************
9388 Ensure we don't use sendfile if server smb signing is active.
9389 ********************************************************************/
9391 static uint32 spoolss_state;
9393 bool lp_disable_spoolss( void )
9395 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9396 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9398 return spoolss_state == SVCCTL_STOPPED ? True : False;
9401 void lp_set_spoolss_state( uint32 state )
9403 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9405 spoolss_state = state;
9408 uint32 lp_get_spoolss_state( void )
9410 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9413 /*******************************************************************
9414 Ensure we don't use sendfile if server smb signing is active.
9415 ********************************************************************/
9417 bool lp_use_sendfile(int snum)
9419 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9420 if (Protocol < PROTOCOL_NT1) {
9423 return (_lp_use_sendfile(snum) &&
9424 (get_remote_arch() != RA_WIN95) &&
9425 !srv_is_signing_active());
9428 /*******************************************************************
9429 Turn off sendfile if we find the underlying OS doesn't support it.
9430 ********************************************************************/
9432 void set_use_sendfile(int snum, bool val)
9434 if (LP_SNUM_OK(snum))
9435 ServicePtrs[snum]->bUseSendfile = val;
9437 sDefault.bUseSendfile = val;
9440 /*******************************************************************
9441 Turn off storing DOS attributes if this share doesn't support it.
9442 ********************************************************************/
9444 void set_store_dos_attributes(int snum, bool val)
9446 if (!LP_SNUM_OK(snum))
9448 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9451 void lp_set_mangling_method(const char *new_method)
9453 string_set(&Globals.szManglingMethod, new_method);
9456 /*******************************************************************
9457 Global state for POSIX pathname processing.
9458 ********************************************************************/
9460 static bool posix_pathnames;
9462 bool lp_posix_pathnames(void)
9464 return posix_pathnames;
9467 /*******************************************************************
9468 Change everything needed to ensure POSIX pathname processing (currently
9470 ********************************************************************/
9472 void lp_set_posix_pathnames(void)
9474 posix_pathnames = True;
9477 /*******************************************************************
9478 Global state for POSIX lock processing - CIFS unix extensions.
9479 ********************************************************************/
9481 bool posix_default_lock_was_set;
9482 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9484 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9486 if (posix_default_lock_was_set) {
9487 return posix_cifsx_locktype;
9489 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9493 /*******************************************************************
9494 ********************************************************************/
9496 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9498 posix_default_lock_was_set = True;
9499 posix_cifsx_locktype = val;
9502 int lp_min_receive_file_size(void)
9504 if (Globals.iminreceivefile < 0) {
9507 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9510 /*******************************************************************
9511 If socket address is an empty character string, it is necessary to
9512 define it as "0.0.0.0".
9513 ********************************************************************/
9515 const char *lp_socket_address(void)
9517 char *sock_addr = Globals.szSocketAddress;
9519 if (sock_addr[0] == '\0'){
9520 string_set(&Globals.szSocketAddress, "0.0.0.0");
9522 return Globals.szSocketAddress;