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
56 #include "lib/smbconf/smbconf.h"
57 #include "lib/smbconf/smbconf_init.h"
58 #include "lib/smbconf/smbconf_reg.h"
61 #include "../librpc/gen_ndr/svcctl.h"
63 #ifdef HAVE_SYS_SYSCTL_H
64 #include <sys/sysctl.h>
67 #ifdef HAVE_HTTPCONNECTENCRYPT
68 #include <cups/http.h>
73 extern userdom_struct current_user_info;
76 #define GLOBAL_NAME "global"
80 #define PRINTERS_NAME "printers"
84 #define HOMES_NAME "homes"
87 /* the special value for the include parameter
88 * to be interpreted not as a file name but to
89 * trigger loading of the global smb.conf options
91 #ifndef INCLUDE_REGISTRY_NAME
92 #define INCLUDE_REGISTRY_NAME "registry"
95 static bool in_client = False; /* Not in the client by default */
96 static struct smbconf_csn conf_last_csn;
98 #define CONFIG_BACKEND_FILE 0
99 #define CONFIG_BACKEND_REGISTRY 1
101 static int config_backend = CONFIG_BACKEND_FILE;
103 /* some helpful bits */
104 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
105 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
107 #define USERSHARE_VALID 1
108 #define USERSHARE_PENDING_DELETE 2
110 static bool defaults_saved = False;
112 struct param_opt_struct {
113 struct param_opt_struct *prev, *next;
120 * This structure describes global (ie., server-wide) parameters.
127 char *display_charset;
128 char *szPrintcapname;
129 char *szAddPortCommand;
130 char *szEnumPortsCommand;
131 char *szAddPrinterCommand;
132 char *szDeletePrinterCommand;
133 char *szOs2DriverMap;
139 char *szDefaultService;
143 char *szServerString;
144 char *szAutoServices;
145 char *szPasswdProgram;
149 char *szSMBPasswdFile;
151 char *szPassdbBackend;
152 char **szPreloadModules;
153 char *szPasswordServer;
154 char *szSocketOptions;
156 char *szAfsUsernameMap;
157 int iAfsTokenLifetime;
158 char *szLogNtTokenCommand;
164 char **szWINSservers;
166 char *szRemoteAnnounce;
167 char *szRemoteBrowseSync;
168 char *szSocketAddress;
169 bool bNmbdBindExplicitBroadcast;
170 char *szNISHomeMapName;
171 char *szAnnounceVersion; /* This is initialised in init_globals */
174 char **szNetbiosAliases;
175 char *szNetbiosScope;
176 char *szNameResolveOrder;
178 char *szAddUserScript;
179 char *szRenameUserScript;
180 char *szDelUserScript;
181 char *szAddGroupScript;
182 char *szDelGroupScript;
183 char *szAddUserToGroupScript;
184 char *szDelUserFromGroupScript;
185 char *szSetPrimaryGroupScript;
186 char *szAddMachineScript;
187 char *szShutdownScript;
188 char *szAbortShutdownScript;
189 char *szUsernameMapScript;
190 int iUsernameMapCacheTime;
191 char *szCheckPasswordScript;
198 bool bPassdbExpandExplicit;
199 int AlgorithmicRidBase;
200 char *szTemplateHomedir;
201 char *szTemplateShell;
202 char *szWinbindSeparator;
203 bool bWinbindEnumUsers;
204 bool bWinbindEnumGroups;
205 bool bWinbindUseDefaultDomain;
206 bool bWinbindTrustedDomainsOnly;
207 bool bWinbindNestedGroups;
208 int winbind_expand_groups;
209 bool bWinbindRefreshTickets;
210 bool bWinbindOfflineLogon;
211 bool bWinbindNormalizeNames;
212 bool bWinbindRpcOnly;
213 bool bCreateKrb5Conf;
214 char *szIdmapBackend;
216 char *szAddShareCommand;
217 char *szChangeShareCommand;
218 char *szDeleteShareCommand;
220 char *szGuestaccount;
221 char *szManglingMethod;
222 char **szServicesList;
223 char *szUsersharePath;
224 char *szUsershareTemplateShare;
225 char **szUsersharePrefixAllowList;
226 char **szUsersharePrefixDenyList;
233 int open_files_db_hash_size;
242 bool paranoid_server_security;
245 int iMaxSmbdProcesses;
246 bool bDisableSpoolss;
249 bool enhanced_browsing;
255 int announce_as; /* This is initialised in init_globals */
256 int machine_password_timeout;
258 int oplock_break_wait_time;
259 int winbind_cache_time;
260 int winbind_reconnect_delay;
261 int winbind_max_idle_children;
262 char **szWinbindNssInfo;
264 char *szLdapMachineSuffix;
265 char *szLdapUserSuffix;
266 char *szLdapIdmapSuffix;
267 char *szLdapGroupSuffix;
271 int ldap_follow_referral;
274 int ldap_debug_level;
275 int ldap_debug_threshold;
279 char *szIPrintServer;
281 char **szClusterAddresses;
284 int ctdb_locktime_warn_threshold;
285 int ldap_passwd_sync;
286 int ldap_replication_sleep;
287 int ldap_timeout; /* This is initialised in init_globals */
288 int ldap_connection_timeout;
291 bool bMsAddPrinterWizard;
296 int iPreferredMaster;
299 char **szInitLogonDelayedHosts;
301 bool bEncryptPasswords;
306 bool bObeyPamRestrictions;
308 int PrintcapCacheTime;
309 bool bLargeReadwrite;
316 bool bBindInterfacesOnly;
317 bool bPamPasswordChange;
318 bool bUnixPasswdSync;
319 bool bPasswdChatDebug;
320 int iPasswdChatTimeout;
324 bool bNTStatusSupport;
326 int iMaxStatCacheSize;
328 bool bAllowTrustedDomains;
332 bool bClientLanManAuth;
333 bool bClientNTLMv2Auth;
334 bool bClientPlaintextAuth;
335 bool bClientUseSpnego;
336 bool bDebugPrefixTimestamp;
337 bool bDebugHiresTimestamp;
341 bool bEnableCoreFiles;
344 bool bHostnameLookups;
345 bool bUnixExtensions;
346 bool bDisableNetbios;
347 char * szDedicatedKeytabFile;
349 bool bDeferSharingViolations;
350 bool bEnablePrivileges;
352 bool bUsershareOwnerOnly;
353 bool bUsershareAllowGuests;
354 bool bRegistryShares;
355 int restrict_anonymous;
356 int name_cache_timeout;
359 int client_ldap_sasl_wrapping;
360 int iUsershareMaxShares;
362 int iIdmapNegativeCacheTime;
364 bool bLogWriteableFilesOnExit;
367 struct param_opt_struct *param_opt;
368 int cups_connection_timeout;
369 char *szSMBPerfcountModule;
370 bool bMapUntrustedToDomain;
371 bool bAsyncSMBEchoHandler;
377 static struct global Globals;
380 * This structure describes a single service.
386 struct timespec usershare_last_mod;
390 char **szInvalidUsers;
398 char *szRootPostExec;
400 char *szPrintcommand;
403 char *szLppausecommand;
404 char *szLpresumecommand;
405 char *szQueuepausecommand;
406 char *szQueueresumecommand;
408 char *szPrintjobUsername;
416 char *szVetoOplockFiles;
422 char **printer_admin;
427 char *szAioWriteBehind;
431 int iMaxReportedPrintJobs;
434 int iCreate_force_mode;
436 int iSecurity_force_mode;
439 int iDir_Security_mask;
440 int iDir_Security_force_mode;
444 int iOplockContentionLimit;
449 bool bRootpreexecClose;
452 bool bShortCasePreserve;
454 bool bHideSpecialFiles;
455 bool bHideUnReadable;
456 bool bHideUnWriteableFiles;
458 bool bAccessBasedShareEnum;
463 bool bAdministrative_share;
469 bool bStoreDosAttributes;
482 bool bStrictAllocate;
485 struct bitmap *copymap;
486 bool bDeleteReadonly;
488 bool bDeleteVetoFiles;
491 bool bDosFiletimeResolution;
492 bool bFakeDirCreateTimes;
498 bool bUseClientDriver;
499 bool bDefaultDevmode;
500 bool bForcePrintername;
502 bool bForceUnknownAclUser;
505 bool bMap_acl_inherit;
508 bool bAclCheckPermissions;
509 bool bAclMapFullControl;
510 bool bAclGroupControl;
512 bool bKernelChangeNotify;
513 int iallocation_roundup_size;
517 int iDirectoryNameCacheSize;
519 struct param_opt_struct *param_opt;
521 char dummy[3]; /* for alignment */
525 /* This is a default service used to prime a services structure */
526 static struct service sDefault = {
528 False, /* not autoloaded */
529 0, /* not a usershare */
530 {0, }, /* No last mod time */
531 NULL, /* szService */
533 NULL, /* szUsername */
534 NULL, /* szInvalidUsers */
535 NULL, /* szValidUsers */
536 NULL, /* szAdminUsers */
538 NULL, /* szInclude */
539 NULL, /* szPreExec */
540 NULL, /* szPostExec */
541 NULL, /* szRootPreExec */
542 NULL, /* szRootPostExec */
543 NULL, /* szCupsOptions */
544 NULL, /* szPrintcommand */
545 NULL, /* szLpqcommand */
546 NULL, /* szLprmcommand */
547 NULL, /* szLppausecommand */
548 NULL, /* szLpresumecommand */
549 NULL, /* szQueuepausecommand */
550 NULL, /* szQueueresumecommand */
551 NULL, /* szPrintername */
552 NULL, /* szPrintjobUsername */
553 NULL, /* szDontdescend */
554 NULL, /* szHostsallow */
555 NULL, /* szHostsdeny */
556 NULL, /* szMagicScript */
557 NULL, /* szMagicOutput */
558 NULL, /* szVetoFiles */
559 NULL, /* szHideFiles */
560 NULL, /* szVetoOplockFiles */
562 NULL, /* force user */
563 NULL, /* force group */
565 NULL, /* writelist */
566 NULL, /* printer admin */
569 NULL, /* vfs objects */
570 NULL, /* szMSDfsProxy */
571 NULL, /* szAioWriteBehind */
573 0, /* iMinPrintSpace */
574 1000, /* iMaxPrintJobs */
575 0, /* iMaxReportedPrintJobs */
576 0, /* iWriteCacheSize */
577 0744, /* iCreate_mask */
578 0000, /* iCreate_force_mode */
579 0777, /* iSecurity_mask */
580 0, /* iSecurity_force_mode */
581 0755, /* iDir_mask */
582 0000, /* iDir_force_mode */
583 0777, /* iDir_Security_mask */
584 0, /* iDir_Security_force_mode */
585 0, /* iMaxConnections */
586 CASE_LOWER, /* iDefaultCase */
587 DEFAULT_PRINTING, /* iPrinting */
588 2, /* iOplockContentionLimit */
590 1024, /* iBlock_size */
591 0, /* iDfreeCacheTime */
592 False, /* bPreexecClose */
593 False, /* bRootpreexecClose */
594 Auto, /* case sensitive */
595 True, /* case preserve */
596 True, /* short case preserve */
597 True, /* bHideDotFiles */
598 False, /* bHideSpecialFiles */
599 False, /* bHideUnReadable */
600 False, /* bHideUnWriteableFiles */
601 True, /* bBrowseable */
602 False, /* bAccessBasedShareEnum */
603 True, /* bAvailable */
604 True, /* bRead_only */
605 True, /* bNo_set_dir */
606 False, /* bGuest_only */
607 False, /* bAdministrative_share */
608 False, /* bGuest_ok */
609 False, /* bPrint_ok */
610 False, /* bMap_system */
611 False, /* bMap_hidden */
612 True, /* bMap_archive */
613 False, /* bStoreDosAttributes */
614 False, /* bDmapiSupport */
616 Auto, /* iStrictLocking */
617 True, /* bPosixLocking */
618 True, /* bShareModes */
620 True, /* bLevel2OpLocks */
621 False, /* bOnlyUser */
622 True, /* bMangledNames */
623 false, /* bWidelinks */
624 True, /* bSymlinks */
625 False, /* bSyncAlways */
626 False, /* bStrictAllocate */
627 False, /* bStrictSync */
628 '~', /* magic char */
630 False, /* bDeleteReadonly */
631 False, /* bFakeOplocks */
632 False, /* bDeleteVetoFiles */
633 False, /* bDosFilemode */
634 True, /* bDosFiletimes */
635 False, /* bDosFiletimeResolution */
636 False, /* bFakeDirCreateTimes */
637 True, /* bBlockingLocks */
638 False, /* bInheritPerms */
639 False, /* bInheritACLS */
640 False, /* bInheritOwner */
641 False, /* bMSDfsRoot */
642 False, /* bUseClientDriver */
643 True, /* bDefaultDevmode */
644 False, /* bForcePrintername */
645 True, /* bNTAclSupport */
646 False, /* bForceUnknownAclUser */
647 False, /* bUseSendfile */
648 False, /* bProfileAcls */
649 False, /* bMap_acl_inherit */
650 False, /* bAfs_Share */
651 False, /* bEASupport */
652 True, /* bAclCheckPermissions */
653 True, /* bAclMapFullControl */
654 False, /* bAclGroupControl */
655 True, /* bChangeNotify */
656 True, /* bKernelChangeNotify */
657 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
658 0, /* iAioReadSize */
659 0, /* iAioWriteSize */
660 MAP_READONLY_YES, /* iMap_readonly */
661 #ifdef BROKEN_DIRECTORY_HANDLING
662 0, /* iDirectoryNameCacheSize */
664 100, /* iDirectoryNameCacheSize */
666 Auto, /* ismb_encrypt */
667 NULL, /* Parametric options */
672 /* local variables */
673 static struct service **ServicePtrs = NULL;
674 static int iNumServices = 0;
675 static int iServiceIndex = 0;
676 static struct db_context *ServiceHash;
677 static int *invalid_services = NULL;
678 static int num_invalid_services = 0;
679 static bool bInGlobalSection = True;
680 static bool bGlobalOnly = False;
681 static int default_server_announce;
683 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
685 /* prototypes for the special type handlers */
686 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
687 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
688 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
689 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
690 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
691 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
692 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
693 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
694 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
695 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
696 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
697 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
699 static void set_default_server_announce_type(void);
700 static void set_allowed_client_auth(void);
702 static void *lp_local_ptr(struct service *service, void *ptr);
704 static void add_to_file_list(const char *fname, const char *subfname);
706 static const struct enum_list enum_protocol[] = {
707 {PROTOCOL_SMB2, "SMB2"},
708 {PROTOCOL_NT1, "NT1"},
709 {PROTOCOL_LANMAN2, "LANMAN2"},
710 {PROTOCOL_LANMAN1, "LANMAN1"},
711 {PROTOCOL_CORE, "CORE"},
712 {PROTOCOL_COREPLUS, "COREPLUS"},
713 {PROTOCOL_COREPLUS, "CORE+"},
717 static const struct enum_list enum_security[] = {
718 {SEC_SHARE, "SHARE"},
720 {SEC_SERVER, "SERVER"},
721 {SEC_DOMAIN, "DOMAIN"},
728 static const struct enum_list enum_printing[] = {
729 {PRINT_SYSV, "sysv"},
731 {PRINT_HPUX, "hpux"},
735 {PRINT_LPRNG, "lprng"},
736 {PRINT_CUPS, "cups"},
737 {PRINT_IPRINT, "iprint"},
739 {PRINT_LPROS2, "os2"},
741 {PRINT_TEST, "test"},
743 #endif /* DEVELOPER */
747 static const struct enum_list enum_ldap_sasl_wrapping[] = {
749 {ADS_AUTH_SASL_SIGN, "sign"},
750 {ADS_AUTH_SASL_SEAL, "seal"},
754 static const struct enum_list enum_ldap_ssl[] = {
755 {LDAP_SSL_OFF, "no"},
756 {LDAP_SSL_OFF, "off"},
757 {LDAP_SSL_START_TLS, "start tls"},
758 {LDAP_SSL_START_TLS, "start_tls"},
762 /* LDAP Dereferencing Alias types */
763 #define SAMBA_LDAP_DEREF_NEVER 0
764 #define SAMBA_LDAP_DEREF_SEARCHING 1
765 #define SAMBA_LDAP_DEREF_FINDING 2
766 #define SAMBA_LDAP_DEREF_ALWAYS 3
768 static const struct enum_list enum_ldap_deref[] = {
769 {SAMBA_LDAP_DEREF_NEVER, "never"},
770 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
771 {SAMBA_LDAP_DEREF_FINDING, "finding"},
772 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
776 static const struct enum_list enum_ldap_passwd_sync[] = {
777 {LDAP_PASSWD_SYNC_OFF, "no"},
778 {LDAP_PASSWD_SYNC_OFF, "off"},
779 {LDAP_PASSWD_SYNC_ON, "yes"},
780 {LDAP_PASSWD_SYNC_ON, "on"},
781 {LDAP_PASSWD_SYNC_ONLY, "only"},
785 /* Types of machine we can announce as. */
786 #define ANNOUNCE_AS_NT_SERVER 1
787 #define ANNOUNCE_AS_WIN95 2
788 #define ANNOUNCE_AS_WFW 3
789 #define ANNOUNCE_AS_NT_WORKSTATION 4
791 static const struct enum_list enum_announce_as[] = {
792 {ANNOUNCE_AS_NT_SERVER, "NT"},
793 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
794 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
795 {ANNOUNCE_AS_WIN95, "win95"},
796 {ANNOUNCE_AS_WFW, "WfW"},
800 static const struct enum_list enum_map_readonly[] = {
801 {MAP_READONLY_NO, "no"},
802 {MAP_READONLY_NO, "false"},
803 {MAP_READONLY_NO, "0"},
804 {MAP_READONLY_YES, "yes"},
805 {MAP_READONLY_YES, "true"},
806 {MAP_READONLY_YES, "1"},
807 {MAP_READONLY_PERMISSIONS, "permissions"},
808 {MAP_READONLY_PERMISSIONS, "perms"},
812 static const struct enum_list enum_case[] = {
813 {CASE_LOWER, "lower"},
814 {CASE_UPPER, "upper"},
820 static const struct enum_list enum_bool_auto[] = {
831 static const struct enum_list enum_csc_policy[] = {
832 {CSC_POLICY_MANUAL, "manual"},
833 {CSC_POLICY_DOCUMENTS, "documents"},
834 {CSC_POLICY_PROGRAMS, "programs"},
835 {CSC_POLICY_DISABLE, "disable"},
839 /* SMB signing types. */
840 static const struct enum_list enum_smb_signing_vals[] = {
852 {Required, "required"},
853 {Required, "mandatory"},
855 {Required, "forced"},
856 {Required, "enforced"},
860 /* ACL compatibility options. */
861 static const struct enum_list enum_acl_compat_vals[] = {
862 { ACL_COMPAT_AUTO, "auto" },
863 { ACL_COMPAT_WINNT, "winnt" },
864 { ACL_COMPAT_WIN2K, "win2k" },
869 Do you want session setups at user level security with a invalid
870 password to be rejected or allowed in as guest? WinNT rejects them
871 but it can be a pain as it means "net view" needs to use a password
873 You have 3 choices in the setting of map_to_guest:
875 "Never" means session setups with an invalid password
876 are rejected. This is the default.
878 "Bad User" means session setups with an invalid password
879 are rejected, unless the username does not exist, in which case it
880 is treated as a guest login
882 "Bad Password" means session setups with an invalid password
883 are treated as a guest login
885 Note that map_to_guest only has an effect in user or server
889 static const struct enum_list enum_map_to_guest[] = {
890 {NEVER_MAP_TO_GUEST, "Never"},
891 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
892 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
893 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
897 /* Config backend options */
899 static const struct enum_list enum_config_backend[] = {
900 {CONFIG_BACKEND_FILE, "file"},
901 {CONFIG_BACKEND_REGISTRY, "registry"},
905 /* ADS kerberos ticket verification options */
907 static const struct enum_list enum_kerberos_method[] = {
908 {KERBEROS_VERIFY_SECRETS, "default"},
909 {KERBEROS_VERIFY_SECRETS, "secrets only"},
910 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
911 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
912 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
916 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
918 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
919 * screen in SWAT. This is used to exclude parameters as well as to squash all
920 * parameters that have been duplicated by pseudonyms.
922 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
923 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
924 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
927 * NOTE2: Handling of duplicated (synonym) parameters:
928 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
929 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
930 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
931 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
934 static struct parm_struct parm_table[] = {
935 {N_("Base Options"), P_SEP, P_SEPARATOR},
938 .label = "dos charset",
941 .ptr = &Globals.dos_charset,
942 .special = handle_charset,
944 .flags = FLAG_ADVANCED
947 .label = "unix charset",
950 .ptr = &Globals.unix_charset,
951 .special = handle_charset,
953 .flags = FLAG_ADVANCED
956 .label = "display charset",
959 .ptr = &Globals.display_charset,
960 .special = handle_charset,
962 .flags = FLAG_ADVANCED
968 .ptr = &sDefault.comment,
971 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
977 .ptr = &sDefault.szPath,
980 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
983 .label = "directory",
986 .ptr = &sDefault.szPath,
992 .label = "workgroup",
995 .ptr = &Globals.szWorkgroup,
996 .special = handle_workgroup,
998 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1004 .p_class = P_GLOBAL,
1005 .ptr = &Globals.szRealm,
1008 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1012 .label = "netbios name",
1014 .p_class = P_GLOBAL,
1015 .ptr = &Globals.szNetbiosName,
1016 .special = handle_netbios_name,
1018 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1021 .label = "netbios aliases",
1023 .p_class = P_GLOBAL,
1024 .ptr = &Globals.szNetbiosAliases,
1025 .special = handle_netbios_aliases,
1027 .flags = FLAG_ADVANCED,
1030 .label = "netbios scope",
1032 .p_class = P_GLOBAL,
1033 .ptr = &Globals.szNetbiosScope,
1034 .special = handle_netbios_scope,
1036 .flags = FLAG_ADVANCED,
1039 .label = "server string",
1041 .p_class = P_GLOBAL,
1042 .ptr = &Globals.szServerString,
1045 .flags = FLAG_BASIC | FLAG_ADVANCED,
1048 .label = "interfaces",
1050 .p_class = P_GLOBAL,
1051 .ptr = &Globals.szInterfaces,
1054 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1057 .label = "bind interfaces only",
1059 .p_class = P_GLOBAL,
1060 .ptr = &Globals.bBindInterfacesOnly,
1063 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1066 .label = "config backend",
1068 .p_class = P_GLOBAL,
1069 .ptr = &Globals.ConfigBackend,
1071 .enum_list = enum_config_backend,
1072 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1075 {N_("Security Options"), P_SEP, P_SEPARATOR},
1078 .label = "security",
1080 .p_class = P_GLOBAL,
1081 .ptr = &Globals.security,
1083 .enum_list = enum_security,
1084 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1087 .label = "auth methods",
1089 .p_class = P_GLOBAL,
1090 .ptr = &Globals.AuthMethods,
1093 .flags = FLAG_ADVANCED,
1096 .label = "encrypt passwords",
1098 .p_class = P_GLOBAL,
1099 .ptr = &Globals.bEncryptPasswords,
1102 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1105 .label = "client schannel",
1107 .p_class = P_GLOBAL,
1108 .ptr = &Globals.clientSchannel,
1110 .enum_list = enum_bool_auto,
1111 .flags = FLAG_BASIC | FLAG_ADVANCED,
1114 .label = "server schannel",
1116 .p_class = P_GLOBAL,
1117 .ptr = &Globals.serverSchannel,
1119 .enum_list = enum_bool_auto,
1120 .flags = FLAG_BASIC | FLAG_ADVANCED,
1123 .label = "allow trusted domains",
1125 .p_class = P_GLOBAL,
1126 .ptr = &Globals.bAllowTrustedDomains,
1129 .flags = FLAG_ADVANCED,
1132 .label = "map to guest",
1134 .p_class = P_GLOBAL,
1135 .ptr = &Globals.map_to_guest,
1137 .enum_list = enum_map_to_guest,
1138 .flags = FLAG_ADVANCED,
1141 .label = "null passwords",
1143 .p_class = P_GLOBAL,
1144 .ptr = &Globals.bNullPasswords,
1147 .flags = FLAG_ADVANCED,
1150 .label = "obey pam restrictions",
1152 .p_class = P_GLOBAL,
1153 .ptr = &Globals.bObeyPamRestrictions,
1156 .flags = FLAG_ADVANCED,
1159 .label = "password server",
1161 .p_class = P_GLOBAL,
1162 .ptr = &Globals.szPasswordServer,
1165 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1168 .label = "smb passwd file",
1170 .p_class = P_GLOBAL,
1171 .ptr = &Globals.szSMBPasswdFile,
1174 .flags = FLAG_ADVANCED,
1177 .label = "private dir",
1179 .p_class = P_GLOBAL,
1180 .ptr = &Globals.szPrivateDir,
1183 .flags = FLAG_ADVANCED,
1186 .label = "passdb backend",
1188 .p_class = P_GLOBAL,
1189 .ptr = &Globals.szPassdbBackend,
1192 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1195 .label = "algorithmic rid base",
1197 .p_class = P_GLOBAL,
1198 .ptr = &Globals.AlgorithmicRidBase,
1201 .flags = FLAG_ADVANCED,
1204 .label = "root directory",
1206 .p_class = P_GLOBAL,
1207 .ptr = &Globals.szRootdir,
1210 .flags = FLAG_ADVANCED,
1213 .label = "root dir",
1215 .p_class = P_GLOBAL,
1216 .ptr = &Globals.szRootdir,
1224 .p_class = P_GLOBAL,
1225 .ptr = &Globals.szRootdir,
1231 .label = "guest account",
1233 .p_class = P_GLOBAL,
1234 .ptr = &Globals.szGuestaccount,
1237 .flags = FLAG_BASIC | FLAG_ADVANCED,
1240 .label = "enable privileges",
1242 .p_class = P_GLOBAL,
1243 .ptr = &Globals.bEnablePrivileges,
1246 .flags = FLAG_ADVANCED,
1250 .label = "pam password change",
1252 .p_class = P_GLOBAL,
1253 .ptr = &Globals.bPamPasswordChange,
1256 .flags = FLAG_ADVANCED,
1259 .label = "passwd program",
1261 .p_class = P_GLOBAL,
1262 .ptr = &Globals.szPasswdProgram,
1265 .flags = FLAG_ADVANCED,
1268 .label = "passwd chat",
1270 .p_class = P_GLOBAL,
1271 .ptr = &Globals.szPasswdChat,
1274 .flags = FLAG_ADVANCED,
1277 .label = "passwd chat debug",
1279 .p_class = P_GLOBAL,
1280 .ptr = &Globals.bPasswdChatDebug,
1283 .flags = FLAG_ADVANCED,
1286 .label = "passwd chat timeout",
1288 .p_class = P_GLOBAL,
1289 .ptr = &Globals.iPasswdChatTimeout,
1292 .flags = FLAG_ADVANCED,
1295 .label = "check password script",
1297 .p_class = P_GLOBAL,
1298 .ptr = &Globals.szCheckPasswordScript,
1301 .flags = FLAG_ADVANCED,
1304 .label = "username map",
1306 .p_class = P_GLOBAL,
1307 .ptr = &Globals.szUsernameMap,
1310 .flags = FLAG_ADVANCED,
1313 .label = "password level",
1315 .p_class = P_GLOBAL,
1316 .ptr = &Globals.pwordlevel,
1319 .flags = FLAG_ADVANCED,
1322 .label = "username level",
1324 .p_class = P_GLOBAL,
1325 .ptr = &Globals.unamelevel,
1328 .flags = FLAG_ADVANCED,
1331 .label = "unix password sync",
1333 .p_class = P_GLOBAL,
1334 .ptr = &Globals.bUnixPasswdSync,
1337 .flags = FLAG_ADVANCED,
1340 .label = "restrict anonymous",
1342 .p_class = P_GLOBAL,
1343 .ptr = &Globals.restrict_anonymous,
1346 .flags = FLAG_ADVANCED,
1349 .label = "lanman auth",
1351 .p_class = P_GLOBAL,
1352 .ptr = &Globals.bLanmanAuth,
1355 .flags = FLAG_ADVANCED,
1358 .label = "ntlm auth",
1360 .p_class = P_GLOBAL,
1361 .ptr = &Globals.bNTLMAuth,
1364 .flags = FLAG_ADVANCED,
1367 .label = "client NTLMv2 auth",
1369 .p_class = P_GLOBAL,
1370 .ptr = &Globals.bClientNTLMv2Auth,
1373 .flags = FLAG_ADVANCED,
1376 .label = "client lanman auth",
1378 .p_class = P_GLOBAL,
1379 .ptr = &Globals.bClientLanManAuth,
1382 .flags = FLAG_ADVANCED,
1385 .label = "client plaintext auth",
1387 .p_class = P_GLOBAL,
1388 .ptr = &Globals.bClientPlaintextAuth,
1391 .flags = FLAG_ADVANCED,
1394 .label = "username",
1397 .ptr = &sDefault.szUsername,
1400 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1406 .ptr = &sDefault.szUsername,
1415 .ptr = &sDefault.szUsername,
1421 .label = "invalid users",
1424 .ptr = &sDefault.szInvalidUsers,
1427 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1430 .label = "valid users",
1433 .ptr = &sDefault.szValidUsers,
1436 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1439 .label = "admin users",
1442 .ptr = &sDefault.szAdminUsers,
1445 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1448 .label = "read list",
1451 .ptr = &sDefault.readlist,
1454 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1457 .label = "write list",
1460 .ptr = &sDefault.writelist,
1463 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1466 .label = "printer admin",
1469 .ptr = &sDefault.printer_admin,
1472 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1475 .label = "force user",
1478 .ptr = &sDefault.force_user,
1481 .flags = FLAG_ADVANCED | FLAG_SHARE,
1484 .label = "force group",
1487 .ptr = &sDefault.force_group,
1490 .flags = FLAG_ADVANCED | FLAG_SHARE,
1496 .ptr = &sDefault.force_group,
1499 .flags = FLAG_ADVANCED,
1502 .label = "read only",
1505 .ptr = &sDefault.bRead_only,
1508 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1511 .label = "write ok",
1514 .ptr = &sDefault.bRead_only,
1520 .label = "writeable",
1523 .ptr = &sDefault.bRead_only,
1529 .label = "writable",
1532 .ptr = &sDefault.bRead_only,
1538 .label = "acl check permissions",
1541 .ptr = &sDefault.bAclCheckPermissions,
1544 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1547 .label = "acl group control",
1550 .ptr = &sDefault.bAclGroupControl,
1553 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1556 .label = "acl map full control",
1559 .ptr = &sDefault.bAclMapFullControl,
1562 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1565 .label = "create mask",
1568 .ptr = &sDefault.iCreate_mask,
1571 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1574 .label = "create mode",
1577 .ptr = &sDefault.iCreate_mask,
1583 .label = "force create mode",
1586 .ptr = &sDefault.iCreate_force_mode,
1589 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1592 .label = "security mask",
1595 .ptr = &sDefault.iSecurity_mask,
1598 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1601 .label = "force security mode",
1604 .ptr = &sDefault.iSecurity_force_mode,
1607 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1610 .label = "directory mask",
1613 .ptr = &sDefault.iDir_mask,
1616 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1619 .label = "directory mode",
1622 .ptr = &sDefault.iDir_mask,
1625 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1628 .label = "force directory mode",
1631 .ptr = &sDefault.iDir_force_mode,
1634 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1637 .label = "directory security mask",
1640 .ptr = &sDefault.iDir_Security_mask,
1643 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1646 .label = "force directory security mode",
1649 .ptr = &sDefault.iDir_Security_force_mode,
1652 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1655 .label = "force unknown acl user",
1658 .ptr = &sDefault.bForceUnknownAclUser,
1661 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1664 .label = "inherit permissions",
1667 .ptr = &sDefault.bInheritPerms,
1670 .flags = FLAG_ADVANCED | FLAG_SHARE,
1673 .label = "inherit acls",
1676 .ptr = &sDefault.bInheritACLS,
1679 .flags = FLAG_ADVANCED | FLAG_SHARE,
1682 .label = "inherit owner",
1685 .ptr = &sDefault.bInheritOwner,
1688 .flags = FLAG_ADVANCED | FLAG_SHARE,
1691 .label = "guest only",
1694 .ptr = &sDefault.bGuest_only,
1697 .flags = FLAG_ADVANCED | FLAG_SHARE,
1700 .label = "only guest",
1703 .ptr = &sDefault.bGuest_only,
1709 .label = "administrative share",
1712 .ptr = &sDefault.bAdministrative_share,
1715 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1719 .label = "guest ok",
1722 .ptr = &sDefault.bGuest_ok,
1725 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1731 .ptr = &sDefault.bGuest_ok,
1737 .label = "only user",
1740 .ptr = &sDefault.bOnlyUser,
1743 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1746 .label = "hosts allow",
1749 .ptr = &sDefault.szHostsallow,
1752 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1755 .label = "allow hosts",
1758 .ptr = &sDefault.szHostsallow,
1764 .label = "hosts deny",
1767 .ptr = &sDefault.szHostsdeny,
1770 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1773 .label = "deny hosts",
1776 .ptr = &sDefault.szHostsdeny,
1782 .label = "preload modules",
1784 .p_class = P_GLOBAL,
1785 .ptr = &Globals.szPreloadModules,
1788 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1791 .label = "dedicated keytab file",
1793 .p_class = P_GLOBAL,
1794 .ptr = &Globals.szDedicatedKeytabFile,
1797 .flags = FLAG_ADVANCED,
1800 .label = "kerberos method",
1802 .p_class = P_GLOBAL,
1803 .ptr = &Globals.iKerberosMethod,
1805 .enum_list = enum_kerberos_method,
1806 .flags = FLAG_ADVANCED,
1809 .label = "map untrusted to domain",
1811 .p_class = P_GLOBAL,
1812 .ptr = &Globals.bMapUntrustedToDomain,
1815 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1819 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1822 .label = "log level",
1824 .p_class = P_GLOBAL,
1825 .ptr = &Globals.szLogLevel,
1826 .special = handle_debug_list,
1828 .flags = FLAG_ADVANCED,
1831 .label = "debuglevel",
1833 .p_class = P_GLOBAL,
1834 .ptr = &Globals.szLogLevel,
1835 .special = handle_debug_list,
1842 .p_class = P_GLOBAL,
1843 .ptr = &Globals.syslog,
1846 .flags = FLAG_ADVANCED,
1849 .label = "syslog only",
1851 .p_class = P_GLOBAL,
1852 .ptr = &Globals.bSyslogOnly,
1855 .flags = FLAG_ADVANCED,
1858 .label = "log file",
1860 .p_class = P_GLOBAL,
1861 .ptr = &Globals.szLogFile,
1864 .flags = FLAG_ADVANCED,
1867 .label = "max log size",
1869 .p_class = P_GLOBAL,
1870 .ptr = &Globals.max_log_size,
1873 .flags = FLAG_ADVANCED,
1876 .label = "debug timestamp",
1878 .p_class = P_GLOBAL,
1879 .ptr = &Globals.bTimestampLogs,
1882 .flags = FLAG_ADVANCED,
1885 .label = "timestamp logs",
1887 .p_class = P_GLOBAL,
1888 .ptr = &Globals.bTimestampLogs,
1891 .flags = FLAG_ADVANCED,
1894 .label = "debug prefix timestamp",
1896 .p_class = P_GLOBAL,
1897 .ptr = &Globals.bDebugPrefixTimestamp,
1900 .flags = FLAG_ADVANCED,
1903 .label = "debug hires timestamp",
1905 .p_class = P_GLOBAL,
1906 .ptr = &Globals.bDebugHiresTimestamp,
1909 .flags = FLAG_ADVANCED,
1912 .label = "debug pid",
1914 .p_class = P_GLOBAL,
1915 .ptr = &Globals.bDebugPid,
1918 .flags = FLAG_ADVANCED,
1921 .label = "debug uid",
1923 .p_class = P_GLOBAL,
1924 .ptr = &Globals.bDebugUid,
1927 .flags = FLAG_ADVANCED,
1930 .label = "debug class",
1932 .p_class = P_GLOBAL,
1933 .ptr = &Globals.bDebugClass,
1936 .flags = FLAG_ADVANCED,
1939 .label = "enable core files",
1941 .p_class = P_GLOBAL,
1942 .ptr = &Globals.bEnableCoreFiles,
1945 .flags = FLAG_ADVANCED,
1948 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1951 .label = "allocation roundup size",
1954 .ptr = &sDefault.iallocation_roundup_size,
1957 .flags = FLAG_ADVANCED,
1960 .label = "aio read size",
1963 .ptr = &sDefault.iAioReadSize,
1966 .flags = FLAG_ADVANCED,
1969 .label = "aio write size",
1972 .ptr = &sDefault.iAioWriteSize,
1975 .flags = FLAG_ADVANCED,
1978 .label = "aio write behind",
1981 .ptr = &sDefault.szAioWriteBehind,
1984 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1987 .label = "smb ports",
1989 .p_class = P_GLOBAL,
1990 .ptr = &Globals.smb_ports,
1993 .flags = FLAG_ADVANCED,
1996 .label = "large readwrite",
1998 .p_class = P_GLOBAL,
1999 .ptr = &Globals.bLargeReadwrite,
2002 .flags = FLAG_ADVANCED,
2005 .label = "max protocol",
2007 .p_class = P_GLOBAL,
2008 .ptr = &Globals.maxprotocol,
2010 .enum_list = enum_protocol,
2011 .flags = FLAG_ADVANCED,
2014 .label = "protocol",
2016 .p_class = P_GLOBAL,
2017 .ptr = &Globals.maxprotocol,
2019 .enum_list = enum_protocol,
2020 .flags = FLAG_ADVANCED,
2023 .label = "min protocol",
2025 .p_class = P_GLOBAL,
2026 .ptr = &Globals.minprotocol,
2028 .enum_list = enum_protocol,
2029 .flags = FLAG_ADVANCED,
2032 .label = "min receivefile size",
2034 .p_class = P_GLOBAL,
2035 .ptr = &Globals.iminreceivefile,
2038 .flags = FLAG_ADVANCED,
2041 .label = "read raw",
2043 .p_class = P_GLOBAL,
2044 .ptr = &Globals.bReadRaw,
2047 .flags = FLAG_ADVANCED,
2050 .label = "write raw",
2052 .p_class = P_GLOBAL,
2053 .ptr = &Globals.bWriteRaw,
2056 .flags = FLAG_ADVANCED,
2059 .label = "disable netbios",
2061 .p_class = P_GLOBAL,
2062 .ptr = &Globals.bDisableNetbios,
2065 .flags = FLAG_ADVANCED,
2068 .label = "reset on zero vc",
2070 .p_class = P_GLOBAL,
2071 .ptr = &Globals.bResetOnZeroVC,
2074 .flags = FLAG_ADVANCED,
2077 .label = "log writeable files on exit",
2079 .p_class = P_GLOBAL,
2080 .ptr = &Globals.bLogWriteableFilesOnExit,
2083 .flags = FLAG_ADVANCED,
2086 .label = "acl compatibility",
2088 .p_class = P_GLOBAL,
2089 .ptr = &Globals.iAclCompat,
2091 .enum_list = enum_acl_compat_vals,
2092 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2095 .label = "defer sharing violations",
2097 .p_class = P_GLOBAL,
2098 .ptr = &Globals.bDeferSharingViolations,
2101 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2104 .label = "ea support",
2107 .ptr = &sDefault.bEASupport,
2110 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2113 .label = "nt acl support",
2116 .ptr = &sDefault.bNTAclSupport,
2119 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2122 .label = "nt pipe support",
2124 .p_class = P_GLOBAL,
2125 .ptr = &Globals.bNTPipeSupport,
2128 .flags = FLAG_ADVANCED,
2131 .label = "nt status support",
2133 .p_class = P_GLOBAL,
2134 .ptr = &Globals.bNTStatusSupport,
2137 .flags = FLAG_ADVANCED,
2140 .label = "profile acls",
2143 .ptr = &sDefault.bProfileAcls,
2146 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2149 .label = "announce version",
2151 .p_class = P_GLOBAL,
2152 .ptr = &Globals.szAnnounceVersion,
2155 .flags = FLAG_ADVANCED,
2158 .label = "announce as",
2160 .p_class = P_GLOBAL,
2161 .ptr = &Globals.announce_as,
2163 .enum_list = enum_announce_as,
2164 .flags = FLAG_ADVANCED,
2167 .label = "map acl inherit",
2170 .ptr = &sDefault.bMap_acl_inherit,
2173 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2176 .label = "afs share",
2179 .ptr = &sDefault.bAfs_Share,
2182 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2187 .p_class = P_GLOBAL,
2188 .ptr = &Globals.max_mux,
2191 .flags = FLAG_ADVANCED,
2194 .label = "max xmit",
2196 .p_class = P_GLOBAL,
2197 .ptr = &Globals.max_xmit,
2200 .flags = FLAG_ADVANCED,
2203 .label = "name resolve order",
2205 .p_class = P_GLOBAL,
2206 .ptr = &Globals.szNameResolveOrder,
2209 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2214 .p_class = P_GLOBAL,
2215 .ptr = &Globals.max_ttl,
2218 .flags = FLAG_ADVANCED,
2221 .label = "max wins ttl",
2223 .p_class = P_GLOBAL,
2224 .ptr = &Globals.max_wins_ttl,
2227 .flags = FLAG_ADVANCED,
2230 .label = "min wins ttl",
2232 .p_class = P_GLOBAL,
2233 .ptr = &Globals.min_wins_ttl,
2236 .flags = FLAG_ADVANCED,
2239 .label = "time server",
2241 .p_class = P_GLOBAL,
2242 .ptr = &Globals.bTimeServer,
2245 .flags = FLAG_ADVANCED,
2248 .label = "unix extensions",
2250 .p_class = P_GLOBAL,
2251 .ptr = &Globals.bUnixExtensions,
2254 .flags = FLAG_ADVANCED,
2257 .label = "use spnego",
2259 .p_class = P_GLOBAL,
2260 .ptr = &Globals.bUseSpnego,
2263 .flags = FLAG_ADVANCED,
2266 .label = "client signing",
2268 .p_class = P_GLOBAL,
2269 .ptr = &Globals.client_signing,
2271 .enum_list = enum_smb_signing_vals,
2272 .flags = FLAG_ADVANCED,
2275 .label = "server signing",
2277 .p_class = P_GLOBAL,
2278 .ptr = &Globals.server_signing,
2280 .enum_list = enum_smb_signing_vals,
2281 .flags = FLAG_ADVANCED,
2284 .label = "smb encrypt",
2287 .ptr = &sDefault.ismb_encrypt,
2289 .enum_list = enum_smb_signing_vals,
2290 .flags = FLAG_ADVANCED,
2293 .label = "client use spnego",
2295 .p_class = P_GLOBAL,
2296 .ptr = &Globals.bClientUseSpnego,
2299 .flags = FLAG_ADVANCED,
2302 .label = "client ldap sasl wrapping",
2304 .p_class = P_GLOBAL,
2305 .ptr = &Globals.client_ldap_sasl_wrapping,
2307 .enum_list = enum_ldap_sasl_wrapping,
2308 .flags = FLAG_ADVANCED,
2311 .label = "enable asu support",
2313 .p_class = P_GLOBAL,
2314 .ptr = &Globals.bASUSupport,
2317 .flags = FLAG_ADVANCED,
2320 .label = "svcctl list",
2322 .p_class = P_GLOBAL,
2323 .ptr = &Globals.szServicesList,
2326 .flags = FLAG_ADVANCED,
2329 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2332 .label = "block size",
2335 .ptr = &sDefault.iBlock_size,
2338 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2341 .label = "deadtime",
2343 .p_class = P_GLOBAL,
2344 .ptr = &Globals.deadtime,
2347 .flags = FLAG_ADVANCED,
2350 .label = "getwd cache",
2352 .p_class = P_GLOBAL,
2353 .ptr = &Globals.getwd_cache,
2356 .flags = FLAG_ADVANCED,
2359 .label = "keepalive",
2361 .p_class = P_GLOBAL,
2362 .ptr = &Globals.iKeepalive,
2365 .flags = FLAG_ADVANCED,
2368 .label = "change notify",
2371 .ptr = &sDefault.bChangeNotify,
2374 .flags = FLAG_ADVANCED | FLAG_SHARE,
2377 .label = "directory name cache size",
2380 .ptr = &sDefault.iDirectoryNameCacheSize,
2383 .flags = FLAG_ADVANCED | FLAG_SHARE,
2386 .label = "kernel change notify",
2389 .ptr = &sDefault.bKernelChangeNotify,
2392 .flags = FLAG_ADVANCED | FLAG_SHARE,
2395 .label = "lpq cache time",
2397 .p_class = P_GLOBAL,
2398 .ptr = &Globals.lpqcachetime,
2401 .flags = FLAG_ADVANCED,
2404 .label = "max smbd processes",
2406 .p_class = P_GLOBAL,
2407 .ptr = &Globals.iMaxSmbdProcesses,
2410 .flags = FLAG_ADVANCED,
2413 .label = "max connections",
2416 .ptr = &sDefault.iMaxConnections,
2419 .flags = FLAG_ADVANCED | FLAG_SHARE,
2422 .label = "paranoid server security",
2424 .p_class = P_GLOBAL,
2425 .ptr = &Globals.paranoid_server_security,
2428 .flags = FLAG_ADVANCED,
2431 .label = "max disk size",
2433 .p_class = P_GLOBAL,
2434 .ptr = &Globals.maxdisksize,
2437 .flags = FLAG_ADVANCED,
2440 .label = "max open files",
2442 .p_class = P_GLOBAL,
2443 .ptr = &Globals.max_open_files,
2446 .flags = FLAG_ADVANCED,
2449 .label = "min print space",
2452 .ptr = &sDefault.iMinPrintSpace,
2455 .flags = FLAG_ADVANCED | FLAG_PRINT,
2458 .label = "socket options",
2460 .p_class = P_GLOBAL,
2461 .ptr = &Globals.szSocketOptions,
2464 .flags = FLAG_ADVANCED,
2467 .label = "strict allocate",
2470 .ptr = &sDefault.bStrictAllocate,
2473 .flags = FLAG_ADVANCED | FLAG_SHARE,
2476 .label = "strict sync",
2479 .ptr = &sDefault.bStrictSync,
2482 .flags = FLAG_ADVANCED | FLAG_SHARE,
2485 .label = "sync always",
2488 .ptr = &sDefault.bSyncAlways,
2491 .flags = FLAG_ADVANCED | FLAG_SHARE,
2494 .label = "use mmap",
2496 .p_class = P_GLOBAL,
2497 .ptr = &Globals.bUseMmap,
2500 .flags = FLAG_ADVANCED,
2503 .label = "use sendfile",
2506 .ptr = &sDefault.bUseSendfile,
2509 .flags = FLAG_ADVANCED | FLAG_SHARE,
2512 .label = "hostname lookups",
2514 .p_class = P_GLOBAL,
2515 .ptr = &Globals.bHostnameLookups,
2518 .flags = FLAG_ADVANCED,
2521 .label = "write cache size",
2524 .ptr = &sDefault.iWriteCacheSize,
2527 .flags = FLAG_ADVANCED | FLAG_SHARE,
2530 .label = "name cache timeout",
2532 .p_class = P_GLOBAL,
2533 .ptr = &Globals.name_cache_timeout,
2536 .flags = FLAG_ADVANCED,
2539 .label = "ctdbd socket",
2541 .p_class = P_GLOBAL,
2542 .ptr = &Globals.ctdbdSocket,
2545 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2548 .label = "cluster addresses",
2550 .p_class = P_GLOBAL,
2551 .ptr = &Globals.szClusterAddresses,
2554 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2557 .label = "clustering",
2559 .p_class = P_GLOBAL,
2560 .ptr = &Globals.clustering,
2563 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2566 .label = "ctdb timeout",
2568 .p_class = P_GLOBAL,
2569 .ptr = &Globals.ctdb_timeout,
2572 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2575 .label = "ctdb locktime warn threshold",
2577 .p_class = P_GLOBAL,
2578 .ptr = &Globals.ctdb_locktime_warn_threshold,
2581 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2584 .label = "smb2 max read",
2586 .p_class = P_GLOBAL,
2587 .ptr = &Globals.ismb2_max_read,
2590 .flags = FLAG_ADVANCED,
2593 .label = "smb2 max write",
2595 .p_class = P_GLOBAL,
2596 .ptr = &Globals.ismb2_max_write,
2599 .flags = FLAG_ADVANCED,
2602 .label = "smb2 max trans",
2604 .p_class = P_GLOBAL,
2605 .ptr = &Globals.ismb2_max_trans,
2608 .flags = FLAG_ADVANCED,
2611 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2614 .label = "max reported print jobs",
2617 .ptr = &sDefault.iMaxReportedPrintJobs,
2620 .flags = FLAG_ADVANCED | FLAG_PRINT,
2623 .label = "max print jobs",
2626 .ptr = &sDefault.iMaxPrintJobs,
2629 .flags = FLAG_ADVANCED | FLAG_PRINT,
2632 .label = "load printers",
2634 .p_class = P_GLOBAL,
2635 .ptr = &Globals.bLoadPrinters,
2638 .flags = FLAG_ADVANCED | FLAG_PRINT,
2641 .label = "printcap cache time",
2643 .p_class = P_GLOBAL,
2644 .ptr = &Globals.PrintcapCacheTime,
2647 .flags = FLAG_ADVANCED | FLAG_PRINT,
2650 .label = "printcap name",
2652 .p_class = P_GLOBAL,
2653 .ptr = &Globals.szPrintcapname,
2656 .flags = FLAG_ADVANCED | FLAG_PRINT,
2659 .label = "printcap",
2661 .p_class = P_GLOBAL,
2662 .ptr = &Globals.szPrintcapname,
2668 .label = "printable",
2671 .ptr = &sDefault.bPrint_ok,
2674 .flags = FLAG_ADVANCED | FLAG_PRINT,
2677 .label = "print ok",
2680 .ptr = &sDefault.bPrint_ok,
2686 .label = "printing",
2689 .ptr = &sDefault.iPrinting,
2690 .special = handle_printing,
2691 .enum_list = enum_printing,
2692 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2695 .label = "cups options",
2698 .ptr = &sDefault.szCupsOptions,
2701 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2704 .label = "cups server",
2706 .p_class = P_GLOBAL,
2707 .ptr = &Globals.szCupsServer,
2710 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2713 .label = "cups encrypt",
2715 .p_class = P_GLOBAL,
2716 .ptr = &Globals.CupsEncrypt,
2718 .enum_list = enum_bool_auto,
2719 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2723 .label = "cups connection timeout",
2725 .p_class = P_GLOBAL,
2726 .ptr = &Globals.cups_connection_timeout,
2729 .flags = FLAG_ADVANCED,
2732 .label = "iprint server",
2734 .p_class = P_GLOBAL,
2735 .ptr = &Globals.szIPrintServer,
2738 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2741 .label = "print command",
2744 .ptr = &sDefault.szPrintcommand,
2747 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2750 .label = "disable spoolss",
2752 .p_class = P_GLOBAL,
2753 .ptr = &Globals.bDisableSpoolss,
2756 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2759 .label = "enable spoolss",
2761 .p_class = P_GLOBAL,
2762 .ptr = &Globals.bDisableSpoolss,
2768 .label = "lpq command",
2771 .ptr = &sDefault.szLpqcommand,
2774 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2777 .label = "lprm command",
2780 .ptr = &sDefault.szLprmcommand,
2783 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2786 .label = "lppause command",
2789 .ptr = &sDefault.szLppausecommand,
2792 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2795 .label = "lpresume command",
2798 .ptr = &sDefault.szLpresumecommand,
2801 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2804 .label = "queuepause command",
2807 .ptr = &sDefault.szQueuepausecommand,
2810 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2813 .label = "queueresume command",
2816 .ptr = &sDefault.szQueueresumecommand,
2819 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2822 .label = "addport command",
2824 .p_class = P_GLOBAL,
2825 .ptr = &Globals.szAddPortCommand,
2828 .flags = FLAG_ADVANCED,
2831 .label = "enumports command",
2833 .p_class = P_GLOBAL,
2834 .ptr = &Globals.szEnumPortsCommand,
2837 .flags = FLAG_ADVANCED,
2840 .label = "addprinter command",
2842 .p_class = P_GLOBAL,
2843 .ptr = &Globals.szAddPrinterCommand,
2846 .flags = FLAG_ADVANCED,
2849 .label = "deleteprinter command",
2851 .p_class = P_GLOBAL,
2852 .ptr = &Globals.szDeletePrinterCommand,
2855 .flags = FLAG_ADVANCED,
2858 .label = "show add printer wizard",
2860 .p_class = P_GLOBAL,
2861 .ptr = &Globals.bMsAddPrinterWizard,
2864 .flags = FLAG_ADVANCED,
2867 .label = "os2 driver map",
2869 .p_class = P_GLOBAL,
2870 .ptr = &Globals.szOs2DriverMap,
2873 .flags = FLAG_ADVANCED,
2877 .label = "printer name",
2880 .ptr = &sDefault.szPrintername,
2883 .flags = FLAG_ADVANCED | FLAG_PRINT,
2889 .ptr = &sDefault.szPrintername,
2895 .label = "use client driver",
2898 .ptr = &sDefault.bUseClientDriver,
2901 .flags = FLAG_ADVANCED | FLAG_PRINT,
2904 .label = "default devmode",
2907 .ptr = &sDefault.bDefaultDevmode,
2910 .flags = FLAG_ADVANCED | FLAG_PRINT,
2913 .label = "force printername",
2916 .ptr = &sDefault.bForcePrintername,
2919 .flags = FLAG_ADVANCED | FLAG_PRINT,
2922 .label = "printjob username",
2925 .ptr = &sDefault.szPrintjobUsername,
2928 .flags = FLAG_ADVANCED | FLAG_PRINT,
2931 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2934 .label = "mangling method",
2936 .p_class = P_GLOBAL,
2937 .ptr = &Globals.szManglingMethod,
2940 .flags = FLAG_ADVANCED,
2943 .label = "mangle prefix",
2945 .p_class = P_GLOBAL,
2946 .ptr = &Globals.mangle_prefix,
2949 .flags = FLAG_ADVANCED,
2953 .label = "default case",
2956 .ptr = &sDefault.iDefaultCase,
2958 .enum_list = enum_case,
2959 .flags = FLAG_ADVANCED | FLAG_SHARE,
2962 .label = "case sensitive",
2965 .ptr = &sDefault.iCaseSensitive,
2967 .enum_list = enum_bool_auto,
2968 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2971 .label = "casesignames",
2974 .ptr = &sDefault.iCaseSensitive,
2976 .enum_list = enum_bool_auto,
2977 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2980 .label = "preserve case",
2983 .ptr = &sDefault.bCasePreserve,
2986 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2989 .label = "short preserve case",
2992 .ptr = &sDefault.bShortCasePreserve,
2995 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2998 .label = "mangling char",
3001 .ptr = &sDefault.magic_char,
3004 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3007 .label = "hide dot files",
3010 .ptr = &sDefault.bHideDotFiles,
3013 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3016 .label = "hide special files",
3019 .ptr = &sDefault.bHideSpecialFiles,
3022 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3025 .label = "hide unreadable",
3028 .ptr = &sDefault.bHideUnReadable,
3031 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3034 .label = "hide unwriteable files",
3037 .ptr = &sDefault.bHideUnWriteableFiles,
3040 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3043 .label = "delete veto files",
3046 .ptr = &sDefault.bDeleteVetoFiles,
3049 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3052 .label = "veto files",
3055 .ptr = &sDefault.szVetoFiles,
3058 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3061 .label = "hide files",
3064 .ptr = &sDefault.szHideFiles,
3067 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3070 .label = "veto oplock files",
3073 .ptr = &sDefault.szVetoOplockFiles,
3076 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3079 .label = "map archive",
3082 .ptr = &sDefault.bMap_archive,
3085 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3088 .label = "map hidden",
3091 .ptr = &sDefault.bMap_hidden,
3094 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3097 .label = "map system",
3100 .ptr = &sDefault.bMap_system,
3103 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3106 .label = "map readonly",
3109 .ptr = &sDefault.iMap_readonly,
3111 .enum_list = enum_map_readonly,
3112 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3115 .label = "mangled names",
3118 .ptr = &sDefault.bMangledNames,
3121 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3124 .label = "max stat cache size",
3126 .p_class = P_GLOBAL,
3127 .ptr = &Globals.iMaxStatCacheSize,
3130 .flags = FLAG_ADVANCED,
3133 .label = "stat cache",
3135 .p_class = P_GLOBAL,
3136 .ptr = &Globals.bStatCache,
3139 .flags = FLAG_ADVANCED,
3142 .label = "store dos attributes",
3145 .ptr = &sDefault.bStoreDosAttributes,
3148 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3151 .label = "dmapi support",
3154 .ptr = &sDefault.bDmapiSupport,
3157 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3161 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3164 .label = "machine password timeout",
3166 .p_class = P_GLOBAL,
3167 .ptr = &Globals.machine_password_timeout,
3170 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3173 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3176 .label = "add user script",
3178 .p_class = P_GLOBAL,
3179 .ptr = &Globals.szAddUserScript,
3182 .flags = FLAG_ADVANCED,
3185 .label = "rename user script",
3187 .p_class = P_GLOBAL,
3188 .ptr = &Globals.szRenameUserScript,
3191 .flags = FLAG_ADVANCED,
3194 .label = "delete user script",
3196 .p_class = P_GLOBAL,
3197 .ptr = &Globals.szDelUserScript,
3200 .flags = FLAG_ADVANCED,
3203 .label = "add group script",
3205 .p_class = P_GLOBAL,
3206 .ptr = &Globals.szAddGroupScript,
3209 .flags = FLAG_ADVANCED,
3212 .label = "delete group script",
3214 .p_class = P_GLOBAL,
3215 .ptr = &Globals.szDelGroupScript,
3218 .flags = FLAG_ADVANCED,
3221 .label = "add user to group script",
3223 .p_class = P_GLOBAL,
3224 .ptr = &Globals.szAddUserToGroupScript,
3227 .flags = FLAG_ADVANCED,
3230 .label = "delete user from group script",
3232 .p_class = P_GLOBAL,
3233 .ptr = &Globals.szDelUserFromGroupScript,
3236 .flags = FLAG_ADVANCED,
3239 .label = "set primary group script",
3241 .p_class = P_GLOBAL,
3242 .ptr = &Globals.szSetPrimaryGroupScript,
3245 .flags = FLAG_ADVANCED,
3248 .label = "add machine script",
3250 .p_class = P_GLOBAL,
3251 .ptr = &Globals.szAddMachineScript,
3254 .flags = FLAG_ADVANCED,
3257 .label = "shutdown script",
3259 .p_class = P_GLOBAL,
3260 .ptr = &Globals.szShutdownScript,
3263 .flags = FLAG_ADVANCED,
3266 .label = "abort shutdown script",
3268 .p_class = P_GLOBAL,
3269 .ptr = &Globals.szAbortShutdownScript,
3272 .flags = FLAG_ADVANCED,
3275 .label = "username map script",
3277 .p_class = P_GLOBAL,
3278 .ptr = &Globals.szUsernameMapScript,
3281 .flags = FLAG_ADVANCED,
3284 .label = "username map cache time",
3286 .p_class = P_GLOBAL,
3287 .ptr = &Globals.iUsernameMapCacheTime,
3290 .flags = FLAG_ADVANCED,
3293 .label = "logon script",
3295 .p_class = P_GLOBAL,
3296 .ptr = &Globals.szLogonScript,
3299 .flags = FLAG_ADVANCED,
3302 .label = "logon path",
3304 .p_class = P_GLOBAL,
3305 .ptr = &Globals.szLogonPath,
3308 .flags = FLAG_ADVANCED,
3311 .label = "logon drive",
3313 .p_class = P_GLOBAL,
3314 .ptr = &Globals.szLogonDrive,
3317 .flags = FLAG_ADVANCED,
3320 .label = "logon home",
3322 .p_class = P_GLOBAL,
3323 .ptr = &Globals.szLogonHome,
3326 .flags = FLAG_ADVANCED,
3329 .label = "domain logons",
3331 .p_class = P_GLOBAL,
3332 .ptr = &Globals.bDomainLogons,
3335 .flags = FLAG_ADVANCED,
3339 .label = "init logon delayed hosts",
3341 .p_class = P_GLOBAL,
3342 .ptr = &Globals.szInitLogonDelayedHosts,
3345 .flags = FLAG_ADVANCED,
3349 .label = "init logon delay",
3351 .p_class = P_GLOBAL,
3352 .ptr = &Globals.InitLogonDelay,
3355 .flags = FLAG_ADVANCED,
3359 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3362 .label = "os level",
3364 .p_class = P_GLOBAL,
3365 .ptr = &Globals.os_level,
3368 .flags = FLAG_BASIC | FLAG_ADVANCED,
3371 .label = "lm announce",
3373 .p_class = P_GLOBAL,
3374 .ptr = &Globals.lm_announce,
3376 .enum_list = enum_bool_auto,
3377 .flags = FLAG_ADVANCED,
3380 .label = "lm interval",
3382 .p_class = P_GLOBAL,
3383 .ptr = &Globals.lm_interval,
3386 .flags = FLAG_ADVANCED,
3389 .label = "preferred master",
3391 .p_class = P_GLOBAL,
3392 .ptr = &Globals.iPreferredMaster,
3394 .enum_list = enum_bool_auto,
3395 .flags = FLAG_BASIC | FLAG_ADVANCED,
3398 .label = "prefered master",
3400 .p_class = P_GLOBAL,
3401 .ptr = &Globals.iPreferredMaster,
3403 .enum_list = enum_bool_auto,
3407 .label = "local master",
3409 .p_class = P_GLOBAL,
3410 .ptr = &Globals.bLocalMaster,
3413 .flags = FLAG_BASIC | FLAG_ADVANCED,
3416 .label = "domain master",
3418 .p_class = P_GLOBAL,
3419 .ptr = &Globals.iDomainMaster,
3421 .enum_list = enum_bool_auto,
3422 .flags = FLAG_BASIC | FLAG_ADVANCED,
3425 .label = "browse list",
3427 .p_class = P_GLOBAL,
3428 .ptr = &Globals.bBrowseList,
3431 .flags = FLAG_ADVANCED,
3434 .label = "browseable",
3437 .ptr = &sDefault.bBrowseable,
3440 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3443 .label = "browsable",
3446 .ptr = &sDefault.bBrowseable,
3452 .label = "access based share enum",
3455 .ptr = &sDefault.bAccessBasedShareEnum,
3458 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3461 .label = "enhanced browsing",
3463 .p_class = P_GLOBAL,
3464 .ptr = &Globals.enhanced_browsing,
3467 .flags = FLAG_ADVANCED,
3470 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3473 .label = "dns proxy",
3475 .p_class = P_GLOBAL,
3476 .ptr = &Globals.bDNSproxy,
3479 .flags = FLAG_ADVANCED,
3482 .label = "wins proxy",
3484 .p_class = P_GLOBAL,
3485 .ptr = &Globals.bWINSproxy,
3488 .flags = FLAG_ADVANCED,
3491 .label = "wins server",
3493 .p_class = P_GLOBAL,
3494 .ptr = &Globals.szWINSservers,
3497 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3500 .label = "wins support",
3502 .p_class = P_GLOBAL,
3503 .ptr = &Globals.bWINSsupport,
3506 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3509 .label = "wins hook",
3511 .p_class = P_GLOBAL,
3512 .ptr = &Globals.szWINSHook,
3515 .flags = FLAG_ADVANCED,
3518 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3521 .label = "blocking locks",
3524 .ptr = &sDefault.bBlockingLocks,
3527 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3530 .label = "csc policy",
3533 .ptr = &sDefault.iCSCPolicy,
3535 .enum_list = enum_csc_policy,
3536 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3539 .label = "fake oplocks",
3542 .ptr = &sDefault.bFakeOplocks,
3545 .flags = FLAG_ADVANCED | FLAG_SHARE,
3548 .label = "kernel oplocks",
3550 .p_class = P_GLOBAL,
3551 .ptr = &Globals.bKernelOplocks,
3554 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3560 .ptr = &sDefault.bLocking,
3563 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3566 .label = "lock spin time",
3568 .p_class = P_GLOBAL,
3569 .ptr = &Globals.iLockSpinTime,
3572 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3578 .ptr = &sDefault.bOpLocks,
3581 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3584 .label = "level2 oplocks",
3587 .ptr = &sDefault.bLevel2OpLocks,
3590 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3593 .label = "oplock break wait time",
3595 .p_class = P_GLOBAL,
3596 .ptr = &Globals.oplock_break_wait_time,
3599 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3602 .label = "oplock contention limit",
3605 .ptr = &sDefault.iOplockContentionLimit,
3608 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3611 .label = "posix locking",
3614 .ptr = &sDefault.bPosixLocking,
3617 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3620 .label = "strict locking",
3623 .ptr = &sDefault.iStrictLocking,
3625 .enum_list = enum_bool_auto,
3626 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3629 .label = "share modes",
3632 .ptr = &sDefault.bShareModes,
3635 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3638 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3641 .label = "ldap admin dn",
3643 .p_class = P_GLOBAL,
3644 .ptr = &Globals.szLdapAdminDn,
3647 .flags = FLAG_ADVANCED,
3650 .label = "ldap delete dn",
3652 .p_class = P_GLOBAL,
3653 .ptr = &Globals.ldap_delete_dn,
3656 .flags = FLAG_ADVANCED,
3659 .label = "ldap group suffix",
3661 .p_class = P_GLOBAL,
3662 .ptr = &Globals.szLdapGroupSuffix,
3665 .flags = FLAG_ADVANCED,
3668 .label = "ldap idmap suffix",
3670 .p_class = P_GLOBAL,
3671 .ptr = &Globals.szLdapIdmapSuffix,
3674 .flags = FLAG_ADVANCED,
3677 .label = "ldap machine suffix",
3679 .p_class = P_GLOBAL,
3680 .ptr = &Globals.szLdapMachineSuffix,
3683 .flags = FLAG_ADVANCED,
3686 .label = "ldap passwd sync",
3688 .p_class = P_GLOBAL,
3689 .ptr = &Globals.ldap_passwd_sync,
3691 .enum_list = enum_ldap_passwd_sync,
3692 .flags = FLAG_ADVANCED,
3695 .label = "ldap password sync",
3697 .p_class = P_GLOBAL,
3698 .ptr = &Globals.ldap_passwd_sync,
3700 .enum_list = enum_ldap_passwd_sync,
3704 .label = "ldap replication sleep",
3706 .p_class = P_GLOBAL,
3707 .ptr = &Globals.ldap_replication_sleep,
3710 .flags = FLAG_ADVANCED,
3713 .label = "ldap suffix",
3715 .p_class = P_GLOBAL,
3716 .ptr = &Globals.szLdapSuffix,
3719 .flags = FLAG_ADVANCED,
3722 .label = "ldap ssl",
3724 .p_class = P_GLOBAL,
3725 .ptr = &Globals.ldap_ssl,
3727 .enum_list = enum_ldap_ssl,
3728 .flags = FLAG_ADVANCED,
3731 .label = "ldap ssl ads",
3733 .p_class = P_GLOBAL,
3734 .ptr = &Globals.ldap_ssl_ads,
3737 .flags = FLAG_ADVANCED,
3740 .label = "ldap deref",
3742 .p_class = P_GLOBAL,
3743 .ptr = &Globals.ldap_deref,
3745 .enum_list = enum_ldap_deref,
3746 .flags = FLAG_ADVANCED,
3749 .label = "ldap follow referral",
3751 .p_class = P_GLOBAL,
3752 .ptr = &Globals.ldap_follow_referral,
3754 .enum_list = enum_bool_auto,
3755 .flags = FLAG_ADVANCED,
3758 .label = "ldap timeout",
3760 .p_class = P_GLOBAL,
3761 .ptr = &Globals.ldap_timeout,
3764 .flags = FLAG_ADVANCED,
3767 .label = "ldap connection timeout",
3769 .p_class = P_GLOBAL,
3770 .ptr = &Globals.ldap_connection_timeout,
3773 .flags = FLAG_ADVANCED,
3776 .label = "ldap page size",
3778 .p_class = P_GLOBAL,
3779 .ptr = &Globals.ldap_page_size,
3782 .flags = FLAG_ADVANCED,
3785 .label = "ldap user suffix",
3787 .p_class = P_GLOBAL,
3788 .ptr = &Globals.szLdapUserSuffix,
3791 .flags = FLAG_ADVANCED,
3794 .label = "ldap debug level",
3796 .p_class = P_GLOBAL,
3797 .ptr = &Globals.ldap_debug_level,
3798 .special = handle_ldap_debug_level,
3800 .flags = FLAG_ADVANCED,
3803 .label = "ldap debug threshold",
3805 .p_class = P_GLOBAL,
3806 .ptr = &Globals.ldap_debug_threshold,
3809 .flags = FLAG_ADVANCED,
3812 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3815 .label = "eventlog list",
3817 .p_class = P_GLOBAL,
3818 .ptr = &Globals.szEventLogs,
3821 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3824 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3827 .label = "add share command",
3829 .p_class = P_GLOBAL,
3830 .ptr = &Globals.szAddShareCommand,
3833 .flags = FLAG_ADVANCED,
3836 .label = "change share command",
3838 .p_class = P_GLOBAL,
3839 .ptr = &Globals.szChangeShareCommand,
3842 .flags = FLAG_ADVANCED,
3845 .label = "delete share command",
3847 .p_class = P_GLOBAL,
3848 .ptr = &Globals.szDeleteShareCommand,
3851 .flags = FLAG_ADVANCED,
3854 .label = "config file",
3856 .p_class = P_GLOBAL,
3857 .ptr = &Globals.szConfigFile,
3860 .flags = FLAG_HIDE|FLAG_META,
3865 .p_class = P_GLOBAL,
3866 .ptr = &Globals.szAutoServices,
3869 .flags = FLAG_ADVANCED,
3872 .label = "auto services",
3874 .p_class = P_GLOBAL,
3875 .ptr = &Globals.szAutoServices,
3878 .flags = FLAG_ADVANCED,
3881 .label = "lock directory",
3883 .p_class = P_GLOBAL,
3884 .ptr = &Globals.szLockDir,
3887 .flags = FLAG_ADVANCED,
3890 .label = "lock dir",
3892 .p_class = P_GLOBAL,
3893 .ptr = &Globals.szLockDir,
3899 .label = "state directory",
3901 .p_class = P_GLOBAL,
3902 .ptr = &Globals.szStateDir,
3905 .flags = FLAG_ADVANCED,
3908 .label = "cache directory",
3910 .p_class = P_GLOBAL,
3911 .ptr = &Globals.szCacheDir,
3914 .flags = FLAG_ADVANCED,
3917 .label = "pid directory",
3919 .p_class = P_GLOBAL,
3920 .ptr = &Globals.szPidDir,
3923 .flags = FLAG_ADVANCED,
3927 .label = "utmp directory",
3929 .p_class = P_GLOBAL,
3930 .ptr = &Globals.szUtmpDir,
3933 .flags = FLAG_ADVANCED,
3936 .label = "wtmp directory",
3938 .p_class = P_GLOBAL,
3939 .ptr = &Globals.szWtmpDir,
3942 .flags = FLAG_ADVANCED,
3947 .p_class = P_GLOBAL,
3948 .ptr = &Globals.bUtmp,
3951 .flags = FLAG_ADVANCED,
3955 .label = "default service",
3957 .p_class = P_GLOBAL,
3958 .ptr = &Globals.szDefaultService,
3961 .flags = FLAG_ADVANCED,
3966 .p_class = P_GLOBAL,
3967 .ptr = &Globals.szDefaultService,
3970 .flags = FLAG_ADVANCED,
3973 .label = "message command",
3975 .p_class = P_GLOBAL,
3976 .ptr = &Globals.szMsgCommand,
3979 .flags = FLAG_ADVANCED,
3982 .label = "dfree cache time",
3985 .ptr = &sDefault.iDfreeCacheTime,
3988 .flags = FLAG_ADVANCED,
3991 .label = "dfree command",
3994 .ptr = &sDefault.szDfree,
3997 .flags = FLAG_ADVANCED,
4000 .label = "get quota command",
4002 .p_class = P_GLOBAL,
4003 .ptr = &Globals.szGetQuota,
4006 .flags = FLAG_ADVANCED,
4009 .label = "set quota command",
4011 .p_class = P_GLOBAL,
4012 .ptr = &Globals.szSetQuota,
4015 .flags = FLAG_ADVANCED,
4018 .label = "remote announce",
4020 .p_class = P_GLOBAL,
4021 .ptr = &Globals.szRemoteAnnounce,
4024 .flags = FLAG_ADVANCED,
4027 .label = "remote browse sync",
4029 .p_class = P_GLOBAL,
4030 .ptr = &Globals.szRemoteBrowseSync,
4033 .flags = FLAG_ADVANCED,
4036 .label = "socket address",
4038 .p_class = P_GLOBAL,
4039 .ptr = &Globals.szSocketAddress,
4042 .flags = FLAG_ADVANCED,
4045 .label = "nmbd bind explicit broadcast",
4047 .p_class = P_GLOBAL,
4048 .ptr = &Globals.bNmbdBindExplicitBroadcast,
4051 .flags = FLAG_ADVANCED,
4054 .label = "homedir map",
4056 .p_class = P_GLOBAL,
4057 .ptr = &Globals.szNISHomeMapName,
4060 .flags = FLAG_ADVANCED,
4063 .label = "afs username map",
4065 .p_class = P_GLOBAL,
4066 .ptr = &Globals.szAfsUsernameMap,
4069 .flags = FLAG_ADVANCED,
4072 .label = "afs token lifetime",
4074 .p_class = P_GLOBAL,
4075 .ptr = &Globals.iAfsTokenLifetime,
4078 .flags = FLAG_ADVANCED,
4081 .label = "log nt token command",
4083 .p_class = P_GLOBAL,
4084 .ptr = &Globals.szLogNtTokenCommand,
4087 .flags = FLAG_ADVANCED,
4090 .label = "time offset",
4092 .p_class = P_GLOBAL,
4093 .ptr = &extra_time_offset,
4096 .flags = FLAG_ADVANCED,
4099 .label = "NIS homedir",
4101 .p_class = P_GLOBAL,
4102 .ptr = &Globals.bNISHomeMap,
4105 .flags = FLAG_ADVANCED,
4111 .ptr = &sDefault.valid,
4120 .ptr = &sDefault.szCopy,
4121 .special = handle_copy,
4129 .ptr = &sDefault.szInclude,
4130 .special = handle_include,
4132 .flags = FLAG_HIDE|FLAG_META,
4138 .ptr = &sDefault.szPreExec,
4141 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4147 .ptr = &sDefault.szPreExec,
4150 .flags = FLAG_ADVANCED,
4153 .label = "preexec close",
4156 .ptr = &sDefault.bPreexecClose,
4159 .flags = FLAG_ADVANCED | FLAG_SHARE,
4162 .label = "postexec",
4165 .ptr = &sDefault.szPostExec,
4168 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4171 .label = "root preexec",
4174 .ptr = &sDefault.szRootPreExec,
4177 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4180 .label = "root preexec close",
4183 .ptr = &sDefault.bRootpreexecClose,
4186 .flags = FLAG_ADVANCED | FLAG_SHARE,
4189 .label = "root postexec",
4192 .ptr = &sDefault.szRootPostExec,
4195 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4198 .label = "available",
4201 .ptr = &sDefault.bAvailable,
4204 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4207 .label = "registry shares",
4209 .p_class = P_GLOBAL,
4210 .ptr = &Globals.bRegistryShares,
4213 .flags = FLAG_ADVANCED,
4216 .label = "usershare allow guests",
4218 .p_class = P_GLOBAL,
4219 .ptr = &Globals.bUsershareAllowGuests,
4222 .flags = FLAG_ADVANCED,
4225 .label = "usershare max shares",
4227 .p_class = P_GLOBAL,
4228 .ptr = &Globals.iUsershareMaxShares,
4231 .flags = FLAG_ADVANCED,
4234 .label = "usershare owner only",
4236 .p_class = P_GLOBAL,
4237 .ptr = &Globals.bUsershareOwnerOnly,
4240 .flags = FLAG_ADVANCED,
4243 .label = "usershare path",
4245 .p_class = P_GLOBAL,
4246 .ptr = &Globals.szUsersharePath,
4249 .flags = FLAG_ADVANCED,
4252 .label = "usershare prefix allow list",
4254 .p_class = P_GLOBAL,
4255 .ptr = &Globals.szUsersharePrefixAllowList,
4258 .flags = FLAG_ADVANCED,
4261 .label = "usershare prefix deny list",
4263 .p_class = P_GLOBAL,
4264 .ptr = &Globals.szUsersharePrefixDenyList,
4267 .flags = FLAG_ADVANCED,
4270 .label = "usershare template share",
4272 .p_class = P_GLOBAL,
4273 .ptr = &Globals.szUsershareTemplateShare,
4276 .flags = FLAG_ADVANCED,
4282 .ptr = &sDefault.volume,
4285 .flags = FLAG_ADVANCED | FLAG_SHARE,
4291 .ptr = &sDefault.fstype,
4294 .flags = FLAG_ADVANCED | FLAG_SHARE,
4297 .label = "set directory",
4300 .ptr = &sDefault.bNo_set_dir,
4303 .flags = FLAG_ADVANCED | FLAG_SHARE,
4306 .label = "wide links",
4309 .ptr = &sDefault.bWidelinks,
4312 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4315 .label = "follow symlinks",
4318 .ptr = &sDefault.bSymlinks,
4321 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4324 .label = "dont descend",
4327 .ptr = &sDefault.szDontdescend,
4330 .flags = FLAG_ADVANCED | FLAG_SHARE,
4333 .label = "magic script",
4336 .ptr = &sDefault.szMagicScript,
4339 .flags = FLAG_ADVANCED | FLAG_SHARE,
4342 .label = "magic output",
4345 .ptr = &sDefault.szMagicOutput,
4348 .flags = FLAG_ADVANCED | FLAG_SHARE,
4351 .label = "delete readonly",
4354 .ptr = &sDefault.bDeleteReadonly,
4357 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4360 .label = "dos filemode",
4363 .ptr = &sDefault.bDosFilemode,
4366 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4369 .label = "dos filetimes",
4372 .ptr = &sDefault.bDosFiletimes,
4375 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4378 .label = "dos filetime resolution",
4381 .ptr = &sDefault.bDosFiletimeResolution,
4384 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4387 .label = "fake directory create times",
4390 .ptr = &sDefault.bFakeDirCreateTimes,
4393 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4396 .label = "async smb echo handler",
4398 .p_class = P_GLOBAL,
4399 .ptr = &Globals.bAsyncSMBEchoHandler,
4402 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4405 .label = "panic action",
4407 .p_class = P_GLOBAL,
4408 .ptr = &Globals.szPanicAction,
4411 .flags = FLAG_ADVANCED,
4414 .label = "perfcount module",
4416 .p_class = P_GLOBAL,
4417 .ptr = &Globals.szSMBPerfcountModule,
4420 .flags = FLAG_ADVANCED,
4423 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4426 .label = "vfs objects",
4429 .ptr = &sDefault.szVfsObjects,
4432 .flags = FLAG_ADVANCED | FLAG_SHARE,
4435 .label = "vfs object",
4438 .ptr = &sDefault.szVfsObjects,
4445 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4448 .label = "msdfs root",
4451 .ptr = &sDefault.bMSDfsRoot,
4454 .flags = FLAG_ADVANCED | FLAG_SHARE,
4457 .label = "msdfs proxy",
4460 .ptr = &sDefault.szMSDfsProxy,
4463 .flags = FLAG_ADVANCED | FLAG_SHARE,
4466 .label = "host msdfs",
4468 .p_class = P_GLOBAL,
4469 .ptr = &Globals.bHostMSDfs,
4472 .flags = FLAG_ADVANCED,
4475 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4478 .label = "passdb expand explicit",
4480 .p_class = P_GLOBAL,
4481 .ptr = &Globals.bPassdbExpandExplicit,
4484 .flags = FLAG_ADVANCED,
4487 .label = "idmap backend",
4489 .p_class = P_GLOBAL,
4490 .ptr = &Globals.szIdmapBackend,
4493 .flags = FLAG_ADVANCED,
4496 .label = "idmap read only",
4498 .p_class = P_GLOBAL,
4499 .ptr = &Globals.bIdmapReadOnly,
4502 .flags = FLAG_ADVANCED,
4505 .label = "idmap cache time",
4507 .p_class = P_GLOBAL,
4508 .ptr = &Globals.iIdmapCacheTime,
4511 .flags = FLAG_ADVANCED,
4514 .label = "idmap negative cache time",
4516 .p_class = P_GLOBAL,
4517 .ptr = &Globals.iIdmapNegativeCacheTime,
4520 .flags = FLAG_ADVANCED,
4523 .label = "idmap uid",
4525 .p_class = P_GLOBAL,
4526 .ptr = &Globals.szIdmapUID,
4527 .special = handle_idmap_uid,
4529 .flags = FLAG_ADVANCED,
4532 .label = "winbind uid",
4534 .p_class = P_GLOBAL,
4535 .ptr = &Globals.szIdmapUID,
4536 .special = handle_idmap_uid,
4541 .label = "idmap gid",
4543 .p_class = P_GLOBAL,
4544 .ptr = &Globals.szIdmapGID,
4545 .special = handle_idmap_gid,
4547 .flags = FLAG_ADVANCED,
4550 .label = "winbind gid",
4552 .p_class = P_GLOBAL,
4553 .ptr = &Globals.szIdmapGID,
4554 .special = handle_idmap_gid,
4559 .label = "template homedir",
4561 .p_class = P_GLOBAL,
4562 .ptr = &Globals.szTemplateHomedir,
4565 .flags = FLAG_ADVANCED,
4568 .label = "template shell",
4570 .p_class = P_GLOBAL,
4571 .ptr = &Globals.szTemplateShell,
4574 .flags = FLAG_ADVANCED,
4577 .label = "winbind separator",
4579 .p_class = P_GLOBAL,
4580 .ptr = &Globals.szWinbindSeparator,
4583 .flags = FLAG_ADVANCED,
4586 .label = "winbind cache time",
4588 .p_class = P_GLOBAL,
4589 .ptr = &Globals.winbind_cache_time,
4592 .flags = FLAG_ADVANCED,
4595 .label = "winbind reconnect delay",
4597 .p_class = P_GLOBAL,
4598 .ptr = &Globals.winbind_reconnect_delay,
4601 .flags = FLAG_ADVANCED,
4604 .label = "winbind enum users",
4606 .p_class = P_GLOBAL,
4607 .ptr = &Globals.bWinbindEnumUsers,
4610 .flags = FLAG_ADVANCED,
4613 .label = "winbind enum groups",
4615 .p_class = P_GLOBAL,
4616 .ptr = &Globals.bWinbindEnumGroups,
4619 .flags = FLAG_ADVANCED,
4622 .label = "winbind use default domain",
4624 .p_class = P_GLOBAL,
4625 .ptr = &Globals.bWinbindUseDefaultDomain,
4628 .flags = FLAG_ADVANCED,
4631 .label = "winbind trusted domains only",
4633 .p_class = P_GLOBAL,
4634 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4637 .flags = FLAG_ADVANCED,
4640 .label = "winbind nested groups",
4642 .p_class = P_GLOBAL,
4643 .ptr = &Globals.bWinbindNestedGroups,
4646 .flags = FLAG_ADVANCED,
4649 .label = "winbind expand groups",
4651 .p_class = P_GLOBAL,
4652 .ptr = &Globals.winbind_expand_groups,
4655 .flags = FLAG_ADVANCED,
4658 .label = "winbind nss info",
4660 .p_class = P_GLOBAL,
4661 .ptr = &Globals.szWinbindNssInfo,
4664 .flags = FLAG_ADVANCED,
4667 .label = "winbind refresh tickets",
4669 .p_class = P_GLOBAL,
4670 .ptr = &Globals.bWinbindRefreshTickets,
4673 .flags = FLAG_ADVANCED,
4676 .label = "winbind offline logon",
4678 .p_class = P_GLOBAL,
4679 .ptr = &Globals.bWinbindOfflineLogon,
4682 .flags = FLAG_ADVANCED,
4685 .label = "winbind normalize names",
4687 .p_class = P_GLOBAL,
4688 .ptr = &Globals.bWinbindNormalizeNames,
4691 .flags = FLAG_ADVANCED,
4694 .label = "winbind rpc only",
4696 .p_class = P_GLOBAL,
4697 .ptr = &Globals.bWinbindRpcOnly,
4700 .flags = FLAG_ADVANCED,
4703 .label = "create krb5 conf",
4705 .p_class = P_GLOBAL,
4706 .ptr = &Globals.bCreateKrb5Conf,
4709 .flags = FLAG_ADVANCED,
4712 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4715 /***************************************************************************
4716 Initialise the sDefault parameter structure for the printer values.
4717 ***************************************************************************/
4719 static void init_printer_values(struct service *pService)
4721 /* choose defaults depending on the type of printing */
4722 switch (pService->iPrinting) {
4727 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4728 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4729 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4734 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4735 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4736 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4737 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4738 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4739 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4740 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4746 /* set the lpq command to contain the destination printer
4747 name only. This is used by cups_queue_get() */
4748 string_set(&pService->szLpqcommand, "%p");
4749 string_set(&pService->szLprmcommand, "");
4750 string_set(&pService->szPrintcommand, "");
4751 string_set(&pService->szLppausecommand, "");
4752 string_set(&pService->szLpresumecommand, "");
4753 string_set(&pService->szQueuepausecommand, "");
4754 string_set(&pService->szQueueresumecommand, "");
4756 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4757 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4758 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4759 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4760 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4761 string_set(&pService->szQueuepausecommand, "disable '%p'");
4762 string_set(&pService->szQueueresumecommand, "enable '%p'");
4763 #endif /* HAVE_CUPS */
4768 string_set(&pService->szLpqcommand, "lpstat -o%p");
4769 string_set(&pService->szLprmcommand, "cancel %p-%j");
4770 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4771 string_set(&pService->szQueuepausecommand, "disable %p");
4772 string_set(&pService->szQueueresumecommand, "enable %p");
4774 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4775 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4780 string_set(&pService->szLpqcommand, "lpq -P%p");
4781 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4782 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4788 string_set(&pService->szPrintcommand, "vlp print %p %s");
4789 string_set(&pService->szLpqcommand, "vlp lpq %p");
4790 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4791 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4792 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4793 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4794 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4796 #endif /* DEVELOPER */
4801 * Function to return the default value for the maximum number of open
4802 * file descriptors permitted. This function tries to consult the
4803 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4804 * the smaller of those.
4806 static int max_open_files(void)
4808 int sysctl_max = MAX_OPEN_FILES;
4809 int rlimit_max = MAX_OPEN_FILES;
4811 #ifdef HAVE_SYSCTLBYNAME
4813 size_t size = sizeof(sysctl_max);
4814 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4819 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4825 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4826 rlimit_max = rl.rlim_cur;
4828 #if defined(RLIM_INFINITY)
4829 if(rl.rlim_cur == RLIM_INFINITY)
4830 rlimit_max = MAX_OPEN_FILES;
4835 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4836 DEBUG(2,("max_open_files: sysctl_max (%d) below "
4837 "minimum Windows limit (%d)\n",
4839 MIN_OPEN_FILES_WINDOWS));
4840 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4843 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4844 DEBUG(2,("rlimit_max: rlimit_max (%d) below "
4845 "minimum Windows limit (%d)\n",
4847 MIN_OPEN_FILES_WINDOWS));
4848 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4851 return MIN(sysctl_max, rlimit_max);
4855 * Common part of freeing allocated data for one parameter.
4857 static void free_one_parameter_common(void *parm_ptr,
4858 struct parm_struct parm)
4860 if ((parm.type == P_STRING) ||
4861 (parm.type == P_USTRING))
4863 string_free((char**)parm_ptr);
4864 } else if (parm.type == P_LIST) {
4865 TALLOC_FREE(*((char***)parm_ptr));
4870 * Free the allocated data for one parameter for a share
4871 * given as a service struct.
4873 static void free_one_parameter(struct service *service,
4874 struct parm_struct parm)
4878 if (parm.p_class != P_LOCAL) {
4882 parm_ptr = lp_local_ptr(service, parm.ptr);
4884 free_one_parameter_common(parm_ptr, parm);
4888 * Free the allocated parameter data of a share given
4889 * as a service struct.
4891 static void free_parameters(struct service *service)
4895 for (i=0; parm_table[i].label; i++) {
4896 free_one_parameter(service, parm_table[i]);
4901 * Free the allocated data for one parameter for a given share
4902 * specified by an snum.
4904 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4908 if (parm.ptr == NULL) {
4913 parm_ptr = parm.ptr;
4914 } else if (parm.p_class != P_LOCAL) {
4917 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4920 free_one_parameter_common(parm_ptr, parm);
4924 * Free the allocated parameter data for a share specified
4927 static void free_parameters_by_snum(int snum)
4931 for (i=0; parm_table[i].label; i++) {
4932 free_one_parameter_by_snum(snum, parm_table[i]);
4937 * Free the allocated global parameters.
4939 static void free_global_parameters(void)
4941 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4944 /***************************************************************************
4945 Initialise the global parameter structure.
4946 ***************************************************************************/
4948 static void init_globals(bool first_time_only)
4950 static bool done_init = False;
4954 /* If requested to initialize only once and we've already done it... */
4955 if (first_time_only && done_init) {
4956 /* ... then we have nothing more to do */
4961 /* The logfile can be set before this is invoked. Free it if so. */
4962 if (Globals.szLogFile != NULL) {
4963 string_free(&Globals.szLogFile);
4964 Globals.szLogFile = NULL;
4968 free_global_parameters();
4971 memset((void *)&Globals, '\0', sizeof(Globals));
4973 for (i = 0; parm_table[i].label; i++) {
4974 if ((parm_table[i].type == P_STRING ||
4975 parm_table[i].type == P_USTRING) &&
4978 string_set((char **)parm_table[i].ptr, "");
4982 string_set(&sDefault.fstype, FSTYPE_STRING);
4983 string_set(&sDefault.szPrintjobUsername, "%U");
4985 init_printer_values(&sDefault);
4988 DEBUG(3, ("Initialising global parameters\n"));
4990 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4991 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4993 /* use the new 'hash2' method by default, with a prefix of 1 */
4994 string_set(&Globals.szManglingMethod, "hash2");
4995 Globals.mangle_prefix = 1;
4997 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4999 /* using UTF8 by default allows us to support all chars */
5000 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5002 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
5003 /* If the system supports nl_langinfo(), try to grab the value
5004 from the user's locale */
5005 string_set(&Globals.display_charset, "LOCALE");
5007 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
5010 /* Use codepage 850 as a default for the dos character set */
5011 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5014 * Allow the default PASSWD_CHAT to be overridden in local.h.
5016 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5018 set_global_myname(myhostname());
5019 string_set(&Globals.szNetbiosName,global_myname());
5021 set_global_myworkgroup(WORKGROUP);
5022 string_set(&Globals.szWorkgroup, lp_workgroup());
5024 string_set(&Globals.szPasswdProgram, "");
5025 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5026 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5027 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5028 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5029 string_set(&Globals.szSocketAddress, "0.0.0.0");
5031 * By default support explicit binding to broadcast
5034 Globals.bNmbdBindExplicitBroadcast = true;
5036 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5037 smb_panic("init_globals: ENOMEM");
5039 string_set(&Globals.szServerString, s);
5041 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5042 DEFAULT_MINOR_VERSION) < 0) {
5043 smb_panic("init_globals: ENOMEM");
5045 string_set(&Globals.szAnnounceVersion, s);
5048 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5051 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5053 string_set(&Globals.szLogonDrive, "");
5054 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5055 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5056 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5058 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5059 string_set(&Globals.szPasswordServer, "*");
5061 Globals.AlgorithmicRidBase = BASE_RID;
5063 Globals.bLoadPrinters = True;
5064 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
5066 Globals.ConfigBackend = config_backend;
5068 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5069 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5070 Globals.max_xmit = 0x4104;
5071 Globals.max_mux = 50; /* This is *needed* for profile support. */
5072 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
5073 Globals.bDisableSpoolss = False;
5074 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5075 Globals.pwordlevel = 0;
5076 Globals.unamelevel = 0;
5077 Globals.deadtime = 0;
5078 Globals.getwd_cache = true;
5079 Globals.bLargeReadwrite = True;
5080 Globals.max_log_size = 5000;
5081 Globals.max_open_files = max_open_files();
5082 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5083 Globals.maxprotocol = PROTOCOL_NT1;
5084 Globals.minprotocol = PROTOCOL_CORE;
5085 Globals.security = SEC_USER;
5086 Globals.paranoid_server_security = True;
5087 Globals.bEncryptPasswords = True;
5088 Globals.bUpdateEncrypt = False;
5089 Globals.clientSchannel = Auto;
5090 Globals.serverSchannel = Auto;
5091 Globals.bReadRaw = True;
5092 Globals.bWriteRaw = True;
5093 Globals.bNullPasswords = False;
5094 Globals.bObeyPamRestrictions = False;
5096 Globals.bSyslogOnly = False;
5097 Globals.bTimestampLogs = True;
5098 string_set(&Globals.szLogLevel, "0");
5099 Globals.bDebugPrefixTimestamp = False;
5100 Globals.bDebugHiresTimestamp = true;
5101 Globals.bDebugPid = False;
5102 Globals.bDebugUid = False;
5103 Globals.bDebugClass = False;
5104 Globals.bEnableCoreFiles = True;
5105 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5106 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5107 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5108 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5109 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5110 Globals.lm_interval = 60;
5111 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5112 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5113 Globals.bNISHomeMap = False;
5114 #ifdef WITH_NISPLUS_HOME
5115 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5117 string_set(&Globals.szNISHomeMapName, "auto.home");
5120 Globals.bTimeServer = False;
5121 Globals.bBindInterfacesOnly = False;
5122 Globals.bUnixPasswdSync = False;
5123 Globals.bPamPasswordChange = False;
5124 Globals.bPasswdChatDebug = False;
5125 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5126 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5127 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5128 Globals.bStatCache = True; /* use stat cache by default */
5129 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5130 Globals.restrict_anonymous = 0;
5131 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5132 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5133 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5134 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5135 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
5136 /* Note, that we will use NTLM2 session security (which is different), if it is available */
5138 Globals.map_to_guest = 0; /* By Default, "Never" */
5139 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5140 Globals.enhanced_browsing = true;
5141 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5142 #ifdef MMAP_BLACKLIST
5143 Globals.bUseMmap = False;
5145 Globals.bUseMmap = True;
5147 Globals.bUnixExtensions = True;
5148 Globals.bResetOnZeroVC = False;
5149 Globals.bLogWriteableFilesOnExit = False;
5150 Globals.bCreateKrb5Conf = true;
5152 /* hostname lookups can be very expensive and are broken on
5153 a large number of sites (tridge) */
5154 Globals.bHostnameLookups = False;
5156 string_set(&Globals.szPassdbBackend, "tdbsam");
5157 string_set(&Globals.szLdapSuffix, "");
5158 string_set(&Globals.szLdapMachineSuffix, "");
5159 string_set(&Globals.szLdapUserSuffix, "");
5160 string_set(&Globals.szLdapGroupSuffix, "");
5161 string_set(&Globals.szLdapIdmapSuffix, "");
5163 string_set(&Globals.szLdapAdminDn, "");
5164 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5165 Globals.ldap_ssl_ads = False;
5166 Globals.ldap_deref = -1;
5167 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5168 Globals.ldap_delete_dn = False;
5169 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5170 Globals.ldap_follow_referral = Auto;
5171 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5172 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5173 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5175 Globals.ldap_debug_level = 0;
5176 Globals.ldap_debug_threshold = 10;
5178 /* This is what we tell the afs client. in reality we set the token
5179 * to never expire, though, when this runs out the afs client will
5180 * forget the token. Set to 0 to get NEVERDATE.*/
5181 Globals.iAfsTokenLifetime = 604800;
5182 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5184 /* these parameters are set to defaults that are more appropriate
5185 for the increasing samba install base:
5187 as a member of the workgroup, that will possibly become a
5188 _local_ master browser (lm = True). this is opposed to a forced
5189 local master browser startup (pm = True).
5191 doesn't provide WINS server service by default (wsupp = False),
5192 and doesn't provide domain master browser services by default, either.
5196 Globals.bMsAddPrinterWizard = True;
5197 Globals.os_level = 20;
5198 Globals.bLocalMaster = True;
5199 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5200 Globals.bDomainLogons = False;
5201 Globals.bBrowseList = True;
5202 Globals.bWINSsupport = False;
5203 Globals.bWINSproxy = False;
5205 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5206 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5208 Globals.bDNSproxy = True;
5210 /* this just means to use them if they exist */
5211 Globals.bKernelOplocks = True;
5213 Globals.bAllowTrustedDomains = True;
5214 string_set(&Globals.szIdmapBackend, "tdb");
5215 Globals.bIdmapReadOnly = false;
5217 string_set(&Globals.szTemplateShell, "/bin/false");
5218 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5219 string_set(&Globals.szWinbindSeparator, "\\");
5221 string_set(&Globals.szCupsServer, "");
5222 string_set(&Globals.szIPrintServer, "");
5224 string_set(&Globals.ctdbdSocket, "");
5225 Globals.szClusterAddresses = NULL;
5226 Globals.clustering = False;
5227 Globals.ctdb_timeout = 0;
5228 Globals.ctdb_locktime_warn_threshold = 0;
5230 Globals.winbind_cache_time = 300; /* 5 minutes */
5231 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5232 Globals.bWinbindEnumUsers = False;
5233 Globals.bWinbindEnumGroups = False;
5234 Globals.bWinbindUseDefaultDomain = False;
5235 Globals.bWinbindTrustedDomainsOnly = False;
5236 Globals.bWinbindNestedGroups = True;
5237 Globals.winbind_expand_groups = 1;
5238 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5239 Globals.bWinbindRefreshTickets = False;
5240 Globals.bWinbindOfflineLogon = False;
5242 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5243 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5245 Globals.bPassdbExpandExplicit = False;
5247 Globals.name_cache_timeout = 660; /* In seconds */
5249 Globals.bUseSpnego = True;
5250 Globals.bClientUseSpnego = True;
5252 Globals.client_signing = Auto;
5253 Globals.server_signing = False;
5255 Globals.bDeferSharingViolations = True;
5256 string_set(&Globals.smb_ports, SMB_PORTS);
5258 Globals.bEnablePrivileges = True;
5259 Globals.bHostMSDfs = True;
5260 Globals.bASUSupport = False;
5262 /* User defined shares. */
5263 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5264 smb_panic("init_globals: ENOMEM");
5266 string_set(&Globals.szUsersharePath, s);
5268 string_set(&Globals.szUsershareTemplateShare, "");
5269 Globals.iUsershareMaxShares = 0;
5270 /* By default disallow sharing of directories not owned by the sharer. */
5271 Globals.bUsershareOwnerOnly = True;
5272 /* By default disallow guest access to usershares. */
5273 Globals.bUsershareAllowGuests = False;
5275 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5277 /* By default no shares out of the registry */
5278 Globals.bRegistryShares = False;
5280 Globals.iminreceivefile = 0;
5282 Globals.bMapUntrustedToDomain = false;
5284 Globals.ismb2_max_read = 1024*1024;
5285 Globals.ismb2_max_write = 1024*1024;
5286 Globals.ismb2_max_trans = 1024*1024;
5289 /*******************************************************************
5290 Convenience routine to grab string parameters into temporary memory
5291 and run standard_sub_basic on them. The buffers can be written to by
5292 callers without affecting the source string.
5293 ********************************************************************/
5295 static char *lp_string(const char *s)
5298 TALLOC_CTX *ctx = talloc_tos();
5300 /* The follow debug is useful for tracking down memory problems
5301 especially if you have an inner loop that is calling a lp_*()
5302 function that returns a string. Perhaps this debug should be
5303 present all the time? */
5306 DEBUG(10, ("lp_string(%s)\n", s));
5312 ret = talloc_sub_basic(ctx,
5313 get_current_username(),
5314 current_user_info.domain,
5316 if (trim_char(ret, '\"', '\"')) {
5317 if (strchr(ret,'\"') != NULL) {
5319 ret = talloc_sub_basic(ctx,
5320 get_current_username(),
5321 current_user_info.domain,
5329 In this section all the functions that are used to access the
5330 parameters from the rest of the program are defined
5333 #define FN_GLOBAL_STRING(fn_name,ptr) \
5334 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5335 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5336 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5337 #define FN_GLOBAL_LIST(fn_name,ptr) \
5338 const char **fn_name(void) {return(*(const char ***)(ptr));}
5339 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5340 bool fn_name(void) {return(*(bool *)(ptr));}
5341 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5342 char fn_name(void) {return(*(char *)(ptr));}
5343 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5344 int fn_name(void) {return(*(int *)(ptr));}
5346 #define FN_LOCAL_STRING(fn_name,val) \
5347 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5348 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5349 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5350 #define FN_LOCAL_LIST(fn_name,val) \
5351 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5352 #define FN_LOCAL_BOOL(fn_name,val) \
5353 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5354 #define FN_LOCAL_INTEGER(fn_name,val) \
5355 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5357 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5358 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5359 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5360 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5361 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5362 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));}
5363 #define FN_LOCAL_CHAR(fn_name,val) \
5364 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5366 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5367 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5368 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5369 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5370 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5371 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5372 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5373 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5374 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5375 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5376 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5377 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5378 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5379 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5380 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5381 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5382 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5383 * build process or in smb.conf, we use that value. Otherwise they
5384 * default to the value of lp_lockdir(). */
5385 char *lp_statedir(void) {
5386 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5387 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5388 return(lp_string(*(char **)(&Globals.szStateDir) ?
5389 *(char **)(&Globals.szStateDir) : ""));
5391 return(lp_string(*(char **)(&Globals.szLockDir) ?
5392 *(char **)(&Globals.szLockDir) : ""));
5394 char *lp_cachedir(void) {
5395 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5396 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5397 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5398 *(char **)(&Globals.szCacheDir) : ""));
5400 return(lp_string(*(char **)(&Globals.szLockDir) ?
5401 *(char **)(&Globals.szLockDir) : ""));
5403 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5404 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5405 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5406 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5407 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5408 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5409 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5410 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5411 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5412 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5413 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5414 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5415 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5416 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5417 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5418 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5419 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5420 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5421 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5422 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5423 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5424 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5425 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5426 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5427 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5428 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5429 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5430 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5431 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5432 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5433 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5434 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5435 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5436 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5437 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5438 * lp_passdb_backend() should be replace by the this macro again after
5441 const char *lp_passdb_backend(void)
5443 char *delim, *quote;
5445 delim = strchr( Globals.szPassdbBackend, ' ');
5446 /* no space at all */
5447 if (delim == NULL) {
5451 quote = strchr(Globals.szPassdbBackend, '"');
5452 /* no quote char or non in the first part */
5453 if (quote == NULL || quote > delim) {
5458 quote = strchr(quote+1, '"');
5459 if (quote == NULL) {
5460 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5462 } else if (*(quote+1) == '\0') {
5463 /* space, fitting quote char, and one backend only */
5466 /* terminate string after the fitting quote char */
5471 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5472 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5473 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5474 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5477 return Globals.szPassdbBackend;
5479 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5480 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5481 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5482 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5483 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5485 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5486 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5487 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5488 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5489 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5490 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5492 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5494 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5495 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5496 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5497 FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
5499 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5501 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5502 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5503 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5504 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5505 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5506 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5507 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5508 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5509 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5510 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5511 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5512 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5513 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5514 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5515 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5516 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5518 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5519 FN_GLOBAL_BOOL(lp_idmap_read_only, &Globals.bIdmapReadOnly)
5520 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5521 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5522 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5523 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5525 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5526 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5527 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5528 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5529 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5530 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5531 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5532 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5533 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5534 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5535 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5536 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5537 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5538 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5539 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5540 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5541 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5542 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5543 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5544 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5546 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5548 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5549 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5550 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5551 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5552 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5553 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5554 &Globals.bLogWriteableFilesOnExit)
5555 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5556 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5557 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5558 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5559 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5560 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5561 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5562 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5563 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5564 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5565 FN_GLOBAL_BOOL(_lp_readraw, &Globals.bReadRaw)
5566 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5567 FN_GLOBAL_BOOL(_lp_writeraw, &Globals.bWriteRaw)
5568 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5569 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5570 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5571 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5572 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5573 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5574 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5575 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5576 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5577 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5578 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5579 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5580 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5581 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5582 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5583 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5584 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5585 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5586 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5587 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5588 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5589 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5590 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5591 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5592 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5593 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5594 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5595 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5596 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5597 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5598 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5599 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5600 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5601 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5602 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5603 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5604 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5605 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5606 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5607 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5608 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5609 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5610 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5611 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5612 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5613 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5614 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5615 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5616 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5617 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5618 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5619 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5620 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5621 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5622 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5623 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5624 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5625 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5626 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5627 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5628 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5629 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5630 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5631 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5632 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5633 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5634 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5635 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5636 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5637 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5638 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5639 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5640 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5641 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5642 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5643 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5644 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5645 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5646 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5647 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5648 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5649 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5650 FN_GLOBAL_INTEGER(lp_smb2_max_read, &Globals.ismb2_max_read)
5651 FN_GLOBAL_INTEGER(lp_smb2_max_write, &Globals.ismb2_max_write)
5652 FN_GLOBAL_INTEGER(lp_smb2_max_trans, &Globals.ismb2_max_trans)
5654 FN_LOCAL_STRING(lp_preexec, szPreExec)
5655 FN_LOCAL_STRING(lp_postexec, szPostExec)
5656 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5657 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5658 FN_LOCAL_STRING(lp_servicename, szService)
5659 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5660 FN_LOCAL_STRING(lp_pathname, szPath)
5661 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5662 FN_LOCAL_STRING(lp_username, szUsername)
5663 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5664 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5665 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5666 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5667 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5668 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5669 int lp_cups_encrypt(void)
5672 #ifdef HAVE_HTTPCONNECTENCRYPT
5673 switch (Globals.CupsEncrypt) {
5675 result = HTTP_ENCRYPT_REQUIRED;
5678 result = HTTP_ENCRYPT_ALWAYS;
5681 result = HTTP_ENCRYPT_NEVER;
5687 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5688 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5689 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5690 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5691 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5692 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5693 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, &Globals.ctdb_locktime_warn_threshold)
5694 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5695 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5696 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5697 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5698 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5699 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5700 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5701 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5702 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5703 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5704 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5705 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5706 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5707 FN_LOCAL_STRING(lp_comment, comment)
5708 FN_LOCAL_STRING(lp_force_user, force_user)
5709 FN_LOCAL_STRING(lp_force_group, force_group)
5710 FN_LOCAL_LIST(lp_readlist, readlist)
5711 FN_LOCAL_LIST(lp_writelist, writelist)
5712 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5713 FN_LOCAL_STRING(lp_fstype, fstype)
5714 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5715 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5716 static FN_LOCAL_STRING(lp_volume, volume)
5717 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5718 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5719 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5720 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5721 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5722 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5723 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5724 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5725 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5726 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5727 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5728 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5729 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5730 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5731 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5732 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5733 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5734 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5735 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5736 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5737 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5738 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5739 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5740 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5741 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5742 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5743 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5744 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5745 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5746 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5747 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5748 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5749 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5750 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5751 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5752 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5753 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5754 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5755 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5756 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5757 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5758 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5759 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5760 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5761 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5762 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5763 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5764 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5765 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5766 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5767 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5768 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5769 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5770 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5771 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5772 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5773 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5774 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5775 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5776 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5777 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5778 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5779 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5780 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5781 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5782 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5783 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5784 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5785 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5786 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5787 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5788 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5789 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5790 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5791 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5792 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5793 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5794 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5795 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5796 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5797 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5798 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5799 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5800 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5801 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5802 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5803 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5804 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5805 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5806 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5807 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5808 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5809 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5810 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5811 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5812 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5813 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5814 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5815 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5817 /* local prototypes */
5819 static int map_parameter(const char *pszParmName);
5820 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5821 static const char *get_boolean(bool bool_value);
5822 static int getservicebyname(const char *pszServiceName,
5823 struct service *pserviceDest);
5824 static void copy_service(struct service *pserviceDest,
5825 struct service *pserviceSource,
5826 struct bitmap *pcopymapDest);
5827 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5829 static bool do_section(const char *pszSectionName, void *userdata);
5830 static void init_copymap(struct service *pservice);
5831 static bool hash_a_service(const char *name, int number);
5832 static void free_service_byindex(int iService);
5833 static void free_param_opts(struct param_opt_struct **popts);
5834 static void show_parameter(int parmIndex);
5835 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5838 * This is a helper function for parametrical options support. It returns a
5839 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5840 * parametrical functions are quite simple
5842 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5845 bool global_section = False;
5847 struct param_opt_struct *data;
5849 if (snum >= iNumServices) return NULL;
5852 data = Globals.param_opt;
5853 global_section = True;
5855 data = ServicePtrs[snum]->param_opt;
5858 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5859 DEBUG(0,("asprintf failed!\n"));
5864 if (strwicmp(data->key, param_key) == 0) {
5865 string_free(¶m_key);
5871 if (!global_section) {
5872 /* Try to fetch the same option but from globals */
5873 /* but only if we are not already working with Globals */
5874 data = Globals.param_opt;
5876 if (strwicmp(data->key, param_key) == 0) {
5877 string_free(¶m_key);
5884 string_free(¶m_key);
5890 #define MISSING_PARAMETER(name) \
5891 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5893 /*******************************************************************
5894 convenience routine to return int parameters.
5895 ********************************************************************/
5896 static int lp_int(const char *s)
5900 MISSING_PARAMETER(lp_int);
5904 return (int)strtol(s, NULL, 0);
5907 /*******************************************************************
5908 convenience routine to return unsigned long parameters.
5909 ********************************************************************/
5910 static unsigned long lp_ulong(const char *s)
5914 MISSING_PARAMETER(lp_ulong);
5918 return strtoul(s, NULL, 0);
5921 /*******************************************************************
5922 convenience routine to return boolean parameters.
5923 ********************************************************************/
5924 static bool lp_bool(const char *s)
5929 MISSING_PARAMETER(lp_bool);
5933 if (!set_boolean(s, &ret)) {
5934 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5941 /*******************************************************************
5942 convenience routine to return enum parameters.
5943 ********************************************************************/
5944 static int lp_enum(const char *s,const struct enum_list *_enum)
5948 if (!s || !*s || !_enum) {
5949 MISSING_PARAMETER(lp_enum);
5953 for (i=0; _enum[i].name; i++) {
5954 if (strequal(_enum[i].name,s))
5955 return _enum[i].value;
5958 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5962 #undef MISSING_PARAMETER
5964 /* DO NOT USE lp_parm_string ANYMORE!!!!
5965 * use lp_parm_const_string or lp_parm_talloc_string
5967 * lp_parm_string is only used to let old modules find this symbol
5969 #undef lp_parm_string
5970 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5971 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5973 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5976 /* Return parametric option from a given service. Type is a part of option before ':' */
5977 /* Parametric option has following syntax: 'Type: option = value' */
5978 /* the returned value is talloced on the talloc_tos() */
5979 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5981 struct param_opt_struct *data = get_parametrics(snum, type, option);
5983 if (data == NULL||data->value==NULL) {
5985 return lp_string(def);
5991 return lp_string(data->value);
5994 /* Return parametric option from a given service. Type is a part of option before ':' */
5995 /* Parametric option has following syntax: 'Type: option = value' */
5996 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5998 struct param_opt_struct *data = get_parametrics(snum, type, option);
6000 if (data == NULL||data->value==NULL)
6006 /* Return parametric option from a given service. Type is a part of option before ':' */
6007 /* Parametric option has following syntax: 'Type: option = value' */
6009 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6011 struct param_opt_struct *data = get_parametrics(snum, type, option);
6013 if (data == NULL||data->value==NULL)
6014 return (const char **)def;
6016 if (data->list==NULL) {
6017 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
6020 return (const char **)data->list;
6023 /* Return parametric option from a given service. Type is a part of option before ':' */
6024 /* Parametric option has following syntax: 'Type: option = value' */
6026 int lp_parm_int(int snum, const char *type, const char *option, int def)
6028 struct param_opt_struct *data = get_parametrics(snum, type, option);
6030 if (data && data->value && *data->value)
6031 return lp_int(data->value);
6036 /* Return parametric option from a given service. Type is a part of option before ':' */
6037 /* Parametric option has following syntax: 'Type: option = value' */
6039 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6041 struct param_opt_struct *data = get_parametrics(snum, type, option);
6043 if (data && data->value && *data->value)
6044 return lp_ulong(data->value);
6049 /* Return parametric option from a given service. Type is a part of option before ':' */
6050 /* Parametric option has following syntax: 'Type: option = value' */
6052 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6054 struct param_opt_struct *data = get_parametrics(snum, type, option);
6056 if (data && data->value && *data->value)
6057 return lp_bool(data->value);
6062 /* Return parametric option from a given service. Type is a part of option before ':' */
6063 /* Parametric option has following syntax: 'Type: option = value' */
6065 int lp_parm_enum(int snum, const char *type, const char *option,
6066 const struct enum_list *_enum, int def)
6068 struct param_opt_struct *data = get_parametrics(snum, type, option);
6070 if (data && data->value && *data->value && _enum)
6071 return lp_enum(data->value, _enum);
6077 /***************************************************************************
6078 Initialise a service to the defaults.
6079 ***************************************************************************/
6081 static void init_service(struct service *pservice)
6083 memset((char *)pservice, '\0', sizeof(struct service));
6084 copy_service(pservice, &sDefault, NULL);
6089 * free a param_opts structure.
6090 * param_opts handling should be moved to talloc;
6091 * then this whole functions reduces to a TALLOC_FREE().
6094 static void free_param_opts(struct param_opt_struct **popts)
6096 struct param_opt_struct *opt, *next_opt;
6098 if (popts == NULL) {
6102 if (*popts != NULL) {
6103 DEBUG(5, ("Freeing parametrics:\n"));
6106 while (opt != NULL) {
6107 string_free(&opt->key);
6108 string_free(&opt->value);
6109 TALLOC_FREE(opt->list);
6110 next_opt = opt->next;
6117 /***************************************************************************
6118 Free the dynamically allocated parts of a service struct.
6119 ***************************************************************************/
6121 static void free_service(struct service *pservice)
6126 if (pservice->szService)
6127 DEBUG(5, ("free_service: Freeing service %s\n",
6128 pservice->szService));
6130 free_parameters(pservice);
6132 string_free(&pservice->szService);
6133 TALLOC_FREE(pservice->copymap);
6135 free_param_opts(&pservice->param_opt);
6137 ZERO_STRUCTP(pservice);
6141 /***************************************************************************
6142 remove a service indexed in the ServicePtrs array from the ServiceHash
6143 and free the dynamically allocated parts
6144 ***************************************************************************/
6146 static void free_service_byindex(int idx)
6148 if ( !LP_SNUM_OK(idx) )
6151 ServicePtrs[idx]->valid = False;
6152 invalid_services[num_invalid_services++] = idx;
6154 /* we have to cleanup the hash record */
6156 if (ServicePtrs[idx]->szService) {
6157 char *canon_name = canonicalize_servicename(
6159 ServicePtrs[idx]->szService );
6161 dbwrap_delete_bystring(ServiceHash, canon_name );
6162 TALLOC_FREE(canon_name);
6165 free_service(ServicePtrs[idx]);
6168 /***************************************************************************
6169 Add a new service to the services array initialising it with the given
6171 ***************************************************************************/
6173 static int add_a_service(const struct service *pservice, const char *name)
6176 struct service tservice;
6177 int num_to_alloc = iNumServices + 1;
6179 tservice = *pservice;
6181 /* it might already exist */
6183 i = getservicebyname(name, NULL);
6185 /* Clean all parametric options for service */
6186 /* They will be added during parsing again */
6187 free_param_opts(&ServicePtrs[i]->param_opt);
6192 /* find an invalid one */
6194 if (num_invalid_services > 0) {
6195 i = invalid_services[--num_invalid_services];
6198 /* if not, then create one */
6199 if (i == iNumServices) {
6200 struct service **tsp;
6203 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6205 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6209 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6210 if (!ServicePtrs[iNumServices]) {
6211 DEBUG(0,("add_a_service: out of memory!\n"));
6216 /* enlarge invalid_services here for now... */
6217 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6219 if (tinvalid == NULL) {
6220 DEBUG(0,("add_a_service: failed to enlarge "
6221 "invalid_services!\n"));
6224 invalid_services = tinvalid;
6226 free_service_byindex(i);
6229 ServicePtrs[i]->valid = True;
6231 init_service(ServicePtrs[i]);
6232 copy_service(ServicePtrs[i], &tservice, NULL);
6234 string_set(&ServicePtrs[i]->szService, name);
6236 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6237 i, ServicePtrs[i]->szService));
6239 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6246 /***************************************************************************
6247 Convert a string to uppercase and remove whitespaces.
6248 ***************************************************************************/
6250 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6255 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6259 result = talloc_strdup(ctx, src);
6260 SMB_ASSERT(result != NULL);
6266 /***************************************************************************
6267 Add a name/index pair for the services array to the hash table.
6268 ***************************************************************************/
6270 static bool hash_a_service(const char *name, int idx)
6274 if ( !ServiceHash ) {
6275 DEBUG(10,("hash_a_service: creating servicehash\n"));
6276 ServiceHash = db_open_rbt(NULL);
6277 if ( !ServiceHash ) {
6278 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6283 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6286 canon_name = canonicalize_servicename(talloc_tos(), name );
6288 dbwrap_store_bystring(ServiceHash, canon_name,
6289 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6292 TALLOC_FREE(canon_name);
6297 /***************************************************************************
6298 Add a new home service, with the specified home directory, defaults coming
6300 ***************************************************************************/
6302 bool lp_add_home(const char *pszHomename, int iDefaultService,
6303 const char *user, const char *pszHomedir)
6307 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6308 pszHomedir[0] == '\0') {
6312 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6317 if (!(*(ServicePtrs[iDefaultService]->szPath))
6318 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6319 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6322 if (!(*(ServicePtrs[i]->comment))) {
6323 char *comment = NULL;
6324 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6327 string_set(&ServicePtrs[i]->comment, comment);
6331 /* set the browseable flag from the global default */
6333 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6334 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6336 ServicePtrs[i]->autoloaded = True;
6338 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6339 user, ServicePtrs[i]->szPath ));
6344 /***************************************************************************
6345 Add a new service, based on an old one.
6346 ***************************************************************************/
6348 int lp_add_service(const char *pszService, int iDefaultService)
6350 if (iDefaultService < 0) {
6351 return add_a_service(&sDefault, pszService);
6354 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6357 /***************************************************************************
6358 Add the IPC service.
6359 ***************************************************************************/
6361 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6363 char *comment = NULL;
6364 int i = add_a_service(&sDefault, ipc_name);
6369 if (asprintf(&comment, "IPC Service (%s)",
6370 Globals.szServerString) < 0) {
6374 string_set(&ServicePtrs[i]->szPath, tmpdir());
6375 string_set(&ServicePtrs[i]->szUsername, "");
6376 string_set(&ServicePtrs[i]->comment, comment);
6377 string_set(&ServicePtrs[i]->fstype, "IPC");
6378 ServicePtrs[i]->iMaxConnections = 0;
6379 ServicePtrs[i]->bAvailable = True;
6380 ServicePtrs[i]->bRead_only = True;
6381 ServicePtrs[i]->bGuest_only = False;
6382 ServicePtrs[i]->bAdministrative_share = True;
6383 ServicePtrs[i]->bGuest_ok = guest_ok;
6384 ServicePtrs[i]->bPrint_ok = False;
6385 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6387 DEBUG(3, ("adding IPC service\n"));
6393 /***************************************************************************
6394 Add a new printer service, with defaults coming from service iFrom.
6395 ***************************************************************************/
6397 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6399 const char *comment = "From Printcap";
6400 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6405 /* note that we do NOT default the availability flag to True - */
6406 /* we take it from the default service passed. This allows all */
6407 /* dynamic printers to be disabled by disabling the [printers] */
6408 /* entry (if/when the 'available' keyword is implemented!). */
6410 /* the printer name is set to the service name. */
6411 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6412 string_set(&ServicePtrs[i]->comment, comment);
6414 /* set the browseable flag from the gloabl default */
6415 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6417 /* Printers cannot be read_only. */
6418 ServicePtrs[i]->bRead_only = False;
6419 /* No share modes on printer services. */
6420 ServicePtrs[i]->bShareModes = False;
6421 /* No oplocks on printer services. */
6422 ServicePtrs[i]->bOpLocks = False;
6423 /* Printer services must be printable. */
6424 ServicePtrs[i]->bPrint_ok = True;
6426 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6432 /***************************************************************************
6433 Check whether the given parameter name is valid.
6434 Parametric options (names containing a colon) are considered valid.
6435 ***************************************************************************/
6437 bool lp_parameter_is_valid(const char *pszParmName)
6439 return ((map_parameter(pszParmName) != -1) ||
6440 (strchr(pszParmName, ':') != NULL));
6443 /***************************************************************************
6444 Check whether the given name is the name of a global parameter.
6445 Returns True for strings belonging to parameters of class
6446 P_GLOBAL, False for all other strings, also for parametric options
6447 and strings not belonging to any option.
6448 ***************************************************************************/
6450 bool lp_parameter_is_global(const char *pszParmName)
6452 int num = map_parameter(pszParmName);
6455 return (parm_table[num].p_class == P_GLOBAL);
6461 /**************************************************************************
6462 Check whether the given name is the canonical name of a parameter.
6463 Returns False if it is not a valid parameter Name.
6464 For parametric options, True is returned.
6465 **************************************************************************/
6467 bool lp_parameter_is_canonical(const char *parm_name)
6469 if (!lp_parameter_is_valid(parm_name)) {
6473 return (map_parameter(parm_name) ==
6474 map_parameter_canonical(parm_name, NULL));
6477 /**************************************************************************
6478 Determine the canonical name for a parameter.
6479 Indicate when it is an inverse (boolean) synonym instead of a
6481 **************************************************************************/
6483 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6488 if (!lp_parameter_is_valid(parm_name)) {
6493 num = map_parameter_canonical(parm_name, inverse);
6495 /* parametric option */
6496 *canon_parm = parm_name;
6498 *canon_parm = parm_table[num].label;
6505 /**************************************************************************
6506 Determine the canonical name for a parameter.
6507 Turn the value given into the inverse boolean expression when
6508 the synonym is an invers boolean synonym.
6510 Return True if parm_name is a valid parameter name and
6511 in case it is an invers boolean synonym, if the val string could
6512 successfully be converted to the reverse bool.
6513 Return false in all other cases.
6514 **************************************************************************/
6516 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6518 const char **canon_parm,
6519 const char **canon_val)
6524 if (!lp_parameter_is_valid(parm_name)) {
6530 num = map_parameter_canonical(parm_name, &inverse);
6532 /* parametric option */
6533 *canon_parm = parm_name;
6536 *canon_parm = parm_table[num].label;
6538 if (!lp_invert_boolean(val, canon_val)) {
6550 /***************************************************************************
6551 Map a parameter's string representation to something we can use.
6552 Returns False if the parameter string is not recognised, else TRUE.
6553 ***************************************************************************/
6555 static int map_parameter(const char *pszParmName)
6559 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6562 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6563 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6566 /* Warn only if it isn't parametric option */
6567 if (strchr(pszParmName, ':') == NULL)
6568 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6569 /* We do return 'fail' for parametric options as well because they are
6570 stored in different storage
6575 /***************************************************************************
6576 Map a parameter's string representation to the index of the canonical
6577 form of the parameter (it might be a synonym).
6578 Returns -1 if the parameter string is not recognised.
6579 ***************************************************************************/
6581 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6583 int parm_num, canon_num;
6584 bool loc_inverse = False;
6586 parm_num = map_parameter(pszParmName);
6587 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6588 /* invalid, parametric or no canidate for synonyms ... */
6592 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6593 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6594 parm_num = canon_num;
6600 if (inverse != NULL) {
6601 *inverse = loc_inverse;
6606 /***************************************************************************
6607 return true if parameter number parm1 is a synonym of parameter
6608 number parm2 (parm2 being the principal name).
6609 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6611 ***************************************************************************/
6613 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6615 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6616 (parm_table[parm1].flags & FLAG_HIDE) &&
6617 !(parm_table[parm2].flags & FLAG_HIDE))
6619 if (inverse != NULL) {
6620 if ((parm_table[parm1].type == P_BOOLREV) &&
6621 (parm_table[parm2].type == P_BOOL))
6633 /***************************************************************************
6634 Show one parameter's name, type, [values,] and flags.
6635 (helper functions for show_parameter_list)
6636 ***************************************************************************/
6638 static void show_parameter(int parmIndex)
6640 int enumIndex, flagIndex;
6645 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6646 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6648 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6649 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6650 FLAG_HIDE, FLAG_DOS_STRING};
6651 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6652 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6653 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6655 printf("%s=%s", parm_table[parmIndex].label,
6656 type[parm_table[parmIndex].type]);
6657 if (parm_table[parmIndex].type == P_ENUM) {
6660 parm_table[parmIndex].enum_list[enumIndex].name;
6664 enumIndex ? "|" : "",
6665 parm_table[parmIndex].enum_list[enumIndex].name);
6670 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6671 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6674 flag_names[flagIndex]);
6679 /* output synonyms */
6681 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6682 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6683 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6684 parm_table[parmIndex2].label);
6685 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6687 printf(" (synonyms: ");
6692 printf("%s%s", parm_table[parmIndex2].label,
6693 inverse ? "[i]" : "");
6703 /***************************************************************************
6704 Show all parameter's name, type, [values,] and flags.
6705 ***************************************************************************/
6707 void show_parameter_list(void)
6709 int classIndex, parmIndex;
6710 const char *section_names[] = { "local", "global", NULL};
6712 for (classIndex=0; section_names[classIndex]; classIndex++) {
6713 printf("[%s]\n", section_names[classIndex]);
6714 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6715 if (parm_table[parmIndex].p_class == classIndex) {
6716 show_parameter(parmIndex);
6722 /***************************************************************************
6723 Check if a given string correctly represents a boolean value.
6724 ***************************************************************************/
6726 bool lp_string_is_valid_boolean(const char *parm_value)
6728 return set_boolean(parm_value, NULL);
6731 /***************************************************************************
6732 Get the standard string representation of a boolean value ("yes" or "no")
6733 ***************************************************************************/
6735 static const char *get_boolean(bool bool_value)
6737 static const char *yes_str = "yes";
6738 static const char *no_str = "no";
6740 return (bool_value ? yes_str : no_str);
6743 /***************************************************************************
6744 Provide the string of the negated boolean value associated to the boolean
6745 given as a string. Returns False if the passed string does not correctly
6746 represent a boolean.
6747 ***************************************************************************/
6749 bool lp_invert_boolean(const char *str, const char **inverse_str)
6753 if (!set_boolean(str, &val)) {
6757 *inverse_str = get_boolean(!val);
6761 /***************************************************************************
6762 Provide the canonical string representation of a boolean value given
6763 as a string. Return True on success, False if the string given does
6764 not correctly represent a boolean.
6765 ***************************************************************************/
6767 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6771 if (!set_boolean(str, &val)) {
6775 *canon_str = get_boolean(val);
6779 /***************************************************************************
6780 Find a service by name. Otherwise works like get_service.
6781 ***************************************************************************/
6783 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6789 if (ServiceHash == NULL) {
6793 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6795 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6797 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6798 iService = *(int *)data.dptr;
6801 TALLOC_FREE(canon_name);
6803 if ((iService != -1) && (LP_SNUM_OK(iService))
6804 && (pserviceDest != NULL)) {
6805 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6811 /***************************************************************************
6812 Copy a service structure to another.
6813 If pcopymapDest is NULL then copy all fields
6814 ***************************************************************************/
6817 * Add a parametric option to a param_opt_struct,
6818 * replacing old value, if already present.
6820 static void set_param_opt(struct param_opt_struct **opt_list,
6821 const char *opt_name,
6822 const char *opt_value)
6824 struct param_opt_struct *new_opt, *opt;
6827 if (opt_list == NULL) {
6834 /* Traverse destination */
6836 /* If we already have same option, override it */
6837 if (strwicmp(opt->key, opt_name) == 0) {
6838 string_free(&opt->value);
6839 TALLOC_FREE(opt->list);
6840 opt->value = SMB_STRDUP(opt_value);
6847 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6848 new_opt->key = SMB_STRDUP(opt_name);
6849 new_opt->value = SMB_STRDUP(opt_value);
6850 new_opt->list = NULL;
6851 DLIST_ADD(*opt_list, new_opt);
6855 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6856 struct bitmap *pcopymapDest)
6859 bool bcopyall = (pcopymapDest == NULL);
6860 struct param_opt_struct *data;
6862 for (i = 0; parm_table[i].label; i++)
6863 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6864 (bcopyall || bitmap_query(pcopymapDest,i))) {
6865 void *def_ptr = parm_table[i].ptr;
6867 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6870 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6873 switch (parm_table[i].type) {
6876 *(bool *)dest_ptr = *(bool *)src_ptr;
6882 *(int *)dest_ptr = *(int *)src_ptr;
6886 *(char *)dest_ptr = *(char *)src_ptr;
6890 string_set((char **)dest_ptr,
6895 string_set((char **)dest_ptr,
6897 strupper_m(*(char **)dest_ptr);
6900 TALLOC_FREE(*((char ***)dest_ptr));
6901 *((char ***)dest_ptr) = str_list_copy(NULL,
6902 *(const char ***)src_ptr);
6910 init_copymap(pserviceDest);
6911 if (pserviceSource->copymap)
6912 bitmap_copy(pserviceDest->copymap,
6913 pserviceSource->copymap);
6916 data = pserviceSource->param_opt;
6918 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6923 /***************************************************************************
6924 Check a service for consistency. Return False if the service is in any way
6925 incomplete or faulty, else True.
6926 ***************************************************************************/
6928 bool service_ok(int iService)
6933 if (ServicePtrs[iService]->szService[0] == '\0') {
6934 DEBUG(0, ("The following message indicates an internal error:\n"));
6935 DEBUG(0, ("No service name in service entry.\n"));
6939 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6940 /* I can't see why you'd want a non-printable printer service... */
6941 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6942 if (!ServicePtrs[iService]->bPrint_ok) {
6943 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6944 ServicePtrs[iService]->szService));
6945 ServicePtrs[iService]->bPrint_ok = True;
6947 /* [printers] service must also be non-browsable. */
6948 if (ServicePtrs[iService]->bBrowseable)
6949 ServicePtrs[iService]->bBrowseable = False;
6952 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6953 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6954 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6956 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6957 ServicePtrs[iService]->szService));
6958 ServicePtrs[iService]->bAvailable = False;
6961 /* If a service is flagged unavailable, log the fact at level 1. */
6962 if (!ServicePtrs[iService]->bAvailable)
6963 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6964 ServicePtrs[iService]->szService));
6969 static struct smbconf_ctx *lp_smbconf_ctx(void)
6972 static struct smbconf_ctx *conf_ctx = NULL;
6974 if (conf_ctx == NULL) {
6975 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6976 if (!W_ERROR_IS_OK(werr)) {
6977 DEBUG(1, ("error initializing registry configuration: "
6978 "%s\n", win_errstr(werr)));
6986 static bool process_smbconf_service(struct smbconf_service *service)
6991 if (service == NULL) {
6995 ret = do_section(service->name, NULL);
6999 for (count = 0; count < service->num_params; count++) {
7000 ret = do_parameter(service->param_names[count],
7001 service->param_values[count],
7007 if (iServiceIndex >= 0) {
7008 return service_ok(iServiceIndex);
7014 * load a service from registry and activate it
7016 bool process_registry_service(const char *service_name)
7019 struct smbconf_service *service = NULL;
7020 TALLOC_CTX *mem_ctx = talloc_stackframe();
7021 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7024 if (conf_ctx == NULL) {
7028 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7030 if (!smbconf_share_exists(conf_ctx, service_name)) {
7032 * Registry does not contain data for this service (yet),
7033 * but make sure lp_load doesn't return false.
7039 werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7040 if (!W_ERROR_IS_OK(werr)) {
7044 ret = process_smbconf_service(service);
7050 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7053 TALLOC_FREE(mem_ctx);
7058 * process_registry_globals
7060 static bool process_registry_globals(void)
7064 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7066 ret = do_parameter("registry shares", "yes", NULL);
7071 return process_registry_service(GLOBAL_NAME);
7074 bool process_registry_shares(void)
7078 struct smbconf_service **service = NULL;
7079 uint32_t num_shares = 0;
7080 TALLOC_CTX *mem_ctx = talloc_stackframe();
7081 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7084 if (conf_ctx == NULL) {
7088 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7089 if (!W_ERROR_IS_OK(werr)) {
7095 for (count = 0; count < num_shares; count++) {
7096 if (strequal(service[count]->name, GLOBAL_NAME)) {
7099 ret = process_smbconf_service(service[count]);
7106 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7109 TALLOC_FREE(mem_ctx);
7113 #define MAX_INCLUDE_DEPTH 100
7115 static uint8_t include_depth;
7117 static struct file_lists {
7118 struct file_lists *next;
7122 } *file_lists = NULL;
7124 /*******************************************************************
7125 Keep a linked list of all config files so we know when one has changed
7126 it's date and needs to be reloaded.
7127 ********************************************************************/
7129 static void add_to_file_list(const char *fname, const char *subfname)
7131 struct file_lists *f = file_lists;
7134 if (f->name && !strcmp(f->name, fname))
7140 f = SMB_MALLOC_P(struct file_lists);
7143 f->next = file_lists;
7144 f->name = SMB_STRDUP(fname);
7149 f->subfname = SMB_STRDUP(subfname);
7156 f->modtime = file_modtime(subfname);
7158 time_t t = file_modtime(subfname);
7166 * Free the file lists
7168 static void free_file_list(void)
7170 struct file_lists *f;
7171 struct file_lists *next;
7176 SAFE_FREE( f->name );
7177 SAFE_FREE( f->subfname );
7186 * Utility function for outsiders to check if we're running on registry.
7188 bool lp_config_backend_is_registry(void)
7190 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7194 * Utility function to check if the config backend is FILE.
7196 bool lp_config_backend_is_file(void)
7198 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7201 /*******************************************************************
7202 Check if a config file has changed date.
7203 ********************************************************************/
7205 bool lp_file_list_changed(void)
7207 struct file_lists *f = file_lists;
7209 DEBUG(6, ("lp_file_list_changed()\n"));
7214 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7215 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7217 if (conf_ctx == NULL) {
7220 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7223 DEBUGADD(6, ("registry config changed\n"));
7228 n2 = talloc_sub_basic(talloc_tos(),
7229 get_current_username(),
7230 current_user_info.domain,
7235 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7236 f->name, n2, ctime(&f->modtime)));
7238 mod_time = file_modtime(n2);
7241 ((f->modtime != mod_time) ||
7242 (f->subfname == NULL) ||
7243 (strcmp(n2, f->subfname) != 0)))
7246 ("file %s modified: %s\n", n2,
7248 f->modtime = mod_time;
7249 SAFE_FREE(f->subfname);
7250 f->subfname = SMB_STRDUP(n2);
7262 /***************************************************************************
7263 Run standard_sub_basic on netbios name... needed because global_myname
7264 is not accessed through any lp_ macro.
7265 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7266 ***************************************************************************/
7268 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7271 char *netbios_name = talloc_sub_basic(
7272 talloc_tos(), get_current_username(), current_user_info.domain,
7275 ret = set_global_myname(netbios_name);
7276 TALLOC_FREE(netbios_name);
7277 string_set(&Globals.szNetbiosName,global_myname());
7279 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7285 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7287 if (strcmp(*ptr, pszParmValue) != 0) {
7288 string_set(ptr, pszParmValue);
7296 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7300 ret = set_global_myworkgroup(pszParmValue);
7301 string_set(&Globals.szWorkgroup,lp_workgroup());
7306 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7310 ret = set_global_scope(pszParmValue);
7311 string_set(&Globals.szNetbiosScope,global_scope());
7316 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7318 TALLOC_FREE(Globals.szNetbiosAliases);
7319 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7320 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7323 /***************************************************************************
7324 Handle the include operation.
7325 ***************************************************************************/
7326 static bool bAllowIncludeRegistry = true;
7328 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7332 if (include_depth >= MAX_INCLUDE_DEPTH) {
7333 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7338 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7339 if (!bAllowIncludeRegistry) {
7342 if (bInGlobalSection) {
7345 ret = process_registry_globals();
7349 DEBUG(1, ("\"include = registry\" only effective "
7350 "in %s section\n", GLOBAL_NAME));
7355 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7356 current_user_info.domain,
7359 add_to_file_list(pszParmValue, fname);
7361 string_set(ptr, fname);
7363 if (file_exist(fname)) {
7366 ret = pm_process(fname, do_section, do_parameter, NULL);
7372 DEBUG(2, ("Can't find include file %s\n", fname));
7377 /***************************************************************************
7378 Handle the interpretation of the copy parameter.
7379 ***************************************************************************/
7381 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7385 struct service serviceTemp;
7387 string_set(ptr, pszParmValue);
7389 init_service(&serviceTemp);
7393 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7395 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7396 if (iTemp == iServiceIndex) {
7397 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7399 copy_service(ServicePtrs[iServiceIndex],
7401 ServicePtrs[iServiceIndex]->copymap);
7405 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7409 free_service(&serviceTemp);
7413 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7415 Globals.ldap_debug_level = lp_int(pszParmValue);
7416 init_ldap_debugging();
7420 /***************************************************************************
7421 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7426 idmap uid = 1000-1999
7429 We only do simple parsing checks here. The strings are parsed into useful
7430 structures in the idmap daemon code.
7432 ***************************************************************************/
7434 /* Some lp_ routines to return idmap [ug]id information */
7436 static uid_t idmap_uid_low, idmap_uid_high;
7437 static gid_t idmap_gid_low, idmap_gid_high;
7439 bool lp_idmap_uid(uid_t *low, uid_t *high)
7441 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7445 *low = idmap_uid_low;
7448 *high = idmap_uid_high;
7453 bool lp_idmap_gid(gid_t *low, gid_t *high)
7455 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7459 *low = idmap_gid_low;
7462 *high = idmap_gid_high;
7467 /* Do some simple checks on "idmap [ug]id" parameter values */
7469 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7473 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7478 string_set(ptr, pszParmValue);
7480 idmap_uid_low = low;
7481 idmap_uid_high = high;
7486 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7490 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7495 string_set(ptr, pszParmValue);
7497 idmap_gid_low = low;
7498 idmap_gid_high = high;
7503 /***************************************************************************
7504 Handle the DEBUG level list.
7505 ***************************************************************************/
7507 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7509 string_set(ptr, pszParmValueIn);
7510 return debug_parse_levels(pszParmValueIn);
7513 /***************************************************************************
7514 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7515 ***************************************************************************/
7517 static const char *append_ldap_suffix( const char *str )
7519 const char *suffix_string;
7522 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7523 Globals.szLdapSuffix );
7524 if ( !suffix_string ) {
7525 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7529 return suffix_string;
7532 const char *lp_ldap_machine_suffix(void)
7534 if (Globals.szLdapMachineSuffix[0])
7535 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7537 return lp_string(Globals.szLdapSuffix);
7540 const char *lp_ldap_user_suffix(void)
7542 if (Globals.szLdapUserSuffix[0])
7543 return append_ldap_suffix(Globals.szLdapUserSuffix);
7545 return lp_string(Globals.szLdapSuffix);
7548 const char *lp_ldap_group_suffix(void)
7550 if (Globals.szLdapGroupSuffix[0])
7551 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7553 return lp_string(Globals.szLdapSuffix);
7556 const char *lp_ldap_idmap_suffix(void)
7558 if (Globals.szLdapIdmapSuffix[0])
7559 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7561 return lp_string(Globals.szLdapSuffix);
7564 /****************************************************************************
7565 set the value for a P_ENUM
7566 ***************************************************************************/
7568 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7573 for (i = 0; parm->enum_list[i].name; i++) {
7574 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7575 *ptr = parm->enum_list[i].value;
7579 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7580 pszParmValue, parm->label));
7583 /***************************************************************************
7584 ***************************************************************************/
7586 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7588 static int parm_num = -1;
7591 if ( parm_num == -1 )
7592 parm_num = map_parameter( "printing" );
7594 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7599 s = ServicePtrs[snum];
7601 init_printer_values( s );
7607 /***************************************************************************
7608 Initialise a copymap.
7609 ***************************************************************************/
7611 static void init_copymap(struct service *pservice)
7615 TALLOC_FREE(pservice->copymap);
7617 pservice->copymap = bitmap_talloc(talloc_autofree_context(),
7619 if (!pservice->copymap)
7621 ("Couldn't allocate copymap!! (size %d)\n",
7622 (int)NUMPARAMETERS));
7624 for (i = 0; i < NUMPARAMETERS; i++)
7625 bitmap_set(pservice->copymap, i);
7628 /***************************************************************************
7629 Return the local pointer to a parameter given a service struct and the
7630 pointer into the default structure.
7631 ***************************************************************************/
7633 static void *lp_local_ptr(struct service *service, void *ptr)
7635 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7638 /***************************************************************************
7639 Return the local pointer to a parameter given the service number and the
7640 pointer into the default structure.
7641 ***************************************************************************/
7643 void *lp_local_ptr_by_snum(int snum, void *ptr)
7645 return lp_local_ptr(ServicePtrs[snum], ptr);
7648 /***************************************************************************
7649 Process a parameter for a particular service number. If snum < 0
7650 then assume we are in the globals.
7651 ***************************************************************************/
7653 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7656 void *parm_ptr = NULL; /* where we are going to store the result */
7657 void *def_ptr = NULL;
7658 struct param_opt_struct **opt_list;
7660 parmnum = map_parameter(pszParmName);
7663 if (strchr(pszParmName, ':') == NULL) {
7664 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7670 * We've got a parametric option
7673 opt_list = (snum < 0)
7674 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7675 set_param_opt(opt_list, pszParmName, pszParmValue);
7680 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7681 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7685 def_ptr = parm_table[parmnum].ptr;
7687 /* we might point at a service, the default service or a global */
7691 if (parm_table[parmnum].p_class == P_GLOBAL) {
7693 ("Global parameter %s found in service section!\n",
7697 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7701 if (!ServicePtrs[snum]->copymap)
7702 init_copymap(ServicePtrs[snum]);
7704 /* this handles the aliases - set the copymap for other entries with
7705 the same data pointer */
7706 for (i = 0; parm_table[i].label; i++)
7707 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7708 bitmap_clear(ServicePtrs[snum]->copymap, i);
7711 /* if it is a special case then go ahead */
7712 if (parm_table[parmnum].special) {
7713 return parm_table[parmnum].special(snum, pszParmValue,
7717 /* now switch on the type of variable it is */
7718 switch (parm_table[parmnum].type)
7721 *(bool *)parm_ptr = lp_bool(pszParmValue);
7725 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7729 *(int *)parm_ptr = lp_int(pszParmValue);
7733 *(char *)parm_ptr = *pszParmValue;
7737 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7739 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7744 TALLOC_FREE(*((char ***)parm_ptr));
7745 *(char ***)parm_ptr = str_list_make_v3(
7746 talloc_autofree_context(), pszParmValue, NULL);
7750 string_set((char **)parm_ptr, pszParmValue);
7754 string_set((char **)parm_ptr, pszParmValue);
7755 strupper_m(*(char **)parm_ptr);
7759 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7768 /***************************************************************************
7769 Process a parameter.
7770 ***************************************************************************/
7772 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7775 if (!bInGlobalSection && bGlobalOnly)
7778 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7780 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7781 pszParmName, pszParmValue));
7784 /***************************************************************************
7785 Print a parameter of the specified type.
7786 ***************************************************************************/
7788 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7794 for (i = 0; p->enum_list[i].name; i++) {
7795 if (*(int *)ptr == p->enum_list[i].value) {
7797 p->enum_list[i].name);
7804 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7808 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7812 fprintf(f, "%d", *(int *)ptr);
7816 fprintf(f, "%c", *(char *)ptr);
7820 char *o = octal_string(*(int *)ptr);
7821 fprintf(f, "%s", o);
7827 if ((char ***)ptr && *(char ***)ptr) {
7828 char **list = *(char ***)ptr;
7829 for (; *list; list++) {
7830 /* surround strings with whitespace in double quotes */
7831 if ( strchr_m( *list, ' ' ) )
7832 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7834 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7841 if (*(char **)ptr) {
7842 fprintf(f, "%s", *(char **)ptr);
7850 /***************************************************************************
7851 Check if two parameters are equal.
7852 ***************************************************************************/
7854 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7859 return (*((bool *)ptr1) == *((bool *)ptr2));
7864 return (*((int *)ptr1) == *((int *)ptr2));
7867 return (*((char *)ptr1) == *((char *)ptr2));
7870 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7875 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7880 return (p1 == p2 || strequal(p1, p2));
7888 /***************************************************************************
7889 Initialize any local varients in the sDefault table.
7890 ***************************************************************************/
7892 void init_locals(void)
7897 /***************************************************************************
7898 Process a new section (service). At this stage all sections are services.
7899 Later we'll have special sections that permit server parameters to be set.
7900 Returns True on success, False on failure.
7901 ***************************************************************************/
7903 static bool do_section(const char *pszSectionName, void *userdata)
7906 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7907 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7910 /* if we were in a global section then do the local inits */
7911 if (bInGlobalSection && !isglobal)
7914 /* if we've just struck a global section, note the fact. */
7915 bInGlobalSection = isglobal;
7917 /* check for multiple global sections */
7918 if (bInGlobalSection) {
7919 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7923 if (!bInGlobalSection && bGlobalOnly)
7926 /* if we have a current service, tidy it up before moving on */
7929 if (iServiceIndex >= 0)
7930 bRetval = service_ok(iServiceIndex);
7932 /* if all is still well, move to the next record in the services array */
7934 /* We put this here to avoid an odd message order if messages are */
7935 /* issued by the post-processing of a previous section. */
7936 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7938 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7940 DEBUG(0, ("Failed to add a new service\n"));
7949 /***************************************************************************
7950 Determine if a partcular base parameter is currentl set to the default value.
7951 ***************************************************************************/
7953 static bool is_default(int i)
7955 if (!defaults_saved)
7957 switch (parm_table[i].type) {
7959 return str_list_equal((const char **)parm_table[i].def.lvalue,
7960 *(const char ***)parm_table[i].ptr);
7963 return strequal(parm_table[i].def.svalue,
7964 *(char **)parm_table[i].ptr);
7967 return parm_table[i].def.bvalue ==
7968 *(bool *)parm_table[i].ptr;
7970 return parm_table[i].def.cvalue ==
7971 *(char *)parm_table[i].ptr;
7975 return parm_table[i].def.ivalue ==
7976 *(int *)parm_table[i].ptr;
7983 /***************************************************************************
7984 Display the contents of the global structure.
7985 ***************************************************************************/
7987 static void dump_globals(FILE *f)
7990 struct param_opt_struct *data;
7992 fprintf(f, "[global]\n");
7994 for (i = 0; parm_table[i].label; i++)
7995 if (parm_table[i].p_class == P_GLOBAL &&
7996 !(parm_table[i].flags & FLAG_META) &&
7997 parm_table[i].ptr &&
7998 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7999 if (defaults_saved && is_default(i))
8001 fprintf(f, "\t%s = ", parm_table[i].label);
8002 print_parameter(&parm_table[i], parm_table[i].ptr, f);
8005 if (Globals.param_opt != NULL) {
8006 data = Globals.param_opt;
8008 fprintf(f, "\t%s = %s\n", data->key, data->value);
8015 /***************************************************************************
8016 Return True if a local parameter is currently set to the global default.
8017 ***************************************************************************/
8019 bool lp_is_default(int snum, struct parm_struct *parm)
8021 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8023 return equal_parameter(parm->type,
8024 ((char *)ServicePtrs[snum]) + pdiff,
8025 ((char *)&sDefault) + pdiff);
8028 /***************************************************************************
8029 Display the contents of a single services record.
8030 ***************************************************************************/
8032 static void dump_a_service(struct service *pService, FILE * f)
8035 struct param_opt_struct *data;
8037 if (pService != &sDefault)
8038 fprintf(f, "[%s]\n", pService->szService);
8040 for (i = 0; parm_table[i].label; i++) {
8042 if (parm_table[i].p_class == P_LOCAL &&
8043 !(parm_table[i].flags & FLAG_META) &&
8044 parm_table[i].ptr &&
8045 (*parm_table[i].label != '-') &&
8046 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8048 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8050 if (pService == &sDefault) {
8051 if (defaults_saved && is_default(i))
8054 if (equal_parameter(parm_table[i].type,
8055 ((char *)pService) +
8057 ((char *)&sDefault) +
8062 fprintf(f, "\t%s = ", parm_table[i].label);
8063 print_parameter(&parm_table[i],
8064 ((char *)pService) + pdiff, f);
8069 if (pService->param_opt != NULL) {
8070 data = pService->param_opt;
8072 fprintf(f, "\t%s = %s\n", data->key, data->value);
8078 /***************************************************************************
8079 Display the contents of a parameter of a single services record.
8080 ***************************************************************************/
8082 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8085 bool result = False;
8088 fstring local_parm_name;
8090 const char *parm_opt_value;
8092 /* check for parametrical option */
8093 fstrcpy( local_parm_name, parm_name);
8094 parm_opt = strchr( local_parm_name, ':');
8099 if (strlen(parm_opt)) {
8100 parm_opt_value = lp_parm_const_string( snum,
8101 local_parm_name, parm_opt, NULL);
8102 if (parm_opt_value) {
8103 printf( "%s\n", parm_opt_value);
8110 /* check for a key and print the value */
8117 for (i = 0; parm_table[i].label; i++) {
8118 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8119 !(parm_table[i].flags & FLAG_META) &&
8120 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8121 parm_table[i].ptr &&
8122 (*parm_table[i].label != '-') &&
8123 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8128 ptr = parm_table[i].ptr;
8130 struct service *pService = ServicePtrs[snum];
8131 ptr = ((char *)pService) +
8132 PTR_DIFF(parm_table[i].ptr, &sDefault);
8135 print_parameter(&parm_table[i],
8146 /***************************************************************************
8147 Return info about the requested parameter (given as a string).
8148 Return NULL when the string is not a valid parameter name.
8149 ***************************************************************************/
8151 struct parm_struct *lp_get_parameter(const char *param_name)
8153 int num = map_parameter(param_name);
8159 return &parm_table[num];
8162 /***************************************************************************
8163 Return info about the next parameter in a service.
8164 snum==GLOBAL_SECTION_SNUM gives the globals.
8165 Return NULL when out of parameters.
8166 ***************************************************************************/
8168 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8171 /* do the globals */
8172 for (; parm_table[*i].label; (*i)++) {
8173 if (parm_table[*i].p_class == P_SEPARATOR)
8174 return &parm_table[(*i)++];
8176 if (!parm_table[*i].ptr
8177 || (*parm_table[*i].label == '-'))
8181 && (parm_table[*i].ptr ==
8182 parm_table[(*i) - 1].ptr))
8185 if (is_default(*i) && !allparameters)
8188 return &parm_table[(*i)++];
8191 struct service *pService = ServicePtrs[snum];
8193 for (; parm_table[*i].label; (*i)++) {
8194 if (parm_table[*i].p_class == P_SEPARATOR)
8195 return &parm_table[(*i)++];
8197 if (parm_table[*i].p_class == P_LOCAL &&
8198 parm_table[*i].ptr &&
8199 (*parm_table[*i].label != '-') &&
8201 (parm_table[*i].ptr !=
8202 parm_table[(*i) - 1].ptr)))
8205 PTR_DIFF(parm_table[*i].ptr,
8208 if (allparameters ||
8209 !equal_parameter(parm_table[*i].type,
8210 ((char *)pService) +
8212 ((char *)&sDefault) +
8215 return &parm_table[(*i)++];
8226 /***************************************************************************
8227 Display the contents of a single copy structure.
8228 ***************************************************************************/
8229 static void dump_copy_map(bool *pcopymap)
8235 printf("\n\tNon-Copied parameters:\n");
8237 for (i = 0; parm_table[i].label; i++)
8238 if (parm_table[i].p_class == P_LOCAL &&
8239 parm_table[i].ptr && !pcopymap[i] &&
8240 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8242 printf("\t\t%s\n", parm_table[i].label);
8247 /***************************************************************************
8248 Return TRUE if the passed service number is within range.
8249 ***************************************************************************/
8251 bool lp_snum_ok(int iService)
8253 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8256 /***************************************************************************
8257 Auto-load some home services.
8258 ***************************************************************************/
8260 static void lp_add_auto_services(char *str)
8270 s = SMB_STRDUP(str);
8274 homes = lp_servicenumber(HOMES_NAME);
8276 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8277 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8280 if (lp_servicenumber(p) >= 0)
8283 home = get_user_home_dir(talloc_tos(), p);
8285 if (home && home[0] && homes >= 0)
8286 lp_add_home(p, homes, p, home);
8293 /***************************************************************************
8294 Auto-load one printer.
8295 ***************************************************************************/
8297 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8299 int printers = lp_servicenumber(PRINTERS_NAME);
8302 if (lp_servicenumber(name) < 0) {
8303 lp_add_printer(name, printers);
8304 if ((i = lp_servicenumber(name)) >= 0) {
8305 string_set(&ServicePtrs[i]->comment, comment);
8306 ServicePtrs[i]->autoloaded = True;
8311 /***************************************************************************
8312 Have we loaded a services file yet?
8313 ***************************************************************************/
8315 bool lp_loaded(void)
8320 /***************************************************************************
8321 Unload unused services.
8322 ***************************************************************************/
8324 void lp_killunused(bool (*snumused) (int))
8327 for (i = 0; i < iNumServices; i++) {
8331 /* don't kill autoloaded or usershare services */
8332 if ( ServicePtrs[i]->autoloaded ||
8333 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8337 if (!snumused || !snumused(i)) {
8338 free_service_byindex(i);
8344 * Kill all except autoloaded and usershare services - convenience wrapper
8346 void lp_kill_all_services(void)
8348 lp_killunused(NULL);
8351 /***************************************************************************
8353 ***************************************************************************/
8355 void lp_killservice(int iServiceIn)
8357 if (VALID(iServiceIn)) {
8358 free_service_byindex(iServiceIn);
8362 /***************************************************************************
8363 Save the curent values of all global and sDefault parameters into the
8364 defaults union. This allows swat and testparm to show only the
8365 changed (ie. non-default) parameters.
8366 ***************************************************************************/
8368 static void lp_save_defaults(void)
8371 for (i = 0; parm_table[i].label; i++) {
8372 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8374 switch (parm_table[i].type) {
8376 parm_table[i].def.lvalue = str_list_copy(
8377 NULL, *(const char ***)parm_table[i].ptr);
8381 if (parm_table[i].ptr) {
8382 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8384 parm_table[i].def.svalue = NULL;
8389 parm_table[i].def.bvalue =
8390 *(bool *)parm_table[i].ptr;
8393 parm_table[i].def.cvalue =
8394 *(char *)parm_table[i].ptr;
8399 parm_table[i].def.ivalue =
8400 *(int *)parm_table[i].ptr;
8406 defaults_saved = True;
8409 /***********************************************************
8410 If we should send plaintext/LANMAN passwords in the clinet
8411 ************************************************************/
8413 static void set_allowed_client_auth(void)
8415 if (Globals.bClientNTLMv2Auth) {
8416 Globals.bClientLanManAuth = False;
8418 if (!Globals.bClientLanManAuth) {
8419 Globals.bClientPlaintextAuth = False;
8423 /***************************************************************************
8425 The following code allows smbd to read a user defined share file.
8426 Yes, this is my intent. Yes, I'm comfortable with that...
8428 THE FOLLOWING IS SECURITY CRITICAL CODE.
8430 It washes your clothes, it cleans your house, it guards you while you sleep...
8431 Do not f%^k with it....
8432 ***************************************************************************/
8434 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8436 /***************************************************************************
8437 Check allowed stat state of a usershare file.
8438 Ensure we print out who is dicking with us so the admin can
8439 get their sorry ass fired.
8440 ***************************************************************************/
8442 static bool check_usershare_stat(const char *fname,
8443 const SMB_STRUCT_STAT *psbuf)
8445 if (!S_ISREG(psbuf->st_ex_mode)) {
8446 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8447 "not a regular file\n",
8448 fname, (unsigned int)psbuf->st_ex_uid ));
8452 /* Ensure this doesn't have the other write bit set. */
8453 if (psbuf->st_ex_mode & S_IWOTH) {
8454 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8455 "public write. Refusing to allow as a usershare file.\n",
8456 fname, (unsigned int)psbuf->st_ex_uid ));
8460 /* Should be 10k or less. */
8461 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8462 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8463 "too large (%u) to be a user share file.\n",
8464 fname, (unsigned int)psbuf->st_ex_uid,
8465 (unsigned int)psbuf->st_ex_size ));
8472 /***************************************************************************
8473 Parse the contents of a usershare file.
8474 ***************************************************************************/
8476 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8477 SMB_STRUCT_STAT *psbuf,
8478 const char *servicename,
8482 char **pp_sharepath,
8484 char **pp_cp_servicename,
8485 struct security_descriptor **ppsd,
8488 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8489 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8492 SMB_STRUCT_STAT sbuf;
8493 char *sharepath = NULL;
8494 char *comment = NULL;
8496 *pp_sharepath = NULL;
8499 *pallow_guest = False;
8502 return USERSHARE_MALFORMED_FILE;
8505 if (strcmp(lines[0], "#VERSION 1") == 0) {
8507 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8510 return USERSHARE_MALFORMED_FILE;
8513 return USERSHARE_BAD_VERSION;
8516 if (strncmp(lines[1], "path=", 5) != 0) {
8517 return USERSHARE_MALFORMED_PATH;
8520 sharepath = talloc_strdup(ctx, &lines[1][5]);
8522 return USERSHARE_POSIX_ERR;
8524 trim_string(sharepath, " ", " ");
8526 if (strncmp(lines[2], "comment=", 8) != 0) {
8527 return USERSHARE_MALFORMED_COMMENT_DEF;
8530 comment = talloc_strdup(ctx, &lines[2][8]);
8532 return USERSHARE_POSIX_ERR;
8534 trim_string(comment, " ", " ");
8535 trim_char(comment, '"', '"');
8537 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8538 return USERSHARE_MALFORMED_ACL_DEF;
8541 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8542 return USERSHARE_ACL_ERR;
8546 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8547 return USERSHARE_MALFORMED_ACL_DEF;
8549 if (lines[4][9] == 'y') {
8550 *pallow_guest = True;
8553 /* Backwards compatible extension to file version #2. */
8555 if (strncmp(lines[5], "sharename=", 10) != 0) {
8556 return USERSHARE_MALFORMED_SHARENAME_DEF;
8558 if (!strequal(&lines[5][10], servicename)) {
8559 return USERSHARE_BAD_SHARENAME;
8561 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8562 if (!*pp_cp_servicename) {
8563 return USERSHARE_POSIX_ERR;
8568 if (*pp_cp_servicename == NULL) {
8569 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8570 if (!*pp_cp_servicename) {
8571 return USERSHARE_POSIX_ERR;
8575 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8576 /* Path didn't change, no checks needed. */
8577 *pp_sharepath = sharepath;
8578 *pp_comment = comment;
8579 return USERSHARE_OK;
8582 /* The path *must* be absolute. */
8583 if (sharepath[0] != '/') {
8584 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8585 servicename, sharepath));
8586 return USERSHARE_PATH_NOT_ABSOLUTE;
8589 /* If there is a usershare prefix deny list ensure one of these paths
8590 doesn't match the start of the user given path. */
8591 if (prefixdenylist) {
8593 for ( i=0; prefixdenylist[i]; i++ ) {
8594 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8595 servicename, i, prefixdenylist[i], sharepath ));
8596 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8597 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8598 "usershare prefix deny list entries.\n",
8599 servicename, sharepath));
8600 return USERSHARE_PATH_IS_DENIED;
8605 /* If there is a usershare prefix allow list ensure one of these paths
8606 does match the start of the user given path. */
8608 if (prefixallowlist) {
8610 for ( i=0; prefixallowlist[i]; i++ ) {
8611 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8612 servicename, i, prefixallowlist[i], sharepath ));
8613 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8617 if (prefixallowlist[i] == NULL) {
8618 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8619 "usershare prefix allow list entries.\n",
8620 servicename, sharepath));
8621 return USERSHARE_PATH_NOT_ALLOWED;
8625 /* Ensure this is pointing to a directory. */
8626 dp = sys_opendir(sharepath);
8629 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8630 servicename, sharepath));
8631 return USERSHARE_PATH_NOT_DIRECTORY;
8634 /* Ensure the owner of the usershare file has permission to share
8637 if (sys_stat(sharepath, &sbuf, false) == -1) {
8638 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8639 servicename, sharepath, strerror(errno) ));
8641 return USERSHARE_POSIX_ERR;
8646 if (!S_ISDIR(sbuf.st_ex_mode)) {
8647 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8648 servicename, sharepath ));
8649 return USERSHARE_PATH_NOT_DIRECTORY;
8652 /* Check if sharing is restricted to owner-only. */
8653 /* psbuf is the stat of the usershare definition file,
8654 sbuf is the stat of the target directory to be shared. */
8656 if (lp_usershare_owner_only()) {
8657 /* root can share anything. */
8658 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8659 return USERSHARE_PATH_NOT_ALLOWED;
8663 *pp_sharepath = sharepath;
8664 *pp_comment = comment;
8665 return USERSHARE_OK;
8668 /***************************************************************************
8669 Deal with a usershare file.
8672 -1 - Bad name, invalid contents.
8673 - service name already existed and not a usershare, problem
8674 with permissions to share directory etc.
8675 ***************************************************************************/
8677 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8679 SMB_STRUCT_STAT sbuf;
8680 SMB_STRUCT_STAT lsbuf;
8682 char *sharepath = NULL;
8683 char *comment = NULL;
8684 char *cp_service_name = NULL;
8685 char **lines = NULL;
8689 TALLOC_CTX *ctx = talloc_stackframe();
8690 struct security_descriptor *psd = NULL;
8691 bool guest_ok = False;
8692 char *canon_name = NULL;
8693 bool added_service = false;
8696 /* Ensure share name doesn't contain invalid characters. */
8697 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8698 DEBUG(0,("process_usershare_file: share name %s contains "
8699 "invalid characters (any of %s)\n",
8700 file_name, INVALID_SHARENAME_CHARS ));
8704 canon_name = canonicalize_servicename(ctx, file_name);
8709 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8714 /* Minimize the race condition by doing an lstat before we
8715 open and fstat. Ensure this isn't a symlink link. */
8717 if (sys_lstat(fname, &lsbuf, false) != 0) {
8718 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8719 fname, strerror(errno) ));
8723 /* This must be a regular file, not a symlink, directory or
8724 other strange filetype. */
8725 if (!check_usershare_stat(fname, &lsbuf)) {
8730 TDB_DATA data = dbwrap_fetch_bystring(
8731 ServiceHash, canon_name, canon_name);
8735 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8736 iService = *(int *)data.dptr;
8740 if (iService != -1 &&
8741 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8742 &lsbuf.st_ex_mtime) == 0) {
8743 /* Nothing changed - Mark valid and return. */
8744 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8746 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8751 /* Try and open the file read only - no symlinks allowed. */
8753 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8755 fd = sys_open(fname, O_RDONLY, 0);
8759 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8760 fname, strerror(errno) ));
8764 /* Now fstat to be *SURE* it's a regular file. */
8765 if (sys_fstat(fd, &sbuf, false) != 0) {
8767 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8768 fname, strerror(errno) ));
8772 /* Is it the same dev/inode as was lstated ? */
8773 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8775 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8776 "Symlink spoofing going on ?\n", fname ));
8780 /* This must be a regular file, not a symlink, directory or
8781 other strange filetype. */
8782 if (!check_usershare_stat(fname, &sbuf)) {
8786 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8789 if (lines == NULL) {
8790 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8791 fname, (unsigned int)sbuf.st_ex_uid ));
8795 if (parse_usershare_file(ctx, &sbuf, file_name,
8796 iService, lines, numlines, &sharepath,
8797 &comment, &cp_service_name,
8798 &psd, &guest_ok) != USERSHARE_OK) {
8802 /* Everything ok - add the service possibly using a template. */
8804 const struct service *sp = &sDefault;
8805 if (snum_template != -1) {
8806 sp = ServicePtrs[snum_template];
8809 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8810 DEBUG(0, ("process_usershare_file: Failed to add "
8811 "new service %s\n", cp_service_name));
8815 added_service = true;
8817 /* Read only is controlled by usershare ACL below. */
8818 ServicePtrs[iService]->bRead_only = False;
8821 /* Write the ACL of the new/modified share. */
8822 if (!set_share_security(canon_name, psd)) {
8823 DEBUG(0, ("process_usershare_file: Failed to set share "
8824 "security for user share %s\n",
8829 /* If from a template it may be marked invalid. */
8830 ServicePtrs[iService]->valid = True;
8832 /* Set the service as a valid usershare. */
8833 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8835 /* Set guest access. */
8836 if (lp_usershare_allow_guests()) {
8837 ServicePtrs[iService]->bGuest_ok = guest_ok;
8840 /* And note when it was loaded. */
8841 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8842 string_set(&ServicePtrs[iService]->szPath, sharepath);
8843 string_set(&ServicePtrs[iService]->comment, comment);
8849 if (ret == -1 && iService != -1 && added_service) {
8850 lp_remove_service(iService);
8858 /***************************************************************************
8859 Checks if a usershare entry has been modified since last load.
8860 ***************************************************************************/
8862 static bool usershare_exists(int iService, struct timespec *last_mod)
8864 SMB_STRUCT_STAT lsbuf;
8865 const char *usersharepath = Globals.szUsersharePath;
8868 if (asprintf(&fname, "%s/%s",
8870 ServicePtrs[iService]->szService) < 0) {
8874 if (sys_lstat(fname, &lsbuf, false) != 0) {
8879 if (!S_ISREG(lsbuf.st_ex_mode)) {
8885 *last_mod = lsbuf.st_ex_mtime;
8889 /***************************************************************************
8890 Load a usershare service by name. Returns a valid servicenumber or -1.
8891 ***************************************************************************/
8893 int load_usershare_service(const char *servicename)
8895 SMB_STRUCT_STAT sbuf;
8896 const char *usersharepath = Globals.szUsersharePath;
8897 int max_user_shares = Globals.iUsershareMaxShares;
8898 int snum_template = -1;
8900 if (*usersharepath == 0 || max_user_shares == 0) {
8904 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8905 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8906 usersharepath, strerror(errno) ));
8910 if (!S_ISDIR(sbuf.st_ex_mode)) {
8911 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8917 * This directory must be owned by root, and have the 't' bit set.
8918 * It also must not be writable by "other".
8922 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8924 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8926 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8927 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8932 /* Ensure the template share exists if it's set. */
8933 if (Globals.szUsershareTemplateShare[0]) {
8934 /* We can't use lp_servicenumber here as we are recommending that
8935 template shares have -valid=False set. */
8936 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8937 if (ServicePtrs[snum_template]->szService &&
8938 strequal(ServicePtrs[snum_template]->szService,
8939 Globals.szUsershareTemplateShare)) {
8944 if (snum_template == -1) {
8945 DEBUG(0,("load_usershare_service: usershare template share %s "
8946 "does not exist.\n",
8947 Globals.szUsershareTemplateShare ));
8952 return process_usershare_file(usersharepath, servicename, snum_template);
8955 /***************************************************************************
8956 Load all user defined shares from the user share directory.
8957 We only do this if we're enumerating the share list.
8958 This is the function that can delete usershares that have
8960 ***************************************************************************/
8962 int load_usershare_shares(void)
8965 SMB_STRUCT_STAT sbuf;
8966 SMB_STRUCT_DIRENT *de;
8967 int num_usershares = 0;
8968 int max_user_shares = Globals.iUsershareMaxShares;
8969 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8970 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8971 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8973 int snum_template = -1;
8974 const char *usersharepath = Globals.szUsersharePath;
8975 int ret = lp_numservices();
8977 if (max_user_shares == 0 || *usersharepath == '\0') {
8978 return lp_numservices();
8981 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8982 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8983 usersharepath, strerror(errno) ));
8988 * This directory must be owned by root, and have the 't' bit set.
8989 * It also must not be writable by "other".
8993 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8995 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8997 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8998 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9003 /* Ensure the template share exists if it's set. */
9004 if (Globals.szUsershareTemplateShare[0]) {
9005 /* We can't use lp_servicenumber here as we are recommending that
9006 template shares have -valid=False set. */
9007 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9008 if (ServicePtrs[snum_template]->szService &&
9009 strequal(ServicePtrs[snum_template]->szService,
9010 Globals.szUsershareTemplateShare)) {
9015 if (snum_template == -1) {
9016 DEBUG(0,("load_usershare_shares: usershare template share %s "
9017 "does not exist.\n",
9018 Globals.szUsershareTemplateShare ));
9023 /* Mark all existing usershares as pending delete. */
9024 for (iService = iNumServices - 1; iService >= 0; iService--) {
9025 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9026 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9030 dp = sys_opendir(usersharepath);
9032 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9033 usersharepath, strerror(errno) ));
9037 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9038 (de = sys_readdir(dp));
9039 num_dir_entries++ ) {
9041 const char *n = de->d_name;
9043 /* Ignore . and .. */
9045 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9051 /* Temporary file used when creating a share. */
9052 num_tmp_dir_entries++;
9055 /* Allow 20% tmp entries. */
9056 if (num_tmp_dir_entries > allowed_tmp_entries) {
9057 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9058 "in directory %s\n",
9059 num_tmp_dir_entries, usersharepath));
9063 r = process_usershare_file(usersharepath, n, snum_template);
9065 /* Update the services count. */
9067 if (num_usershares >= max_user_shares) {
9068 DEBUG(0,("load_usershare_shares: max user shares reached "
9069 "on file %s in directory %s\n",
9070 n, usersharepath ));
9073 } else if (r == -1) {
9074 num_bad_dir_entries++;
9077 /* Allow 20% bad entries. */
9078 if (num_bad_dir_entries > allowed_bad_entries) {
9079 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9080 "in directory %s\n",
9081 num_bad_dir_entries, usersharepath));
9085 /* Allow 20% bad entries. */
9086 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9087 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9088 "in directory %s\n",
9089 num_dir_entries, usersharepath));
9096 /* Sweep through and delete any non-refreshed usershares that are
9097 not currently in use. */
9098 for (iService = iNumServices - 1; iService >= 0; iService--) {
9099 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9100 if (conn_snum_used(iService)) {
9103 /* Remove from the share ACL db. */
9104 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9105 lp_servicename(iService) ));
9106 delete_share_security(lp_servicename(iService));
9107 free_service_byindex(iService);
9111 return lp_numservices();
9114 /********************************************************
9115 Destroy global resources allocated in this file
9116 ********************************************************/
9118 void gfree_loadparm(void)
9124 /* Free resources allocated to services */
9126 for ( i = 0; i < iNumServices; i++ ) {
9128 free_service_byindex(i);
9132 SAFE_FREE( ServicePtrs );
9135 /* Now release all resources allocated to global
9136 parameters and the default service */
9138 free_global_parameters();
9142 /***************************************************************************
9143 Allow client apps to specify that they are a client
9144 ***************************************************************************/
9145 void lp_set_in_client(bool b)
9151 /***************************************************************************
9152 Determine if we're running in a client app
9153 ***************************************************************************/
9154 bool lp_is_in_client(void)
9159 /***************************************************************************
9160 Load the services array from the services file. Return True on success,
9162 ***************************************************************************/
9164 bool lp_load_ex(const char *pszFname,
9168 bool initialize_globals,
9169 bool allow_include_registry,
9170 bool allow_registry_shares)
9177 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9179 bInGlobalSection = True;
9180 bGlobalOnly = global_only;
9181 bAllowIncludeRegistry = allow_include_registry;
9183 init_globals(! initialize_globals);
9188 if (save_defaults) {
9193 free_param_opts(&Globals.param_opt);
9195 /* We get sections first, so have to start 'behind' to make up */
9198 if (lp_config_backend_is_file()) {
9199 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9200 current_user_info.domain,
9203 smb_panic("lp_load_ex: out of memory");
9206 add_to_file_list(pszFname, n2);
9208 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9211 /* finish up the last section */
9212 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9214 if (iServiceIndex >= 0) {
9215 bRetval = service_ok(iServiceIndex);
9219 if (lp_config_backend_is_registry()) {
9220 /* config backend changed to registry in config file */
9222 * We need to use this extra global variable here to
9223 * survive restart: init_globals uses this as a default
9224 * for ConfigBackend. Otherwise, init_globals would
9225 * send us into an endless loop here.
9227 config_backend = CONFIG_BACKEND_REGISTRY;
9229 DEBUG(1, ("lp_load_ex: changing to config backend "
9231 init_globals(false);
9232 lp_kill_all_services();
9233 return lp_load_ex(pszFname, global_only, save_defaults,
9234 add_ipc, initialize_globals,
9235 allow_include_registry,
9236 allow_registry_shares);
9238 } else if (lp_config_backend_is_registry()) {
9239 bRetval = process_registry_globals();
9241 DEBUG(0, ("Illegal config backend given: %d\n",
9242 lp_config_backend()));
9246 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9247 bRetval = process_registry_shares();
9250 lp_add_auto_services(lp_auto_services());
9253 /* When 'restrict anonymous = 2' guest connections to ipc$
9255 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9256 if ( lp_enable_asu_support() ) {
9257 lp_add_ipc("ADMIN$", false);
9262 set_default_server_announce_type();
9263 set_allowed_client_auth();
9267 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9268 /* if bWINSsupport is true and we are in the client */
9269 if (lp_is_in_client() && Globals.bWINSsupport) {
9270 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9275 bAllowIncludeRegistry = true;
9280 bool lp_load(const char *pszFname,
9284 bool initialize_globals)
9286 return lp_load_ex(pszFname,
9291 true, /* allow_include_registry */
9292 false); /* allow_registry_shares*/
9295 bool lp_load_initial_only(const char *pszFname)
9297 return lp_load_ex(pszFname,
9298 true, /* global only */
9299 false, /* save_defaults */
9300 false, /* add_ipc */
9301 true, /* initialize_globals */
9302 false, /* allow_include_registry */
9303 false); /* allow_registry_shares*/
9306 bool lp_load_with_registry_shares(const char *pszFname,
9310 bool initialize_globals)
9312 return lp_load_ex(pszFname,
9317 true, /* allow_include_registry */
9318 true); /* allow_registry_shares*/
9321 /***************************************************************************
9322 Return the max number of services.
9323 ***************************************************************************/
9325 int lp_numservices(void)
9327 return (iNumServices);
9330 /***************************************************************************
9331 Display the contents of the services array in human-readable form.
9332 ***************************************************************************/
9334 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9339 defaults_saved = False;
9343 dump_a_service(&sDefault, f);
9345 for (iService = 0; iService < maxtoprint; iService++) {
9347 lp_dump_one(f, show_defaults, iService);
9351 /***************************************************************************
9352 Display the contents of one service in human-readable form.
9353 ***************************************************************************/
9355 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9358 if (ServicePtrs[snum]->szService[0] == '\0')
9360 dump_a_service(ServicePtrs[snum], f);
9364 /***************************************************************************
9365 Return the number of the service with the given name, or -1 if it doesn't
9366 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9367 getservicebyname()! This works ONLY if all services have been loaded, and
9368 does not copy the found service.
9369 ***************************************************************************/
9371 int lp_servicenumber(const char *pszServiceName)
9374 fstring serviceName;
9376 if (!pszServiceName) {
9377 return GLOBAL_SECTION_SNUM;
9380 for (iService = iNumServices - 1; iService >= 0; iService--) {
9381 if (VALID(iService) && ServicePtrs[iService]->szService) {
9383 * The substitution here is used to support %U is
9386 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9387 standard_sub_basic(get_current_username(),
9388 current_user_info.domain,
9389 serviceName,sizeof(serviceName));
9390 if (strequal(serviceName, pszServiceName)) {
9396 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9397 struct timespec last_mod;
9399 if (!usershare_exists(iService, &last_mod)) {
9400 /* Remove the share security tdb entry for it. */
9401 delete_share_security(lp_servicename(iService));
9402 /* Remove it from the array. */
9403 free_service_byindex(iService);
9404 /* Doesn't exist anymore. */
9405 return GLOBAL_SECTION_SNUM;
9408 /* Has it been modified ? If so delete and reload. */
9409 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9411 /* Remove it from the array. */
9412 free_service_byindex(iService);
9413 /* and now reload it. */
9414 iService = load_usershare_service(pszServiceName);
9419 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9420 return GLOBAL_SECTION_SNUM;
9426 bool share_defined(const char *service_name)
9428 return (lp_servicenumber(service_name) != -1);
9431 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9432 const char *sharename)
9434 struct share_params *result;
9438 if (!(sname = SMB_STRDUP(sharename))) {
9442 snum = find_service(sname);
9449 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9450 DEBUG(0, ("talloc failed\n"));
9454 result->service = snum;
9458 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9460 struct share_iterator *result;
9462 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9463 DEBUG(0, ("talloc failed\n"));
9467 result->next_id = 0;
9471 struct share_params *next_share(struct share_iterator *list)
9473 struct share_params *result;
9475 while (!lp_snum_ok(list->next_id) &&
9476 (list->next_id < lp_numservices())) {
9480 if (list->next_id >= lp_numservices()) {
9484 if (!(result = TALLOC_P(list, struct share_params))) {
9485 DEBUG(0, ("talloc failed\n"));
9489 result->service = list->next_id;
9494 struct share_params *next_printer(struct share_iterator *list)
9496 struct share_params *result;
9498 while ((result = next_share(list)) != NULL) {
9499 if (lp_print_ok(result->service)) {
9507 * This is a hack for a transition period until we transformed all code from
9508 * service numbers to struct share_params.
9511 struct share_params *snum2params_static(int snum)
9513 static struct share_params result;
9514 result.service = snum;
9518 /*******************************************************************
9519 A useful volume label function.
9520 ********************************************************************/
9522 const char *volume_label(int snum)
9525 const char *label = lp_volume(snum);
9527 label = lp_servicename(snum);
9530 /* This returns a 33 byte guarenteed null terminated string. */
9531 ret = talloc_strndup(talloc_tos(), label, 32);
9538 /*******************************************************************
9539 Set the server type we will announce as via nmbd.
9540 ********************************************************************/
9542 static void set_default_server_announce_type(void)
9544 default_server_announce = 0;
9545 default_server_announce |= SV_TYPE_WORKSTATION;
9546 default_server_announce |= SV_TYPE_SERVER;
9547 default_server_announce |= SV_TYPE_SERVER_UNIX;
9549 /* note that the flag should be set only if we have a
9550 printer service but nmbd doesn't actually load the
9551 services so we can't tell --jerry */
9553 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9555 switch (lp_announce_as()) {
9556 case ANNOUNCE_AS_NT_SERVER:
9557 default_server_announce |= SV_TYPE_SERVER_NT;
9558 /* fall through... */
9559 case ANNOUNCE_AS_NT_WORKSTATION:
9560 default_server_announce |= SV_TYPE_NT;
9562 case ANNOUNCE_AS_WIN95:
9563 default_server_announce |= SV_TYPE_WIN95_PLUS;
9565 case ANNOUNCE_AS_WFW:
9566 default_server_announce |= SV_TYPE_WFW;
9572 switch (lp_server_role()) {
9573 case ROLE_DOMAIN_MEMBER:
9574 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9576 case ROLE_DOMAIN_PDC:
9577 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9579 case ROLE_DOMAIN_BDC:
9580 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9582 case ROLE_STANDALONE:
9586 if (lp_time_server())
9587 default_server_announce |= SV_TYPE_TIME_SOURCE;
9589 if (lp_host_msdfs())
9590 default_server_announce |= SV_TYPE_DFS_SERVER;
9593 /***********************************************************
9594 If we are PDC then prefer us as DMB
9595 ************************************************************/
9597 bool lp_domain_master(void)
9599 if (Globals.iDomainMaster == Auto)
9600 return (lp_server_role() == ROLE_DOMAIN_PDC);
9602 return (bool)Globals.iDomainMaster;
9605 /***********************************************************
9606 If we are PDC then prefer us as DMB
9607 ************************************************************/
9609 bool lp_domain_master_true_or_auto(void)
9611 if (Globals.iDomainMaster) /* auto or yes */
9617 /***********************************************************
9618 If we are DMB then prefer us as LMB
9619 ************************************************************/
9621 bool lp_preferred_master(void)
9623 if (Globals.iPreferredMaster == Auto)
9624 return (lp_local_master() && lp_domain_master());
9626 return (bool)Globals.iPreferredMaster;
9629 /*******************************************************************
9631 ********************************************************************/
9633 void lp_remove_service(int snum)
9635 ServicePtrs[snum]->valid = False;
9636 invalid_services[num_invalid_services++] = snum;
9639 /*******************************************************************
9641 ********************************************************************/
9643 void lp_copy_service(int snum, const char *new_name)
9645 do_section(new_name, NULL);
9647 snum = lp_servicenumber(new_name);
9649 lp_do_parameter(snum, "copy", lp_servicename(snum));
9654 /*******************************************************************
9655 Get the default server type we will announce as via nmbd.
9656 ********************************************************************/
9658 int lp_default_server_announce(void)
9660 return default_server_announce;
9663 /*******************************************************************
9664 Split the announce version into major and minor numbers.
9665 ********************************************************************/
9667 int lp_major_announce_version(void)
9669 static bool got_major = False;
9670 static int major_version = DEFAULT_MAJOR_VERSION;
9675 return major_version;
9678 if ((vers = lp_announce_version()) == NULL)
9679 return major_version;
9681 if ((p = strchr_m(vers, '.')) == 0)
9682 return major_version;
9685 major_version = atoi(vers);
9686 return major_version;
9689 int lp_minor_announce_version(void)
9691 static bool got_minor = False;
9692 static int minor_version = DEFAULT_MINOR_VERSION;
9697 return minor_version;
9700 if ((vers = lp_announce_version()) == NULL)
9701 return minor_version;
9703 if ((p = strchr_m(vers, '.')) == 0)
9704 return minor_version;
9707 minor_version = atoi(p);
9708 return minor_version;
9711 /***********************************************************
9712 Set the global name resolution order (used in smbclient).
9713 ************************************************************/
9715 void lp_set_name_resolve_order(const char *new_order)
9717 string_set(&Globals.szNameResolveOrder, new_order);
9720 const char *lp_printername(int snum)
9722 const char *ret = _lp_printername(snum);
9723 if (ret == NULL || (ret != NULL && *ret == '\0'))
9724 ret = lp_const_servicename(snum);
9730 /***********************************************************
9731 Allow daemons such as winbindd to fix their logfile name.
9732 ************************************************************/
9734 void lp_set_logfile(const char *name)
9736 string_set(&Globals.szLogFile, name);
9737 debug_set_logfile(name);
9740 /*******************************************************************
9741 Return the max print jobs per queue.
9742 ********************************************************************/
9744 int lp_maxprintjobs(int snum)
9746 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9747 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9748 maxjobs = PRINT_MAX_JOBID - 1;
9753 const char *lp_printcapname(void)
9755 if ((Globals.szPrintcapname != NULL) &&
9756 (Globals.szPrintcapname[0] != '\0'))
9757 return Globals.szPrintcapname;
9759 if (sDefault.iPrinting == PRINT_CUPS) {
9767 if (sDefault.iPrinting == PRINT_BSD)
9768 return "/etc/printcap";
9770 return PRINTCAP_NAME;
9773 static uint32 spoolss_state;
9775 bool lp_disable_spoolss( void )
9777 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9778 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9780 return spoolss_state == SVCCTL_STOPPED ? True : False;
9783 void lp_set_spoolss_state( uint32 state )
9785 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9787 spoolss_state = state;
9790 uint32 lp_get_spoolss_state( void )
9792 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9795 /*******************************************************************
9796 Ensure we don't use sendfile if server smb signing is active.
9797 ********************************************************************/
9799 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9801 bool sign_active = false;
9803 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9804 if (get_Protocol() < PROTOCOL_NT1) {
9807 if (signing_state) {
9808 sign_active = smb_signing_is_active(signing_state);
9810 return (_lp_use_sendfile(snum) &&
9811 (get_remote_arch() != RA_WIN95) &&
9815 /*******************************************************************
9816 Turn off sendfile if we find the underlying OS doesn't support it.
9817 ********************************************************************/
9819 void set_use_sendfile(int snum, bool val)
9821 if (LP_SNUM_OK(snum))
9822 ServicePtrs[snum]->bUseSendfile = val;
9824 sDefault.bUseSendfile = val;
9827 /*******************************************************************
9828 Turn off storing DOS attributes if this share doesn't support it.
9829 ********************************************************************/
9831 void set_store_dos_attributes(int snum, bool val)
9833 if (!LP_SNUM_OK(snum))
9835 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9838 void lp_set_mangling_method(const char *new_method)
9840 string_set(&Globals.szManglingMethod, new_method);
9843 /*******************************************************************
9844 Global state for POSIX pathname processing.
9845 ********************************************************************/
9847 static bool posix_pathnames;
9849 bool lp_posix_pathnames(void)
9851 return posix_pathnames;
9854 /*******************************************************************
9855 Change everything needed to ensure POSIX pathname processing (currently
9857 ********************************************************************/
9859 void lp_set_posix_pathnames(void)
9861 posix_pathnames = True;
9864 /*******************************************************************
9865 Global state for POSIX lock processing - CIFS unix extensions.
9866 ********************************************************************/
9868 bool posix_default_lock_was_set;
9869 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9871 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9873 if (posix_default_lock_was_set) {
9874 return posix_cifsx_locktype;
9876 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9880 /*******************************************************************
9881 ********************************************************************/
9883 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9885 posix_default_lock_was_set = True;
9886 posix_cifsx_locktype = val;
9889 int lp_min_receive_file_size(void)
9891 if (Globals.iminreceivefile < 0) {
9894 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9897 /*******************************************************************
9898 If socket address is an empty character string, it is necessary to
9899 define it as "0.0.0.0".
9900 ********************************************************************/
9902 const char *lp_socket_address(void)
9904 char *sock_addr = Globals.szSocketAddress;
9906 if (sock_addr[0] == '\0'){
9907 string_set(&Globals.szSocketAddress, "0.0.0.0");
9909 return Globals.szSocketAddress;
9912 void lp_set_passdb_backend(const char *backend)
9914 string_set(&Globals.szPassdbBackend, backend);
9917 /*******************************************************************
9918 Safe wide links checks.
9919 This helper function always verify the validity of wide links,
9920 even after a configuration file reload.
9921 ********************************************************************/
9923 static bool lp_widelinks_internal(int snum)
9925 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9926 sDefault.bWidelinks);
9929 void widelinks_warning(int snum)
9931 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9932 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9933 "These parameters are incompatible. "
9934 "Wide links will be disabled for this share.\n",
9935 lp_servicename(snum) ));
9939 bool lp_widelinks(int snum)
9941 /* wide links is always incompatible with unix extensions */
9942 if (lp_unix_extensions()) {
9946 return lp_widelinks_internal(snum);
9949 bool lp_writeraw(void)
9951 if (lp_async_smb_echo_handler()) {
9954 return _lp_writeraw();
9957 bool lp_readraw(void)
9959 if (lp_async_smb_echo_handler()) {
9962 return _lp_readraw();