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 static bool in_client = False; /* Not in the client by default */
74 static uint64_t conf_last_seqnum = 0;
75 static struct smbconf_ctx *conf_ctx = NULL;
77 #define CONFIG_BACKEND_FILE 0
78 #define CONFIG_BACKEND_REGISTRY 1
80 static int config_backend = CONFIG_BACKEND_FILE;
82 /* some helpful bits */
83 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
84 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
86 #define USERSHARE_VALID 1
87 #define USERSHARE_PENDING_DELETE 2
89 extern int extra_time_offset;
91 static bool defaults_saved = False;
93 typedef struct _param_opt_struct param_opt_struct;
94 struct _param_opt_struct {
95 param_opt_struct *prev, *next;
102 * This structure describes global (ie., server-wide) parameters.
109 char *display_charset;
110 char *szPrintcapname;
111 char *szAddPortCommand;
112 char *szEnumPortsCommand;
113 char *szAddPrinterCommand;
114 char *szDeletePrinterCommand;
115 char *szOs2DriverMap;
119 char *szDefaultService;
123 char *szServerString;
124 char *szAutoServices;
125 char *szPasswdProgram;
129 char *szSMBPasswdFile;
131 char *szPassdbBackend;
132 char **szPreloadModules;
133 char *szPasswordServer;
134 char *szSocketOptions;
136 char *szAfsUsernameMap;
137 int iAfsTokenLifetime;
138 char *szLogNtTokenCommand;
144 char **szWINSservers;
146 char *szRemoteAnnounce;
147 char *szRemoteBrowseSync;
148 char *szSocketAddress;
149 char *szNISHomeMapName;
150 char *szAnnounceVersion; /* This is initialised in init_globals */
153 char **szNetbiosAliases;
154 char *szNetbiosScope;
155 char *szNameResolveOrder;
157 char *szAddUserScript;
158 char *szRenameUserScript;
159 char *szDelUserScript;
160 char *szAddGroupScript;
161 char *szDelGroupScript;
162 char *szAddUserToGroupScript;
163 char *szDelUserFromGroupScript;
164 char *szSetPrimaryGroupScript;
165 char *szAddMachineScript;
166 char *szShutdownScript;
167 char *szAbortShutdownScript;
168 char *szUsernameMapScript;
169 char *szCheckPasswordScript;
176 bool bPassdbExpandExplicit;
177 int AlgorithmicRidBase;
178 char *szTemplateHomedir;
179 char *szTemplateShell;
180 char *szWinbindSeparator;
181 bool bWinbindEnumUsers;
182 bool bWinbindEnumGroups;
183 bool bWinbindUseDefaultDomain;
184 bool bWinbindTrustedDomainsOnly;
185 bool bWinbindNestedGroups;
186 int winbind_expand_groups;
187 bool bWinbindRefreshTickets;
188 bool bWinbindOfflineLogon;
189 bool bWinbindNormalizeNames;
190 bool bWinbindRpcOnly;
191 char **szIdmapDomains;
192 char **szIdmapBackend; /* deprecated */
193 char *szIdmapAllocBackend;
194 char *szAddShareCommand;
195 char *szChangeShareCommand;
196 char *szDeleteShareCommand;
198 char *szGuestaccount;
199 char *szManglingMethod;
200 char **szServicesList;
201 char *szUsersharePath;
202 char *szUsershareTemplateShare;
203 char **szUsersharePrefixAllowList;
204 char **szUsersharePrefixDenyList;
211 int open_files_db_hash_size;
220 bool paranoid_server_security;
223 int iMaxSmbdProcesses;
224 bool bDisableSpoolss;
227 bool enhanced_browsing;
233 int announce_as; /* This is initialised in init_globals */
234 int machine_password_timeout;
236 int oplock_break_wait_time;
237 int winbind_cache_time;
238 int winbind_max_idle_children;
239 char **szWinbindNssInfo;
241 char *szLdapMachineSuffix;
242 char *szLdapUserSuffix;
243 char *szLdapIdmapSuffix;
244 char *szLdapGroupSuffix;
248 int ldap_debug_level;
249 int ldap_debug_threshold;
252 char *szIPrintServer;
254 char **szClusterAddresses;
256 int ldap_passwd_sync;
257 int ldap_replication_sleep;
258 int ldap_timeout; /* This is initialised in init_globals */
261 bool bMsAddPrinterWizard;
266 int iPreferredMaster;
269 bool bEncryptPasswords;
274 bool bObeyPamRestrictions;
276 int PrintcapCacheTime;
277 bool bLargeReadwrite;
284 bool bBindInterfacesOnly;
285 bool bPamPasswordChange;
286 bool bUnixPasswdSync;
287 bool bPasswdChatDebug;
288 int iPasswdChatTimeout;
292 bool bNTStatusSupport;
294 int iMaxStatCacheSize;
296 bool bAllowTrustedDomains;
300 bool bClientLanManAuth;
301 bool bClientNTLMv2Auth;
302 bool bClientPlaintextAuth;
303 bool bClientUseSpnego;
304 bool bDebugPrefixTimestamp;
305 bool bDebugHiresTimestamp;
309 bool bEnableCoreFiles;
312 bool bHostnameLookups;
313 bool bUnixExtensions;
314 bool bDisableNetbios;
315 bool bUseKerberosKeytab;
316 bool bDeferSharingViolations;
317 bool bEnablePrivileges;
319 bool bUsershareOwnerOnly;
320 bool bUsershareAllowGuests;
321 bool bRegistryShares;
322 int restrict_anonymous;
323 int name_cache_timeout;
326 int client_ldap_sasl_wrapping;
327 int iUsershareMaxShares;
329 int iIdmapNegativeCacheTime;
333 param_opt_struct *param_opt;
336 static struct global Globals;
339 * This structure describes a single service.
345 time_t usershare_last_mod;
349 char **szInvalidUsers;
357 char *szRootPostExec;
359 char *szPrintcommand;
362 char *szLppausecommand;
363 char *szLpresumecommand;
364 char *szQueuepausecommand;
365 char *szQueueresumecommand;
367 char *szPrintjobUsername;
375 char *szVetoOplockFiles;
381 char **printer_admin;
386 char *szAioWriteBehind;
390 int iMaxReportedPrintJobs;
393 int iCreate_force_mode;
395 int iSecurity_force_mode;
398 int iDir_Security_mask;
399 int iDir_Security_force_mode;
403 int iOplockContentionLimit;
408 bool bRootpreexecClose;
411 bool bShortCasePreserve;
413 bool bHideSpecialFiles;
414 bool bHideUnReadable;
415 bool bHideUnWriteableFiles;
421 bool bAdministrative_share;
427 bool bStoreDosAttributes;
440 bool bStrictAllocate;
443 struct bitmap *copymap;
444 bool bDeleteReadonly;
446 bool bDeleteVetoFiles;
449 bool bDosFiletimeResolution;
450 bool bFakeDirCreateTimes;
456 bool bUseClientDriver;
457 bool bDefaultDevmode;
458 bool bForcePrintername;
460 bool bForceUnknownAclUser;
463 bool bMap_acl_inherit;
466 bool bAclCheckPermissions;
467 bool bAclMapFullControl;
468 bool bAclGroupControl;
470 bool bKernelChangeNotify;
471 int iallocation_roundup_size;
475 int iDirectoryNameCacheSize;
477 param_opt_struct *param_opt;
479 char dummy[3]; /* for alignment */
483 /* This is a default service used to prime a services structure */
484 static struct service sDefault = {
486 False, /* not autoloaded */
487 0, /* not a usershare */
488 (time_t)0, /* No last mod time */
489 NULL, /* szService */
491 NULL, /* szUsername */
492 NULL, /* szInvalidUsers */
493 NULL, /* szValidUsers */
494 NULL, /* szAdminUsers */
496 NULL, /* szInclude */
497 NULL, /* szPreExec */
498 NULL, /* szPostExec */
499 NULL, /* szRootPreExec */
500 NULL, /* szRootPostExec */
501 NULL, /* szCupsOptions */
502 NULL, /* szPrintcommand */
503 NULL, /* szLpqcommand */
504 NULL, /* szLprmcommand */
505 NULL, /* szLppausecommand */
506 NULL, /* szLpresumecommand */
507 NULL, /* szQueuepausecommand */
508 NULL, /* szQueueresumecommand */
509 NULL, /* szPrintername */
510 NULL, /* szPrintjobUsername */
511 NULL, /* szDontdescend */
512 NULL, /* szHostsallow */
513 NULL, /* szHostsdeny */
514 NULL, /* szMagicScript */
515 NULL, /* szMagicOutput */
516 NULL, /* szVetoFiles */
517 NULL, /* szHideFiles */
518 NULL, /* szVetoOplockFiles */
520 NULL, /* force user */
521 NULL, /* force group */
523 NULL, /* writelist */
524 NULL, /* printer admin */
527 NULL, /* vfs objects */
528 NULL, /* szMSDfsProxy */
529 NULL, /* szAioWriteBehind */
531 0, /* iMinPrintSpace */
532 1000, /* iMaxPrintJobs */
533 0, /* iMaxReportedPrintJobs */
534 0, /* iWriteCacheSize */
535 0744, /* iCreate_mask */
536 0000, /* iCreate_force_mode */
537 0777, /* iSecurity_mask */
538 0, /* iSecurity_force_mode */
539 0755, /* iDir_mask */
540 0000, /* iDir_force_mode */
541 0777, /* iDir_Security_mask */
542 0, /* iDir_Security_force_mode */
543 0, /* iMaxConnections */
544 CASE_LOWER, /* iDefaultCase */
545 DEFAULT_PRINTING, /* iPrinting */
546 2, /* iOplockContentionLimit */
548 1024, /* iBlock_size */
549 0, /* iDfreeCacheTime */
550 False, /* bPreexecClose */
551 False, /* bRootpreexecClose */
552 Auto, /* case sensitive */
553 True, /* case preserve */
554 True, /* short case preserve */
555 True, /* bHideDotFiles */
556 False, /* bHideSpecialFiles */
557 False, /* bHideUnReadable */
558 False, /* bHideUnWriteableFiles */
559 True, /* bBrowseable */
560 True, /* bAvailable */
561 True, /* bRead_only */
562 True, /* bNo_set_dir */
563 False, /* bGuest_only */
564 False, /* bAdministrative_share */
565 False, /* bGuest_ok */
566 False, /* bPrint_ok */
567 False, /* bMap_system */
568 False, /* bMap_hidden */
569 True, /* bMap_archive */
570 False, /* bStoreDosAttributes */
571 False, /* bDmapiSupport */
573 Auto, /* iStrictLocking */
574 True, /* bPosixLocking */
575 True, /* bShareModes */
577 True, /* bLevel2OpLocks */
578 False, /* bOnlyUser */
579 True, /* bMangledNames */
580 True, /* bWidelinks */
581 True, /* bSymlinks */
582 False, /* bSyncAlways */
583 False, /* bStrictAllocate */
584 False, /* bStrictSync */
585 '~', /* magic char */
587 False, /* bDeleteReadonly */
588 False, /* bFakeOplocks */
589 False, /* bDeleteVetoFiles */
590 False, /* bDosFilemode */
591 True, /* bDosFiletimes */
592 False, /* bDosFiletimeResolution */
593 False, /* bFakeDirCreateTimes */
594 True, /* bBlockingLocks */
595 False, /* bInheritPerms */
596 False, /* bInheritACLS */
597 False, /* bInheritOwner */
598 False, /* bMSDfsRoot */
599 False, /* bUseClientDriver */
600 True, /* bDefaultDevmode */
601 False, /* bForcePrintername */
602 True, /* bNTAclSupport */
603 False, /* bForceUnknownAclUser */
604 False, /* bUseSendfile */
605 False, /* bProfileAcls */
606 False, /* bMap_acl_inherit */
607 False, /* bAfs_Share */
608 False, /* bEASupport */
609 True, /* bAclCheckPermissions */
610 True, /* bAclMapFullControl */
611 False, /* bAclGroupControl */
612 True, /* bChangeNotify */
613 True, /* bKernelChangeNotify */
614 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
615 0, /* iAioReadSize */
616 0, /* iAioWriteSize */
617 MAP_READONLY_YES, /* iMap_readonly */
618 #ifdef BROKEN_DIRECTORY_HANDLING
619 0, /* iDirectoryNameCacheSize */
621 100, /* iDirectoryNameCacheSize */
623 Auto, /* ismb_encrypt */
624 NULL, /* Parametric options */
629 /* local variables */
630 static struct service **ServicePtrs = NULL;
631 static int iNumServices = 0;
632 static int iServiceIndex = 0;
633 static struct db_context *ServiceHash;
634 static int *invalid_services = NULL;
635 static int num_invalid_services = 0;
636 static bool bInGlobalSection = True;
637 static bool bGlobalOnly = False;
638 static int server_role;
639 static int default_server_announce;
641 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
643 /* prototypes for the special type handlers */
644 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
645 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
646 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
647 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
648 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
649 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
650 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
651 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
652 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
653 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
654 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
655 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
657 static void set_server_role(void);
658 static void set_default_server_announce_type(void);
659 static void set_allowed_client_auth(void);
661 static const struct enum_list enum_protocol[] = {
662 {PROTOCOL_NT1, "NT1"},
663 {PROTOCOL_LANMAN2, "LANMAN2"},
664 {PROTOCOL_LANMAN1, "LANMAN1"},
665 {PROTOCOL_CORE, "CORE"},
666 {PROTOCOL_COREPLUS, "COREPLUS"},
667 {PROTOCOL_COREPLUS, "CORE+"},
671 static const struct enum_list enum_security[] = {
672 {SEC_SHARE, "SHARE"},
674 {SEC_SERVER, "SERVER"},
675 {SEC_DOMAIN, "DOMAIN"},
682 static const struct enum_list enum_printing[] = {
683 {PRINT_SYSV, "sysv"},
685 {PRINT_HPUX, "hpux"},
689 {PRINT_LPRNG, "lprng"},
690 {PRINT_CUPS, "cups"},
691 {PRINT_IPRINT, "iprint"},
693 {PRINT_LPROS2, "os2"},
695 {PRINT_TEST, "test"},
697 #endif /* DEVELOPER */
701 static const struct enum_list enum_ldap_sasl_wrapping[] = {
703 {ADS_AUTH_SASL_SIGN, "sign"},
704 {ADS_AUTH_SASL_SEAL, "seal"},
708 static const struct enum_list enum_ldap_ssl[] = {
709 {LDAP_SSL_OFF, "no"},
710 {LDAP_SSL_OFF, "No"},
711 {LDAP_SSL_OFF, "off"},
712 {LDAP_SSL_OFF, "Off"},
713 {LDAP_SSL_START_TLS, "start tls"},
714 {LDAP_SSL_START_TLS, "Start_tls"},
718 static const struct enum_list enum_ldap_passwd_sync[] = {
719 {LDAP_PASSWD_SYNC_OFF, "no"},
720 {LDAP_PASSWD_SYNC_OFF, "No"},
721 {LDAP_PASSWD_SYNC_OFF, "off"},
722 {LDAP_PASSWD_SYNC_OFF, "Off"},
723 {LDAP_PASSWD_SYNC_ON, "Yes"},
724 {LDAP_PASSWD_SYNC_ON, "yes"},
725 {LDAP_PASSWD_SYNC_ON, "on"},
726 {LDAP_PASSWD_SYNC_ON, "On"},
727 {LDAP_PASSWD_SYNC_ONLY, "Only"},
728 {LDAP_PASSWD_SYNC_ONLY, "only"},
732 /* Types of machine we can announce as. */
733 #define ANNOUNCE_AS_NT_SERVER 1
734 #define ANNOUNCE_AS_WIN95 2
735 #define ANNOUNCE_AS_WFW 3
736 #define ANNOUNCE_AS_NT_WORKSTATION 4
738 static const struct enum_list enum_announce_as[] = {
739 {ANNOUNCE_AS_NT_SERVER, "NT"},
740 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
741 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
742 {ANNOUNCE_AS_WIN95, "win95"},
743 {ANNOUNCE_AS_WFW, "WfW"},
747 static const struct enum_list enum_map_readonly[] = {
748 {MAP_READONLY_NO, "no"},
749 {MAP_READONLY_NO, "false"},
750 {MAP_READONLY_NO, "0"},
751 {MAP_READONLY_YES, "yes"},
752 {MAP_READONLY_YES, "true"},
753 {MAP_READONLY_YES, "1"},
754 {MAP_READONLY_PERMISSIONS, "permissions"},
755 {MAP_READONLY_PERMISSIONS, "perms"},
759 static const struct enum_list enum_case[] = {
760 {CASE_LOWER, "lower"},
761 {CASE_UPPER, "upper"},
765 static const struct enum_list enum_bool_auto[] = {
776 /* Client-side offline caching policy types */
777 #define CSC_POLICY_MANUAL 0
778 #define CSC_POLICY_DOCUMENTS 1
779 #define CSC_POLICY_PROGRAMS 2
780 #define CSC_POLICY_DISABLE 3
782 static const struct enum_list enum_csc_policy[] = {
783 {CSC_POLICY_MANUAL, "manual"},
784 {CSC_POLICY_DOCUMENTS, "documents"},
785 {CSC_POLICY_PROGRAMS, "programs"},
786 {CSC_POLICY_DISABLE, "disable"},
790 /* SMB signing types. */
791 static const struct enum_list enum_smb_signing_vals[] = {
803 {Required, "required"},
804 {Required, "mandatory"},
806 {Required, "forced"},
807 {Required, "enforced"},
811 /* ACL compatibility options. */
812 static const struct enum_list enum_acl_compat_vals[] = {
813 { ACL_COMPAT_AUTO, "auto" },
814 { ACL_COMPAT_WINNT, "winnt" },
815 { ACL_COMPAT_WIN2K, "win2k" },
820 Do you want session setups at user level security with a invalid
821 password to be rejected or allowed in as guest? WinNT rejects them
822 but it can be a pain as it means "net view" needs to use a password
824 You have 3 choices in the setting of map_to_guest:
826 "Never" means session setups with an invalid password
827 are rejected. This is the default.
829 "Bad User" means session setups with an invalid password
830 are rejected, unless the username does not exist, in which case it
831 is treated as a guest login
833 "Bad Password" means session setups with an invalid password
834 are treated as a guest login
836 Note that map_to_guest only has an effect in user or server
840 static const struct enum_list enum_map_to_guest[] = {
841 {NEVER_MAP_TO_GUEST, "Never"},
842 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
843 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
844 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
848 /* Config backend options */
850 static const struct enum_list enum_config_backend[] = {
851 {CONFIG_BACKEND_FILE, "file"},
852 {CONFIG_BACKEND_REGISTRY, "registry"},
856 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
858 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
859 * screen in SWAT. This is used to exclude parameters as well as to squash all
860 * parameters that have been duplicated by pseudonyms.
862 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
863 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
864 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
867 * NOTE2: Handling of duplicated (synonym) paramters:
868 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
869 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
870 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
871 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
874 static struct parm_struct parm_table[] = {
875 {N_("Base Options"), P_SEP, P_SEPARATOR},
878 .label = "dos charset",
881 .ptr = &Globals.dos_charset,
882 .special = handle_charset,
884 .flags = FLAG_ADVANCED
887 .label = "unix charset",
890 .ptr = &Globals.unix_charset,
891 .special = handle_charset,
893 .flags = FLAG_ADVANCED
896 .label = "display charset",
899 .ptr = &Globals.display_charset,
900 .special = handle_charset,
902 .flags = FLAG_ADVANCED
908 .ptr = &sDefault.comment,
911 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
917 .ptr = &sDefault.szPath,
920 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
923 .label = "directory",
926 .ptr = &sDefault.szPath,
932 .label = "workgroup",
935 .ptr = &Globals.szWorkgroup,
936 .special = handle_workgroup,
938 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
945 .ptr = &Globals.szRealm,
948 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
952 .label = "netbios name",
955 .ptr = &Globals.szNetbiosName,
956 .special = handle_netbios_name,
958 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
961 .label = "netbios aliases",
964 .ptr = &Globals.szNetbiosAliases,
965 .special = handle_netbios_aliases,
967 .flags = FLAG_ADVANCED,
970 .label = "netbios scope",
973 .ptr = &Globals.szNetbiosScope,
974 .special = handle_netbios_scope,
976 .flags = FLAG_ADVANCED,
979 .label = "server string",
982 .ptr = &Globals.szServerString,
985 .flags = FLAG_BASIC | FLAG_ADVANCED,
988 .label = "interfaces",
991 .ptr = &Globals.szInterfaces,
994 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
997 .label = "bind interfaces only",
1000 .ptr = &Globals.bBindInterfacesOnly,
1003 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1006 .label = "config backend",
1008 .p_class = P_GLOBAL,
1009 .ptr = &Globals.ConfigBackend,
1011 .enum_list = enum_config_backend,
1012 .flags = FLAG_ADVANCED,
1015 {N_("Security Options"), P_SEP, P_SEPARATOR},
1018 .label = "security",
1020 .p_class = P_GLOBAL,
1021 .ptr = &Globals.security,
1023 .enum_list = enum_security,
1024 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1027 .label = "auth methods",
1029 .p_class = P_GLOBAL,
1030 .ptr = &Globals.AuthMethods,
1033 .flags = FLAG_ADVANCED,
1036 .label = "encrypt passwords",
1038 .p_class = P_GLOBAL,
1039 .ptr = &Globals.bEncryptPasswords,
1042 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1045 .label = "update encrypted",
1047 .p_class = P_GLOBAL,
1048 .ptr = &Globals.bUpdateEncrypt,
1051 .flags = FLAG_ADVANCED,
1054 .label = "client schannel",
1056 .p_class = P_GLOBAL,
1057 .ptr = &Globals.clientSchannel,
1059 .enum_list = enum_bool_auto,
1060 .flags = FLAG_BASIC | FLAG_ADVANCED,
1063 .label = "server schannel",
1065 .p_class = P_GLOBAL,
1066 .ptr = &Globals.serverSchannel,
1068 .enum_list = enum_bool_auto,
1069 .flags = FLAG_BASIC | FLAG_ADVANCED,
1072 .label = "allow trusted domains",
1074 .p_class = P_GLOBAL,
1075 .ptr = &Globals.bAllowTrustedDomains,
1078 .flags = FLAG_ADVANCED,
1081 .label = "map to guest",
1083 .p_class = P_GLOBAL,
1084 .ptr = &Globals.map_to_guest,
1086 .enum_list = enum_map_to_guest,
1087 .flags = FLAG_ADVANCED,
1090 .label = "null passwords",
1092 .p_class = P_GLOBAL,
1093 .ptr = &Globals.bNullPasswords,
1096 .flags = FLAG_ADVANCED,
1099 .label = "obey pam restrictions",
1101 .p_class = P_GLOBAL,
1102 .ptr = &Globals.bObeyPamRestrictions,
1105 .flags = FLAG_ADVANCED,
1108 .label = "password server",
1110 .p_class = P_GLOBAL,
1111 .ptr = &Globals.szPasswordServer,
1114 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1117 .label = "smb passwd file",
1119 .p_class = P_GLOBAL,
1120 .ptr = &Globals.szSMBPasswdFile,
1123 .flags = FLAG_ADVANCED,
1126 .label = "private dir",
1128 .p_class = P_GLOBAL,
1129 .ptr = &Globals.szPrivateDir,
1132 .flags = FLAG_ADVANCED,
1135 .label = "passdb backend",
1137 .p_class = P_GLOBAL,
1138 .ptr = &Globals.szPassdbBackend,
1141 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1144 .label = "algorithmic rid base",
1146 .p_class = P_GLOBAL,
1147 .ptr = &Globals.AlgorithmicRidBase,
1150 .flags = FLAG_ADVANCED,
1153 .label = "root directory",
1155 .p_class = P_GLOBAL,
1156 .ptr = &Globals.szRootdir,
1159 .flags = FLAG_ADVANCED,
1162 .label = "root dir",
1164 .p_class = P_GLOBAL,
1165 .ptr = &Globals.szRootdir,
1173 .p_class = P_GLOBAL,
1174 .ptr = &Globals.szRootdir,
1180 .label = "guest account",
1182 .p_class = P_GLOBAL,
1183 .ptr = &Globals.szGuestaccount,
1186 .flags = FLAG_BASIC | FLAG_ADVANCED,
1189 .label = "enable privileges",
1191 .p_class = P_GLOBAL,
1192 .ptr = &Globals.bEnablePrivileges,
1195 .flags = FLAG_ADVANCED,
1199 .label = "pam password change",
1201 .p_class = P_GLOBAL,
1202 .ptr = &Globals.bPamPasswordChange,
1205 .flags = FLAG_ADVANCED,
1208 .label = "passwd program",
1210 .p_class = P_GLOBAL,
1211 .ptr = &Globals.szPasswdProgram,
1214 .flags = FLAG_ADVANCED,
1217 .label = "passwd chat",
1219 .p_class = P_GLOBAL,
1220 .ptr = &Globals.szPasswdChat,
1223 .flags = FLAG_ADVANCED,
1226 .label = "passwd chat debug",
1228 .p_class = P_GLOBAL,
1229 .ptr = &Globals.bPasswdChatDebug,
1232 .flags = FLAG_ADVANCED,
1235 .label = "passwd chat timeout",
1237 .p_class = P_GLOBAL,
1238 .ptr = &Globals.iPasswdChatTimeout,
1241 .flags = FLAG_ADVANCED,
1244 .label = "check password script",
1246 .p_class = P_GLOBAL,
1247 .ptr = &Globals.szCheckPasswordScript,
1250 .flags = FLAG_ADVANCED,
1253 .label = "username map",
1255 .p_class = P_GLOBAL,
1256 .ptr = &Globals.szUsernameMap,
1259 .flags = FLAG_ADVANCED,
1262 .label = "password level",
1264 .p_class = P_GLOBAL,
1265 .ptr = &Globals.pwordlevel,
1268 .flags = FLAG_ADVANCED,
1271 .label = "username level",
1273 .p_class = P_GLOBAL,
1274 .ptr = &Globals.unamelevel,
1277 .flags = FLAG_ADVANCED,
1280 .label = "unix password sync",
1282 .p_class = P_GLOBAL,
1283 .ptr = &Globals.bUnixPasswdSync,
1286 .flags = FLAG_ADVANCED,
1289 .label = "restrict anonymous",
1291 .p_class = P_GLOBAL,
1292 .ptr = &Globals.restrict_anonymous,
1295 .flags = FLAG_ADVANCED,
1298 .label = "lanman auth",
1300 .p_class = P_GLOBAL,
1301 .ptr = &Globals.bLanmanAuth,
1304 .flags = FLAG_ADVANCED,
1307 .label = "ntlm auth",
1309 .p_class = P_GLOBAL,
1310 .ptr = &Globals.bNTLMAuth,
1313 .flags = FLAG_ADVANCED,
1316 .label = "client NTLMv2 auth",
1318 .p_class = P_GLOBAL,
1319 .ptr = &Globals.bClientNTLMv2Auth,
1322 .flags = FLAG_ADVANCED,
1325 .label = "client lanman auth",
1327 .p_class = P_GLOBAL,
1328 .ptr = &Globals.bClientLanManAuth,
1331 .flags = FLAG_ADVANCED,
1334 .label = "client plaintext auth",
1336 .p_class = P_GLOBAL,
1337 .ptr = &Globals.bClientPlaintextAuth,
1340 .flags = FLAG_ADVANCED,
1343 .label = "username",
1346 .ptr = &sDefault.szUsername,
1349 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1355 .ptr = &sDefault.szUsername,
1364 .ptr = &sDefault.szUsername,
1370 .label = "invalid users",
1373 .ptr = &sDefault.szInvalidUsers,
1376 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1379 .label = "valid users",
1382 .ptr = &sDefault.szValidUsers,
1385 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1388 .label = "admin users",
1391 .ptr = &sDefault.szAdminUsers,
1394 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1397 .label = "read list",
1400 .ptr = &sDefault.readlist,
1403 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1406 .label = "write list",
1409 .ptr = &sDefault.writelist,
1412 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1415 .label = "printer admin",
1418 .ptr = &sDefault.printer_admin,
1421 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1424 .label = "force user",
1427 .ptr = &sDefault.force_user,
1430 .flags = FLAG_ADVANCED | FLAG_SHARE,
1433 .label = "force group",
1436 .ptr = &sDefault.force_group,
1439 .flags = FLAG_ADVANCED | FLAG_SHARE,
1445 .ptr = &sDefault.force_group,
1448 .flags = FLAG_ADVANCED,
1451 .label = "read only",
1454 .ptr = &sDefault.bRead_only,
1457 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1460 .label = "write ok",
1463 .ptr = &sDefault.bRead_only,
1469 .label = "writeable",
1472 .ptr = &sDefault.bRead_only,
1478 .label = "writable",
1481 .ptr = &sDefault.bRead_only,
1487 .label = "acl check permissions",
1490 .ptr = &sDefault.bAclCheckPermissions,
1493 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1496 .label = "acl group control",
1499 .ptr = &sDefault.bAclGroupControl,
1502 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1505 .label = "acl map full control",
1508 .ptr = &sDefault.bAclMapFullControl,
1511 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1514 .label = "create mask",
1517 .ptr = &sDefault.iCreate_mask,
1520 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1523 .label = "create mode",
1526 .ptr = &sDefault.iCreate_mask,
1532 .label = "force create mode",
1535 .ptr = &sDefault.iCreate_force_mode,
1538 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1541 .label = "security mask",
1544 .ptr = &sDefault.iSecurity_mask,
1547 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1550 .label = "force security mode",
1553 .ptr = &sDefault.iSecurity_force_mode,
1556 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1559 .label = "directory mask",
1562 .ptr = &sDefault.iDir_mask,
1565 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1568 .label = "directory mode",
1571 .ptr = &sDefault.iDir_mask,
1574 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1577 .label = "force directory mode",
1580 .ptr = &sDefault.iDir_force_mode,
1583 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1586 .label = "directory security mask",
1589 .ptr = &sDefault.iDir_Security_mask,
1592 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1595 .label = "force directory security mode",
1598 .ptr = &sDefault.iDir_Security_force_mode,
1601 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1604 .label = "force unknown acl user",
1607 .ptr = &sDefault.bForceUnknownAclUser,
1610 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1613 .label = "inherit permissions",
1616 .ptr = &sDefault.bInheritPerms,
1619 .flags = FLAG_ADVANCED | FLAG_SHARE,
1622 .label = "inherit acls",
1625 .ptr = &sDefault.bInheritACLS,
1628 .flags = FLAG_ADVANCED | FLAG_SHARE,
1631 .label = "inherit owner",
1634 .ptr = &sDefault.bInheritOwner,
1637 .flags = FLAG_ADVANCED | FLAG_SHARE,
1640 .label = "guest only",
1643 .ptr = &sDefault.bGuest_only,
1646 .flags = FLAG_ADVANCED | FLAG_SHARE,
1649 .label = "only guest",
1652 .ptr = &sDefault.bGuest_only,
1658 .label = "administrative share",
1661 .ptr = &sDefault.bAdministrative_share,
1664 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1668 .label = "guest ok",
1671 .ptr = &sDefault.bGuest_ok,
1674 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1680 .ptr = &sDefault.bGuest_ok,
1686 .label = "only user",
1689 .ptr = &sDefault.bOnlyUser,
1692 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1695 .label = "hosts allow",
1698 .ptr = &sDefault.szHostsallow,
1701 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1704 .label = "allow hosts",
1707 .ptr = &sDefault.szHostsallow,
1713 .label = "hosts deny",
1716 .ptr = &sDefault.szHostsdeny,
1719 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1722 .label = "deny hosts",
1725 .ptr = &sDefault.szHostsdeny,
1731 .label = "preload modules",
1733 .p_class = P_GLOBAL,
1734 .ptr = &Globals.szPreloadModules,
1737 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1740 .label = "use kerberos keytab",
1742 .p_class = P_GLOBAL,
1743 .ptr = &Globals.bUseKerberosKeytab,
1746 .flags = FLAG_ADVANCED,
1749 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1752 .label = "log level",
1754 .p_class = P_GLOBAL,
1755 .ptr = &Globals.szLogLevel,
1756 .special = handle_debug_list,
1758 .flags = FLAG_ADVANCED,
1761 .label = "debuglevel",
1763 .p_class = P_GLOBAL,
1764 .ptr = &Globals.szLogLevel,
1765 .special = handle_debug_list,
1772 .p_class = P_GLOBAL,
1773 .ptr = &Globals.syslog,
1776 .flags = FLAG_ADVANCED,
1779 .label = "syslog only",
1781 .p_class = P_GLOBAL,
1782 .ptr = &Globals.bSyslogOnly,
1785 .flags = FLAG_ADVANCED,
1788 .label = "log file",
1790 .p_class = P_GLOBAL,
1791 .ptr = &Globals.szLogFile,
1794 .flags = FLAG_ADVANCED,
1797 .label = "max log size",
1799 .p_class = P_GLOBAL,
1800 .ptr = &Globals.max_log_size,
1803 .flags = FLAG_ADVANCED,
1806 .label = "debug timestamp",
1808 .p_class = P_GLOBAL,
1809 .ptr = &Globals.bTimestampLogs,
1812 .flags = FLAG_ADVANCED,
1815 .label = "timestamp logs",
1817 .p_class = P_GLOBAL,
1818 .ptr = &Globals.bTimestampLogs,
1821 .flags = FLAG_ADVANCED,
1824 .label = "debug prefix timestamp",
1826 .p_class = P_GLOBAL,
1827 .ptr = &Globals.bDebugPrefixTimestamp,
1830 .flags = FLAG_ADVANCED,
1833 .label = "debug hires timestamp",
1835 .p_class = P_GLOBAL,
1836 .ptr = &Globals.bDebugHiresTimestamp,
1839 .flags = FLAG_ADVANCED,
1842 .label = "debug pid",
1844 .p_class = P_GLOBAL,
1845 .ptr = &Globals.bDebugPid,
1848 .flags = FLAG_ADVANCED,
1851 .label = "debug uid",
1853 .p_class = P_GLOBAL,
1854 .ptr = &Globals.bDebugUid,
1857 .flags = FLAG_ADVANCED,
1860 .label = "debug class",
1862 .p_class = P_GLOBAL,
1863 .ptr = &Globals.bDebugClass,
1866 .flags = FLAG_ADVANCED,
1869 .label = "enable core files",
1871 .p_class = P_GLOBAL,
1872 .ptr = &Globals.bEnableCoreFiles,
1875 .flags = FLAG_ADVANCED,
1878 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1881 .label = "allocation roundup size",
1884 .ptr = &sDefault.iallocation_roundup_size,
1887 .flags = FLAG_ADVANCED,
1890 .label = "aio read size",
1893 .ptr = &sDefault.iAioReadSize,
1896 .flags = FLAG_ADVANCED,
1899 .label = "aio write size",
1902 .ptr = &sDefault.iAioWriteSize,
1905 .flags = FLAG_ADVANCED,
1908 .label = "aio write behind",
1911 .ptr = &sDefault.szAioWriteBehind,
1914 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1917 .label = "smb ports",
1919 .p_class = P_GLOBAL,
1920 .ptr = &Globals.smb_ports,
1923 .flags = FLAG_ADVANCED,
1926 .label = "large readwrite",
1928 .p_class = P_GLOBAL,
1929 .ptr = &Globals.bLargeReadwrite,
1932 .flags = FLAG_ADVANCED,
1935 .label = "max protocol",
1937 .p_class = P_GLOBAL,
1938 .ptr = &Globals.maxprotocol,
1940 .enum_list = enum_protocol,
1941 .flags = FLAG_ADVANCED,
1944 .label = "protocol",
1946 .p_class = P_GLOBAL,
1947 .ptr = &Globals.maxprotocol,
1949 .enum_list = enum_protocol,
1950 .flags = FLAG_ADVANCED,
1953 .label = "min protocol",
1955 .p_class = P_GLOBAL,
1956 .ptr = &Globals.minprotocol,
1958 .enum_list = enum_protocol,
1959 .flags = FLAG_ADVANCED,
1962 .label = "min receivefile size",
1964 .p_class = P_GLOBAL,
1965 .ptr = &Globals.iminreceivefile,
1968 .flags = FLAG_ADVANCED,
1971 .label = "read raw",
1973 .p_class = P_GLOBAL,
1974 .ptr = &Globals.bReadRaw,
1977 .flags = FLAG_ADVANCED,
1980 .label = "write raw",
1982 .p_class = P_GLOBAL,
1983 .ptr = &Globals.bWriteRaw,
1986 .flags = FLAG_ADVANCED,
1989 .label = "disable netbios",
1991 .p_class = P_GLOBAL,
1992 .ptr = &Globals.bDisableNetbios,
1995 .flags = FLAG_ADVANCED,
1998 .label = "reset on zero vc",
2000 .p_class = P_GLOBAL,
2001 .ptr = &Globals.bResetOnZeroVC,
2004 .flags = FLAG_ADVANCED,
2007 .label = "acl compatibility",
2009 .p_class = P_GLOBAL,
2010 .ptr = &Globals.iAclCompat,
2012 .enum_list = enum_acl_compat_vals,
2013 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2016 .label = "defer sharing violations",
2018 .p_class = P_GLOBAL,
2019 .ptr = &Globals.bDeferSharingViolations,
2022 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2025 .label = "ea support",
2028 .ptr = &sDefault.bEASupport,
2031 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2034 .label = "nt acl support",
2037 .ptr = &sDefault.bNTAclSupport,
2040 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2043 .label = "nt pipe support",
2045 .p_class = P_GLOBAL,
2046 .ptr = &Globals.bNTPipeSupport,
2049 .flags = FLAG_ADVANCED,
2052 .label = "nt status support",
2054 .p_class = P_GLOBAL,
2055 .ptr = &Globals.bNTStatusSupport,
2058 .flags = FLAG_ADVANCED,
2061 .label = "profile acls",
2064 .ptr = &sDefault.bProfileAcls,
2067 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2070 .label = "announce version",
2072 .p_class = P_GLOBAL,
2073 .ptr = &Globals.szAnnounceVersion,
2076 .flags = FLAG_ADVANCED,
2079 .label = "announce as",
2081 .p_class = P_GLOBAL,
2082 .ptr = &Globals.announce_as,
2084 .enum_list = enum_announce_as,
2085 .flags = FLAG_ADVANCED,
2088 .label = "map acl inherit",
2091 .ptr = &sDefault.bMap_acl_inherit,
2094 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2097 .label = "afs share",
2100 .ptr = &sDefault.bAfs_Share,
2103 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2108 .p_class = P_GLOBAL,
2109 .ptr = &Globals.max_mux,
2112 .flags = FLAG_ADVANCED,
2115 .label = "max xmit",
2117 .p_class = P_GLOBAL,
2118 .ptr = &Globals.max_xmit,
2121 .flags = FLAG_ADVANCED,
2124 .label = "name resolve order",
2126 .p_class = P_GLOBAL,
2127 .ptr = &Globals.szNameResolveOrder,
2130 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2135 .p_class = P_GLOBAL,
2136 .ptr = &Globals.max_ttl,
2139 .flags = FLAG_ADVANCED,
2142 .label = "max wins ttl",
2144 .p_class = P_GLOBAL,
2145 .ptr = &Globals.max_wins_ttl,
2148 .flags = FLAG_ADVANCED,
2151 .label = "min wins ttl",
2153 .p_class = P_GLOBAL,
2154 .ptr = &Globals.min_wins_ttl,
2157 .flags = FLAG_ADVANCED,
2160 .label = "time server",
2162 .p_class = P_GLOBAL,
2163 .ptr = &Globals.bTimeServer,
2166 .flags = FLAG_ADVANCED,
2169 .label = "unix extensions",
2171 .p_class = P_GLOBAL,
2172 .ptr = &Globals.bUnixExtensions,
2175 .flags = FLAG_ADVANCED,
2178 .label = "use spnego",
2180 .p_class = P_GLOBAL,
2181 .ptr = &Globals.bUseSpnego,
2184 .flags = FLAG_ADVANCED,
2187 .label = "client signing",
2189 .p_class = P_GLOBAL,
2190 .ptr = &Globals.client_signing,
2192 .enum_list = enum_smb_signing_vals,
2193 .flags = FLAG_ADVANCED,
2196 .label = "server signing",
2198 .p_class = P_GLOBAL,
2199 .ptr = &Globals.server_signing,
2201 .enum_list = enum_smb_signing_vals,
2202 .flags = FLAG_ADVANCED,
2205 .label = "smb encrypt",
2208 .ptr = &sDefault.ismb_encrypt,
2210 .enum_list = enum_smb_signing_vals,
2211 .flags = FLAG_ADVANCED,
2214 .label = "client use spnego",
2216 .p_class = P_GLOBAL,
2217 .ptr = &Globals.bClientUseSpnego,
2220 .flags = FLAG_ADVANCED,
2223 .label = "client ldap sasl wrapping",
2225 .p_class = P_GLOBAL,
2226 .ptr = &Globals.client_ldap_sasl_wrapping,
2228 .enum_list = enum_ldap_sasl_wrapping,
2229 .flags = FLAG_ADVANCED,
2232 .label = "enable asu support",
2234 .p_class = P_GLOBAL,
2235 .ptr = &Globals.bASUSupport,
2238 .flags = FLAG_ADVANCED,
2241 .label = "svcctl list",
2243 .p_class = P_GLOBAL,
2244 .ptr = &Globals.szServicesList,
2247 .flags = FLAG_ADVANCED,
2250 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2253 .label = "block size",
2256 .ptr = &sDefault.iBlock_size,
2259 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2262 .label = "deadtime",
2264 .p_class = P_GLOBAL,
2265 .ptr = &Globals.deadtime,
2268 .flags = FLAG_ADVANCED,
2271 .label = "getwd cache",
2273 .p_class = P_GLOBAL,
2274 .ptr = &Globals.getwd_cache,
2277 .flags = FLAG_ADVANCED,
2280 .label = "keepalive",
2282 .p_class = P_GLOBAL,
2283 .ptr = &Globals.iKeepalive,
2286 .flags = FLAG_ADVANCED,
2289 .label = "change notify",
2292 .ptr = &sDefault.bChangeNotify,
2295 .flags = FLAG_ADVANCED | FLAG_SHARE,
2298 .label = "directory name cache size",
2301 .ptr = &sDefault.iDirectoryNameCacheSize,
2304 .flags = FLAG_ADVANCED | FLAG_SHARE,
2307 .label = "kernel change notify",
2310 .ptr = &sDefault.bKernelChangeNotify,
2313 .flags = FLAG_ADVANCED | FLAG_SHARE,
2316 .label = "lpq cache time",
2318 .p_class = P_GLOBAL,
2319 .ptr = &Globals.lpqcachetime,
2322 .flags = FLAG_ADVANCED,
2325 .label = "max smbd processes",
2327 .p_class = P_GLOBAL,
2328 .ptr = &Globals.iMaxSmbdProcesses,
2331 .flags = FLAG_ADVANCED,
2334 .label = "max connections",
2337 .ptr = &sDefault.iMaxConnections,
2340 .flags = FLAG_ADVANCED | FLAG_SHARE,
2343 .label = "paranoid server security",
2345 .p_class = P_GLOBAL,
2346 .ptr = &Globals.paranoid_server_security,
2349 .flags = FLAG_ADVANCED,
2352 .label = "max disk size",
2354 .p_class = P_GLOBAL,
2355 .ptr = &Globals.maxdisksize,
2358 .flags = FLAG_ADVANCED,
2361 .label = "max open files",
2363 .p_class = P_GLOBAL,
2364 .ptr = &Globals.max_open_files,
2367 .flags = FLAG_ADVANCED,
2370 .label = "min print space",
2373 .ptr = &sDefault.iMinPrintSpace,
2376 .flags = FLAG_ADVANCED | FLAG_PRINT,
2379 .label = "socket options",
2381 .p_class = P_GLOBAL,
2382 .ptr = &Globals.szSocketOptions,
2385 .flags = FLAG_ADVANCED,
2388 .label = "strict allocate",
2391 .ptr = &sDefault.bStrictAllocate,
2394 .flags = FLAG_ADVANCED | FLAG_SHARE,
2397 .label = "strict sync",
2400 .ptr = &sDefault.bStrictSync,
2403 .flags = FLAG_ADVANCED | FLAG_SHARE,
2406 .label = "sync always",
2409 .ptr = &sDefault.bSyncAlways,
2412 .flags = FLAG_ADVANCED | FLAG_SHARE,
2415 .label = "use mmap",
2417 .p_class = P_GLOBAL,
2418 .ptr = &Globals.bUseMmap,
2421 .flags = FLAG_ADVANCED,
2424 .label = "use sendfile",
2427 .ptr = &sDefault.bUseSendfile,
2430 .flags = FLAG_ADVANCED | FLAG_SHARE,
2433 .label = "hostname lookups",
2435 .p_class = P_GLOBAL,
2436 .ptr = &Globals.bHostnameLookups,
2439 .flags = FLAG_ADVANCED,
2442 .label = "write cache size",
2445 .ptr = &sDefault.iWriteCacheSize,
2448 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2451 .label = "name cache timeout",
2453 .p_class = P_GLOBAL,
2454 .ptr = &Globals.name_cache_timeout,
2457 .flags = FLAG_ADVANCED,
2460 .label = "ctdbd socket",
2462 .p_class = P_GLOBAL,
2463 .ptr = &Globals.ctdbdSocket,
2466 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2469 .label = "cluster addresses",
2471 .p_class = P_GLOBAL,
2472 .ptr = &Globals.szClusterAddresses,
2475 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2478 .label = "clustering",
2480 .p_class = P_GLOBAL,
2481 .ptr = &Globals.clustering,
2484 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2487 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2490 .label = "max reported print jobs",
2493 .ptr = &sDefault.iMaxReportedPrintJobs,
2496 .flags = FLAG_ADVANCED | FLAG_PRINT,
2499 .label = "max print jobs",
2502 .ptr = &sDefault.iMaxPrintJobs,
2505 .flags = FLAG_ADVANCED | FLAG_PRINT,
2508 .label = "load printers",
2510 .p_class = P_GLOBAL,
2511 .ptr = &Globals.bLoadPrinters,
2514 .flags = FLAG_ADVANCED | FLAG_PRINT,
2517 .label = "printcap cache time",
2519 .p_class = P_GLOBAL,
2520 .ptr = &Globals.PrintcapCacheTime,
2523 .flags = FLAG_ADVANCED | FLAG_PRINT,
2526 .label = "printcap name",
2528 .p_class = P_GLOBAL,
2529 .ptr = &Globals.szPrintcapname,
2532 .flags = FLAG_ADVANCED | FLAG_PRINT,
2535 .label = "printcap",
2537 .p_class = P_GLOBAL,
2538 .ptr = &Globals.szPrintcapname,
2544 .label = "printable",
2547 .ptr = &sDefault.bPrint_ok,
2550 .flags = FLAG_ADVANCED | FLAG_PRINT,
2553 .label = "print ok",
2556 .ptr = &sDefault.bPrint_ok,
2562 .label = "printing",
2565 .ptr = &sDefault.iPrinting,
2566 .special = handle_printing,
2567 .enum_list = enum_printing,
2568 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2571 .label = "cups options",
2574 .ptr = &sDefault.szCupsOptions,
2577 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2580 .label = "cups server",
2582 .p_class = P_GLOBAL,
2583 .ptr = &Globals.szCupsServer,
2586 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2589 .label = "iprint server",
2591 .p_class = P_GLOBAL,
2592 .ptr = &Globals.szIPrintServer,
2595 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2598 .label = "print command",
2601 .ptr = &sDefault.szPrintcommand,
2604 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2607 .label = "disable spoolss",
2609 .p_class = P_GLOBAL,
2610 .ptr = &Globals.bDisableSpoolss,
2613 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2616 .label = "enable spoolss",
2618 .p_class = P_GLOBAL,
2619 .ptr = &Globals.bDisableSpoolss,
2625 .label = "lpq command",
2628 .ptr = &sDefault.szLpqcommand,
2631 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2634 .label = "lprm command",
2637 .ptr = &sDefault.szLprmcommand,
2640 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2643 .label = "lppause command",
2646 .ptr = &sDefault.szLppausecommand,
2649 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2652 .label = "lpresume command",
2655 .ptr = &sDefault.szLpresumecommand,
2658 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2661 .label = "queuepause command",
2664 .ptr = &sDefault.szQueuepausecommand,
2667 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2670 .label = "queueresume command",
2673 .ptr = &sDefault.szQueueresumecommand,
2676 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2679 .label = "addport command",
2681 .p_class = P_GLOBAL,
2682 .ptr = &Globals.szAddPortCommand,
2685 .flags = FLAG_ADVANCED,
2688 .label = "enumports command",
2690 .p_class = P_GLOBAL,
2691 .ptr = &Globals.szEnumPortsCommand,
2694 .flags = FLAG_ADVANCED,
2697 .label = "addprinter command",
2699 .p_class = P_GLOBAL,
2700 .ptr = &Globals.szAddPrinterCommand,
2703 .flags = FLAG_ADVANCED,
2706 .label = "deleteprinter command",
2708 .p_class = P_GLOBAL,
2709 .ptr = &Globals.szDeletePrinterCommand,
2712 .flags = FLAG_ADVANCED,
2715 .label = "show add printer wizard",
2717 .p_class = P_GLOBAL,
2718 .ptr = &Globals.bMsAddPrinterWizard,
2721 .flags = FLAG_ADVANCED,
2724 .label = "os2 driver map",
2726 .p_class = P_GLOBAL,
2727 .ptr = &Globals.szOs2DriverMap,
2730 .flags = FLAG_ADVANCED,
2734 .label = "printer name",
2737 .ptr = &sDefault.szPrintername,
2740 .flags = FLAG_ADVANCED | FLAG_PRINT,
2746 .ptr = &sDefault.szPrintername,
2752 .label = "use client driver",
2755 .ptr = &sDefault.bUseClientDriver,
2758 .flags = FLAG_ADVANCED | FLAG_PRINT,
2761 .label = "default devmode",
2764 .ptr = &sDefault.bDefaultDevmode,
2767 .flags = FLAG_ADVANCED | FLAG_PRINT,
2770 .label = "force printername",
2773 .ptr = &sDefault.bForcePrintername,
2776 .flags = FLAG_ADVANCED | FLAG_PRINT,
2779 .label = "printjob username",
2782 .ptr = &sDefault.szPrintjobUsername,
2785 .flags = FLAG_ADVANCED | FLAG_PRINT,
2788 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2791 .label = "mangling method",
2793 .p_class = P_GLOBAL,
2794 .ptr = &Globals.szManglingMethod,
2797 .flags = FLAG_ADVANCED,
2800 .label = "mangle prefix",
2802 .p_class = P_GLOBAL,
2803 .ptr = &Globals.mangle_prefix,
2806 .flags = FLAG_ADVANCED,
2810 .label = "default case",
2813 .ptr = &sDefault.iDefaultCase,
2815 .enum_list = enum_case,
2816 .flags = FLAG_ADVANCED | FLAG_SHARE,
2819 .label = "case sensitive",
2822 .ptr = &sDefault.iCaseSensitive,
2824 .enum_list = enum_bool_auto,
2825 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2828 .label = "casesignames",
2831 .ptr = &sDefault.iCaseSensitive,
2833 .enum_list = enum_bool_auto,
2834 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2837 .label = "preserve case",
2840 .ptr = &sDefault.bCasePreserve,
2843 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2846 .label = "short preserve case",
2849 .ptr = &sDefault.bShortCasePreserve,
2852 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2855 .label = "mangling char",
2858 .ptr = &sDefault.magic_char,
2861 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2864 .label = "hide dot files",
2867 .ptr = &sDefault.bHideDotFiles,
2870 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2873 .label = "hide special files",
2876 .ptr = &sDefault.bHideSpecialFiles,
2879 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2882 .label = "hide unreadable",
2885 .ptr = &sDefault.bHideUnReadable,
2888 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2891 .label = "hide unwriteable files",
2894 .ptr = &sDefault.bHideUnWriteableFiles,
2897 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2900 .label = "delete veto files",
2903 .ptr = &sDefault.bDeleteVetoFiles,
2906 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2909 .label = "veto files",
2912 .ptr = &sDefault.szVetoFiles,
2915 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2918 .label = "hide files",
2921 .ptr = &sDefault.szHideFiles,
2924 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2927 .label = "veto oplock files",
2930 .ptr = &sDefault.szVetoOplockFiles,
2933 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2936 .label = "map archive",
2939 .ptr = &sDefault.bMap_archive,
2942 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2945 .label = "map hidden",
2948 .ptr = &sDefault.bMap_hidden,
2951 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2954 .label = "map system",
2957 .ptr = &sDefault.bMap_system,
2960 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2963 .label = "map readonly",
2966 .ptr = &sDefault.iMap_readonly,
2968 .enum_list = enum_map_readonly,
2969 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2972 .label = "mangled names",
2975 .ptr = &sDefault.bMangledNames,
2978 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2981 .label = "max stat cache size",
2983 .p_class = P_GLOBAL,
2984 .ptr = &Globals.iMaxStatCacheSize,
2987 .flags = FLAG_ADVANCED,
2990 .label = "stat cache",
2992 .p_class = P_GLOBAL,
2993 .ptr = &Globals.bStatCache,
2996 .flags = FLAG_ADVANCED,
2999 .label = "store dos attributes",
3002 .ptr = &sDefault.bStoreDosAttributes,
3005 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3008 .label = "dmapi support",
3011 .ptr = &sDefault.bDmapiSupport,
3014 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3018 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3021 .label = "machine password timeout",
3023 .p_class = P_GLOBAL,
3024 .ptr = &Globals.machine_password_timeout,
3027 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3030 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3033 .label = "add user script",
3035 .p_class = P_GLOBAL,
3036 .ptr = &Globals.szAddUserScript,
3039 .flags = FLAG_ADVANCED,
3042 .label = "rename user script",
3044 .p_class = P_GLOBAL,
3045 .ptr = &Globals.szRenameUserScript,
3048 .flags = FLAG_ADVANCED,
3051 .label = "delete user script",
3053 .p_class = P_GLOBAL,
3054 .ptr = &Globals.szDelUserScript,
3057 .flags = FLAG_ADVANCED,
3060 .label = "add group script",
3062 .p_class = P_GLOBAL,
3063 .ptr = &Globals.szAddGroupScript,
3066 .flags = FLAG_ADVANCED,
3069 .label = "delete group script",
3071 .p_class = P_GLOBAL,
3072 .ptr = &Globals.szDelGroupScript,
3075 .flags = FLAG_ADVANCED,
3078 .label = "add user to group script",
3080 .p_class = P_GLOBAL,
3081 .ptr = &Globals.szAddUserToGroupScript,
3084 .flags = FLAG_ADVANCED,
3087 .label = "delete user from group script",
3089 .p_class = P_GLOBAL,
3090 .ptr = &Globals.szDelUserFromGroupScript,
3093 .flags = FLAG_ADVANCED,
3096 .label = "set primary group script",
3098 .p_class = P_GLOBAL,
3099 .ptr = &Globals.szSetPrimaryGroupScript,
3102 .flags = FLAG_ADVANCED,
3105 .label = "add machine script",
3107 .p_class = P_GLOBAL,
3108 .ptr = &Globals.szAddMachineScript,
3111 .flags = FLAG_ADVANCED,
3114 .label = "shutdown script",
3116 .p_class = P_GLOBAL,
3117 .ptr = &Globals.szShutdownScript,
3120 .flags = FLAG_ADVANCED,
3123 .label = "abort shutdown script",
3125 .p_class = P_GLOBAL,
3126 .ptr = &Globals.szAbortShutdownScript,
3129 .flags = FLAG_ADVANCED,
3132 .label = "username map script",
3134 .p_class = P_GLOBAL,
3135 .ptr = &Globals.szUsernameMapScript,
3138 .flags = FLAG_ADVANCED,
3141 .label = "logon script",
3143 .p_class = P_GLOBAL,
3144 .ptr = &Globals.szLogonScript,
3147 .flags = FLAG_ADVANCED,
3150 .label = "logon path",
3152 .p_class = P_GLOBAL,
3153 .ptr = &Globals.szLogonPath,
3156 .flags = FLAG_ADVANCED,
3159 .label = "logon drive",
3161 .p_class = P_GLOBAL,
3162 .ptr = &Globals.szLogonDrive,
3165 .flags = FLAG_ADVANCED,
3168 .label = "logon home",
3170 .p_class = P_GLOBAL,
3171 .ptr = &Globals.szLogonHome,
3174 .flags = FLAG_ADVANCED,
3177 .label = "domain logons",
3179 .p_class = P_GLOBAL,
3180 .ptr = &Globals.bDomainLogons,
3183 .flags = FLAG_ADVANCED,
3186 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3189 .label = "os level",
3191 .p_class = P_GLOBAL,
3192 .ptr = &Globals.os_level,
3195 .flags = FLAG_BASIC | FLAG_ADVANCED,
3198 .label = "lm announce",
3200 .p_class = P_GLOBAL,
3201 .ptr = &Globals.lm_announce,
3203 .enum_list = enum_bool_auto,
3204 .flags = FLAG_ADVANCED,
3207 .label = "lm interval",
3209 .p_class = P_GLOBAL,
3210 .ptr = &Globals.lm_interval,
3213 .flags = FLAG_ADVANCED,
3216 .label = "preferred master",
3218 .p_class = P_GLOBAL,
3219 .ptr = &Globals.iPreferredMaster,
3221 .enum_list = enum_bool_auto,
3222 .flags = FLAG_BASIC | FLAG_ADVANCED,
3225 .label = "prefered master",
3227 .p_class = P_GLOBAL,
3228 .ptr = &Globals.iPreferredMaster,
3230 .enum_list = enum_bool_auto,
3234 .label = "local master",
3236 .p_class = P_GLOBAL,
3237 .ptr = &Globals.bLocalMaster,
3240 .flags = FLAG_BASIC | FLAG_ADVANCED,
3243 .label = "domain master",
3245 .p_class = P_GLOBAL,
3246 .ptr = &Globals.iDomainMaster,
3248 .enum_list = enum_bool_auto,
3249 .flags = FLAG_BASIC | FLAG_ADVANCED,
3252 .label = "browse list",
3254 .p_class = P_GLOBAL,
3255 .ptr = &Globals.bBrowseList,
3258 .flags = FLAG_ADVANCED,
3261 .label = "browseable",
3264 .ptr = &sDefault.bBrowseable,
3267 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3270 .label = "browsable",
3273 .ptr = &sDefault.bBrowseable,
3279 .label = "enhanced browsing",
3281 .p_class = P_GLOBAL,
3282 .ptr = &Globals.enhanced_browsing,
3285 .flags = FLAG_ADVANCED,
3288 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3291 .label = "dns proxy",
3293 .p_class = P_GLOBAL,
3294 .ptr = &Globals.bDNSproxy,
3297 .flags = FLAG_ADVANCED,
3300 .label = "wins proxy",
3302 .p_class = P_GLOBAL,
3303 .ptr = &Globals.bWINSproxy,
3306 .flags = FLAG_ADVANCED,
3309 .label = "wins server",
3311 .p_class = P_GLOBAL,
3312 .ptr = &Globals.szWINSservers,
3315 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3318 .label = "wins support",
3320 .p_class = P_GLOBAL,
3321 .ptr = &Globals.bWINSsupport,
3324 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3327 .label = "wins hook",
3329 .p_class = P_GLOBAL,
3330 .ptr = &Globals.szWINSHook,
3333 .flags = FLAG_ADVANCED,
3336 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3339 .label = "blocking locks",
3342 .ptr = &sDefault.bBlockingLocks,
3345 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3348 .label = "csc policy",
3351 .ptr = &sDefault.iCSCPolicy,
3353 .enum_list = enum_csc_policy,
3354 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3357 .label = "fake oplocks",
3360 .ptr = &sDefault.bFakeOplocks,
3363 .flags = FLAG_ADVANCED | FLAG_SHARE,
3366 .label = "kernel oplocks",
3368 .p_class = P_GLOBAL,
3369 .ptr = &Globals.bKernelOplocks,
3372 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3378 .ptr = &sDefault.bLocking,
3381 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3384 .label = "lock spin time",
3386 .p_class = P_GLOBAL,
3387 .ptr = &Globals.iLockSpinTime,
3390 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3396 .ptr = &sDefault.bOpLocks,
3399 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3402 .label = "level2 oplocks",
3405 .ptr = &sDefault.bLevel2OpLocks,
3408 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3411 .label = "oplock break wait time",
3413 .p_class = P_GLOBAL,
3414 .ptr = &Globals.oplock_break_wait_time,
3417 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3420 .label = "oplock contention limit",
3423 .ptr = &sDefault.iOplockContentionLimit,
3426 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3429 .label = "posix locking",
3432 .ptr = &sDefault.bPosixLocking,
3435 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3438 .label = "strict locking",
3441 .ptr = &sDefault.iStrictLocking,
3443 .enum_list = enum_bool_auto,
3444 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3447 .label = "share modes",
3450 .ptr = &sDefault.bShareModes,
3453 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3456 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3459 .label = "ldap admin dn",
3461 .p_class = P_GLOBAL,
3462 .ptr = &Globals.szLdapAdminDn,
3465 .flags = FLAG_ADVANCED,
3468 .label = "ldap delete dn",
3470 .p_class = P_GLOBAL,
3471 .ptr = &Globals.ldap_delete_dn,
3474 .flags = FLAG_ADVANCED,
3477 .label = "ldap group suffix",
3479 .p_class = P_GLOBAL,
3480 .ptr = &Globals.szLdapGroupSuffix,
3483 .flags = FLAG_ADVANCED,
3486 .label = "ldap idmap suffix",
3488 .p_class = P_GLOBAL,
3489 .ptr = &Globals.szLdapIdmapSuffix,
3492 .flags = FLAG_ADVANCED,
3495 .label = "ldap machine suffix",
3497 .p_class = P_GLOBAL,
3498 .ptr = &Globals.szLdapMachineSuffix,
3501 .flags = FLAG_ADVANCED,
3504 .label = "ldap passwd sync",
3506 .p_class = P_GLOBAL,
3507 .ptr = &Globals.ldap_passwd_sync,
3509 .enum_list = enum_ldap_passwd_sync,
3510 .flags = FLAG_ADVANCED,
3513 .label = "ldap password sync",
3515 .p_class = P_GLOBAL,
3516 .ptr = &Globals.ldap_passwd_sync,
3518 .enum_list = enum_ldap_passwd_sync,
3522 .label = "ldap replication sleep",
3524 .p_class = P_GLOBAL,
3525 .ptr = &Globals.ldap_replication_sleep,
3528 .flags = FLAG_ADVANCED,
3531 .label = "ldap suffix",
3533 .p_class = P_GLOBAL,
3534 .ptr = &Globals.szLdapSuffix,
3537 .flags = FLAG_ADVANCED,
3540 .label = "ldap ssl",
3542 .p_class = P_GLOBAL,
3543 .ptr = &Globals.ldap_ssl,
3545 .enum_list = enum_ldap_ssl,
3546 .flags = FLAG_ADVANCED,
3549 .label = "ldap timeout",
3551 .p_class = P_GLOBAL,
3552 .ptr = &Globals.ldap_timeout,
3555 .flags = FLAG_ADVANCED,
3558 .label = "ldap page size",
3560 .p_class = P_GLOBAL,
3561 .ptr = &Globals.ldap_page_size,
3564 .flags = FLAG_ADVANCED,
3567 .label = "ldap user suffix",
3569 .p_class = P_GLOBAL,
3570 .ptr = &Globals.szLdapUserSuffix,
3573 .flags = FLAG_ADVANCED,
3576 .label = "ldap debug level",
3578 .p_class = P_GLOBAL,
3579 .ptr = &Globals.ldap_debug_level,
3580 .special = handle_ldap_debug_level,
3582 .flags = FLAG_ADVANCED,
3585 .label = "ldap debug threshold",
3587 .p_class = P_GLOBAL,
3588 .ptr = &Globals.ldap_debug_threshold,
3591 .flags = FLAG_ADVANCED,
3594 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3597 .label = "eventlog list",
3599 .p_class = P_GLOBAL,
3600 .ptr = &Globals.szEventLogs,
3603 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3606 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3609 .label = "add share command",
3611 .p_class = P_GLOBAL,
3612 .ptr = &Globals.szAddShareCommand,
3615 .flags = FLAG_ADVANCED,
3618 .label = "change share command",
3620 .p_class = P_GLOBAL,
3621 .ptr = &Globals.szChangeShareCommand,
3624 .flags = FLAG_ADVANCED,
3627 .label = "delete share command",
3629 .p_class = P_GLOBAL,
3630 .ptr = &Globals.szDeleteShareCommand,
3633 .flags = FLAG_ADVANCED,
3636 .label = "config file",
3638 .p_class = P_GLOBAL,
3639 .ptr = &Globals.szConfigFile,
3647 .p_class = P_GLOBAL,
3648 .ptr = &Globals.szAutoServices,
3651 .flags = FLAG_ADVANCED,
3654 .label = "auto services",
3656 .p_class = P_GLOBAL,
3657 .ptr = &Globals.szAutoServices,
3660 .flags = FLAG_ADVANCED,
3663 .label = "lock directory",
3665 .p_class = P_GLOBAL,
3666 .ptr = &Globals.szLockDir,
3669 .flags = FLAG_ADVANCED,
3672 .label = "lock dir",
3674 .p_class = P_GLOBAL,
3675 .ptr = &Globals.szLockDir,
3681 .label = "pid directory",
3683 .p_class = P_GLOBAL,
3684 .ptr = &Globals.szPidDir,
3687 .flags = FLAG_ADVANCED,
3691 .label = "utmp directory",
3693 .p_class = P_GLOBAL,
3694 .ptr = &Globals.szUtmpDir,
3697 .flags = FLAG_ADVANCED,
3700 .label = "wtmp directory",
3702 .p_class = P_GLOBAL,
3703 .ptr = &Globals.szWtmpDir,
3706 .flags = FLAG_ADVANCED,
3711 .p_class = P_GLOBAL,
3712 .ptr = &Globals.bUtmp,
3715 .flags = FLAG_ADVANCED,
3719 .label = "default service",
3721 .p_class = P_GLOBAL,
3722 .ptr = &Globals.szDefaultService,
3725 .flags = FLAG_ADVANCED,
3730 .p_class = P_GLOBAL,
3731 .ptr = &Globals.szDefaultService,
3734 .flags = FLAG_ADVANCED,
3737 .label = "message command",
3739 .p_class = P_GLOBAL,
3740 .ptr = &Globals.szMsgCommand,
3743 .flags = FLAG_ADVANCED,
3746 .label = "dfree cache time",
3749 .ptr = &sDefault.iDfreeCacheTime,
3752 .flags = FLAG_ADVANCED,
3755 .label = "dfree command",
3758 .ptr = &sDefault.szDfree,
3761 .flags = FLAG_ADVANCED,
3764 .label = "get quota command",
3766 .p_class = P_GLOBAL,
3767 .ptr = &Globals.szGetQuota,
3770 .flags = FLAG_ADVANCED,
3773 .label = "set quota command",
3775 .p_class = P_GLOBAL,
3776 .ptr = &Globals.szSetQuota,
3779 .flags = FLAG_ADVANCED,
3782 .label = "remote announce",
3784 .p_class = P_GLOBAL,
3785 .ptr = &Globals.szRemoteAnnounce,
3788 .flags = FLAG_ADVANCED,
3791 .label = "remote browse sync",
3793 .p_class = P_GLOBAL,
3794 .ptr = &Globals.szRemoteBrowseSync,
3797 .flags = FLAG_ADVANCED,
3800 .label = "socket address",
3802 .p_class = P_GLOBAL,
3803 .ptr = &Globals.szSocketAddress,
3806 .flags = FLAG_ADVANCED,
3809 .label = "homedir map",
3811 .p_class = P_GLOBAL,
3812 .ptr = &Globals.szNISHomeMapName,
3815 .flags = FLAG_ADVANCED,
3818 .label = "afs username map",
3820 .p_class = P_GLOBAL,
3821 .ptr = &Globals.szAfsUsernameMap,
3824 .flags = FLAG_ADVANCED,
3827 .label = "afs token lifetime",
3829 .p_class = P_GLOBAL,
3830 .ptr = &Globals.iAfsTokenLifetime,
3833 .flags = FLAG_ADVANCED,
3836 .label = "log nt token command",
3838 .p_class = P_GLOBAL,
3839 .ptr = &Globals.szLogNtTokenCommand,
3842 .flags = FLAG_ADVANCED,
3845 .label = "time offset",
3847 .p_class = P_GLOBAL,
3848 .ptr = &extra_time_offset,
3851 .flags = FLAG_ADVANCED,
3854 .label = "NIS homedir",
3856 .p_class = P_GLOBAL,
3857 .ptr = &Globals.bNISHomeMap,
3860 .flags = FLAG_ADVANCED,
3866 .ptr = &sDefault.valid,
3875 .ptr = &sDefault.szCopy,
3876 .special = handle_copy,
3884 .ptr = &sDefault.szInclude,
3885 .special = handle_include,
3893 .ptr = &sDefault.szPreExec,
3896 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3902 .ptr = &sDefault.szPreExec,
3905 .flags = FLAG_ADVANCED,
3908 .label = "preexec close",
3911 .ptr = &sDefault.bPreexecClose,
3914 .flags = FLAG_ADVANCED | FLAG_SHARE,
3917 .label = "postexec",
3920 .ptr = &sDefault.szPostExec,
3923 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3926 .label = "root preexec",
3929 .ptr = &sDefault.szRootPreExec,
3932 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3935 .label = "root preexec close",
3938 .ptr = &sDefault.bRootpreexecClose,
3941 .flags = FLAG_ADVANCED | FLAG_SHARE,
3944 .label = "root postexec",
3947 .ptr = &sDefault.szRootPostExec,
3950 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3953 .label = "available",
3956 .ptr = &sDefault.bAvailable,
3959 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3962 .label = "registry shares",
3964 .p_class = P_GLOBAL,
3965 .ptr = &Globals.bRegistryShares,
3968 .flags = FLAG_ADVANCED,
3971 .label = "usershare allow guests",
3973 .p_class = P_GLOBAL,
3974 .ptr = &Globals.bUsershareAllowGuests,
3977 .flags = FLAG_ADVANCED,
3980 .label = "usershare max shares",
3982 .p_class = P_GLOBAL,
3983 .ptr = &Globals.iUsershareMaxShares,
3986 .flags = FLAG_ADVANCED,
3989 .label = "usershare owner only",
3991 .p_class = P_GLOBAL,
3992 .ptr = &Globals.bUsershareOwnerOnly,
3995 .flags = FLAG_ADVANCED,
3998 .label = "usershare path",
4000 .p_class = P_GLOBAL,
4001 .ptr = &Globals.szUsersharePath,
4004 .flags = FLAG_ADVANCED,
4007 .label = "usershare prefix allow list",
4009 .p_class = P_GLOBAL,
4010 .ptr = &Globals.szUsersharePrefixAllowList,
4013 .flags = FLAG_ADVANCED,
4016 .label = "usershare prefix deny list",
4018 .p_class = P_GLOBAL,
4019 .ptr = &Globals.szUsersharePrefixDenyList,
4022 .flags = FLAG_ADVANCED,
4025 .label = "usershare template share",
4027 .p_class = P_GLOBAL,
4028 .ptr = &Globals.szUsershareTemplateShare,
4031 .flags = FLAG_ADVANCED,
4037 .ptr = &sDefault.volume,
4040 .flags = FLAG_ADVANCED | FLAG_SHARE,
4046 .ptr = &sDefault.fstype,
4049 .flags = FLAG_ADVANCED | FLAG_SHARE,
4052 .label = "set directory",
4055 .ptr = &sDefault.bNo_set_dir,
4058 .flags = FLAG_ADVANCED | FLAG_SHARE,
4061 .label = "wide links",
4064 .ptr = &sDefault.bWidelinks,
4067 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4070 .label = "follow symlinks",
4073 .ptr = &sDefault.bSymlinks,
4076 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4079 .label = "dont descend",
4082 .ptr = &sDefault.szDontdescend,
4085 .flags = FLAG_ADVANCED | FLAG_SHARE,
4088 .label = "magic script",
4091 .ptr = &sDefault.szMagicScript,
4094 .flags = FLAG_ADVANCED | FLAG_SHARE,
4097 .label = "magic output",
4100 .ptr = &sDefault.szMagicOutput,
4103 .flags = FLAG_ADVANCED | FLAG_SHARE,
4106 .label = "delete readonly",
4109 .ptr = &sDefault.bDeleteReadonly,
4112 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4115 .label = "dos filemode",
4118 .ptr = &sDefault.bDosFilemode,
4121 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4124 .label = "dos filetimes",
4127 .ptr = &sDefault.bDosFiletimes,
4130 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4133 .label = "dos filetime resolution",
4136 .ptr = &sDefault.bDosFiletimeResolution,
4139 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4142 .label = "fake directory create times",
4145 .ptr = &sDefault.bFakeDirCreateTimes,
4148 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4151 .label = "panic action",
4153 .p_class = P_GLOBAL,
4154 .ptr = &Globals.szPanicAction,
4157 .flags = FLAG_ADVANCED,
4160 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4163 .label = "vfs objects",
4166 .ptr = &sDefault.szVfsObjects,
4169 .flags = FLAG_ADVANCED | FLAG_SHARE,
4172 .label = "vfs object",
4175 .ptr = &sDefault.szVfsObjects,
4182 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4185 .label = "msdfs root",
4188 .ptr = &sDefault.bMSDfsRoot,
4191 .flags = FLAG_ADVANCED | FLAG_SHARE,
4194 .label = "msdfs proxy",
4197 .ptr = &sDefault.szMSDfsProxy,
4200 .flags = FLAG_ADVANCED | FLAG_SHARE,
4203 .label = "host msdfs",
4205 .p_class = P_GLOBAL,
4206 .ptr = &Globals.bHostMSDfs,
4209 .flags = FLAG_ADVANCED,
4212 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4215 .label = "passdb expand explicit",
4217 .p_class = P_GLOBAL,
4218 .ptr = &Globals.bPassdbExpandExplicit,
4221 .flags = FLAG_ADVANCED,
4224 .label = "idmap domains",
4226 .p_class = P_GLOBAL,
4227 .ptr = &Globals.szIdmapDomains,
4230 .flags = FLAG_ADVANCED,
4233 .label = "idmap backend",
4235 .p_class = P_GLOBAL,
4236 .ptr = &Globals.szIdmapBackend,
4239 .flags = FLAG_ADVANCED,
4242 .label = "idmap alloc backend",
4244 .p_class = P_GLOBAL,
4245 .ptr = &Globals.szIdmapAllocBackend,
4248 .flags = FLAG_ADVANCED,
4251 .label = "idmap cache time",
4253 .p_class = P_GLOBAL,
4254 .ptr = &Globals.iIdmapCacheTime,
4257 .flags = FLAG_ADVANCED,
4260 .label = "idmap negative cache time",
4262 .p_class = P_GLOBAL,
4263 .ptr = &Globals.iIdmapNegativeCacheTime,
4266 .flags = FLAG_ADVANCED,
4269 .label = "idmap uid",
4271 .p_class = P_GLOBAL,
4272 .ptr = &Globals.szIdmapUID,
4273 .special = handle_idmap_uid,
4275 .flags = FLAG_ADVANCED,
4278 .label = "winbind uid",
4280 .p_class = P_GLOBAL,
4281 .ptr = &Globals.szIdmapUID,
4282 .special = handle_idmap_uid,
4287 .label = "idmap gid",
4289 .p_class = P_GLOBAL,
4290 .ptr = &Globals.szIdmapGID,
4291 .special = handle_idmap_gid,
4293 .flags = FLAG_ADVANCED,
4296 .label = "winbind gid",
4298 .p_class = P_GLOBAL,
4299 .ptr = &Globals.szIdmapGID,
4300 .special = handle_idmap_gid,
4305 .label = "template homedir",
4307 .p_class = P_GLOBAL,
4308 .ptr = &Globals.szTemplateHomedir,
4311 .flags = FLAG_ADVANCED,
4314 .label = "template shell",
4316 .p_class = P_GLOBAL,
4317 .ptr = &Globals.szTemplateShell,
4320 .flags = FLAG_ADVANCED,
4323 .label = "winbind separator",
4325 .p_class = P_GLOBAL,
4326 .ptr = &Globals.szWinbindSeparator,
4329 .flags = FLAG_ADVANCED,
4332 .label = "winbind cache time",
4334 .p_class = P_GLOBAL,
4335 .ptr = &Globals.winbind_cache_time,
4338 .flags = FLAG_ADVANCED,
4341 .label = "winbind enum users",
4343 .p_class = P_GLOBAL,
4344 .ptr = &Globals.bWinbindEnumUsers,
4347 .flags = FLAG_ADVANCED,
4350 .label = "winbind enum groups",
4352 .p_class = P_GLOBAL,
4353 .ptr = &Globals.bWinbindEnumGroups,
4356 .flags = FLAG_ADVANCED,
4359 .label = "winbind use default domain",
4361 .p_class = P_GLOBAL,
4362 .ptr = &Globals.bWinbindUseDefaultDomain,
4365 .flags = FLAG_ADVANCED,
4368 .label = "winbind trusted domains only",
4370 .p_class = P_GLOBAL,
4371 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4374 .flags = FLAG_ADVANCED,
4377 .label = "winbind nested groups",
4379 .p_class = P_GLOBAL,
4380 .ptr = &Globals.bWinbindNestedGroups,
4383 .flags = FLAG_ADVANCED,
4386 .label = "winbind expand groups",
4388 .p_class = P_GLOBAL,
4389 .ptr = &Globals.winbind_expand_groups,
4392 .flags = FLAG_ADVANCED,
4395 .label = "winbind nss info",
4397 .p_class = P_GLOBAL,
4398 .ptr = &Globals.szWinbindNssInfo,
4401 .flags = FLAG_ADVANCED,
4404 .label = "winbind refresh tickets",
4406 .p_class = P_GLOBAL,
4407 .ptr = &Globals.bWinbindRefreshTickets,
4410 .flags = FLAG_ADVANCED,
4413 .label = "winbind offline logon",
4415 .p_class = P_GLOBAL,
4416 .ptr = &Globals.bWinbindOfflineLogon,
4419 .flags = FLAG_ADVANCED,
4422 .label = "winbind normalize names",
4424 .p_class = P_GLOBAL,
4425 .ptr = &Globals.bWinbindNormalizeNames,
4428 .flags = FLAG_ADVANCED,
4431 .label = "winbind rpc only",
4433 .p_class = P_GLOBAL,
4434 .ptr = &Globals.bWinbindRpcOnly,
4437 .flags = FLAG_ADVANCED,
4440 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4443 /***************************************************************************
4444 Initialise the sDefault parameter structure for the printer values.
4445 ***************************************************************************/
4447 static void init_printer_values(struct service *pService)
4449 /* choose defaults depending on the type of printing */
4450 switch (pService->iPrinting) {
4455 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4456 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4457 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4462 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4463 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4464 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4465 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4466 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4467 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4468 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4474 /* set the lpq command to contain the destination printer
4475 name only. This is used by cups_queue_get() */
4476 string_set(&pService->szLpqcommand, "%p");
4477 string_set(&pService->szLprmcommand, "");
4478 string_set(&pService->szPrintcommand, "");
4479 string_set(&pService->szLppausecommand, "");
4480 string_set(&pService->szLpresumecommand, "");
4481 string_set(&pService->szQueuepausecommand, "");
4482 string_set(&pService->szQueueresumecommand, "");
4484 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4485 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4486 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4487 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4488 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4489 string_set(&pService->szQueuepausecommand, "disable '%p'");
4490 string_set(&pService->szQueueresumecommand, "enable '%p'");
4491 #endif /* HAVE_CUPS */
4496 string_set(&pService->szLpqcommand, "lpstat -o%p");
4497 string_set(&pService->szLprmcommand, "cancel %p-%j");
4498 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4499 string_set(&pService->szQueuepausecommand, "disable %p");
4500 string_set(&pService->szQueueresumecommand, "enable %p");
4502 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4503 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4508 string_set(&pService->szLpqcommand, "lpq -P%p");
4509 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4510 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4516 string_set(&pService->szPrintcommand, "vlp print %p %s");
4517 string_set(&pService->szLpqcommand, "vlp lpq %p");
4518 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4519 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4520 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4521 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4522 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4524 #endif /* DEVELOPER */
4529 /***************************************************************************
4530 Initialise the global parameter structure.
4531 ***************************************************************************/
4533 static void init_globals(bool first_time_only)
4535 static bool done_init = False;
4539 /* If requested to initialize only once and we've already done it... */
4540 if (first_time_only && done_init) {
4541 /* ... then we have nothing more to do */
4546 /* The logfile can be set before this is invoked. Free it if so. */
4547 if (Globals.szLogFile != NULL) {
4548 string_free(&Globals.szLogFile);
4549 Globals.szLogFile = NULL;
4553 for (i = 0; parm_table[i].label; i++) {
4554 if ((parm_table[i].type == P_STRING ||
4555 parm_table[i].type == P_USTRING) &&
4558 string_free((char **)parm_table[i].ptr);
4563 memset((void *)&Globals, '\0', sizeof(Globals));
4565 for (i = 0; parm_table[i].label; i++) {
4566 if ((parm_table[i].type == P_STRING ||
4567 parm_table[i].type == P_USTRING) &&
4570 string_set((char **)parm_table[i].ptr, "");
4574 string_set(&sDefault.fstype, FSTYPE_STRING);
4575 string_set(&sDefault.szPrintjobUsername, "%U");
4577 init_printer_values(&sDefault);
4580 DEBUG(3, ("Initialising global parameters\n"));
4582 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4583 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4585 /* use the new 'hash2' method by default, with a prefix of 1 */
4586 string_set(&Globals.szManglingMethod, "hash2");
4587 Globals.mangle_prefix = 1;
4589 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4591 /* using UTF8 by default allows us to support all chars */
4592 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4594 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4595 /* If the system supports nl_langinfo(), try to grab the value
4596 from the user's locale */
4597 string_set(&Globals.display_charset, "LOCALE");
4599 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4602 /* Use codepage 850 as a default for the dos character set */
4603 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4606 * Allow the default PASSWD_CHAT to be overridden in local.h.
4608 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4610 set_global_myname(myhostname());
4611 string_set(&Globals.szNetbiosName,global_myname());
4613 set_global_myworkgroup(WORKGROUP);
4614 string_set(&Globals.szWorkgroup, lp_workgroup());
4616 string_set(&Globals.szPasswdProgram, "");
4617 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4618 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4619 string_set(&Globals.szSocketAddress, "0.0.0.0");
4621 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4622 smb_panic("init_globals: ENOMEM");
4624 string_set(&Globals.szServerString, s);
4626 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4627 DEFAULT_MINOR_VERSION) < 0) {
4628 smb_panic("init_globals: ENOMEM");
4630 string_set(&Globals.szAnnounceVersion, s);
4633 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4636 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4638 string_set(&Globals.szLogonDrive, "");
4639 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4640 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4641 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4643 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4644 string_set(&Globals.szPasswordServer, "*");
4646 Globals.AlgorithmicRidBase = BASE_RID;
4648 Globals.bLoadPrinters = True;
4649 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4651 Globals.ConfigBackend = config_backend;
4653 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4654 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4655 Globals.max_xmit = 0x4104;
4656 Globals.max_mux = 50; /* This is *needed* for profile support. */
4657 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4658 Globals.bDisableSpoolss = False;
4659 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4660 Globals.pwordlevel = 0;
4661 Globals.unamelevel = 0;
4662 Globals.deadtime = 0;
4663 Globals.getwd_cache = true;
4664 Globals.bLargeReadwrite = True;
4665 Globals.max_log_size = 5000;
4666 Globals.max_open_files = MAX_OPEN_FILES;
4667 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4668 Globals.maxprotocol = PROTOCOL_NT1;
4669 Globals.minprotocol = PROTOCOL_CORE;
4670 Globals.security = SEC_USER;
4671 Globals.paranoid_server_security = True;
4672 Globals.bEncryptPasswords = True;
4673 Globals.bUpdateEncrypt = False;
4674 Globals.clientSchannel = Auto;
4675 Globals.serverSchannel = Auto;
4676 Globals.bReadRaw = True;
4677 Globals.bWriteRaw = True;
4678 Globals.bNullPasswords = False;
4679 Globals.bObeyPamRestrictions = False;
4681 Globals.bSyslogOnly = False;
4682 Globals.bTimestampLogs = True;
4683 string_set(&Globals.szLogLevel, "0");
4684 Globals.bDebugPrefixTimestamp = False;
4685 Globals.bDebugHiresTimestamp = False;
4686 Globals.bDebugPid = False;
4687 Globals.bDebugUid = False;
4688 Globals.bDebugClass = False;
4689 Globals.bEnableCoreFiles = True;
4690 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4691 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4692 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4693 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4694 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4695 Globals.lm_interval = 60;
4696 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4697 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4698 Globals.bNISHomeMap = False;
4699 #ifdef WITH_NISPLUS_HOME
4700 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4702 string_set(&Globals.szNISHomeMapName, "auto.home");
4705 Globals.bTimeServer = False;
4706 Globals.bBindInterfacesOnly = False;
4707 Globals.bUnixPasswdSync = False;
4708 Globals.bPamPasswordChange = False;
4709 Globals.bPasswdChatDebug = False;
4710 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4711 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4712 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4713 Globals.bStatCache = True; /* use stat cache by default */
4714 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4715 Globals.restrict_anonymous = 0;
4716 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4717 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4718 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4719 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4720 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4721 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4723 Globals.map_to_guest = 0; /* By Default, "Never" */
4724 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4725 Globals.enhanced_browsing = true;
4726 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4727 #ifdef MMAP_BLACKLIST
4728 Globals.bUseMmap = False;
4730 Globals.bUseMmap = True;
4732 Globals.bUnixExtensions = True;
4733 Globals.bResetOnZeroVC = False;
4735 /* hostname lookups can be very expensive and are broken on
4736 a large number of sites (tridge) */
4737 Globals.bHostnameLookups = False;
4739 string_set(&Globals.szPassdbBackend, "smbpasswd");
4740 string_set(&Globals.szLdapSuffix, "");
4741 string_set(&Globals.szLdapMachineSuffix, "");
4742 string_set(&Globals.szLdapUserSuffix, "");
4743 string_set(&Globals.szLdapGroupSuffix, "");
4744 string_set(&Globals.szLdapIdmapSuffix, "");
4746 string_set(&Globals.szLdapAdminDn, "");
4747 Globals.ldap_ssl = LDAP_SSL_ON;
4748 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4749 Globals.ldap_delete_dn = False;
4750 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4751 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
4752 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4754 Globals.ldap_debug_level = 0;
4755 Globals.ldap_debug_threshold = 10;
4757 /* This is what we tell the afs client. in reality we set the token
4758 * to never expire, though, when this runs out the afs client will
4759 * forget the token. Set to 0 to get NEVERDATE.*/
4760 Globals.iAfsTokenLifetime = 604800;
4762 /* these parameters are set to defaults that are more appropriate
4763 for the increasing samba install base:
4765 as a member of the workgroup, that will possibly become a
4766 _local_ master browser (lm = True). this is opposed to a forced
4767 local master browser startup (pm = True).
4769 doesn't provide WINS server service by default (wsupp = False),
4770 and doesn't provide domain master browser services by default, either.
4774 Globals.bMsAddPrinterWizard = True;
4775 Globals.os_level = 20;
4776 Globals.bLocalMaster = True;
4777 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4778 Globals.bDomainLogons = False;
4779 Globals.bBrowseList = True;
4780 Globals.bWINSsupport = False;
4781 Globals.bWINSproxy = False;
4783 Globals.bDNSproxy = True;
4785 /* this just means to use them if they exist */
4786 Globals.bKernelOplocks = True;
4788 Globals.bAllowTrustedDomains = True;
4790 string_set(&Globals.szTemplateShell, "/bin/false");
4791 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4792 string_set(&Globals.szWinbindSeparator, "\\");
4794 string_set(&Globals.szCupsServer, "");
4795 string_set(&Globals.szIPrintServer, "");
4797 string_set(&Globals.ctdbdSocket, "");
4798 Globals.szClusterAddresses = NULL;
4799 Globals.clustering = False;
4801 Globals.winbind_cache_time = 300; /* 5 minutes */
4802 Globals.bWinbindEnumUsers = False;
4803 Globals.bWinbindEnumGroups = False;
4804 Globals.bWinbindUseDefaultDomain = False;
4805 Globals.bWinbindTrustedDomainsOnly = False;
4806 Globals.bWinbindNestedGroups = True;
4807 Globals.winbind_expand_groups = 1;
4808 Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4809 Globals.bWinbindRefreshTickets = False;
4810 Globals.bWinbindOfflineLogon = False;
4812 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
4813 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4815 Globals.bPassdbExpandExplicit = False;
4817 Globals.name_cache_timeout = 660; /* In seconds */
4819 Globals.bUseSpnego = True;
4820 Globals.bClientUseSpnego = True;
4822 Globals.client_signing = Auto;
4823 Globals.server_signing = False;
4825 Globals.bDeferSharingViolations = True;
4826 string_set(&Globals.smb_ports, SMB_PORTS);
4828 Globals.bEnablePrivileges = True;
4829 Globals.bHostMSDfs = True;
4830 Globals.bASUSupport = False;
4832 /* User defined shares. */
4833 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4834 smb_panic("init_globals: ENOMEM");
4836 string_set(&Globals.szUsersharePath, s);
4838 string_set(&Globals.szUsershareTemplateShare, "");
4839 Globals.iUsershareMaxShares = 0;
4840 /* By default disallow sharing of directories not owned by the sharer. */
4841 Globals.bUsershareOwnerOnly = True;
4842 /* By default disallow guest access to usershares. */
4843 Globals.bUsershareAllowGuests = False;
4845 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4847 /* By default no shares out of the registry */
4848 Globals.bRegistryShares = False;
4850 Globals.iminreceivefile = 0;
4853 /*******************************************************************
4854 Convenience routine to grab string parameters into temporary memory
4855 and run standard_sub_basic on them. The buffers can be written to by
4856 callers without affecting the source string.
4857 ********************************************************************/
4859 static char *lp_string(const char *s)
4862 TALLOC_CTX *ctx = talloc_tos();
4864 /* The follow debug is useful for tracking down memory problems
4865 especially if you have an inner loop that is calling a lp_*()
4866 function that returns a string. Perhaps this debug should be
4867 present all the time? */
4870 DEBUG(10, ("lp_string(%s)\n", s));
4873 ret = talloc_sub_basic(ctx,
4874 get_current_username(),
4875 current_user_info.domain,
4877 if (trim_char(ret, '\"', '\"')) {
4878 if (strchr(ret,'\"') != NULL) {
4880 ret = talloc_sub_basic(ctx,
4881 get_current_username(),
4882 current_user_info.domain,
4890 In this section all the functions that are used to access the
4891 parameters from the rest of the program are defined
4894 #define FN_GLOBAL_STRING(fn_name,ptr) \
4895 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4896 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4897 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4898 #define FN_GLOBAL_LIST(fn_name,ptr) \
4899 const char **fn_name(void) {return(*(const char ***)(ptr));}
4900 #define FN_GLOBAL_BOOL(fn_name,ptr) \
4901 bool fn_name(void) {return(*(bool *)(ptr));}
4902 #define FN_GLOBAL_CHAR(fn_name,ptr) \
4903 char fn_name(void) {return(*(char *)(ptr));}
4904 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
4905 int fn_name(void) {return(*(int *)(ptr));}
4907 #define FN_LOCAL_STRING(fn_name,val) \
4908 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4909 #define FN_LOCAL_CONST_STRING(fn_name,val) \
4910 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4911 #define FN_LOCAL_LIST(fn_name,val) \
4912 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4913 #define FN_LOCAL_BOOL(fn_name,val) \
4914 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4915 #define FN_LOCAL_INTEGER(fn_name,val) \
4916 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4918 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
4919 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4920 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4921 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4922 #define FN_LOCAL_PARM_STRING(fn_name,val) \
4923 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));}
4924 #define FN_LOCAL_CHAR(fn_name,val) \
4925 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4927 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4928 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4929 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4930 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4931 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4932 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4933 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4934 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4935 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4936 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4937 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4938 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4939 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4940 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4941 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4942 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4943 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4944 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4945 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4946 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4947 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4948 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4949 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4950 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4951 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4952 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4953 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
4954 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
4955 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
4956 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
4957 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
4958 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
4959 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
4960 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
4961 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
4962 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
4963 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
4964 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
4965 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
4966 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
4967 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
4968 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
4969 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
4970 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
4971 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
4972 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
4973 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
4974 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
4975 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
4976 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
4977 * lp_passdb_backend() should be replace by the this macro again after
4980 const char *lp_passdb_backend(void)
4982 char *delim, *quote;
4984 delim = strchr( Globals.szPassdbBackend, ' ');
4985 /* no space at all */
4986 if (delim == NULL) {
4990 quote = strchr(Globals.szPassdbBackend, '"');
4991 /* no quote char or non in the first part */
4992 if (quote == NULL || quote > delim) {
4997 quote = strchr(quote+1, '"');
4998 if (quote == NULL) {
4999 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5001 } else if (*(quote+1) == '\0') {
5002 /* space, fitting quote char, and one backend only */
5005 /* terminate string after the fitting quote char */
5010 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5011 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5012 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5013 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5016 return Globals.szPassdbBackend;
5018 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5019 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5020 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5021 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5022 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5024 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5025 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5026 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5027 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5028 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5029 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5031 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5033 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5034 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5035 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5037 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5039 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5040 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5041 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5042 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5043 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5044 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5045 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5046 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5047 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5048 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5049 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5050 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5051 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5052 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5053 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5055 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
5056 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
5057 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5058 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5059 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5060 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5061 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5063 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5064 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5065 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5066 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5067 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5068 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5069 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5070 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5071 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5072 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5073 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5074 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5075 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5076 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5077 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5078 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5080 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5082 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5083 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5084 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5085 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5086 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5087 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5088 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5089 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5090 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5091 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5092 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5093 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5094 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5095 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5096 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5097 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5098 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5099 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5100 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5101 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5102 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5103 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5104 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5105 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5106 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5107 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5108 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5109 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5110 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5111 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5112 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5113 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5114 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5115 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5116 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5117 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5118 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5119 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5120 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5121 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5122 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5123 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5124 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5125 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5126 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5127 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5128 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5129 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5130 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5131 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5132 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5133 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5134 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5135 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5136 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5137 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5138 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5139 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5140 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5141 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5142 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5143 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5144 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5145 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5146 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5147 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5148 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5149 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5150 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5151 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5152 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5153 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5154 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5155 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5156 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5157 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5158 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5159 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5160 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5161 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5162 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5163 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5164 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5165 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5166 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5167 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5168 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5169 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5170 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5171 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5172 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5173 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5174 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5175 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5176 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5177 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend);
5179 FN_LOCAL_STRING(lp_preexec, szPreExec)
5180 FN_LOCAL_STRING(lp_postexec, szPostExec)
5181 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5182 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5183 FN_LOCAL_STRING(lp_servicename, szService)
5184 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5185 FN_LOCAL_STRING(lp_pathname, szPath)
5186 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5187 FN_LOCAL_STRING(lp_username, szUsername)
5188 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5189 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5190 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5191 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5192 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5193 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5194 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5195 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5196 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5197 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering);
5198 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5199 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5200 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5201 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5202 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5203 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5204 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5205 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5206 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5207 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5208 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5209 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5210 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5211 FN_LOCAL_STRING(lp_comment, comment)
5212 FN_LOCAL_STRING(lp_force_user, force_user)
5213 FN_LOCAL_STRING(lp_force_group, force_group)
5214 FN_LOCAL_LIST(lp_readlist, readlist)
5215 FN_LOCAL_LIST(lp_writelist, writelist)
5216 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5217 FN_LOCAL_STRING(lp_fstype, fstype)
5218 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5219 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5220 static FN_LOCAL_STRING(lp_volume, volume)
5221 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5222 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5223 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5224 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5225 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5226 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5227 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5228 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5229 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5230 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5231 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5232 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5233 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5234 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5235 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5236 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5237 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5238 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5239 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5240 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5241 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5242 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5243 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5244 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5245 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5246 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5247 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5248 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5249 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5250 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5251 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5252 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5253 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5254 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5255 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5256 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5257 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5258 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5259 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5260 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5261 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5262 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5263 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5264 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5265 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5266 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5267 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5268 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5269 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5270 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5271 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5272 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5273 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5274 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5275 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5276 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5277 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5278 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5279 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5280 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5281 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5282 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5283 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5284 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5285 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5286 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5287 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5288 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5289 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5290 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5291 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5292 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5293 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5294 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5295 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5296 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5297 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5298 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5299 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5300 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5301 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5302 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5303 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5304 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5305 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5306 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5307 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5308 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5309 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5310 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5311 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5312 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5313 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5314 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5315 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5316 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5317 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5319 /* local prototypes */
5321 static int map_parameter(const char *pszParmName);
5322 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5323 static bool set_boolean(bool *pb, const char *pszParmValue);
5324 static const char *get_boolean(bool bool_value);
5325 static int getservicebyname(const char *pszServiceName,
5326 struct service *pserviceDest);
5327 static void copy_service(struct service *pserviceDest,
5328 struct service *pserviceSource,
5329 struct bitmap *pcopymapDest);
5330 static bool do_parameter(const char *pszParmName, const char *pszParmValue);
5331 static bool do_section(const char *pszSectionName);
5332 static void init_copymap(struct service *pservice);
5333 static bool hash_a_service(const char *name, int number);
5334 static void free_service_byindex(int iService);
5335 static char * canonicalize_servicename(const char *name);
5336 static void show_parameter(int parmIndex);
5337 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5339 /* This is a helper function for parametrical options support. */
5340 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
5341 /* Actual parametrical functions are quite simple */
5342 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
5344 bool global_section = False;
5346 param_opt_struct *data;
5348 if (snum >= iNumServices) return NULL;
5351 data = Globals.param_opt;
5352 global_section = True;
5354 data = ServicePtrs[snum]->param_opt;
5357 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5358 DEBUG(0,("asprintf failed!\n"));
5363 if (strcmp(data->key, param_key) == 0) {
5364 string_free(¶m_key);
5370 if (!global_section) {
5371 /* Try to fetch the same option but from globals */
5372 /* but only if we are not already working with Globals */
5373 data = Globals.param_opt;
5375 if (strcmp(data->key, param_key) == 0) {
5376 string_free(¶m_key);
5383 string_free(¶m_key);
5389 #define MISSING_PARAMETER(name) \
5390 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5392 /*******************************************************************
5393 convenience routine to return int parameters.
5394 ********************************************************************/
5395 static int lp_int(const char *s)
5399 MISSING_PARAMETER(lp_int);
5403 return (int)strtol(s, NULL, 0);
5406 /*******************************************************************
5407 convenience routine to return unsigned long parameters.
5408 ********************************************************************/
5409 static unsigned long lp_ulong(const char *s)
5413 MISSING_PARAMETER(lp_ulong);
5417 return strtoul(s, NULL, 0);
5420 /*******************************************************************
5421 convenience routine to return boolean parameters.
5422 ********************************************************************/
5423 static bool lp_bool(const char *s)
5428 MISSING_PARAMETER(lp_bool);
5432 if (!set_boolean(&ret,s)) {
5433 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5440 /*******************************************************************
5441 convenience routine to return enum parameters.
5442 ********************************************************************/
5443 static int lp_enum(const char *s,const struct enum_list *_enum)
5447 if (!s || !*s || !_enum) {
5448 MISSING_PARAMETER(lp_enum);
5452 for (i=0; _enum[i].name; i++) {
5453 if (strequal(_enum[i].name,s))
5454 return _enum[i].value;
5457 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5461 #undef MISSING_PARAMETER
5463 /* DO NOT USE lp_parm_string ANYMORE!!!!
5464 * use lp_parm_const_string or lp_parm_talloc_string
5466 * lp_parm_string is only used to let old modules find this symbol
5468 #undef lp_parm_string
5469 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5470 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5472 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5475 /* Return parametric option from a given service. Type is a part of option before ':' */
5476 /* Parametric option has following syntax: 'Type: option = value' */
5477 /* the returned value is talloced on the talloc_tos() */
5478 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5480 param_opt_struct *data = get_parametrics(snum, type, option);
5482 if (data == NULL||data->value==NULL) {
5484 return lp_string(def);
5490 return lp_string(data->value);
5493 /* Return parametric option from a given service. Type is a part of option before ':' */
5494 /* Parametric option has following syntax: 'Type: option = value' */
5495 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5497 param_opt_struct *data = get_parametrics(snum, type, option);
5499 if (data == NULL||data->value==NULL)
5505 /* Return parametric option from a given service. Type is a part of option before ':' */
5506 /* Parametric option has following syntax: 'Type: option = value' */
5508 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5510 param_opt_struct *data = get_parametrics(snum, type, option);
5512 if (data == NULL||data->value==NULL)
5513 return (const char **)def;
5515 if (data->list==NULL) {
5516 data->list = str_list_make(NULL, data->value, NULL);
5519 return (const char **)data->list;
5522 /* Return parametric option from a given service. Type is a part of option before ':' */
5523 /* Parametric option has following syntax: 'Type: option = value' */
5525 int lp_parm_int(int snum, const char *type, const char *option, int def)
5527 param_opt_struct *data = get_parametrics(snum, type, option);
5529 if (data && data->value && *data->value)
5530 return lp_int(data->value);
5535 /* Return parametric option from a given service. Type is a part of option before ':' */
5536 /* Parametric option has following syntax: 'Type: option = value' */
5538 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5540 param_opt_struct *data = get_parametrics(snum, type, option);
5542 if (data && data->value && *data->value)
5543 return lp_ulong(data->value);
5548 /* Return parametric option from a given service. Type is a part of option before ':' */
5549 /* Parametric option has following syntax: 'Type: option = value' */
5551 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5553 param_opt_struct *data = get_parametrics(snum, type, option);
5555 if (data && data->value && *data->value)
5556 return lp_bool(data->value);
5561 /* Return parametric option from a given service. Type is a part of option before ':' */
5562 /* Parametric option has following syntax: 'Type: option = value' */
5564 int lp_parm_enum(int snum, const char *type, const char *option,
5565 const struct enum_list *_enum, int def)
5567 param_opt_struct *data = get_parametrics(snum, type, option);
5569 if (data && data->value && *data->value && _enum)
5570 return lp_enum(data->value, _enum);
5576 /***************************************************************************
5577 Initialise a service to the defaults.
5578 ***************************************************************************/
5580 static void init_service(struct service *pservice)
5582 memset((char *)pservice, '\0', sizeof(struct service));
5583 copy_service(pservice, &sDefault, NULL);
5586 /***************************************************************************
5587 Free the dynamically allocated parts of a service struct.
5588 ***************************************************************************/
5590 static void free_service(struct service *pservice)
5593 param_opt_struct *data, *pdata;
5597 if (pservice->szService)
5598 DEBUG(5, ("free_service: Freeing service %s\n",
5599 pservice->szService));
5601 string_free(&pservice->szService);
5602 bitmap_free(pservice->copymap);
5604 for (i = 0; parm_table[i].label; i++) {
5605 if ((parm_table[i].type == P_STRING ||
5606 parm_table[i].type == P_USTRING) &&
5607 parm_table[i].p_class == P_LOCAL)
5608 string_free((char **)
5609 (((char *)pservice) +
5610 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5611 else if (parm_table[i].type == P_LIST &&
5612 parm_table[i].p_class == P_LOCAL)
5613 TALLOC_FREE(*((char ***)
5614 (((char *)pservice) +
5615 PTR_DIFF(parm_table[i].ptr,
5619 data = pservice->param_opt;
5621 DEBUG(5,("Freeing parametrics:\n"));
5623 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5624 string_free(&data->key);
5625 string_free(&data->value);
5626 TALLOC_FREE(data->list);
5632 ZERO_STRUCTP(pservice);
5636 /***************************************************************************
5637 remove a service indexed in the ServicePtrs array from the ServiceHash
5638 and free the dynamically allocated parts
5639 ***************************************************************************/
5641 static void free_service_byindex(int idx)
5643 if ( !LP_SNUM_OK(idx) )
5646 ServicePtrs[idx]->valid = False;
5647 invalid_services[num_invalid_services++] = idx;
5649 /* we have to cleanup the hash record */
5651 if (ServicePtrs[idx]->szService) {
5652 char *canon_name = canonicalize_servicename(
5653 ServicePtrs[idx]->szService );
5655 dbwrap_delete_bystring(ServiceHash, canon_name );
5656 TALLOC_FREE(canon_name);
5659 free_service(ServicePtrs[idx]);
5662 /***************************************************************************
5663 Add a new service to the services array initialising it with the given
5665 ***************************************************************************/
5667 static int add_a_service(const struct service *pservice, const char *name)
5670 struct service tservice;
5671 int num_to_alloc = iNumServices + 1;
5672 param_opt_struct *data, *pdata;
5674 tservice = *pservice;
5676 /* it might already exist */
5678 i = getservicebyname(name, NULL);
5680 /* Clean all parametric options for service */
5681 /* They will be added during parsing again */
5682 data = ServicePtrs[i]->param_opt;
5684 string_free(&data->key);
5685 string_free(&data->value);
5686 TALLOC_FREE(data->list);
5691 ServicePtrs[i]->param_opt = NULL;
5696 /* find an invalid one */
5698 if (num_invalid_services > 0) {
5699 i = invalid_services[--num_invalid_services];
5702 /* if not, then create one */
5703 if (i == iNumServices) {
5704 struct service **tsp;
5707 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5709 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5713 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5714 if (!ServicePtrs[iNumServices]) {
5715 DEBUG(0,("add_a_service: out of memory!\n"));
5720 /* enlarge invalid_services here for now... */
5721 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5723 if (tinvalid == NULL) {
5724 DEBUG(0,("add_a_service: failed to enlarge "
5725 "invalid_services!\n"));
5728 invalid_services = tinvalid;
5730 free_service_byindex(i);
5733 ServicePtrs[i]->valid = True;
5735 init_service(ServicePtrs[i]);
5736 copy_service(ServicePtrs[i], &tservice, NULL);
5738 string_set(&ServicePtrs[i]->szService, name);
5740 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5741 i, ServicePtrs[i]->szService));
5743 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5750 /***************************************************************************
5751 Convert a string to uppercase and remove whitespaces.
5752 ***************************************************************************/
5754 static char *canonicalize_servicename(const char *src)
5759 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5763 result = talloc_strdup(talloc_tos(), src);
5764 SMB_ASSERT(result != NULL);
5770 /***************************************************************************
5771 Add a name/index pair for the services array to the hash table.
5772 ***************************************************************************/
5774 static bool hash_a_service(const char *name, int idx)
5778 if ( !ServiceHash ) {
5779 DEBUG(10,("hash_a_service: creating servicehash\n"));
5780 ServiceHash = db_open_rbt(NULL);
5781 if ( !ServiceHash ) {
5782 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5787 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5790 canon_name = canonicalize_servicename( name );
5792 dbwrap_store_bystring(ServiceHash, canon_name,
5793 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5796 TALLOC_FREE(canon_name);
5801 /***************************************************************************
5802 Add a new home service, with the specified home directory, defaults coming
5804 ***************************************************************************/
5806 bool lp_add_home(const char *pszHomename, int iDefaultService,
5807 const char *user, const char *pszHomedir)
5811 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5816 if (!(*(ServicePtrs[iDefaultService]->szPath))
5817 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5818 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5821 if (!(*(ServicePtrs[i]->comment))) {
5822 char *comment = NULL;
5823 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5826 string_set(&ServicePtrs[i]->comment, comment);
5830 /* set the browseable flag from the global default */
5832 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5834 ServicePtrs[i]->autoloaded = True;
5836 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5837 user, ServicePtrs[i]->szPath ));
5842 /***************************************************************************
5843 Add a new service, based on an old one.
5844 ***************************************************************************/
5846 int lp_add_service(const char *pszService, int iDefaultService)
5848 if (iDefaultService < 0) {
5849 return add_a_service(&sDefault, pszService);
5852 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5855 /***************************************************************************
5856 Add the IPC service.
5857 ***************************************************************************/
5859 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5861 char *comment = NULL;
5862 int i = add_a_service(&sDefault, ipc_name);
5867 if (asprintf(&comment, "IPC Service (%s)",
5868 Globals.szServerString) < 0) {
5872 string_set(&ServicePtrs[i]->szPath, tmpdir());
5873 string_set(&ServicePtrs[i]->szUsername, "");
5874 string_set(&ServicePtrs[i]->comment, comment);
5875 string_set(&ServicePtrs[i]->fstype, "IPC");
5876 ServicePtrs[i]->iMaxConnections = 0;
5877 ServicePtrs[i]->bAvailable = True;
5878 ServicePtrs[i]->bRead_only = True;
5879 ServicePtrs[i]->bGuest_only = False;
5880 ServicePtrs[i]->bAdministrative_share = True;
5881 ServicePtrs[i]->bGuest_ok = guest_ok;
5882 ServicePtrs[i]->bPrint_ok = False;
5883 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5885 DEBUG(3, ("adding IPC service\n"));
5891 /***************************************************************************
5892 Add a new printer service, with defaults coming from service iFrom.
5893 ***************************************************************************/
5895 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5897 const char *comment = "From Printcap";
5898 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5903 /* note that we do NOT default the availability flag to True - */
5904 /* we take it from the default service passed. This allows all */
5905 /* dynamic printers to be disabled by disabling the [printers] */
5906 /* entry (if/when the 'available' keyword is implemented!). */
5908 /* the printer name is set to the service name. */
5909 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5910 string_set(&ServicePtrs[i]->comment, comment);
5912 /* set the browseable flag from the gloabl default */
5913 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5915 /* Printers cannot be read_only. */
5916 ServicePtrs[i]->bRead_only = False;
5917 /* No share modes on printer services. */
5918 ServicePtrs[i]->bShareModes = False;
5919 /* No oplocks on printer services. */
5920 ServicePtrs[i]->bOpLocks = False;
5921 /* Printer services must be printable. */
5922 ServicePtrs[i]->bPrint_ok = True;
5924 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5930 /***************************************************************************
5931 Check whether the given parameter name is valid.
5932 Parametric options (names containing a colon) are considered valid.
5933 ***************************************************************************/
5935 bool lp_parameter_is_valid(const char *pszParmName)
5937 return ((map_parameter(pszParmName) != -1) ||
5938 (strchr(pszParmName, ':') != NULL));
5941 /***************************************************************************
5942 Check whether the given name is the name of a global parameter.
5943 Returns True for strings belonging to parameters of class
5944 P_GLOBAL, False for all other strings, also for parametric options
5945 and strings not belonging to any option.
5946 ***************************************************************************/
5948 bool lp_parameter_is_global(const char *pszParmName)
5950 int num = map_parameter(pszParmName);
5953 return (parm_table[num].p_class == P_GLOBAL);
5959 /**************************************************************************
5960 Check whether the given name is the canonical name of a parameter.
5961 Returns False if it is not a valid parameter Name.
5962 For parametric options, True is returned.
5963 **************************************************************************/
5965 bool lp_parameter_is_canonical(const char *parm_name)
5967 if (!lp_parameter_is_valid(parm_name)) {
5971 return (map_parameter(parm_name) ==
5972 map_parameter_canonical(parm_name, NULL));
5975 /**************************************************************************
5976 Determine the canonical name for a parameter.
5977 Indicate when it is an inverse (boolean) synonym instead of a
5979 **************************************************************************/
5981 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
5986 if (!lp_parameter_is_valid(parm_name)) {
5991 num = map_parameter_canonical(parm_name, inverse);
5993 /* parametric option */
5994 *canon_parm = parm_name;
5996 *canon_parm = parm_table[num].label;
6003 /**************************************************************************
6004 Determine the canonical name for a parameter.
6005 Turn the value given into the inverse boolean expression when
6006 the synonym is an invers boolean synonym.
6008 Return True if parm_name is a valid parameter name and
6009 in case it is an invers boolean synonym, if the val string could
6010 successfully be converted to the reverse bool.
6011 Return false in all other cases.
6012 **************************************************************************/
6014 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6016 const char **canon_parm,
6017 const char **canon_val)
6022 if (!lp_parameter_is_valid(parm_name)) {
6028 num = map_parameter_canonical(parm_name, &inverse);
6030 /* parametric option */
6031 *canon_parm = parm_name;
6034 *canon_parm = parm_table[num].label;
6036 if (!lp_invert_boolean(val, canon_val)) {
6048 /***************************************************************************
6049 Map a parameter's string representation to something we can use.
6050 Returns False if the parameter string is not recognised, else TRUE.
6051 ***************************************************************************/
6053 static int map_parameter(const char *pszParmName)
6057 if (*pszParmName == '-')
6060 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6061 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6064 /* Warn only if it isn't parametric option */
6065 if (strchr(pszParmName, ':') == NULL)
6066 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6067 /* We do return 'fail' for parametric options as well because they are
6068 stored in different storage
6073 /***************************************************************************
6074 Map a parameter's string representation to the index of the canonical
6075 form of the parameter (it might be a synonym).
6076 Returns -1 if the parameter string is not recognised.
6077 ***************************************************************************/
6079 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6081 int parm_num, canon_num;
6082 bool loc_inverse = False;
6084 parm_num = map_parameter(pszParmName);
6085 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6086 /* invalid, parametric or no canidate for synonyms ... */
6090 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6091 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6092 parm_num = canon_num;
6098 if (inverse != NULL) {
6099 *inverse = loc_inverse;
6104 /***************************************************************************
6105 return true if parameter number parm1 is a synonym of parameter
6106 number parm2 (parm2 being the principal name).
6107 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6109 ***************************************************************************/
6111 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6113 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6114 (parm_table[parm1].flags & FLAG_HIDE) &&
6115 !(parm_table[parm2].flags & FLAG_HIDE))
6117 if (inverse != NULL) {
6118 if ((parm_table[parm1].type == P_BOOLREV) &&
6119 (parm_table[parm2].type == P_BOOL))
6131 /***************************************************************************
6132 Show one parameter's name, type, [values,] and flags.
6133 (helper functions for show_parameter_list)
6134 ***************************************************************************/
6136 static void show_parameter(int parmIndex)
6138 int enumIndex, flagIndex;
6143 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6144 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6146 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6147 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6148 FLAG_HIDE, FLAG_DOS_STRING};
6149 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6150 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6151 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6153 printf("%s=%s", parm_table[parmIndex].label,
6154 type[parm_table[parmIndex].type]);
6155 if (parm_table[parmIndex].type == P_ENUM) {
6158 parm_table[parmIndex].enum_list[enumIndex].name;
6162 enumIndex ? "|" : "",
6163 parm_table[parmIndex].enum_list[enumIndex].name);
6168 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6169 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6172 flag_names[flagIndex]);
6177 /* output synonyms */
6179 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6180 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6181 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6182 parm_table[parmIndex2].label);
6183 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6185 printf(" (synonyms: ");
6190 printf("%s%s", parm_table[parmIndex2].label,
6191 inverse ? "[i]" : "");
6201 /***************************************************************************
6202 Show all parameter's name, type, [values,] and flags.
6203 ***************************************************************************/
6205 void show_parameter_list(void)
6207 int classIndex, parmIndex;
6208 const char *section_names[] = { "local", "global", NULL};
6210 for (classIndex=0; section_names[classIndex]; classIndex++) {
6211 printf("[%s]\n", section_names[classIndex]);
6212 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6213 if (parm_table[parmIndex].p_class == classIndex) {
6214 show_parameter(parmIndex);
6220 /***************************************************************************
6221 Set a boolean variable from the text value stored in the passed string.
6222 Returns True in success, False if the passed string does not correctly
6223 represent a boolean.
6224 ***************************************************************************/
6226 static bool set_boolean(bool *pb, const char *pszParmValue)
6233 if (strwicmp(pszParmValue, "yes") == 0 ||
6234 strwicmp(pszParmValue, "true") == 0 ||
6235 strwicmp(pszParmValue, "1") == 0)
6237 else if (strwicmp(pszParmValue, "no") == 0 ||
6238 strwicmp(pszParmValue, "False") == 0 ||
6239 strwicmp(pszParmValue, "0") == 0)
6243 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6248 if ((pb != NULL) && (bRetval != False)) {
6256 /***************************************************************************
6257 Check if a given string correctly represents a boolean value.
6258 ***************************************************************************/
6260 bool lp_string_is_valid_boolean(const char *parm_value)
6262 return set_boolean(NULL, parm_value);
6265 /***************************************************************************
6266 Get the standard string representation of a boolean value ("yes" or "no")
6267 ***************************************************************************/
6269 static const char *get_boolean(bool bool_value)
6271 static const char *yes_str = "yes";
6272 static const char *no_str = "no";
6274 return (bool_value ? yes_str : no_str);
6277 /***************************************************************************
6278 Provide the string of the negated boolean value associated to the boolean
6279 given as a string. Returns False if the passed string does not correctly
6280 represent a boolean.
6281 ***************************************************************************/
6283 bool lp_invert_boolean(const char *str, const char **inverse_str)
6287 if (!set_boolean(&val, str)) {
6291 *inverse_str = get_boolean(!val);
6295 /***************************************************************************
6296 Provide the canonical string representation of a boolean value given
6297 as a string. Return True on success, False if the string given does
6298 not correctly represent a boolean.
6299 ***************************************************************************/
6301 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6305 if (!set_boolean(&val, str)) {
6309 *canon_str = get_boolean(val);
6313 /***************************************************************************
6314 Find a service by name. Otherwise works like get_service.
6315 ***************************************************************************/
6317 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6323 if (ServiceHash == NULL) {
6327 canon_name = canonicalize_servicename(pszServiceName);
6329 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6331 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6332 iService = *(int *)data.dptr;
6335 TALLOC_FREE(canon_name);
6337 if ((iService != -1) && (LP_SNUM_OK(iService))
6338 && (pserviceDest != NULL)) {
6339 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6345 /***************************************************************************
6346 Copy a service structure to another.
6347 If pcopymapDest is NULL then copy all fields
6348 ***************************************************************************/
6350 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6351 struct bitmap *pcopymapDest)
6354 bool bcopyall = (pcopymapDest == NULL);
6355 param_opt_struct *data, *pdata, *paramo;
6358 for (i = 0; parm_table[i].label; i++)
6359 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6360 (bcopyall || bitmap_query(pcopymapDest,i))) {
6361 void *def_ptr = parm_table[i].ptr;
6363 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6366 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6369 switch (parm_table[i].type) {
6372 *(bool *)dest_ptr = *(bool *)src_ptr;
6378 *(int *)dest_ptr = *(int *)src_ptr;
6382 *(char *)dest_ptr = *(char *)src_ptr;
6386 string_set((char **)dest_ptr,
6391 string_set((char **)dest_ptr,
6393 strupper_m(*(char **)dest_ptr);
6396 TALLOC_FREE(*((char ***)dest_ptr));
6397 str_list_copy(NULL, (char ***)dest_ptr,
6398 *(const char ***)src_ptr);
6406 init_copymap(pserviceDest);
6407 if (pserviceSource->copymap)
6408 bitmap_copy(pserviceDest->copymap,
6409 pserviceSource->copymap);
6412 data = pserviceSource->param_opt;
6415 pdata = pserviceDest->param_opt;
6416 /* Traverse destination */
6418 /* If we already have same option, override it */
6419 if (strcmp(pdata->key, data->key) == 0) {
6420 string_free(&pdata->value);
6421 TALLOC_FREE(data->list);
6422 pdata->value = SMB_STRDUP(data->value);
6426 pdata = pdata->next;
6429 paramo = SMB_XMALLOC_P(param_opt_struct);
6430 paramo->key = SMB_STRDUP(data->key);
6431 paramo->value = SMB_STRDUP(data->value);
6432 paramo->list = NULL;
6433 DLIST_ADD(pserviceDest->param_opt, paramo);
6439 /***************************************************************************
6440 Check a service for consistency. Return False if the service is in any way
6441 incomplete or faulty, else True.
6442 ***************************************************************************/
6444 bool service_ok(int iService)
6449 if (ServicePtrs[iService]->szService[0] == '\0') {
6450 DEBUG(0, ("The following message indicates an internal error:\n"));
6451 DEBUG(0, ("No service name in service entry.\n"));
6455 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6456 /* I can't see why you'd want a non-printable printer service... */
6457 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6458 if (!ServicePtrs[iService]->bPrint_ok) {
6459 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6460 ServicePtrs[iService]->szService));
6461 ServicePtrs[iService]->bPrint_ok = True;
6463 /* [printers] service must also be non-browsable. */
6464 if (ServicePtrs[iService]->bBrowseable)
6465 ServicePtrs[iService]->bBrowseable = False;
6468 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6469 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6470 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6472 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6473 ServicePtrs[iService]->szService));
6474 ServicePtrs[iService]->bAvailable = False;
6477 /* If a service is flagged unavailable, log the fact at level 1. */
6478 if (!ServicePtrs[iService]->bAvailable)
6479 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6480 ServicePtrs[iService]->szService));
6486 * process_registry_globals
6488 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
6492 char **param_values;
6493 uint32_t num_params;
6495 TALLOC_CTX *mem_ctx = talloc_stackframe();
6498 if (conf_ctx == NULL) {
6500 werr = smbconf_open(NULL, &conf_ctx);
6501 if (!W_ERROR_IS_OK(werr)) {
6506 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6507 /* nothing to read from the registry yet but make sure lp_load
6508 * doesn't return false */
6513 werr = smbconf_get_share(mem_ctx, conf_ctx, GLOBAL_NAME,
6514 &num_params, ¶m_names, ¶m_values);
6515 if (!W_ERROR_IS_OK(werr)) {
6519 for (count = 0; count < num_params; count++) {
6520 ret = pfunc(param_names[count], param_values[count]);
6526 ret = pfunc("registry shares", "yes");
6527 conf_last_seqnum = smbconf_get_seqnum(conf_ctx, NULL, NULL);
6530 TALLOC_FREE(mem_ctx);
6534 static struct file_lists {
6535 struct file_lists *next;
6539 } *file_lists = NULL;
6541 /*******************************************************************
6542 Keep a linked list of all config files so we know when one has changed
6543 it's date and needs to be reloaded.
6544 ********************************************************************/
6546 static void add_to_file_list(const char *fname, const char *subfname)
6548 struct file_lists *f = file_lists;
6551 if (f->name && !strcmp(f->name, fname))
6557 f = SMB_MALLOC_P(struct file_lists);
6560 f->next = file_lists;
6561 f->name = SMB_STRDUP(fname);
6566 f->subfname = SMB_STRDUP(subfname);
6572 f->modtime = file_modtime(subfname);
6574 time_t t = file_modtime(subfname);
6581 * Utility function for outsiders to check if we're running on registry.
6583 bool lp_config_backend_is_registry(void)
6585 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6589 * Utility function to check if the config backend is FILE.
6591 bool lp_config_backend_is_file(void)
6593 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6596 /*******************************************************************
6597 Check if a config file has changed date.
6598 ********************************************************************/
6600 bool lp_file_list_changed(void)
6602 struct file_lists *f = file_lists;
6604 DEBUG(6, ("lp_file_list_changed()\n"));
6606 if (lp_config_backend_is_registry()) {
6607 uint64_t conf_cur_seqnum;
6608 if (conf_ctx == NULL) {
6610 werr = smbconf_open(NULL, &conf_ctx);
6611 if (!W_ERROR_IS_OK(werr)) {
6612 DEBUG(0, ("error opening configuration: %s\n",
6617 conf_cur_seqnum = smbconf_get_seqnum(conf_ctx, NULL, NULL);
6618 if (conf_last_seqnum != conf_cur_seqnum) {
6619 DEBUGADD(6, ("regdb seqnum changed: old = %llu, "
6621 (unsigned long long)conf_last_seqnum,
6622 (unsigned long long)conf_cur_seqnum));
6626 * Don't check files when config_backend is registry.
6627 * Remove this to obtain checking of files even with
6628 * registry config backend. That would enable switching
6629 * off registry configuration by changing smb.conf even
6630 * without restarting smbd.
6640 n2 = alloc_sub_basic(get_current_username(),
6641 current_user_info.domain,
6646 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6647 f->name, n2, ctime(&f->modtime)));
6649 mod_time = file_modtime(n2);
6651 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6653 ("file %s modified: %s\n", n2,
6655 f->modtime = mod_time;
6656 SAFE_FREE(f->subfname);
6657 f->subfname = n2; /* Passing ownership of
6658 return from alloc_sub_basic
6669 /***************************************************************************
6670 Run standard_sub_basic on netbios name... needed because global_myname
6671 is not accessed through any lp_ macro.
6672 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6673 ***************************************************************************/
6675 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6678 char *netbios_name = alloc_sub_basic(get_current_username(),
6679 current_user_info.domain,
6682 ret = set_global_myname(netbios_name);
6683 SAFE_FREE(netbios_name);
6684 string_set(&Globals.szNetbiosName,global_myname());
6686 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6692 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6694 if (strcmp(*ptr, pszParmValue) != 0) {
6695 string_set(ptr, pszParmValue);
6703 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6707 ret = set_global_myworkgroup(pszParmValue);
6708 string_set(&Globals.szWorkgroup,lp_workgroup());
6713 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6717 ret = set_global_scope(pszParmValue);
6718 string_set(&Globals.szNetbiosScope,global_scope());
6723 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6725 TALLOC_FREE(Globals.szNetbiosAliases);
6726 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6727 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6730 /***************************************************************************
6731 Handle the include operation.
6732 ***************************************************************************/
6734 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6738 fname = alloc_sub_basic(get_current_username(),
6739 current_user_info.domain,
6742 add_to_file_list(pszParmValue, fname);
6744 string_set(ptr, fname);
6746 if (file_exist(fname, NULL)) {
6747 bool ret = pm_process(fname, do_section, do_parameter);
6752 DEBUG(2, ("Can't find include file %s\n", fname));
6757 /***************************************************************************
6758 Handle the interpretation of the copy parameter.
6759 ***************************************************************************/
6761 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6765 struct service serviceTemp;
6767 string_set(ptr, pszParmValue);
6769 init_service(&serviceTemp);
6773 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6775 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6776 if (iTemp == iServiceIndex) {
6777 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6779 copy_service(ServicePtrs[iServiceIndex],
6781 ServicePtrs[iServiceIndex]->copymap);
6785 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6789 free_service(&serviceTemp);
6793 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6795 Globals.ldap_debug_level = lp_int(pszParmValue);
6796 init_ldap_debugging();
6800 /***************************************************************************
6801 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6806 idmap uid = 1000-1999
6809 We only do simple parsing checks here. The strings are parsed into useful
6810 structures in the idmap daemon code.
6812 ***************************************************************************/
6814 /* Some lp_ routines to return idmap [ug]id information */
6816 static uid_t idmap_uid_low, idmap_uid_high;
6817 static gid_t idmap_gid_low, idmap_gid_high;
6819 bool lp_idmap_uid(uid_t *low, uid_t *high)
6821 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6825 *low = idmap_uid_low;
6828 *high = idmap_uid_high;
6833 bool lp_idmap_gid(gid_t *low, gid_t *high)
6835 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6839 *low = idmap_gid_low;
6842 *high = idmap_gid_high;
6847 /* Do some simple checks on "idmap [ug]id" parameter values */
6849 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6853 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6858 string_set(ptr, pszParmValue);
6860 idmap_uid_low = low;
6861 idmap_uid_high = high;
6866 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6870 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6875 string_set(ptr, pszParmValue);
6877 idmap_gid_low = low;
6878 idmap_gid_high = high;
6883 /***************************************************************************
6884 Handle the DEBUG level list.
6885 ***************************************************************************/
6887 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
6889 string_set(ptr, pszParmValueIn);
6890 return debug_parse_levels(pszParmValueIn);
6893 /***************************************************************************
6894 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
6895 ***************************************************************************/
6897 static const char *append_ldap_suffix( const char *str )
6899 const char *suffix_string;
6902 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
6903 Globals.szLdapSuffix );
6904 if ( !suffix_string ) {
6905 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
6909 return suffix_string;
6912 const char *lp_ldap_machine_suffix(void)
6914 if (Globals.szLdapMachineSuffix[0])
6915 return append_ldap_suffix(Globals.szLdapMachineSuffix);
6917 return lp_string(Globals.szLdapSuffix);
6920 const char *lp_ldap_user_suffix(void)
6922 if (Globals.szLdapUserSuffix[0])
6923 return append_ldap_suffix(Globals.szLdapUserSuffix);
6925 return lp_string(Globals.szLdapSuffix);
6928 const char *lp_ldap_group_suffix(void)
6930 if (Globals.szLdapGroupSuffix[0])
6931 return append_ldap_suffix(Globals.szLdapGroupSuffix);
6933 return lp_string(Globals.szLdapSuffix);
6936 const char *lp_ldap_idmap_suffix(void)
6938 if (Globals.szLdapIdmapSuffix[0])
6939 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
6941 return lp_string(Globals.szLdapSuffix);
6944 /****************************************************************************
6945 set the value for a P_ENUM
6946 ***************************************************************************/
6948 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
6953 for (i = 0; parm->enum_list[i].name; i++) {
6954 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
6955 *ptr = parm->enum_list[i].value;
6961 /***************************************************************************
6962 ***************************************************************************/
6964 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
6966 static int parm_num = -1;
6969 if ( parm_num == -1 )
6970 parm_num = map_parameter( "printing" );
6972 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
6977 s = ServicePtrs[snum];
6979 init_printer_values( s );
6985 /***************************************************************************
6986 Initialise a copymap.
6987 ***************************************************************************/
6989 static void init_copymap(struct service *pservice)
6992 if (pservice->copymap) {
6993 bitmap_free(pservice->copymap);
6995 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
6996 if (!pservice->copymap)
6998 ("Couldn't allocate copymap!! (size %d)\n",
6999 (int)NUMPARAMETERS));
7001 for (i = 0; i < NUMPARAMETERS; i++)
7002 bitmap_set(pservice->copymap, i);
7005 /***************************************************************************
7006 Return the local pointer to a parameter given the service number and the
7007 pointer into the default structure.
7008 ***************************************************************************/
7010 void *lp_local_ptr(int snum, void *ptr)
7012 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7015 /***************************************************************************
7016 Process a parameter for a particular service number. If snum < 0
7017 then assume we are in the globals.
7018 ***************************************************************************/
7020 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7022 int parmnum, i, slen;
7023 void *parm_ptr = NULL; /* where we are going to store the result */
7024 void *def_ptr = NULL;
7025 char *param_key = NULL;
7027 param_opt_struct *paramo, *data;
7030 parmnum = map_parameter(pszParmName);
7033 if ((sep=strchr(pszParmName, ':')) != NULL) {
7034 TALLOC_CTX *frame = talloc_stackframe();
7037 param_key = talloc_asprintf(frame, "%s:", pszParmName);
7042 slen = strlen(param_key);
7043 param_key = talloc_asprintf_append(param_key, sep+1);
7048 trim_char(param_key+slen, ' ', ' ');
7050 data = (snum < 0) ? Globals.param_opt :
7051 ServicePtrs[snum]->param_opt;
7052 /* Traverse destination */
7054 /* If we already have same option, override it */
7055 if (strcmp(data->key, param_key) == 0) {
7056 string_free(&data->value);
7057 TALLOC_FREE(data->list);
7058 data->value = SMB_STRDUP(pszParmValue);
7065 paramo = SMB_XMALLOC_P(param_opt_struct);
7066 paramo->key = SMB_STRDUP(param_key);
7067 paramo->value = SMB_STRDUP(pszParmValue);
7068 paramo->list = NULL;
7070 DLIST_ADD(Globals.param_opt, paramo);
7072 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
7080 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7084 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7085 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7089 def_ptr = parm_table[parmnum].ptr;
7091 /* we might point at a service, the default service or a global */
7095 if (parm_table[parmnum].p_class == P_GLOBAL) {
7097 ("Global parameter %s found in service section!\n",
7102 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7107 if (!ServicePtrs[snum]->copymap)
7108 init_copymap(ServicePtrs[snum]);
7110 /* this handles the aliases - set the copymap for other entries with
7111 the same data pointer */
7112 for (i = 0; parm_table[i].label; i++)
7113 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7114 bitmap_clear(ServicePtrs[snum]->copymap, i);
7117 /* if it is a special case then go ahead */
7118 if (parm_table[parmnum].special) {
7119 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
7123 /* now switch on the type of variable it is */
7124 switch (parm_table[parmnum].type)
7127 *(bool *)parm_ptr = lp_bool(pszParmValue);
7131 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7135 *(int *)parm_ptr = lp_int(pszParmValue);
7139 *(char *)parm_ptr = *pszParmValue;
7143 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7145 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7150 TALLOC_FREE(*((char ***)parm_ptr));
7151 *(char ***)parm_ptr = str_list_make(
7152 NULL, pszParmValue, NULL);
7156 string_set((char **)parm_ptr, pszParmValue);
7160 string_set((char **)parm_ptr, pszParmValue);
7161 strupper_m(*(char **)parm_ptr);
7165 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7174 /***************************************************************************
7175 Process a parameter.
7176 ***************************************************************************/
7178 static bool do_parameter(const char *pszParmName, const char *pszParmValue)
7180 if (!bInGlobalSection && bGlobalOnly)
7183 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7185 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7186 pszParmName, pszParmValue));
7189 /***************************************************************************
7190 Print a parameter of the specified type.
7191 ***************************************************************************/
7193 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7199 for (i = 0; p->enum_list[i].name; i++) {
7200 if (*(int *)ptr == p->enum_list[i].value) {
7202 p->enum_list[i].name);
7209 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7213 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7217 fprintf(f, "%d", *(int *)ptr);
7221 fprintf(f, "%c", *(char *)ptr);
7225 char *o = octal_string(*(int *)ptr);
7226 fprintf(f, "%s", o);
7232 if ((char ***)ptr && *(char ***)ptr) {
7233 char **list = *(char ***)ptr;
7234 for (; *list; list++) {
7235 /* surround strings with whitespace in double quotes */
7236 if ( strchr_m( *list, ' ' ) )
7237 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7239 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7246 if (*(char **)ptr) {
7247 fprintf(f, "%s", *(char **)ptr);
7255 /***************************************************************************
7256 Check if two parameters are equal.
7257 ***************************************************************************/
7259 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7264 return (*((bool *)ptr1) == *((bool *)ptr2));
7269 return (*((int *)ptr1) == *((int *)ptr2));
7272 return (*((char *)ptr1) == *((char *)ptr2));
7275 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7280 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7285 return (p1 == p2 || strequal(p1, p2));
7293 /***************************************************************************
7294 Initialize any local varients in the sDefault table.
7295 ***************************************************************************/
7297 void init_locals(void)
7302 /***************************************************************************
7303 Process a new section (service). At this stage all sections are services.
7304 Later we'll have special sections that permit server parameters to be set.
7305 Returns True on success, False on failure.
7306 ***************************************************************************/
7308 static bool do_section(const char *pszSectionName)
7311 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7312 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7315 /* if we were in a global section then do the local inits */
7316 if (bInGlobalSection && !isglobal)
7319 /* if we've just struck a global section, note the fact. */
7320 bInGlobalSection = isglobal;
7322 /* check for multiple global sections */
7323 if (bInGlobalSection) {
7324 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7328 if (!bInGlobalSection && bGlobalOnly)
7331 /* if we have a current service, tidy it up before moving on */
7334 if (iServiceIndex >= 0)
7335 bRetval = service_ok(iServiceIndex);
7337 /* if all is still well, move to the next record in the services array */
7339 /* We put this here to avoid an odd message order if messages are */
7340 /* issued by the post-processing of a previous section. */
7341 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7343 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7345 DEBUG(0, ("Failed to add a new service\n"));
7354 /***************************************************************************
7355 Determine if a partcular base parameter is currentl set to the default value.
7356 ***************************************************************************/
7358 static bool is_default(int i)
7360 if (!defaults_saved)
7362 switch (parm_table[i].type) {
7364 return str_list_compare (parm_table[i].def.lvalue,
7365 *(char ***)parm_table[i].ptr);
7368 return strequal(parm_table[i].def.svalue,
7369 *(char **)parm_table[i].ptr);
7372 return parm_table[i].def.bvalue ==
7373 *(bool *)parm_table[i].ptr;
7375 return parm_table[i].def.cvalue ==
7376 *(char *)parm_table[i].ptr;
7380 return parm_table[i].def.ivalue ==
7381 *(int *)parm_table[i].ptr;
7388 /***************************************************************************
7389 Display the contents of the global structure.
7390 ***************************************************************************/
7392 static void dump_globals(FILE *f)
7395 param_opt_struct *data;
7397 fprintf(f, "[global]\n");
7399 for (i = 0; parm_table[i].label; i++)
7400 if (parm_table[i].p_class == P_GLOBAL &&
7401 parm_table[i].ptr &&
7402 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7403 if (defaults_saved && is_default(i))
7405 fprintf(f, "\t%s = ", parm_table[i].label);
7406 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7409 if (Globals.param_opt != NULL) {
7410 data = Globals.param_opt;
7412 fprintf(f, "\t%s = %s\n", data->key, data->value);
7419 /***************************************************************************
7420 Return True if a local parameter is currently set to the global default.
7421 ***************************************************************************/
7423 bool lp_is_default(int snum, struct parm_struct *parm)
7425 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7427 return equal_parameter(parm->type,
7428 ((char *)ServicePtrs[snum]) + pdiff,
7429 ((char *)&sDefault) + pdiff);
7432 /***************************************************************************
7433 Display the contents of a single services record.
7434 ***************************************************************************/
7436 static void dump_a_service(struct service *pService, FILE * f)
7439 param_opt_struct *data;
7441 if (pService != &sDefault)
7442 fprintf(f, "[%s]\n", pService->szService);
7444 for (i = 0; parm_table[i].label; i++) {
7446 if (parm_table[i].p_class == P_LOCAL &&
7447 parm_table[i].ptr &&
7448 (*parm_table[i].label != '-') &&
7449 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7452 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7454 if (pService == &sDefault) {
7455 if (defaults_saved && is_default(i))
7458 if (equal_parameter(parm_table[i].type,
7459 ((char *)pService) +
7461 ((char *)&sDefault) +
7466 fprintf(f, "\t%s = ", parm_table[i].label);
7467 print_parameter(&parm_table[i],
7468 ((char *)pService) + pdiff, f);
7473 if (pService->param_opt != NULL) {
7474 data = pService->param_opt;
7476 fprintf(f, "\t%s = %s\n", data->key, data->value);
7482 /***************************************************************************
7483 Display the contents of a parameter of a single services record.
7484 ***************************************************************************/
7486 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7489 bool result = False;
7492 fstring local_parm_name;
7494 const char *parm_opt_value;
7496 /* check for parametrical option */
7497 fstrcpy( local_parm_name, parm_name);
7498 parm_opt = strchr( local_parm_name, ':');
7503 if (strlen(parm_opt)) {
7504 parm_opt_value = lp_parm_const_string( snum,
7505 local_parm_name, parm_opt, NULL);
7506 if (parm_opt_value) {
7507 printf( "%s\n", parm_opt_value);
7514 /* check for a key and print the value */
7521 for (i = 0; parm_table[i].label; i++) {
7522 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7523 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7524 parm_table[i].ptr &&
7525 (*parm_table[i].label != '-') &&
7526 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7531 ptr = parm_table[i].ptr;
7533 struct service *pService = ServicePtrs[snum];
7534 ptr = ((char *)pService) +
7535 PTR_DIFF(parm_table[i].ptr, &sDefault);
7538 print_parameter(&parm_table[i],
7549 /***************************************************************************
7550 Return info about the requested parameter (given as a string).
7551 Return NULL when the string is not a valid parameter name.
7552 ***************************************************************************/
7554 struct parm_struct *lp_get_parameter(const char *param_name)
7556 int num = map_parameter(param_name);
7562 return &parm_table[num];
7565 /***************************************************************************
7566 Return info about the next parameter in a service.
7567 snum==GLOBAL_SECTION_SNUM gives the globals.
7568 Return NULL when out of parameters.
7569 ***************************************************************************/
7571 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7574 /* do the globals */
7575 for (; parm_table[*i].label; (*i)++) {
7576 if (parm_table[*i].p_class == P_SEPARATOR)
7577 return &parm_table[(*i)++];
7579 if (!parm_table[*i].ptr
7580 || (*parm_table[*i].label == '-'))
7584 && (parm_table[*i].ptr ==
7585 parm_table[(*i) - 1].ptr))
7588 if (is_default(*i) && !allparameters)
7591 return &parm_table[(*i)++];
7594 struct service *pService = ServicePtrs[snum];
7596 for (; parm_table[*i].label; (*i)++) {
7597 if (parm_table[*i].p_class == P_SEPARATOR)
7598 return &parm_table[(*i)++];
7600 if (parm_table[*i].p_class == P_LOCAL &&
7601 parm_table[*i].ptr &&
7602 (*parm_table[*i].label != '-') &&
7604 (parm_table[*i].ptr !=
7605 parm_table[(*i) - 1].ptr)))
7608 PTR_DIFF(parm_table[*i].ptr,
7611 if (allparameters ||
7612 !equal_parameter(parm_table[*i].type,
7613 ((char *)pService) +
7615 ((char *)&sDefault) +
7618 return &parm_table[(*i)++];
7629 /***************************************************************************
7630 Display the contents of a single copy structure.
7631 ***************************************************************************/
7632 static void dump_copy_map(bool *pcopymap)
7638 printf("\n\tNon-Copied parameters:\n");
7640 for (i = 0; parm_table[i].label; i++)
7641 if (parm_table[i].p_class == P_LOCAL &&
7642 parm_table[i].ptr && !pcopymap[i] &&
7643 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7645 printf("\t\t%s\n", parm_table[i].label);
7650 /***************************************************************************
7651 Return TRUE if the passed service number is within range.
7652 ***************************************************************************/
7654 bool lp_snum_ok(int iService)
7656 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7659 /***************************************************************************
7660 Auto-load some home services.
7661 ***************************************************************************/
7663 static void lp_add_auto_services(char *str)
7673 s = SMB_STRDUP(str);
7677 homes = lp_servicenumber(HOMES_NAME);
7679 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7680 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7683 if (lp_servicenumber(p) >= 0)
7686 home = get_user_home_dir(talloc_tos(), p);
7688 if (home && homes >= 0)
7689 lp_add_home(p, homes, p, home);
7696 /***************************************************************************
7697 Auto-load one printer.
7698 ***************************************************************************/
7700 void lp_add_one_printer(char *name, char *comment)
7702 int printers = lp_servicenumber(PRINTERS_NAME);
7705 if (lp_servicenumber(name) < 0) {
7706 lp_add_printer(name, printers);
7707 if ((i = lp_servicenumber(name)) >= 0) {
7708 string_set(&ServicePtrs[i]->comment, comment);
7709 ServicePtrs[i]->autoloaded = True;
7714 /***************************************************************************
7715 Have we loaded a services file yet?
7716 ***************************************************************************/
7718 bool lp_loaded(void)
7723 /***************************************************************************
7724 Unload unused services.
7725 ***************************************************************************/
7727 void lp_killunused(bool (*snumused) (int))
7730 for (i = 0; i < iNumServices; i++) {
7734 /* don't kill autoloaded or usershare services */
7735 if ( ServicePtrs[i]->autoloaded ||
7736 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7740 if (!snumused || !snumused(i)) {
7741 free_service_byindex(i);
7747 * Kill all except autoloaded and usershare services - convenience wrapper
7749 void lp_kill_all_services(void)
7751 lp_killunused(NULL);
7754 /***************************************************************************
7756 ***************************************************************************/
7758 void lp_killservice(int iServiceIn)
7760 if (VALID(iServiceIn)) {
7761 free_service_byindex(iServiceIn);
7765 /***************************************************************************
7766 Save the curent values of all global and sDefault parameters into the
7767 defaults union. This allows swat and testparm to show only the
7768 changed (ie. non-default) parameters.
7769 ***************************************************************************/
7771 static void lp_save_defaults(void)
7774 for (i = 0; parm_table[i].label; i++) {
7775 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7777 switch (parm_table[i].type) {
7780 NULL, &(parm_table[i].def.lvalue),
7781 *(const char ***)parm_table[i].ptr);
7785 if (parm_table[i].ptr) {
7786 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7788 parm_table[i].def.svalue = NULL;
7793 parm_table[i].def.bvalue =
7794 *(bool *)parm_table[i].ptr;
7797 parm_table[i].def.cvalue =
7798 *(char *)parm_table[i].ptr;
7803 parm_table[i].def.ivalue =
7804 *(int *)parm_table[i].ptr;
7810 defaults_saved = True;
7813 /*******************************************************************
7814 Set the server type we will announce as via nmbd.
7815 ********************************************************************/
7817 static const struct srv_role_tab {
7819 const char *role_str;
7820 } srv_role_tab [] = {
7821 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7822 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7823 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7824 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7828 const char* server_role_str(uint32 role)
7831 for (i=0; srv_role_tab[i].role_str; i++) {
7832 if (role == srv_role_tab[i].role) {
7833 return srv_role_tab[i].role_str;
7839 static void set_server_role(void)
7841 server_role = ROLE_STANDALONE;
7843 switch (lp_security()) {
7845 if (lp_domain_logons())
7846 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7849 if (lp_domain_logons())
7850 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7851 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7852 server_role = ROLE_STANDALONE;
7855 if (lp_domain_logons()) {
7856 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7857 server_role = ROLE_DOMAIN_BDC;
7860 server_role = ROLE_DOMAIN_MEMBER;
7863 if (lp_domain_logons()) {
7864 server_role = ROLE_DOMAIN_PDC;
7867 server_role = ROLE_DOMAIN_MEMBER;
7870 if (lp_domain_logons()) {
7872 if (Globals.iDomainMaster) /* auto or yes */
7873 server_role = ROLE_DOMAIN_PDC;
7875 server_role = ROLE_DOMAIN_BDC;
7879 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7883 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7886 /***********************************************************
7887 If we should send plaintext/LANMAN passwords in the clinet
7888 ************************************************************/
7890 static void set_allowed_client_auth(void)
7892 if (Globals.bClientNTLMv2Auth) {
7893 Globals.bClientLanManAuth = False;
7895 if (!Globals.bClientLanManAuth) {
7896 Globals.bClientPlaintextAuth = False;
7900 /***************************************************************************
7902 The following code allows smbd to read a user defined share file.
7903 Yes, this is my intent. Yes, I'm comfortable with that...
7905 THE FOLLOWING IS SECURITY CRITICAL CODE.
7907 It washes your clothes, it cleans your house, it guards you while you sleep...
7908 Do not f%^k with it....
7909 ***************************************************************************/
7911 #define MAX_USERSHARE_FILE_SIZE (10*1024)
7913 /***************************************************************************
7914 Check allowed stat state of a usershare file.
7915 Ensure we print out who is dicking with us so the admin can
7916 get their sorry ass fired.
7917 ***************************************************************************/
7919 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
7921 if (!S_ISREG(psbuf->st_mode)) {
7922 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
7923 "not a regular file\n",
7924 fname, (unsigned int)psbuf->st_uid ));
7928 /* Ensure this doesn't have the other write bit set. */
7929 if (psbuf->st_mode & S_IWOTH) {
7930 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
7931 "public write. Refusing to allow as a usershare file.\n",
7932 fname, (unsigned int)psbuf->st_uid ));
7936 /* Should be 10k or less. */
7937 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
7938 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
7939 "too large (%u) to be a user share file.\n",
7940 fname, (unsigned int)psbuf->st_uid,
7941 (unsigned int)psbuf->st_size ));
7948 /***************************************************************************
7949 Parse the contents of a usershare file.
7950 ***************************************************************************/
7952 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
7953 SMB_STRUCT_STAT *psbuf,
7954 const char *servicename,
7958 char **pp_sharepath,
7963 const char **prefixallowlist = lp_usershare_prefix_allow_list();
7964 const char **prefixdenylist = lp_usershare_prefix_deny_list();
7967 SMB_STRUCT_STAT sbuf;
7968 char *sharepath = NULL;
7969 char *comment = NULL;
7971 *pp_sharepath = NULL;
7974 *pallow_guest = False;
7977 return USERSHARE_MALFORMED_FILE;
7980 if (strcmp(lines[0], "#VERSION 1") == 0) {
7982 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
7985 return USERSHARE_MALFORMED_FILE;
7988 return USERSHARE_BAD_VERSION;
7991 if (strncmp(lines[1], "path=", 5) != 0) {
7992 return USERSHARE_MALFORMED_PATH;
7995 sharepath = talloc_strdup(ctx, &lines[1][5]);
7997 return USERSHARE_POSIX_ERR;
7999 trim_string(sharepath, " ", " ");
8001 if (strncmp(lines[2], "comment=", 8) != 0) {
8002 return USERSHARE_MALFORMED_COMMENT_DEF;
8005 comment = talloc_strdup(ctx, &lines[2][8]);
8007 return USERSHARE_POSIX_ERR;
8009 trim_string(comment, " ", " ");
8010 trim_char(comment, '"', '"');
8012 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8013 return USERSHARE_MALFORMED_ACL_DEF;
8016 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8017 return USERSHARE_ACL_ERR;
8021 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8022 return USERSHARE_MALFORMED_ACL_DEF;
8024 if (lines[4][9] == 'y') {
8025 *pallow_guest = True;
8029 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8030 /* Path didn't change, no checks needed. */
8031 *pp_sharepath = sharepath;
8032 *pp_comment = comment;
8033 return USERSHARE_OK;
8036 /* The path *must* be absolute. */
8037 if (sharepath[0] != '/') {
8038 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8039 servicename, sharepath));
8040 return USERSHARE_PATH_NOT_ABSOLUTE;
8043 /* If there is a usershare prefix deny list ensure one of these paths
8044 doesn't match the start of the user given path. */
8045 if (prefixdenylist) {
8047 for ( i=0; prefixdenylist[i]; i++ ) {
8048 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8049 servicename, i, prefixdenylist[i], sharepath ));
8050 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8051 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8052 "usershare prefix deny list entries.\n",
8053 servicename, sharepath));
8054 return USERSHARE_PATH_IS_DENIED;
8059 /* If there is a usershare prefix allow list ensure one of these paths
8060 does match the start of the user given path. */
8062 if (prefixallowlist) {
8064 for ( i=0; prefixallowlist[i]; i++ ) {
8065 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8066 servicename, i, prefixallowlist[i], sharepath ));
8067 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8071 if (prefixallowlist[i] == NULL) {
8072 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8073 "usershare prefix allow list entries.\n",
8074 servicename, sharepath));
8075 return USERSHARE_PATH_NOT_ALLOWED;
8079 /* Ensure this is pointing to a directory. */
8080 dp = sys_opendir(sharepath);
8083 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8084 servicename, sharepath));
8085 return USERSHARE_PATH_NOT_DIRECTORY;
8088 /* Ensure the owner of the usershare file has permission to share
8091 if (sys_stat(sharepath, &sbuf) == -1) {
8092 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8093 servicename, sharepath, strerror(errno) ));
8095 return USERSHARE_POSIX_ERR;
8100 if (!S_ISDIR(sbuf.st_mode)) {
8101 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8102 servicename, sharepath ));
8103 return USERSHARE_PATH_NOT_DIRECTORY;
8106 /* Check if sharing is restricted to owner-only. */
8107 /* psbuf is the stat of the usershare definition file,
8108 sbuf is the stat of the target directory to be shared. */
8110 if (lp_usershare_owner_only()) {
8111 /* root can share anything. */
8112 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8113 return USERSHARE_PATH_NOT_ALLOWED;
8117 *pp_sharepath = sharepath;
8118 *pp_comment = comment;
8119 return USERSHARE_OK;
8122 /***************************************************************************
8123 Deal with a usershare file.
8126 -1 - Bad name, invalid contents.
8127 - service name already existed and not a usershare, problem
8128 with permissions to share directory etc.
8129 ***************************************************************************/
8131 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8133 SMB_STRUCT_STAT sbuf;
8134 SMB_STRUCT_STAT lsbuf;
8136 char *sharepath = NULL;
8137 char *comment = NULL;
8138 fstring service_name;
8139 char **lines = NULL;
8143 TALLOC_CTX *ctx = NULL;
8144 SEC_DESC *psd = NULL;
8145 bool guest_ok = False;
8147 /* Ensure share name doesn't contain invalid characters. */
8148 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8149 DEBUG(0,("process_usershare_file: share name %s contains "
8150 "invalid characters (any of %s)\n",
8151 file_name, INVALID_SHARENAME_CHARS ));
8155 fstrcpy(service_name, file_name);
8157 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8160 /* Minimize the race condition by doing an lstat before we
8161 open and fstat. Ensure this isn't a symlink link. */
8163 if (sys_lstat(fname, &lsbuf) != 0) {
8164 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8165 fname, strerror(errno) ));
8170 /* This must be a regular file, not a symlink, directory or
8171 other strange filetype. */
8172 if (!check_usershare_stat(fname, &lsbuf)) {
8178 char *canon_name = canonicalize_servicename(service_name);
8179 TDB_DATA data = dbwrap_fetch_bystring(
8180 ServiceHash, canon_name, canon_name);
8184 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8185 iService = *(int *)data.dptr;
8187 TALLOC_FREE(canon_name);
8190 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8191 /* Nothing changed - Mark valid and return. */
8192 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8194 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8199 /* Try and open the file read only - no symlinks allowed. */
8201 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8203 fd = sys_open(fname, O_RDONLY, 0);
8207 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8208 fname, strerror(errno) ));
8213 /* Now fstat to be *SURE* it's a regular file. */
8214 if (sys_fstat(fd, &sbuf) != 0) {
8216 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8217 fname, strerror(errno) ));
8222 /* Is it the same dev/inode as was lstated ? */
8223 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8225 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8226 "Symlink spoofing going on ?\n", fname ));
8231 /* This must be a regular file, not a symlink, directory or
8232 other strange filetype. */
8233 if (!check_usershare_stat(fname, &sbuf)) {
8238 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8241 if (lines == NULL) {
8242 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8243 fname, (unsigned int)sbuf.st_uid ));
8250 /* Should we allow printers to be shared... ? */
8251 ctx = talloc_init("usershare_sd_xctx");
8253 file_lines_free(lines);
8257 if (parse_usershare_file(ctx, &sbuf, service_name,
8258 iService, lines, numlines, &sharepath,
8259 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8260 talloc_destroy(ctx);
8261 file_lines_free(lines);
8265 file_lines_free(lines);
8267 /* Everything ok - add the service possibly using a template. */
8269 const struct service *sp = &sDefault;
8270 if (snum_template != -1) {
8271 sp = ServicePtrs[snum_template];
8274 if ((iService = add_a_service(sp, service_name)) < 0) {
8275 DEBUG(0, ("process_usershare_file: Failed to add "
8276 "new service %s\n", service_name));
8277 talloc_destroy(ctx);
8281 /* Read only is controlled by usershare ACL below. */
8282 ServicePtrs[iService]->bRead_only = False;
8285 /* Write the ACL of the new/modified share. */
8286 if (!set_share_security(service_name, psd)) {
8287 DEBUG(0, ("process_usershare_file: Failed to set share "
8288 "security for user share %s\n",
8290 lp_remove_service(iService);
8291 talloc_destroy(ctx);
8295 /* If from a template it may be marked invalid. */
8296 ServicePtrs[iService]->valid = True;
8298 /* Set the service as a valid usershare. */
8299 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8301 /* Set guest access. */
8302 if (lp_usershare_allow_guests()) {
8303 ServicePtrs[iService]->bGuest_ok = guest_ok;
8306 /* And note when it was loaded. */
8307 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8308 string_set(&ServicePtrs[iService]->szPath, sharepath);
8309 string_set(&ServicePtrs[iService]->comment, comment);
8311 talloc_destroy(ctx);
8316 /***************************************************************************
8317 Checks if a usershare entry has been modified since last load.
8318 ***************************************************************************/
8320 static bool usershare_exists(int iService, time_t *last_mod)
8322 SMB_STRUCT_STAT lsbuf;
8323 const char *usersharepath = Globals.szUsersharePath;
8326 if (asprintf(&fname, "%s/%s",
8328 ServicePtrs[iService]->szService) < 0) {
8332 if (sys_lstat(fname, &lsbuf) != 0) {
8337 if (!S_ISREG(lsbuf.st_mode)) {
8343 *last_mod = lsbuf.st_mtime;
8347 /***************************************************************************
8348 Load a usershare service by name. Returns a valid servicenumber or -1.
8349 ***************************************************************************/
8351 int load_usershare_service(const char *servicename)
8353 SMB_STRUCT_STAT sbuf;
8354 const char *usersharepath = Globals.szUsersharePath;
8355 int max_user_shares = Globals.iUsershareMaxShares;
8356 int snum_template = -1;
8358 if (*usersharepath == 0 || max_user_shares == 0) {
8362 if (sys_stat(usersharepath, &sbuf) != 0) {
8363 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8364 usersharepath, strerror(errno) ));
8368 if (!S_ISDIR(sbuf.st_mode)) {
8369 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8375 * This directory must be owned by root, and have the 't' bit set.
8376 * It also must not be writable by "other".
8380 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8382 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8384 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8385 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8390 /* Ensure the template share exists if it's set. */
8391 if (Globals.szUsershareTemplateShare[0]) {
8392 /* We can't use lp_servicenumber here as we are recommending that
8393 template shares have -valid=False set. */
8394 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8395 if (ServicePtrs[snum_template]->szService &&
8396 strequal(ServicePtrs[snum_template]->szService,
8397 Globals.szUsershareTemplateShare)) {
8402 if (snum_template == -1) {
8403 DEBUG(0,("load_usershare_service: usershare template share %s "
8404 "does not exist.\n",
8405 Globals.szUsershareTemplateShare ));
8410 return process_usershare_file(usersharepath, servicename, snum_template);
8413 /***************************************************************************
8414 Load all user defined shares from the user share directory.
8415 We only do this if we're enumerating the share list.
8416 This is the function that can delete usershares that have
8418 ***************************************************************************/
8420 int load_usershare_shares(void)
8423 SMB_STRUCT_STAT sbuf;
8424 SMB_STRUCT_DIRENT *de;
8425 int num_usershares = 0;
8426 int max_user_shares = Globals.iUsershareMaxShares;
8427 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8428 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8429 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8431 int snum_template = -1;
8432 const char *usersharepath = Globals.szUsersharePath;
8433 int ret = lp_numservices();
8435 if (max_user_shares == 0 || *usersharepath == '\0') {
8436 return lp_numservices();
8439 if (sys_stat(usersharepath, &sbuf) != 0) {
8440 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8441 usersharepath, strerror(errno) ));
8446 * This directory must be owned by root, and have the 't' bit set.
8447 * It also must not be writable by "other".
8451 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8453 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8455 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8456 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8461 /* Ensure the template share exists if it's set. */
8462 if (Globals.szUsershareTemplateShare[0]) {
8463 /* We can't use lp_servicenumber here as we are recommending that
8464 template shares have -valid=False set. */
8465 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8466 if (ServicePtrs[snum_template]->szService &&
8467 strequal(ServicePtrs[snum_template]->szService,
8468 Globals.szUsershareTemplateShare)) {
8473 if (snum_template == -1) {
8474 DEBUG(0,("load_usershare_shares: usershare template share %s "
8475 "does not exist.\n",
8476 Globals.szUsershareTemplateShare ));
8481 /* Mark all existing usershares as pending delete. */
8482 for (iService = iNumServices - 1; iService >= 0; iService--) {
8483 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8484 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8488 dp = sys_opendir(usersharepath);
8490 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8491 usersharepath, strerror(errno) ));
8495 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8496 (de = sys_readdir(dp));
8497 num_dir_entries++ ) {
8499 const char *n = de->d_name;
8501 /* Ignore . and .. */
8503 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8509 /* Temporary file used when creating a share. */
8510 num_tmp_dir_entries++;
8513 /* Allow 20% tmp entries. */
8514 if (num_tmp_dir_entries > allowed_tmp_entries) {
8515 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8516 "in directory %s\n",
8517 num_tmp_dir_entries, usersharepath));
8521 r = process_usershare_file(usersharepath, n, snum_template);
8523 /* Update the services count. */
8525 if (num_usershares >= max_user_shares) {
8526 DEBUG(0,("load_usershare_shares: max user shares reached "
8527 "on file %s in directory %s\n",
8528 n, usersharepath ));
8531 } else if (r == -1) {
8532 num_bad_dir_entries++;
8535 /* Allow 20% bad entries. */
8536 if (num_bad_dir_entries > allowed_bad_entries) {
8537 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8538 "in directory %s\n",
8539 num_bad_dir_entries, usersharepath));
8543 /* Allow 20% bad entries. */
8544 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8545 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8546 "in directory %s\n",
8547 num_dir_entries, usersharepath));
8554 /* Sweep through and delete any non-refreshed usershares that are
8555 not currently in use. */
8556 for (iService = iNumServices - 1; iService >= 0; iService--) {
8557 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8558 if (conn_snum_used(iService)) {
8561 /* Remove from the share ACL db. */
8562 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8563 lp_servicename(iService) ));
8564 delete_share_security(lp_servicename(iService));
8565 free_service_byindex(iService);
8569 return lp_numservices();
8572 /********************************************************
8573 Destroy global resources allocated in this file
8574 ********************************************************/
8576 void gfree_loadparm(void)
8578 struct file_lists *f;
8579 struct file_lists *next;
8582 /* Free the file lists */
8587 SAFE_FREE( f->name );
8588 SAFE_FREE( f->subfname );
8593 /* Free resources allocated to services */
8595 for ( i = 0; i < iNumServices; i++ ) {
8597 free_service_byindex(i);
8601 SAFE_FREE( ServicePtrs );
8604 /* Now release all resources allocated to global
8605 parameters and the default service */
8607 for (i = 0; parm_table[i].label; i++)
8609 if ( parm_table[i].type == P_STRING
8610 || parm_table[i].type == P_USTRING )
8612 string_free( (char**)parm_table[i].ptr );
8614 else if (parm_table[i].type == P_LIST) {
8615 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8621 /***************************************************************************
8622 Allow client apps to specify that they are a client
8623 ***************************************************************************/
8624 void lp_set_in_client(bool b)
8630 /***************************************************************************
8631 Determine if we're running in a client app
8632 ***************************************************************************/
8633 bool lp_is_in_client(void)
8641 /***************************************************************************
8642 Load the services array from the services file. Return True on success,
8644 ***************************************************************************/
8646 bool lp_load(const char *pszFname,
8650 bool initialize_globals)
8654 param_opt_struct *data, *pdata;
8658 DEBUG(3, ("lp_load: refreshing parameters\n"));
8660 bInGlobalSection = True;
8661 bGlobalOnly = global_only;
8663 init_globals(! initialize_globals);
8666 if (save_defaults) {
8671 if (Globals.param_opt != NULL) {
8672 data = Globals.param_opt;
8674 string_free(&data->key);
8675 string_free(&data->value);
8676 TALLOC_FREE(data->list);
8681 Globals.param_opt = NULL;
8684 if (lp_config_backend_is_file()) {
8685 n2 = alloc_sub_basic(get_current_username(),
8686 current_user_info.domain,
8689 smb_panic("lp_load: out of memory");
8692 add_to_file_list(pszFname, n2);
8694 /* We get sections first, so have to start 'behind' to make up */
8696 bRetval = pm_process(n2, do_section, do_parameter);
8699 /* finish up the last section */
8700 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8702 if (iServiceIndex >= 0) {
8703 bRetval = service_ok(iServiceIndex);
8707 if (lp_config_backend_is_registry()) {
8708 /* config backend changed to registry in config file */
8710 * We need to use this extra global variable here to
8711 * survive restart: init_globals uses this as a default
8712 * for ConfigBackend. Otherwise, init_globals would
8713 * send us into an endless loop here.
8715 config_backend = CONFIG_BACKEND_REGISTRY;
8717 DEBUG(1, ("lp_load: changing to config backend "
8719 init_globals(false);
8720 lp_kill_all_services();
8721 return lp_load(pszFname, global_only, save_defaults,
8722 add_ipc, initialize_globals);
8724 } else if (lp_config_backend_is_registry()) {
8725 bRetval = process_registry_globals(do_parameter);
8727 DEBUG(0, ("Illegal config backend given: %d\n",
8728 lp_config_backend()));
8732 lp_add_auto_services(lp_auto_services());
8735 /* When 'restrict anonymous = 2' guest connections to ipc$
8737 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8738 if ( lp_enable_asu_support() ) {
8739 lp_add_ipc("ADMIN$", false);
8744 set_default_server_announce_type();
8745 set_allowed_client_auth();
8749 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8750 /* if bWINSsupport is true and we are in the client */
8751 if (lp_is_in_client() && Globals.bWINSsupport) {
8752 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8760 /***************************************************************************
8761 Reset the max number of services.
8762 ***************************************************************************/
8764 void lp_resetnumservices(void)
8769 /***************************************************************************
8770 Return the max number of services.
8771 ***************************************************************************/
8773 int lp_numservices(void)
8775 return (iNumServices);
8778 /***************************************************************************
8779 Display the contents of the services array in human-readable form.
8780 ***************************************************************************/
8782 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8787 defaults_saved = False;
8791 dump_a_service(&sDefault, f);
8793 for (iService = 0; iService < maxtoprint; iService++) {
8795 lp_dump_one(f, show_defaults, iService);
8799 /***************************************************************************
8800 Display the contents of one service in human-readable form.
8801 ***************************************************************************/
8803 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8806 if (ServicePtrs[snum]->szService[0] == '\0')
8808 dump_a_service(ServicePtrs[snum], f);
8812 /***************************************************************************
8813 Return the number of the service with the given name, or -1 if it doesn't
8814 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8815 getservicebyname()! This works ONLY if all services have been loaded, and
8816 does not copy the found service.
8817 ***************************************************************************/
8819 int lp_servicenumber(const char *pszServiceName)
8822 fstring serviceName;
8824 if (!pszServiceName) {
8825 return GLOBAL_SECTION_SNUM;
8828 for (iService = iNumServices - 1; iService >= 0; iService--) {
8829 if (VALID(iService) && ServicePtrs[iService]->szService) {
8831 * The substitution here is used to support %U is
8834 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8835 standard_sub_basic(get_current_username(),
8836 current_user_info.domain,
8837 serviceName,sizeof(serviceName));
8838 if (strequal(serviceName, pszServiceName)) {
8844 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8847 if (!usershare_exists(iService, &last_mod)) {
8848 /* Remove the share security tdb entry for it. */
8849 delete_share_security(lp_servicename(iService));
8850 /* Remove it from the array. */
8851 free_service_byindex(iService);
8852 /* Doesn't exist anymore. */
8853 return GLOBAL_SECTION_SNUM;
8856 /* Has it been modified ? If so delete and reload. */
8857 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
8858 /* Remove it from the array. */
8859 free_service_byindex(iService);
8860 /* and now reload it. */
8861 iService = load_usershare_service(pszServiceName);
8866 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
8867 return GLOBAL_SECTION_SNUM;
8873 bool share_defined(const char *service_name)
8875 return (lp_servicenumber(service_name) != -1);
8878 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
8879 const char *sharename)
8881 struct share_params *result;
8885 if (!(sname = SMB_STRDUP(sharename))) {
8889 snum = find_service(sname);
8896 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
8897 DEBUG(0, ("talloc failed\n"));
8901 result->service = snum;
8905 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
8907 struct share_iterator *result;
8909 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
8910 DEBUG(0, ("talloc failed\n"));
8914 result->next_id = 0;
8918 struct share_params *next_share(struct share_iterator *list)
8920 struct share_params *result;
8922 while (!lp_snum_ok(list->next_id) &&
8923 (list->next_id < lp_numservices())) {
8927 if (list->next_id >= lp_numservices()) {
8931 if (!(result = TALLOC_P(list, struct share_params))) {
8932 DEBUG(0, ("talloc failed\n"));
8936 result->service = list->next_id;
8941 struct share_params *next_printer(struct share_iterator *list)
8943 struct share_params *result;
8945 while ((result = next_share(list)) != NULL) {
8946 if (lp_print_ok(result->service)) {
8954 * This is a hack for a transition period until we transformed all code from
8955 * service numbers to struct share_params.
8958 struct share_params *snum2params_static(int snum)
8960 static struct share_params result;
8961 result.service = snum;
8965 /*******************************************************************
8966 A useful volume label function.
8967 ********************************************************************/
8969 const char *volume_label(int snum)
8972 const char *label = lp_volume(snum);
8974 label = lp_servicename(snum);
8977 /* This returns a 33 byte guarenteed null terminated string. */
8978 ret = talloc_strndup(talloc_tos(), label, 32);
8985 /*******************************************************************
8986 Set the server type we will announce as via nmbd.
8987 ********************************************************************/
8989 static void set_default_server_announce_type(void)
8991 default_server_announce = 0;
8992 default_server_announce |= SV_TYPE_WORKSTATION;
8993 default_server_announce |= SV_TYPE_SERVER;
8994 default_server_announce |= SV_TYPE_SERVER_UNIX;
8996 /* note that the flag should be set only if we have a
8997 printer service but nmbd doesn't actually load the
8998 services so we can't tell --jerry */
9000 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9002 switch (lp_announce_as()) {
9003 case ANNOUNCE_AS_NT_SERVER:
9004 default_server_announce |= SV_TYPE_SERVER_NT;
9005 /* fall through... */
9006 case ANNOUNCE_AS_NT_WORKSTATION:
9007 default_server_announce |= SV_TYPE_NT;
9009 case ANNOUNCE_AS_WIN95:
9010 default_server_announce |= SV_TYPE_WIN95_PLUS;
9012 case ANNOUNCE_AS_WFW:
9013 default_server_announce |= SV_TYPE_WFW;
9019 switch (lp_server_role()) {
9020 case ROLE_DOMAIN_MEMBER:
9021 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9023 case ROLE_DOMAIN_PDC:
9024 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9026 case ROLE_DOMAIN_BDC:
9027 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9029 case ROLE_STANDALONE:
9033 if (lp_time_server())
9034 default_server_announce |= SV_TYPE_TIME_SOURCE;
9036 if (lp_host_msdfs())
9037 default_server_announce |= SV_TYPE_DFS_SERVER;
9040 /***********************************************************
9041 returns role of Samba server
9042 ************************************************************/
9044 int lp_server_role(void)
9049 /***********************************************************
9050 If we are PDC then prefer us as DMB
9051 ************************************************************/
9053 bool lp_domain_master(void)
9055 if (Globals.iDomainMaster == Auto)
9056 return (lp_server_role() == ROLE_DOMAIN_PDC);
9058 return (bool)Globals.iDomainMaster;
9061 /***********************************************************
9062 If we are DMB then prefer us as LMB
9063 ************************************************************/
9065 bool lp_preferred_master(void)
9067 if (Globals.iPreferredMaster == Auto)
9068 return (lp_local_master() && lp_domain_master());
9070 return (bool)Globals.iPreferredMaster;
9073 /*******************************************************************
9075 ********************************************************************/
9077 void lp_remove_service(int snum)
9079 ServicePtrs[snum]->valid = False;
9080 invalid_services[num_invalid_services++] = snum;
9083 /*******************************************************************
9085 ********************************************************************/
9087 void lp_copy_service(int snum, const char *new_name)
9089 do_section(new_name);
9091 snum = lp_servicenumber(new_name);
9093 lp_do_parameter(snum, "copy", lp_servicename(snum));
9098 /*******************************************************************
9099 Get the default server type we will announce as via nmbd.
9100 ********************************************************************/
9102 int lp_default_server_announce(void)
9104 return default_server_announce;
9107 /*******************************************************************
9108 Split the announce version into major and minor numbers.
9109 ********************************************************************/
9111 int lp_major_announce_version(void)
9113 static bool got_major = False;
9114 static int major_version = DEFAULT_MAJOR_VERSION;
9119 return major_version;
9122 if ((vers = lp_announce_version()) == NULL)
9123 return major_version;
9125 if ((p = strchr_m(vers, '.')) == 0)
9126 return major_version;
9129 major_version = atoi(vers);
9130 return major_version;
9133 int lp_minor_announce_version(void)
9135 static bool got_minor = False;
9136 static int minor_version = DEFAULT_MINOR_VERSION;
9141 return minor_version;
9144 if ((vers = lp_announce_version()) == NULL)
9145 return minor_version;
9147 if ((p = strchr_m(vers, '.')) == 0)
9148 return minor_version;
9151 minor_version = atoi(p);
9152 return minor_version;
9155 /***********************************************************
9156 Set the global name resolution order (used in smbclient).
9157 ************************************************************/
9159 void lp_set_name_resolve_order(const char *new_order)
9161 string_set(&Globals.szNameResolveOrder, new_order);
9164 const char *lp_printername(int snum)
9166 const char *ret = _lp_printername(snum);
9167 if (ret == NULL || (ret != NULL && *ret == '\0'))
9168 ret = lp_const_servicename(snum);
9174 /***********************************************************
9175 Allow daemons such as winbindd to fix their logfile name.
9176 ************************************************************/
9178 void lp_set_logfile(const char *name)
9180 string_set(&Globals.szLogFile, name);
9181 debug_set_logfile(name);
9184 /*******************************************************************
9185 Return the max print jobs per queue.
9186 ********************************************************************/
9188 int lp_maxprintjobs(int snum)
9190 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9191 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9192 maxjobs = PRINT_MAX_JOBID - 1;
9197 const char *lp_printcapname(void)
9199 if ((Globals.szPrintcapname != NULL) &&
9200 (Globals.szPrintcapname[0] != '\0'))
9201 return Globals.szPrintcapname;
9203 if (sDefault.iPrinting == PRINT_CUPS) {
9211 if (sDefault.iPrinting == PRINT_BSD)
9212 return "/etc/printcap";
9214 return PRINTCAP_NAME;
9217 /*******************************************************************
9218 Ensure we don't use sendfile if server smb signing is active.
9219 ********************************************************************/
9221 static uint32 spoolss_state;
9223 bool lp_disable_spoolss( void )
9225 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9226 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9228 return spoolss_state == SVCCTL_STOPPED ? True : False;
9231 void lp_set_spoolss_state( uint32 state )
9233 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9235 spoolss_state = state;
9238 uint32 lp_get_spoolss_state( void )
9240 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9243 /*******************************************************************
9244 Ensure we don't use sendfile if server smb signing is active.
9245 ********************************************************************/
9247 bool lp_use_sendfile(int snum)
9249 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9250 if (Protocol < PROTOCOL_NT1) {
9253 return (_lp_use_sendfile(snum) &&
9254 (get_remote_arch() != RA_WIN95) &&
9255 !srv_is_signing_active());
9258 /*******************************************************************
9259 Turn off sendfile if we find the underlying OS doesn't support it.
9260 ********************************************************************/
9262 void set_use_sendfile(int snum, bool val)
9264 if (LP_SNUM_OK(snum))
9265 ServicePtrs[snum]->bUseSendfile = val;
9267 sDefault.bUseSendfile = val;
9270 /*******************************************************************
9271 Turn off storing DOS attributes if this share doesn't support it.
9272 ********************************************************************/
9274 void set_store_dos_attributes(int snum, bool val)
9276 if (!LP_SNUM_OK(snum))
9278 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9281 void lp_set_mangling_method(const char *new_method)
9283 string_set(&Globals.szManglingMethod, new_method);
9286 /*******************************************************************
9287 Global state for POSIX pathname processing.
9288 ********************************************************************/
9290 static bool posix_pathnames;
9292 bool lp_posix_pathnames(void)
9294 return posix_pathnames;
9297 /*******************************************************************
9298 Change everything needed to ensure POSIX pathname processing (currently
9300 ********************************************************************/
9302 void lp_set_posix_pathnames(void)
9304 posix_pathnames = True;
9307 /*******************************************************************
9308 Global state for POSIX lock processing - CIFS unix extensions.
9309 ********************************************************************/
9311 bool posix_default_lock_was_set;
9312 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9314 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9316 if (posix_default_lock_was_set) {
9317 return posix_cifsx_locktype;
9319 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9323 /*******************************************************************
9324 ********************************************************************/
9326 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9328 posix_default_lock_was_set = True;
9329 posix_cifsx_locktype = val;
9332 int lp_min_receive_file_size(void)
9334 if (Globals.iminreceivefile < 0) {
9337 return MIN(Globals.iminreceivefile, BUFFER_SIZE);