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
55 #include "system/filesys.h"
58 #include "lib/smbconf/smbconf.h"
59 #include "lib/smbconf/smbconf_init.h"
62 #include "../librpc/gen_ndr/svcctl.h"
64 #include "smb_signing.h"
68 #ifdef HAVE_SYS_SYSCTL_H
69 #include <sys/sysctl.h>
72 #ifdef HAVE_HTTPCONNECTENCRYPT
73 #include <cups/http.h>
78 extern userdom_struct current_user_info;
81 #define GLOBAL_NAME "global"
85 #define PRINTERS_NAME "printers"
89 #define HOMES_NAME "homes"
92 /* the special value for the include parameter
93 * to be interpreted not as a file name but to
94 * trigger loading of the global smb.conf options
96 #ifndef INCLUDE_REGISTRY_NAME
97 #define INCLUDE_REGISTRY_NAME "registry"
100 static bool in_client = False; /* Not in the client by default */
101 static struct smbconf_csn conf_last_csn;
103 #define CONFIG_BACKEND_FILE 0
104 #define CONFIG_BACKEND_REGISTRY 1
106 static int config_backend = CONFIG_BACKEND_FILE;
108 /* some helpful bits */
109 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
110 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
112 #define USERSHARE_VALID 1
113 #define USERSHARE_PENDING_DELETE 2
115 static bool defaults_saved = False;
117 struct param_opt_struct {
118 struct param_opt_struct *prev, *next;
126 * This structure describes global (ie., server-wide) parameters.
133 char *display_charset;
134 char *szPrintcapname;
135 char *szAddPortCommand;
136 char *szEnumPortsCommand;
137 char *szAddPrinterCommand;
138 char *szDeletePrinterCommand;
139 char *szOs2DriverMap;
145 char *szDefaultService;
149 char *szServerString;
150 char *szAutoServices;
151 char *szPasswdProgram;
155 char *szSMBPasswdFile;
157 char *szPassdbBackend;
158 char **szPreloadModules;
159 char *szPasswordServer;
160 char *szSocketOptions;
164 char *szAfsUsernameMap;
165 int iAfsTokenLifetime;
166 char *szLogNtTokenCommand;
172 char **szWINSservers;
174 char *szRemoteAnnounce;
175 char *szRemoteBrowseSync;
176 char *szSocketAddress;
177 bool bNmbdBindExplicitBroadcast;
178 char *szNISHomeMapName;
179 char *szAnnounceVersion; /* This is initialised in init_globals */
182 char **szNetbiosAliases;
183 char *szNetbiosScope;
184 char *szNameResolveOrder;
186 char *szAddUserScript;
187 char *szRenameUserScript;
188 char *szDelUserScript;
189 char *szAddGroupScript;
190 char *szDelGroupScript;
191 char *szAddUserToGroupScript;
192 char *szDelUserFromGroupScript;
193 char *szSetPrimaryGroupScript;
194 char *szAddMachineScript;
195 char *szShutdownScript;
196 char *szAbortShutdownScript;
197 char *szUsernameMapScript;
198 int iUsernameMapCacheTime;
199 char *szCheckPasswordScript;
206 bool bPassdbExpandExplicit;
207 int AlgorithmicRidBase;
208 char *szTemplateHomedir;
209 char *szTemplateShell;
210 char *szWinbindSeparator;
211 bool bWinbindEnumUsers;
212 bool bWinbindEnumGroups;
213 bool bWinbindUseDefaultDomain;
214 bool bWinbindTrustedDomainsOnly;
215 bool bWinbindNestedGroups;
216 int winbind_expand_groups;
217 bool bWinbindRefreshTickets;
218 bool bWinbindOfflineLogon;
219 bool bWinbindNormalizeNames;
220 bool bWinbindRpcOnly;
221 bool bCreateKrb5Conf;
222 int winbindMaxDomainConnections;
223 char *szIdmapBackend;
225 char *szAddShareCommand;
226 char *szChangeShareCommand;
227 char *szDeleteShareCommand;
229 char *szGuestaccount;
230 char *szManglingMethod;
231 char **szServicesList;
232 char *szUsersharePath;
233 char *szUsershareTemplateShare;
234 char **szUsersharePrefixAllowList;
235 char **szUsersharePrefixDenyList;
242 int open_files_db_hash_size;
251 bool paranoid_server_security;
254 int iMaxSmbdProcesses;
255 bool bDisableSpoolss;
258 bool enhanced_browsing;
264 int announce_as; /* This is initialised in init_globals */
265 int machine_password_timeout;
267 int oplock_break_wait_time;
268 int winbind_cache_time;
269 int winbind_reconnect_delay;
270 int winbind_max_clients;
271 char **szWinbindNssInfo;
273 char *szLdapMachineSuffix;
274 char *szLdapUserSuffix;
275 char *szLdapIdmapSuffix;
276 char *szLdapGroupSuffix;
280 int ldap_follow_referral;
283 int ldap_debug_level;
284 int ldap_debug_threshold;
288 char *szIPrintServer;
290 char **szClusterAddresses;
293 int ctdb_locktime_warn_threshold;
294 int ldap_passwd_sync;
295 int ldap_replication_sleep;
296 int ldap_timeout; /* This is initialised in init_globals */
297 int ldap_connection_timeout;
300 bool bMsAddPrinterWizard;
305 int iPreferredMaster;
308 char **szInitLogonDelayedHosts;
310 bool bEncryptPasswords;
315 bool bObeyPamRestrictions;
317 int PrintcapCacheTime;
318 bool bLargeReadwrite;
325 bool bBindInterfacesOnly;
326 bool bPamPasswordChange;
327 bool bUnixPasswdSync;
328 bool bPasswdChatDebug;
329 int iPasswdChatTimeout;
333 bool bNTStatusSupport;
335 int iMaxStatCacheSize;
337 bool bAllowTrustedDomains;
341 bool bClientLanManAuth;
342 bool bClientNTLMv2Auth;
343 bool bClientPlaintextAuth;
344 bool bClientUseSpnego;
345 bool client_use_spnego_principal;
346 bool send_spnego_principal;
347 bool bDebugPrefixTimestamp;
348 bool bDebugHiresTimestamp;
352 bool bEnableCoreFiles;
355 bool bHostnameLookups;
356 bool bUnixExtensions;
357 bool bDisableNetbios;
358 char * szDedicatedKeytabFile;
360 bool bDeferSharingViolations;
361 bool bEnablePrivileges;
363 bool bUsershareOwnerOnly;
364 bool bUsershareAllowGuests;
365 bool bRegistryShares;
366 int restrict_anonymous;
367 int name_cache_timeout;
370 int client_ldap_sasl_wrapping;
371 int iUsershareMaxShares;
373 int iIdmapNegativeCacheTime;
375 bool bLogWriteableFilesOnExit;
378 struct param_opt_struct *param_opt;
379 int cups_connection_timeout;
380 char *szSMBPerfcountModule;
381 bool bMapUntrustedToDomain;
382 bool bAsyncSMBEchoHandler;
383 bool bMulticastDnsRegister;
387 int ismb2_max_credits;
391 static struct global Globals;
394 * This structure describes a single service.
400 struct timespec usershare_last_mod;
404 char **szInvalidUsers;
412 char *szRootPostExec;
414 char *szPrintcommand;
417 char *szLppausecommand;
418 char *szLpresumecommand;
419 char *szQueuepausecommand;
420 char *szQueueresumecommand;
422 char *szPrintjobUsername;
430 char *szVetoOplockFiles;
436 char **printer_admin;
441 char *szAioWriteBehind;
445 int iMaxReportedPrintJobs;
448 int iCreate_force_mode;
450 int iSecurity_force_mode;
453 int iDir_Security_mask;
454 int iDir_Security_force_mode;
458 int iOplockContentionLimit;
463 bool bRootpreexecClose;
466 bool bShortCasePreserve;
468 bool bHideSpecialFiles;
469 bool bHideUnReadable;
470 bool bHideUnWriteableFiles;
472 bool bAccessBasedShareEnum;
477 bool bAdministrative_share;
480 bool bPrintNotifyBackchannel;
484 bool bStoreDosAttributes;
497 bool bStrictAllocate;
500 struct bitmap *copymap;
501 bool bDeleteReadonly;
503 bool bDeleteVetoFiles;
506 bool bDosFiletimeResolution;
507 bool bFakeDirCreateTimes;
513 bool bUseClientDriver;
514 bool bDefaultDevmode;
515 bool bForcePrintername;
517 bool bForceUnknownAclUser;
520 bool bMap_acl_inherit;
523 bool bAclCheckPermissions;
524 bool bAclMapFullControl;
525 bool bAclGroupControl;
527 bool bKernelChangeNotify;
528 int iallocation_roundup_size;
532 int iDirectoryNameCacheSize;
534 struct param_opt_struct *param_opt;
536 char dummy[3]; /* for alignment */
540 /* This is a default service used to prime a services structure */
541 static struct service sDefault = {
543 False, /* not autoloaded */
544 0, /* not a usershare */
545 {0, }, /* No last mod time */
546 NULL, /* szService */
548 NULL, /* szUsername */
549 NULL, /* szInvalidUsers */
550 NULL, /* szValidUsers */
551 NULL, /* szAdminUsers */
553 NULL, /* szInclude */
554 NULL, /* szPreExec */
555 NULL, /* szPostExec */
556 NULL, /* szRootPreExec */
557 NULL, /* szRootPostExec */
558 NULL, /* szCupsOptions */
559 NULL, /* szPrintcommand */
560 NULL, /* szLpqcommand */
561 NULL, /* szLprmcommand */
562 NULL, /* szLppausecommand */
563 NULL, /* szLpresumecommand */
564 NULL, /* szQueuepausecommand */
565 NULL, /* szQueueresumecommand */
566 NULL, /* szPrintername */
567 NULL, /* szPrintjobUsername */
568 NULL, /* szDontdescend */
569 NULL, /* szHostsallow */
570 NULL, /* szHostsdeny */
571 NULL, /* szMagicScript */
572 NULL, /* szMagicOutput */
573 NULL, /* szVetoFiles */
574 NULL, /* szHideFiles */
575 NULL, /* szVetoOplockFiles */
577 NULL, /* force user */
578 NULL, /* force group */
580 NULL, /* writelist */
581 NULL, /* printer admin */
584 NULL, /* vfs objects */
585 NULL, /* szMSDfsProxy */
586 NULL, /* szAioWriteBehind */
588 0, /* iMinPrintSpace */
589 1000, /* iMaxPrintJobs */
590 0, /* iMaxReportedPrintJobs */
591 0, /* iWriteCacheSize */
592 0744, /* iCreate_mask */
593 0000, /* iCreate_force_mode */
594 0777, /* iSecurity_mask */
595 0, /* iSecurity_force_mode */
596 0755, /* iDir_mask */
597 0000, /* iDir_force_mode */
598 0777, /* iDir_Security_mask */
599 0, /* iDir_Security_force_mode */
600 0, /* iMaxConnections */
601 CASE_LOWER, /* iDefaultCase */
602 DEFAULT_PRINTING, /* iPrinting */
603 2, /* iOplockContentionLimit */
605 1024, /* iBlock_size */
606 0, /* iDfreeCacheTime */
607 False, /* bPreexecClose */
608 False, /* bRootpreexecClose */
609 Auto, /* case sensitive */
610 True, /* case preserve */
611 True, /* short case preserve */
612 True, /* bHideDotFiles */
613 False, /* bHideSpecialFiles */
614 False, /* bHideUnReadable */
615 False, /* bHideUnWriteableFiles */
616 True, /* bBrowseable */
617 False, /* bAccessBasedShareEnum */
618 True, /* bAvailable */
619 True, /* bRead_only */
620 True, /* bNo_set_dir */
621 False, /* bGuest_only */
622 False, /* bAdministrative_share */
623 False, /* bGuest_ok */
624 False, /* bPrint_ok */
625 True, /* bPrintNotifyBackchannel */
626 False, /* bMap_system */
627 False, /* bMap_hidden */
628 True, /* bMap_archive */
629 False, /* bStoreDosAttributes */
630 False, /* bDmapiSupport */
632 Auto, /* iStrictLocking */
633 True, /* bPosixLocking */
634 True, /* bShareModes */
636 True, /* bLevel2OpLocks */
637 False, /* bOnlyUser */
638 True, /* bMangledNames */
639 false, /* bWidelinks */
640 True, /* bSymlinks */
641 False, /* bSyncAlways */
642 False, /* bStrictAllocate */
643 False, /* bStrictSync */
644 '~', /* magic char */
646 False, /* bDeleteReadonly */
647 False, /* bFakeOplocks */
648 False, /* bDeleteVetoFiles */
649 False, /* bDosFilemode */
650 True, /* bDosFiletimes */
651 False, /* bDosFiletimeResolution */
652 False, /* bFakeDirCreateTimes */
653 True, /* bBlockingLocks */
654 False, /* bInheritPerms */
655 False, /* bInheritACLS */
656 False, /* bInheritOwner */
657 False, /* bMSDfsRoot */
658 False, /* bUseClientDriver */
659 True, /* bDefaultDevmode */
660 False, /* bForcePrintername */
661 True, /* bNTAclSupport */
662 False, /* bForceUnknownAclUser */
663 False, /* bUseSendfile */
664 False, /* bProfileAcls */
665 False, /* bMap_acl_inherit */
666 False, /* bAfs_Share */
667 False, /* bEASupport */
668 True, /* bAclCheckPermissions */
669 True, /* bAclMapFullControl */
670 False, /* bAclGroupControl */
671 True, /* bChangeNotify */
672 True, /* bKernelChangeNotify */
673 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
674 0, /* iAioReadSize */
675 0, /* iAioWriteSize */
676 MAP_READONLY_YES, /* iMap_readonly */
677 #ifdef BROKEN_DIRECTORY_HANDLING
678 0, /* iDirectoryNameCacheSize */
680 100, /* iDirectoryNameCacheSize */
682 Auto, /* ismb_encrypt */
683 NULL, /* Parametric options */
688 /* local variables */
689 static struct service **ServicePtrs = NULL;
690 static int iNumServices = 0;
691 static int iServiceIndex = 0;
692 static struct db_context *ServiceHash;
693 static int *invalid_services = NULL;
694 static int num_invalid_services = 0;
695 static bool bInGlobalSection = True;
696 static bool bGlobalOnly = False;
697 static int default_server_announce;
699 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
701 /* prototypes for the special type handlers */
702 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
703 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
704 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
705 static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr);
706 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
707 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
708 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
709 static bool handle_realm( int snum, const char *pszParmValue, char **ptr );
710 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
711 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
712 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
713 static bool handle_dos_charset( int snum, const char *pszParmValue, char **ptr );
714 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
715 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
717 static void set_default_server_announce_type(void);
718 static void set_allowed_client_auth(void);
720 static void *lp_local_ptr(struct service *service, void *ptr);
722 static void add_to_file_list(const char *fname, const char *subfname);
723 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
725 static const struct enum_list enum_protocol[] = {
726 {PROTOCOL_SMB2, "SMB2"},
727 {PROTOCOL_NT1, "NT1"},
728 {PROTOCOL_LANMAN2, "LANMAN2"},
729 {PROTOCOL_LANMAN1, "LANMAN1"},
730 {PROTOCOL_CORE, "CORE"},
731 {PROTOCOL_COREPLUS, "COREPLUS"},
732 {PROTOCOL_COREPLUS, "CORE+"},
736 static const struct enum_list enum_security[] = {
737 {SEC_SHARE, "SHARE"},
739 {SEC_SERVER, "SERVER"},
740 {SEC_DOMAIN, "DOMAIN"},
747 static const struct enum_list enum_printing[] = {
748 {PRINT_SYSV, "sysv"},
750 {PRINT_HPUX, "hpux"},
754 {PRINT_LPRNG, "lprng"},
755 {PRINT_CUPS, "cups"},
756 {PRINT_IPRINT, "iprint"},
758 {PRINT_LPROS2, "os2"},
759 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
760 {PRINT_TEST, "test"},
762 #endif /* DEVELOPER */
766 static const struct enum_list enum_ldap_sasl_wrapping[] = {
768 {ADS_AUTH_SASL_SIGN, "sign"},
769 {ADS_AUTH_SASL_SEAL, "seal"},
773 static const struct enum_list enum_ldap_ssl[] = {
774 {LDAP_SSL_OFF, "no"},
775 {LDAP_SSL_OFF, "off"},
776 {LDAP_SSL_START_TLS, "start tls"},
777 {LDAP_SSL_START_TLS, "start_tls"},
781 /* LDAP Dereferencing Alias types */
782 #define SAMBA_LDAP_DEREF_NEVER 0
783 #define SAMBA_LDAP_DEREF_SEARCHING 1
784 #define SAMBA_LDAP_DEREF_FINDING 2
785 #define SAMBA_LDAP_DEREF_ALWAYS 3
787 static const struct enum_list enum_ldap_deref[] = {
788 {SAMBA_LDAP_DEREF_NEVER, "never"},
789 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
790 {SAMBA_LDAP_DEREF_FINDING, "finding"},
791 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
795 static const struct enum_list enum_ldap_passwd_sync[] = {
796 {LDAP_PASSWD_SYNC_OFF, "no"},
797 {LDAP_PASSWD_SYNC_OFF, "off"},
798 {LDAP_PASSWD_SYNC_ON, "yes"},
799 {LDAP_PASSWD_SYNC_ON, "on"},
800 {LDAP_PASSWD_SYNC_ONLY, "only"},
804 /* Types of machine we can announce as. */
805 #define ANNOUNCE_AS_NT_SERVER 1
806 #define ANNOUNCE_AS_WIN95 2
807 #define ANNOUNCE_AS_WFW 3
808 #define ANNOUNCE_AS_NT_WORKSTATION 4
810 static const struct enum_list enum_announce_as[] = {
811 {ANNOUNCE_AS_NT_SERVER, "NT"},
812 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
813 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
814 {ANNOUNCE_AS_WIN95, "win95"},
815 {ANNOUNCE_AS_WFW, "WfW"},
819 static const struct enum_list enum_map_readonly[] = {
820 {MAP_READONLY_NO, "no"},
821 {MAP_READONLY_NO, "false"},
822 {MAP_READONLY_NO, "0"},
823 {MAP_READONLY_YES, "yes"},
824 {MAP_READONLY_YES, "true"},
825 {MAP_READONLY_YES, "1"},
826 {MAP_READONLY_PERMISSIONS, "permissions"},
827 {MAP_READONLY_PERMISSIONS, "perms"},
831 static const struct enum_list enum_case[] = {
832 {CASE_LOWER, "lower"},
833 {CASE_UPPER, "upper"},
839 static const struct enum_list enum_bool_auto[] = {
850 static const struct enum_list enum_csc_policy[] = {
851 {CSC_POLICY_MANUAL, "manual"},
852 {CSC_POLICY_DOCUMENTS, "documents"},
853 {CSC_POLICY_PROGRAMS, "programs"},
854 {CSC_POLICY_DISABLE, "disable"},
858 /* SMB signing types. */
859 static const struct enum_list enum_smb_signing_vals[] = {
871 {Required, "required"},
872 {Required, "mandatory"},
874 {Required, "forced"},
875 {Required, "enforced"},
879 /* ACL compatibility options. */
880 static const struct enum_list enum_acl_compat_vals[] = {
881 { ACL_COMPAT_AUTO, "auto" },
882 { ACL_COMPAT_WINNT, "winnt" },
883 { ACL_COMPAT_WIN2K, "win2k" },
888 Do you want session setups at user level security with a invalid
889 password to be rejected or allowed in as guest? WinNT rejects them
890 but it can be a pain as it means "net view" needs to use a password
892 You have 3 choices in the setting of map_to_guest:
894 "Never" means session setups with an invalid password
895 are rejected. This is the default.
897 "Bad User" means session setups with an invalid password
898 are rejected, unless the username does not exist, in which case it
899 is treated as a guest login
901 "Bad Password" means session setups with an invalid password
902 are treated as a guest login
904 Note that map_to_guest only has an effect in user or server
908 static const struct enum_list enum_map_to_guest[] = {
909 {NEVER_MAP_TO_GUEST, "Never"},
910 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
911 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
912 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
916 /* Config backend options */
918 static const struct enum_list enum_config_backend[] = {
919 {CONFIG_BACKEND_FILE, "file"},
920 {CONFIG_BACKEND_REGISTRY, "registry"},
924 /* ADS kerberos ticket verification options */
926 static const struct enum_list enum_kerberos_method[] = {
927 {KERBEROS_VERIFY_SECRETS, "default"},
928 {KERBEROS_VERIFY_SECRETS, "secrets only"},
929 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
930 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
931 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
935 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
937 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
938 * screen in SWAT. This is used to exclude parameters as well as to squash all
939 * parameters that have been duplicated by pseudonyms.
941 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
942 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
943 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
946 * NOTE2: Handling of duplicated (synonym) parameters:
947 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
948 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
949 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
950 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
953 static struct parm_struct parm_table[] = {
954 {N_("Base Options"), P_SEP, P_SEPARATOR},
957 .label = "dos charset",
960 .ptr = &Globals.dos_charset,
961 .special = handle_dos_charset,
963 .flags = FLAG_ADVANCED
966 .label = "unix charset",
969 .ptr = &Globals.unix_charset,
970 .special = handle_charset,
972 .flags = FLAG_ADVANCED
975 .label = "display charset",
978 .ptr = &Globals.display_charset,
979 .special = handle_charset,
981 .flags = FLAG_ADVANCED
987 .ptr = &sDefault.comment,
990 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
996 .ptr = &sDefault.szPath,
999 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1002 .label = "directory",
1005 .ptr = &sDefault.szPath,
1011 .label = "workgroup",
1013 .p_class = P_GLOBAL,
1014 .ptr = &Globals.szWorkgroup,
1017 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1022 .p_class = P_GLOBAL,
1023 .ptr = &Globals.szRealm,
1024 .special = handle_realm,
1026 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1029 .label = "netbios name",
1031 .p_class = P_GLOBAL,
1032 .ptr = &Globals.szNetbiosName,
1033 .special = handle_netbios_name,
1035 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1038 .label = "netbios aliases",
1040 .p_class = P_GLOBAL,
1041 .ptr = &Globals.szNetbiosAliases,
1042 .special = handle_netbios_aliases,
1044 .flags = FLAG_ADVANCED,
1047 .label = "netbios scope",
1049 .p_class = P_GLOBAL,
1050 .ptr = &Globals.szNetbiosScope,
1051 .special = handle_netbios_scope,
1053 .flags = FLAG_ADVANCED,
1056 .label = "server string",
1058 .p_class = P_GLOBAL,
1059 .ptr = &Globals.szServerString,
1062 .flags = FLAG_BASIC | FLAG_ADVANCED,
1065 .label = "interfaces",
1067 .p_class = P_GLOBAL,
1068 .ptr = &Globals.szInterfaces,
1071 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1074 .label = "bind interfaces only",
1076 .p_class = P_GLOBAL,
1077 .ptr = &Globals.bBindInterfacesOnly,
1080 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1083 .label = "config backend",
1085 .p_class = P_GLOBAL,
1086 .ptr = &Globals.ConfigBackend,
1088 .enum_list = enum_config_backend,
1089 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1092 {N_("Security Options"), P_SEP, P_SEPARATOR},
1095 .label = "security",
1097 .p_class = P_GLOBAL,
1098 .ptr = &Globals.security,
1100 .enum_list = enum_security,
1101 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1104 .label = "auth methods",
1106 .p_class = P_GLOBAL,
1107 .ptr = &Globals.AuthMethods,
1110 .flags = FLAG_ADVANCED,
1113 .label = "encrypt passwords",
1115 .p_class = P_GLOBAL,
1116 .ptr = &Globals.bEncryptPasswords,
1119 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1122 .label = "client schannel",
1124 .p_class = P_GLOBAL,
1125 .ptr = &Globals.clientSchannel,
1127 .enum_list = enum_bool_auto,
1128 .flags = FLAG_BASIC | FLAG_ADVANCED,
1131 .label = "server schannel",
1133 .p_class = P_GLOBAL,
1134 .ptr = &Globals.serverSchannel,
1136 .enum_list = enum_bool_auto,
1137 .flags = FLAG_BASIC | FLAG_ADVANCED,
1140 .label = "allow trusted domains",
1142 .p_class = P_GLOBAL,
1143 .ptr = &Globals.bAllowTrustedDomains,
1146 .flags = FLAG_ADVANCED,
1149 .label = "map to guest",
1151 .p_class = P_GLOBAL,
1152 .ptr = &Globals.map_to_guest,
1154 .enum_list = enum_map_to_guest,
1155 .flags = FLAG_ADVANCED,
1158 .label = "null passwords",
1160 .p_class = P_GLOBAL,
1161 .ptr = &Globals.bNullPasswords,
1164 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1167 .label = "obey pam restrictions",
1169 .p_class = P_GLOBAL,
1170 .ptr = &Globals.bObeyPamRestrictions,
1173 .flags = FLAG_ADVANCED,
1176 .label = "password server",
1178 .p_class = P_GLOBAL,
1179 .ptr = &Globals.szPasswordServer,
1182 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1185 .label = "smb passwd file",
1187 .p_class = P_GLOBAL,
1188 .ptr = &Globals.szSMBPasswdFile,
1191 .flags = FLAG_ADVANCED,
1194 .label = "private dir",
1196 .p_class = P_GLOBAL,
1197 .ptr = &Globals.szPrivateDir,
1200 .flags = FLAG_ADVANCED,
1203 .label = "passdb backend",
1205 .p_class = P_GLOBAL,
1206 .ptr = &Globals.szPassdbBackend,
1209 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1212 .label = "algorithmic rid base",
1214 .p_class = P_GLOBAL,
1215 .ptr = &Globals.AlgorithmicRidBase,
1218 .flags = FLAG_ADVANCED,
1221 .label = "root directory",
1223 .p_class = P_GLOBAL,
1224 .ptr = &Globals.szRootdir,
1227 .flags = FLAG_ADVANCED,
1230 .label = "root dir",
1232 .p_class = P_GLOBAL,
1233 .ptr = &Globals.szRootdir,
1241 .p_class = P_GLOBAL,
1242 .ptr = &Globals.szRootdir,
1248 .label = "guest account",
1250 .p_class = P_GLOBAL,
1251 .ptr = &Globals.szGuestaccount,
1254 .flags = FLAG_BASIC | FLAG_ADVANCED,
1257 .label = "enable privileges",
1259 .p_class = P_GLOBAL,
1260 .ptr = &Globals.bEnablePrivileges,
1263 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1267 .label = "pam password change",
1269 .p_class = P_GLOBAL,
1270 .ptr = &Globals.bPamPasswordChange,
1273 .flags = FLAG_ADVANCED,
1276 .label = "passwd program",
1278 .p_class = P_GLOBAL,
1279 .ptr = &Globals.szPasswdProgram,
1282 .flags = FLAG_ADVANCED,
1285 .label = "passwd chat",
1287 .p_class = P_GLOBAL,
1288 .ptr = &Globals.szPasswdChat,
1291 .flags = FLAG_ADVANCED,
1294 .label = "passwd chat debug",
1296 .p_class = P_GLOBAL,
1297 .ptr = &Globals.bPasswdChatDebug,
1300 .flags = FLAG_ADVANCED,
1303 .label = "passwd chat timeout",
1305 .p_class = P_GLOBAL,
1306 .ptr = &Globals.iPasswdChatTimeout,
1309 .flags = FLAG_ADVANCED,
1312 .label = "check password script",
1314 .p_class = P_GLOBAL,
1315 .ptr = &Globals.szCheckPasswordScript,
1318 .flags = FLAG_ADVANCED,
1321 .label = "username map",
1323 .p_class = P_GLOBAL,
1324 .ptr = &Globals.szUsernameMap,
1327 .flags = FLAG_ADVANCED,
1330 .label = "password level",
1332 .p_class = P_GLOBAL,
1333 .ptr = &Globals.pwordlevel,
1336 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1339 .label = "username level",
1341 .p_class = P_GLOBAL,
1342 .ptr = &Globals.unamelevel,
1345 .flags = FLAG_ADVANCED,
1348 .label = "unix password sync",
1350 .p_class = P_GLOBAL,
1351 .ptr = &Globals.bUnixPasswdSync,
1354 .flags = FLAG_ADVANCED,
1357 .label = "restrict anonymous",
1359 .p_class = P_GLOBAL,
1360 .ptr = &Globals.restrict_anonymous,
1363 .flags = FLAG_ADVANCED,
1366 .label = "lanman auth",
1368 .p_class = P_GLOBAL,
1369 .ptr = &Globals.bLanmanAuth,
1372 .flags = FLAG_ADVANCED,
1375 .label = "ntlm auth",
1377 .p_class = P_GLOBAL,
1378 .ptr = &Globals.bNTLMAuth,
1381 .flags = FLAG_ADVANCED,
1384 .label = "client NTLMv2 auth",
1386 .p_class = P_GLOBAL,
1387 .ptr = &Globals.bClientNTLMv2Auth,
1390 .flags = FLAG_ADVANCED,
1393 .label = "client lanman auth",
1395 .p_class = P_GLOBAL,
1396 .ptr = &Globals.bClientLanManAuth,
1399 .flags = FLAG_ADVANCED,
1402 .label = "client plaintext auth",
1404 .p_class = P_GLOBAL,
1405 .ptr = &Globals.bClientPlaintextAuth,
1408 .flags = FLAG_ADVANCED,
1411 .label = "client use spnego principal",
1413 .p_class = P_GLOBAL,
1414 .ptr = &Globals.client_use_spnego_principal,
1417 .flags = FLAG_ADVANCED,
1420 .label = "send spnego principal",
1422 .p_class = P_GLOBAL,
1423 .ptr = &Globals.send_spnego_principal,
1426 .flags = FLAG_ADVANCED,
1429 .label = "username",
1432 .ptr = &sDefault.szUsername,
1435 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1441 .ptr = &sDefault.szUsername,
1450 .ptr = &sDefault.szUsername,
1456 .label = "invalid users",
1459 .ptr = &sDefault.szInvalidUsers,
1462 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1465 .label = "valid users",
1468 .ptr = &sDefault.szValidUsers,
1471 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1474 .label = "admin users",
1477 .ptr = &sDefault.szAdminUsers,
1480 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1483 .label = "read list",
1486 .ptr = &sDefault.readlist,
1489 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1492 .label = "write list",
1495 .ptr = &sDefault.writelist,
1498 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1501 .label = "printer admin",
1504 .ptr = &sDefault.printer_admin,
1507 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1510 .label = "force user",
1513 .ptr = &sDefault.force_user,
1516 .flags = FLAG_ADVANCED | FLAG_SHARE,
1519 .label = "force group",
1522 .ptr = &sDefault.force_group,
1525 .flags = FLAG_ADVANCED | FLAG_SHARE,
1531 .ptr = &sDefault.force_group,
1534 .flags = FLAG_ADVANCED,
1537 .label = "read only",
1540 .ptr = &sDefault.bRead_only,
1543 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1546 .label = "write ok",
1549 .ptr = &sDefault.bRead_only,
1555 .label = "writeable",
1558 .ptr = &sDefault.bRead_only,
1564 .label = "writable",
1567 .ptr = &sDefault.bRead_only,
1573 .label = "acl check permissions",
1576 .ptr = &sDefault.bAclCheckPermissions,
1579 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1582 .label = "acl group control",
1585 .ptr = &sDefault.bAclGroupControl,
1588 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1591 .label = "acl map full control",
1594 .ptr = &sDefault.bAclMapFullControl,
1597 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1600 .label = "create mask",
1603 .ptr = &sDefault.iCreate_mask,
1606 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1609 .label = "create mode",
1612 .ptr = &sDefault.iCreate_mask,
1618 .label = "force create mode",
1621 .ptr = &sDefault.iCreate_force_mode,
1624 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1627 .label = "security mask",
1630 .ptr = &sDefault.iSecurity_mask,
1633 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1636 .label = "force security mode",
1639 .ptr = &sDefault.iSecurity_force_mode,
1642 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1645 .label = "directory mask",
1648 .ptr = &sDefault.iDir_mask,
1651 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1654 .label = "directory mode",
1657 .ptr = &sDefault.iDir_mask,
1660 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1663 .label = "force directory mode",
1666 .ptr = &sDefault.iDir_force_mode,
1669 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1672 .label = "directory security mask",
1675 .ptr = &sDefault.iDir_Security_mask,
1678 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1681 .label = "force directory security mode",
1684 .ptr = &sDefault.iDir_Security_force_mode,
1687 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1690 .label = "force unknown acl user",
1693 .ptr = &sDefault.bForceUnknownAclUser,
1696 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1699 .label = "inherit permissions",
1702 .ptr = &sDefault.bInheritPerms,
1705 .flags = FLAG_ADVANCED | FLAG_SHARE,
1708 .label = "inherit acls",
1711 .ptr = &sDefault.bInheritACLS,
1714 .flags = FLAG_ADVANCED | FLAG_SHARE,
1717 .label = "inherit owner",
1720 .ptr = &sDefault.bInheritOwner,
1723 .flags = FLAG_ADVANCED | FLAG_SHARE,
1726 .label = "guest only",
1729 .ptr = &sDefault.bGuest_only,
1732 .flags = FLAG_ADVANCED | FLAG_SHARE,
1735 .label = "only guest",
1738 .ptr = &sDefault.bGuest_only,
1744 .label = "administrative share",
1747 .ptr = &sDefault.bAdministrative_share,
1750 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1754 .label = "guest ok",
1757 .ptr = &sDefault.bGuest_ok,
1760 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1766 .ptr = &sDefault.bGuest_ok,
1772 .label = "only user",
1775 .ptr = &sDefault.bOnlyUser,
1778 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1781 .label = "hosts allow",
1784 .ptr = &sDefault.szHostsallow,
1787 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1790 .label = "allow hosts",
1793 .ptr = &sDefault.szHostsallow,
1799 .label = "hosts deny",
1802 .ptr = &sDefault.szHostsdeny,
1805 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1808 .label = "deny hosts",
1811 .ptr = &sDefault.szHostsdeny,
1817 .label = "preload modules",
1819 .p_class = P_GLOBAL,
1820 .ptr = &Globals.szPreloadModules,
1823 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1826 .label = "dedicated keytab file",
1828 .p_class = P_GLOBAL,
1829 .ptr = &Globals.szDedicatedKeytabFile,
1832 .flags = FLAG_ADVANCED,
1835 .label = "kerberos method",
1837 .p_class = P_GLOBAL,
1838 .ptr = &Globals.iKerberosMethod,
1840 .enum_list = enum_kerberos_method,
1841 .flags = FLAG_ADVANCED,
1844 .label = "map untrusted to domain",
1846 .p_class = P_GLOBAL,
1847 .ptr = &Globals.bMapUntrustedToDomain,
1850 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1854 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1857 .label = "log level",
1859 .p_class = P_GLOBAL,
1860 .ptr = &Globals.szLogLevel,
1861 .special = handle_debug_list,
1863 .flags = FLAG_ADVANCED,
1866 .label = "debuglevel",
1868 .p_class = P_GLOBAL,
1869 .ptr = &Globals.szLogLevel,
1870 .special = handle_debug_list,
1877 .p_class = P_GLOBAL,
1878 .ptr = &Globals.syslog,
1881 .flags = FLAG_ADVANCED,
1884 .label = "syslog only",
1886 .p_class = P_GLOBAL,
1887 .ptr = &Globals.bSyslogOnly,
1890 .flags = FLAG_ADVANCED,
1893 .label = "log file",
1895 .p_class = P_GLOBAL,
1896 .ptr = &Globals.szLogFile,
1899 .flags = FLAG_ADVANCED,
1902 .label = "max log size",
1904 .p_class = P_GLOBAL,
1905 .ptr = &Globals.max_log_size,
1908 .flags = FLAG_ADVANCED,
1911 .label = "debug timestamp",
1913 .p_class = P_GLOBAL,
1914 .ptr = &Globals.bTimestampLogs,
1917 .flags = FLAG_ADVANCED,
1920 .label = "timestamp logs",
1922 .p_class = P_GLOBAL,
1923 .ptr = &Globals.bTimestampLogs,
1926 .flags = FLAG_ADVANCED,
1929 .label = "debug prefix timestamp",
1931 .p_class = P_GLOBAL,
1932 .ptr = &Globals.bDebugPrefixTimestamp,
1935 .flags = FLAG_ADVANCED,
1938 .label = "debug hires timestamp",
1940 .p_class = P_GLOBAL,
1941 .ptr = &Globals.bDebugHiresTimestamp,
1944 .flags = FLAG_ADVANCED,
1947 .label = "debug pid",
1949 .p_class = P_GLOBAL,
1950 .ptr = &Globals.bDebugPid,
1953 .flags = FLAG_ADVANCED,
1956 .label = "debug uid",
1958 .p_class = P_GLOBAL,
1959 .ptr = &Globals.bDebugUid,
1962 .flags = FLAG_ADVANCED,
1965 .label = "debug class",
1967 .p_class = P_GLOBAL,
1968 .ptr = &Globals.bDebugClass,
1971 .flags = FLAG_ADVANCED,
1974 .label = "enable core files",
1976 .p_class = P_GLOBAL,
1977 .ptr = &Globals.bEnableCoreFiles,
1980 .flags = FLAG_ADVANCED,
1983 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1986 .label = "allocation roundup size",
1989 .ptr = &sDefault.iallocation_roundup_size,
1992 .flags = FLAG_ADVANCED,
1995 .label = "aio read size",
1998 .ptr = &sDefault.iAioReadSize,
2001 .flags = FLAG_ADVANCED,
2004 .label = "aio write size",
2007 .ptr = &sDefault.iAioWriteSize,
2010 .flags = FLAG_ADVANCED,
2013 .label = "aio write behind",
2016 .ptr = &sDefault.szAioWriteBehind,
2019 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2022 .label = "smb ports",
2024 .p_class = P_GLOBAL,
2025 .ptr = &Globals.smb_ports,
2028 .flags = FLAG_ADVANCED,
2031 .label = "large readwrite",
2033 .p_class = P_GLOBAL,
2034 .ptr = &Globals.bLargeReadwrite,
2037 .flags = FLAG_ADVANCED,
2040 .label = "max protocol",
2042 .p_class = P_GLOBAL,
2043 .ptr = &Globals.maxprotocol,
2045 .enum_list = enum_protocol,
2046 .flags = FLAG_ADVANCED,
2049 .label = "protocol",
2051 .p_class = P_GLOBAL,
2052 .ptr = &Globals.maxprotocol,
2054 .enum_list = enum_protocol,
2055 .flags = FLAG_ADVANCED,
2058 .label = "min protocol",
2060 .p_class = P_GLOBAL,
2061 .ptr = &Globals.minprotocol,
2063 .enum_list = enum_protocol,
2064 .flags = FLAG_ADVANCED,
2067 .label = "min receivefile size",
2069 .p_class = P_GLOBAL,
2070 .ptr = &Globals.iminreceivefile,
2073 .flags = FLAG_ADVANCED,
2076 .label = "read raw",
2078 .p_class = P_GLOBAL,
2079 .ptr = &Globals.bReadRaw,
2082 .flags = FLAG_ADVANCED,
2085 .label = "write raw",
2087 .p_class = P_GLOBAL,
2088 .ptr = &Globals.bWriteRaw,
2091 .flags = FLAG_ADVANCED,
2094 .label = "disable netbios",
2096 .p_class = P_GLOBAL,
2097 .ptr = &Globals.bDisableNetbios,
2100 .flags = FLAG_ADVANCED,
2103 .label = "reset on zero vc",
2105 .p_class = P_GLOBAL,
2106 .ptr = &Globals.bResetOnZeroVC,
2109 .flags = FLAG_ADVANCED,
2112 .label = "log writeable files on exit",
2114 .p_class = P_GLOBAL,
2115 .ptr = &Globals.bLogWriteableFilesOnExit,
2118 .flags = FLAG_ADVANCED,
2121 .label = "acl compatibility",
2123 .p_class = P_GLOBAL,
2124 .ptr = &Globals.iAclCompat,
2126 .enum_list = enum_acl_compat_vals,
2127 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2130 .label = "defer sharing violations",
2132 .p_class = P_GLOBAL,
2133 .ptr = &Globals.bDeferSharingViolations,
2136 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2139 .label = "ea support",
2142 .ptr = &sDefault.bEASupport,
2145 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2148 .label = "nt acl support",
2151 .ptr = &sDefault.bNTAclSupport,
2154 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2157 .label = "nt pipe support",
2159 .p_class = P_GLOBAL,
2160 .ptr = &Globals.bNTPipeSupport,
2163 .flags = FLAG_ADVANCED,
2166 .label = "nt status support",
2168 .p_class = P_GLOBAL,
2169 .ptr = &Globals.bNTStatusSupport,
2172 .flags = FLAG_ADVANCED,
2175 .label = "profile acls",
2178 .ptr = &sDefault.bProfileAcls,
2181 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2184 .label = "announce version",
2186 .p_class = P_GLOBAL,
2187 .ptr = &Globals.szAnnounceVersion,
2190 .flags = FLAG_ADVANCED,
2193 .label = "announce as",
2195 .p_class = P_GLOBAL,
2196 .ptr = &Globals.announce_as,
2198 .enum_list = enum_announce_as,
2199 .flags = FLAG_ADVANCED,
2202 .label = "map acl inherit",
2205 .ptr = &sDefault.bMap_acl_inherit,
2208 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2211 .label = "afs share",
2214 .ptr = &sDefault.bAfs_Share,
2217 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2222 .p_class = P_GLOBAL,
2223 .ptr = &Globals.max_mux,
2226 .flags = FLAG_ADVANCED,
2229 .label = "max xmit",
2231 .p_class = P_GLOBAL,
2232 .ptr = &Globals.max_xmit,
2235 .flags = FLAG_ADVANCED,
2238 .label = "name resolve order",
2240 .p_class = P_GLOBAL,
2241 .ptr = &Globals.szNameResolveOrder,
2244 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2249 .p_class = P_GLOBAL,
2250 .ptr = &Globals.max_ttl,
2253 .flags = FLAG_ADVANCED,
2256 .label = "max wins ttl",
2258 .p_class = P_GLOBAL,
2259 .ptr = &Globals.max_wins_ttl,
2262 .flags = FLAG_ADVANCED,
2265 .label = "min wins ttl",
2267 .p_class = P_GLOBAL,
2268 .ptr = &Globals.min_wins_ttl,
2271 .flags = FLAG_ADVANCED,
2274 .label = "time server",
2276 .p_class = P_GLOBAL,
2277 .ptr = &Globals.bTimeServer,
2280 .flags = FLAG_ADVANCED,
2283 .label = "unix extensions",
2285 .p_class = P_GLOBAL,
2286 .ptr = &Globals.bUnixExtensions,
2289 .flags = FLAG_ADVANCED,
2292 .label = "use spnego",
2294 .p_class = P_GLOBAL,
2295 .ptr = &Globals.bUseSpnego,
2298 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
2301 .label = "client signing",
2303 .p_class = P_GLOBAL,
2304 .ptr = &Globals.client_signing,
2306 .enum_list = enum_smb_signing_vals,
2307 .flags = FLAG_ADVANCED,
2310 .label = "server signing",
2312 .p_class = P_GLOBAL,
2313 .ptr = &Globals.server_signing,
2315 .enum_list = enum_smb_signing_vals,
2316 .flags = FLAG_ADVANCED,
2319 .label = "smb encrypt",
2322 .ptr = &sDefault.ismb_encrypt,
2324 .enum_list = enum_smb_signing_vals,
2325 .flags = FLAG_ADVANCED,
2328 .label = "client use spnego",
2330 .p_class = P_GLOBAL,
2331 .ptr = &Globals.bClientUseSpnego,
2334 .flags = FLAG_ADVANCED,
2337 .label = "client ldap sasl wrapping",
2339 .p_class = P_GLOBAL,
2340 .ptr = &Globals.client_ldap_sasl_wrapping,
2342 .enum_list = enum_ldap_sasl_wrapping,
2343 .flags = FLAG_ADVANCED,
2346 .label = "enable asu support",
2348 .p_class = P_GLOBAL,
2349 .ptr = &Globals.bASUSupport,
2352 .flags = FLAG_ADVANCED,
2355 .label = "svcctl list",
2357 .p_class = P_GLOBAL,
2358 .ptr = &Globals.szServicesList,
2361 .flags = FLAG_ADVANCED,
2364 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2367 .label = "block size",
2370 .ptr = &sDefault.iBlock_size,
2373 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2376 .label = "deadtime",
2378 .p_class = P_GLOBAL,
2379 .ptr = &Globals.deadtime,
2382 .flags = FLAG_ADVANCED,
2385 .label = "getwd cache",
2387 .p_class = P_GLOBAL,
2388 .ptr = &Globals.getwd_cache,
2391 .flags = FLAG_ADVANCED,
2394 .label = "keepalive",
2396 .p_class = P_GLOBAL,
2397 .ptr = &Globals.iKeepalive,
2400 .flags = FLAG_ADVANCED,
2403 .label = "change notify",
2406 .ptr = &sDefault.bChangeNotify,
2409 .flags = FLAG_ADVANCED | FLAG_SHARE,
2412 .label = "directory name cache size",
2415 .ptr = &sDefault.iDirectoryNameCacheSize,
2418 .flags = FLAG_ADVANCED | FLAG_SHARE,
2421 .label = "kernel change notify",
2424 .ptr = &sDefault.bKernelChangeNotify,
2427 .flags = FLAG_ADVANCED | FLAG_SHARE,
2430 .label = "lpq cache time",
2432 .p_class = P_GLOBAL,
2433 .ptr = &Globals.lpqcachetime,
2436 .flags = FLAG_ADVANCED,
2439 .label = "max smbd processes",
2441 .p_class = P_GLOBAL,
2442 .ptr = &Globals.iMaxSmbdProcesses,
2445 .flags = FLAG_ADVANCED,
2448 .label = "max connections",
2451 .ptr = &sDefault.iMaxConnections,
2454 .flags = FLAG_ADVANCED | FLAG_SHARE,
2457 .label = "paranoid server security",
2459 .p_class = P_GLOBAL,
2460 .ptr = &Globals.paranoid_server_security,
2463 .flags = FLAG_ADVANCED,
2466 .label = "max disk size",
2468 .p_class = P_GLOBAL,
2469 .ptr = &Globals.maxdisksize,
2472 .flags = FLAG_ADVANCED,
2475 .label = "max open files",
2477 .p_class = P_GLOBAL,
2478 .ptr = &Globals.max_open_files,
2481 .flags = FLAG_ADVANCED,
2484 .label = "min print space",
2487 .ptr = &sDefault.iMinPrintSpace,
2490 .flags = FLAG_ADVANCED | FLAG_PRINT,
2493 .label = "socket options",
2495 .p_class = P_GLOBAL,
2496 .ptr = &Globals.szSocketOptions,
2499 .flags = FLAG_ADVANCED,
2502 .label = "strict allocate",
2505 .ptr = &sDefault.bStrictAllocate,
2508 .flags = FLAG_ADVANCED | FLAG_SHARE,
2511 .label = "strict sync",
2514 .ptr = &sDefault.bStrictSync,
2517 .flags = FLAG_ADVANCED | FLAG_SHARE,
2520 .label = "sync always",
2523 .ptr = &sDefault.bSyncAlways,
2526 .flags = FLAG_ADVANCED | FLAG_SHARE,
2529 .label = "use mmap",
2531 .p_class = P_GLOBAL,
2532 .ptr = &Globals.bUseMmap,
2535 .flags = FLAG_ADVANCED,
2538 .label = "use sendfile",
2541 .ptr = &sDefault.bUseSendfile,
2544 .flags = FLAG_ADVANCED | FLAG_SHARE,
2547 .label = "hostname lookups",
2549 .p_class = P_GLOBAL,
2550 .ptr = &Globals.bHostnameLookups,
2553 .flags = FLAG_ADVANCED,
2556 .label = "write cache size",
2559 .ptr = &sDefault.iWriteCacheSize,
2562 .flags = FLAG_ADVANCED | FLAG_SHARE,
2565 .label = "name cache timeout",
2567 .p_class = P_GLOBAL,
2568 .ptr = &Globals.name_cache_timeout,
2571 .flags = FLAG_ADVANCED,
2574 .label = "ctdbd socket",
2576 .p_class = P_GLOBAL,
2577 .ptr = &Globals.ctdbdSocket,
2580 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2583 .label = "cluster addresses",
2585 .p_class = P_GLOBAL,
2586 .ptr = &Globals.szClusterAddresses,
2589 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2592 .label = "clustering",
2594 .p_class = P_GLOBAL,
2595 .ptr = &Globals.clustering,
2598 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2601 .label = "ctdb timeout",
2603 .p_class = P_GLOBAL,
2604 .ptr = &Globals.ctdb_timeout,
2607 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2610 .label = "ctdb locktime warn threshold",
2612 .p_class = P_GLOBAL,
2613 .ptr = &Globals.ctdb_locktime_warn_threshold,
2616 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2619 .label = "smb2 max read",
2621 .p_class = P_GLOBAL,
2622 .ptr = &Globals.ismb2_max_read,
2625 .flags = FLAG_ADVANCED,
2628 .label = "smb2 max write",
2630 .p_class = P_GLOBAL,
2631 .ptr = &Globals.ismb2_max_write,
2634 .flags = FLAG_ADVANCED,
2637 .label = "smb2 max trans",
2639 .p_class = P_GLOBAL,
2640 .ptr = &Globals.ismb2_max_trans,
2643 .flags = FLAG_ADVANCED,
2646 .label = "smb2 max credits",
2648 .p_class = P_GLOBAL,
2649 .ptr = &Globals.ismb2_max_credits,
2652 .flags = FLAG_ADVANCED,
2655 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2658 .label = "max reported print jobs",
2661 .ptr = &sDefault.iMaxReportedPrintJobs,
2664 .flags = FLAG_ADVANCED | FLAG_PRINT,
2667 .label = "max print jobs",
2670 .ptr = &sDefault.iMaxPrintJobs,
2673 .flags = FLAG_ADVANCED | FLAG_PRINT,
2676 .label = "load printers",
2678 .p_class = P_GLOBAL,
2679 .ptr = &Globals.bLoadPrinters,
2682 .flags = FLAG_ADVANCED | FLAG_PRINT,
2685 .label = "printcap cache time",
2687 .p_class = P_GLOBAL,
2688 .ptr = &Globals.PrintcapCacheTime,
2691 .flags = FLAG_ADVANCED | FLAG_PRINT,
2694 .label = "printcap name",
2696 .p_class = P_GLOBAL,
2697 .ptr = &Globals.szPrintcapname,
2700 .flags = FLAG_ADVANCED | FLAG_PRINT,
2703 .label = "printcap",
2705 .p_class = P_GLOBAL,
2706 .ptr = &Globals.szPrintcapname,
2712 .label = "printable",
2715 .ptr = &sDefault.bPrint_ok,
2718 .flags = FLAG_ADVANCED | FLAG_PRINT,
2721 .label = "print notify backchannel",
2724 .ptr = &sDefault.bPrintNotifyBackchannel,
2727 .flags = FLAG_ADVANCED,
2730 .label = "print ok",
2733 .ptr = &sDefault.bPrint_ok,
2739 .label = "printing",
2742 .ptr = &sDefault.iPrinting,
2743 .special = handle_printing,
2744 .enum_list = enum_printing,
2745 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2748 .label = "cups options",
2751 .ptr = &sDefault.szCupsOptions,
2754 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2757 .label = "cups server",
2759 .p_class = P_GLOBAL,
2760 .ptr = &Globals.szCupsServer,
2763 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2766 .label = "cups encrypt",
2768 .p_class = P_GLOBAL,
2769 .ptr = &Globals.CupsEncrypt,
2771 .enum_list = enum_bool_auto,
2772 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2776 .label = "cups connection timeout",
2778 .p_class = P_GLOBAL,
2779 .ptr = &Globals.cups_connection_timeout,
2782 .flags = FLAG_ADVANCED,
2785 .label = "iprint server",
2787 .p_class = P_GLOBAL,
2788 .ptr = &Globals.szIPrintServer,
2791 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2794 .label = "print command",
2797 .ptr = &sDefault.szPrintcommand,
2800 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2803 .label = "disable spoolss",
2805 .p_class = P_GLOBAL,
2806 .ptr = &Globals.bDisableSpoolss,
2809 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2812 .label = "enable spoolss",
2814 .p_class = P_GLOBAL,
2815 .ptr = &Globals.bDisableSpoolss,
2821 .label = "lpq command",
2824 .ptr = &sDefault.szLpqcommand,
2827 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2830 .label = "lprm command",
2833 .ptr = &sDefault.szLprmcommand,
2836 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2839 .label = "lppause command",
2842 .ptr = &sDefault.szLppausecommand,
2845 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2848 .label = "lpresume command",
2851 .ptr = &sDefault.szLpresumecommand,
2854 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2857 .label = "queuepause command",
2860 .ptr = &sDefault.szQueuepausecommand,
2863 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2866 .label = "queueresume command",
2869 .ptr = &sDefault.szQueueresumecommand,
2872 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2875 .label = "addport command",
2877 .p_class = P_GLOBAL,
2878 .ptr = &Globals.szAddPortCommand,
2881 .flags = FLAG_ADVANCED,
2884 .label = "enumports command",
2886 .p_class = P_GLOBAL,
2887 .ptr = &Globals.szEnumPortsCommand,
2890 .flags = FLAG_ADVANCED,
2893 .label = "addprinter command",
2895 .p_class = P_GLOBAL,
2896 .ptr = &Globals.szAddPrinterCommand,
2899 .flags = FLAG_ADVANCED,
2902 .label = "deleteprinter command",
2904 .p_class = P_GLOBAL,
2905 .ptr = &Globals.szDeletePrinterCommand,
2908 .flags = FLAG_ADVANCED,
2911 .label = "show add printer wizard",
2913 .p_class = P_GLOBAL,
2914 .ptr = &Globals.bMsAddPrinterWizard,
2917 .flags = FLAG_ADVANCED,
2920 .label = "os2 driver map",
2922 .p_class = P_GLOBAL,
2923 .ptr = &Globals.szOs2DriverMap,
2926 .flags = FLAG_ADVANCED,
2930 .label = "printer name",
2933 .ptr = &sDefault.szPrintername,
2936 .flags = FLAG_ADVANCED | FLAG_PRINT,
2942 .ptr = &sDefault.szPrintername,
2948 .label = "use client driver",
2951 .ptr = &sDefault.bUseClientDriver,
2954 .flags = FLAG_ADVANCED | FLAG_PRINT,
2957 .label = "default devmode",
2960 .ptr = &sDefault.bDefaultDevmode,
2963 .flags = FLAG_ADVANCED | FLAG_PRINT,
2966 .label = "force printername",
2969 .ptr = &sDefault.bForcePrintername,
2972 .flags = FLAG_ADVANCED | FLAG_PRINT,
2975 .label = "printjob username",
2978 .ptr = &sDefault.szPrintjobUsername,
2981 .flags = FLAG_ADVANCED | FLAG_PRINT,
2984 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2987 .label = "mangling method",
2989 .p_class = P_GLOBAL,
2990 .ptr = &Globals.szManglingMethod,
2993 .flags = FLAG_ADVANCED,
2996 .label = "mangle prefix",
2998 .p_class = P_GLOBAL,
2999 .ptr = &Globals.mangle_prefix,
3002 .flags = FLAG_ADVANCED,
3006 .label = "default case",
3009 .ptr = &sDefault.iDefaultCase,
3011 .enum_list = enum_case,
3012 .flags = FLAG_ADVANCED | FLAG_SHARE,
3015 .label = "case sensitive",
3018 .ptr = &sDefault.iCaseSensitive,
3020 .enum_list = enum_bool_auto,
3021 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3024 .label = "casesignames",
3027 .ptr = &sDefault.iCaseSensitive,
3029 .enum_list = enum_bool_auto,
3030 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
3033 .label = "preserve case",
3036 .ptr = &sDefault.bCasePreserve,
3039 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3042 .label = "short preserve case",
3045 .ptr = &sDefault.bShortCasePreserve,
3048 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3051 .label = "mangling char",
3054 .ptr = &sDefault.magic_char,
3057 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3060 .label = "hide dot files",
3063 .ptr = &sDefault.bHideDotFiles,
3066 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3069 .label = "hide special files",
3072 .ptr = &sDefault.bHideSpecialFiles,
3075 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3078 .label = "hide unreadable",
3081 .ptr = &sDefault.bHideUnReadable,
3084 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3087 .label = "hide unwriteable files",
3090 .ptr = &sDefault.bHideUnWriteableFiles,
3093 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3096 .label = "delete veto files",
3099 .ptr = &sDefault.bDeleteVetoFiles,
3102 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3105 .label = "veto files",
3108 .ptr = &sDefault.szVetoFiles,
3111 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3114 .label = "hide files",
3117 .ptr = &sDefault.szHideFiles,
3120 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3123 .label = "veto oplock files",
3126 .ptr = &sDefault.szVetoOplockFiles,
3129 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3132 .label = "map archive",
3135 .ptr = &sDefault.bMap_archive,
3138 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3141 .label = "map hidden",
3144 .ptr = &sDefault.bMap_hidden,
3147 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3150 .label = "map system",
3153 .ptr = &sDefault.bMap_system,
3156 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3159 .label = "map readonly",
3162 .ptr = &sDefault.iMap_readonly,
3164 .enum_list = enum_map_readonly,
3165 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3168 .label = "mangled names",
3171 .ptr = &sDefault.bMangledNames,
3174 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3177 .label = "max stat cache size",
3179 .p_class = P_GLOBAL,
3180 .ptr = &Globals.iMaxStatCacheSize,
3183 .flags = FLAG_ADVANCED,
3186 .label = "stat cache",
3188 .p_class = P_GLOBAL,
3189 .ptr = &Globals.bStatCache,
3192 .flags = FLAG_ADVANCED,
3195 .label = "store dos attributes",
3198 .ptr = &sDefault.bStoreDosAttributes,
3201 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3204 .label = "dmapi support",
3207 .ptr = &sDefault.bDmapiSupport,
3210 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3214 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3217 .label = "machine password timeout",
3219 .p_class = P_GLOBAL,
3220 .ptr = &Globals.machine_password_timeout,
3223 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3226 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3229 .label = "add user script",
3231 .p_class = P_GLOBAL,
3232 .ptr = &Globals.szAddUserScript,
3235 .flags = FLAG_ADVANCED,
3238 .label = "rename user script",
3240 .p_class = P_GLOBAL,
3241 .ptr = &Globals.szRenameUserScript,
3244 .flags = FLAG_ADVANCED,
3247 .label = "delete user script",
3249 .p_class = P_GLOBAL,
3250 .ptr = &Globals.szDelUserScript,
3253 .flags = FLAG_ADVANCED,
3256 .label = "add group script",
3258 .p_class = P_GLOBAL,
3259 .ptr = &Globals.szAddGroupScript,
3262 .flags = FLAG_ADVANCED,
3265 .label = "delete group script",
3267 .p_class = P_GLOBAL,
3268 .ptr = &Globals.szDelGroupScript,
3271 .flags = FLAG_ADVANCED,
3274 .label = "add user to group script",
3276 .p_class = P_GLOBAL,
3277 .ptr = &Globals.szAddUserToGroupScript,
3280 .flags = FLAG_ADVANCED,
3283 .label = "delete user from group script",
3285 .p_class = P_GLOBAL,
3286 .ptr = &Globals.szDelUserFromGroupScript,
3289 .flags = FLAG_ADVANCED,
3292 .label = "set primary group script",
3294 .p_class = P_GLOBAL,
3295 .ptr = &Globals.szSetPrimaryGroupScript,
3298 .flags = FLAG_ADVANCED,
3301 .label = "add machine script",
3303 .p_class = P_GLOBAL,
3304 .ptr = &Globals.szAddMachineScript,
3307 .flags = FLAG_ADVANCED,
3310 .label = "shutdown script",
3312 .p_class = P_GLOBAL,
3313 .ptr = &Globals.szShutdownScript,
3316 .flags = FLAG_ADVANCED,
3319 .label = "abort shutdown script",
3321 .p_class = P_GLOBAL,
3322 .ptr = &Globals.szAbortShutdownScript,
3325 .flags = FLAG_ADVANCED,
3328 .label = "username map script",
3330 .p_class = P_GLOBAL,
3331 .ptr = &Globals.szUsernameMapScript,
3334 .flags = FLAG_ADVANCED,
3337 .label = "username map cache time",
3339 .p_class = P_GLOBAL,
3340 .ptr = &Globals.iUsernameMapCacheTime,
3343 .flags = FLAG_ADVANCED,
3346 .label = "logon script",
3348 .p_class = P_GLOBAL,
3349 .ptr = &Globals.szLogonScript,
3352 .flags = FLAG_ADVANCED,
3355 .label = "logon path",
3357 .p_class = P_GLOBAL,
3358 .ptr = &Globals.szLogonPath,
3361 .flags = FLAG_ADVANCED,
3364 .label = "logon drive",
3366 .p_class = P_GLOBAL,
3367 .ptr = &Globals.szLogonDrive,
3370 .flags = FLAG_ADVANCED,
3373 .label = "logon home",
3375 .p_class = P_GLOBAL,
3376 .ptr = &Globals.szLogonHome,
3379 .flags = FLAG_ADVANCED,
3382 .label = "domain logons",
3384 .p_class = P_GLOBAL,
3385 .ptr = &Globals.bDomainLogons,
3388 .flags = FLAG_ADVANCED,
3392 .label = "init logon delayed hosts",
3394 .p_class = P_GLOBAL,
3395 .ptr = &Globals.szInitLogonDelayedHosts,
3398 .flags = FLAG_ADVANCED,
3402 .label = "init logon delay",
3404 .p_class = P_GLOBAL,
3405 .ptr = &Globals.InitLogonDelay,
3408 .flags = FLAG_ADVANCED,
3412 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3415 .label = "os level",
3417 .p_class = P_GLOBAL,
3418 .ptr = &Globals.os_level,
3421 .flags = FLAG_BASIC | FLAG_ADVANCED,
3424 .label = "lm announce",
3426 .p_class = P_GLOBAL,
3427 .ptr = &Globals.lm_announce,
3429 .enum_list = enum_bool_auto,
3430 .flags = FLAG_ADVANCED,
3433 .label = "lm interval",
3435 .p_class = P_GLOBAL,
3436 .ptr = &Globals.lm_interval,
3439 .flags = FLAG_ADVANCED,
3442 .label = "preferred master",
3444 .p_class = P_GLOBAL,
3445 .ptr = &Globals.iPreferredMaster,
3447 .enum_list = enum_bool_auto,
3448 .flags = FLAG_BASIC | FLAG_ADVANCED,
3451 .label = "prefered master",
3453 .p_class = P_GLOBAL,
3454 .ptr = &Globals.iPreferredMaster,
3456 .enum_list = enum_bool_auto,
3460 .label = "local master",
3462 .p_class = P_GLOBAL,
3463 .ptr = &Globals.bLocalMaster,
3466 .flags = FLAG_BASIC | FLAG_ADVANCED,
3469 .label = "domain master",
3471 .p_class = P_GLOBAL,
3472 .ptr = &Globals.iDomainMaster,
3474 .enum_list = enum_bool_auto,
3475 .flags = FLAG_BASIC | FLAG_ADVANCED,
3478 .label = "browse list",
3480 .p_class = P_GLOBAL,
3481 .ptr = &Globals.bBrowseList,
3484 .flags = FLAG_ADVANCED,
3487 .label = "browseable",
3490 .ptr = &sDefault.bBrowseable,
3493 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3496 .label = "browsable",
3499 .ptr = &sDefault.bBrowseable,
3505 .label = "access based share enum",
3508 .ptr = &sDefault.bAccessBasedShareEnum,
3511 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3514 .label = "enhanced browsing",
3516 .p_class = P_GLOBAL,
3517 .ptr = &Globals.enhanced_browsing,
3520 .flags = FLAG_ADVANCED,
3523 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3526 .label = "dns proxy",
3528 .p_class = P_GLOBAL,
3529 .ptr = &Globals.bDNSproxy,
3532 .flags = FLAG_ADVANCED,
3535 .label = "wins proxy",
3537 .p_class = P_GLOBAL,
3538 .ptr = &Globals.bWINSproxy,
3541 .flags = FLAG_ADVANCED,
3544 .label = "wins server",
3546 .p_class = P_GLOBAL,
3547 .ptr = &Globals.szWINSservers,
3550 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3553 .label = "wins support",
3555 .p_class = P_GLOBAL,
3556 .ptr = &Globals.bWINSsupport,
3559 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3562 .label = "wins hook",
3564 .p_class = P_GLOBAL,
3565 .ptr = &Globals.szWINSHook,
3568 .flags = FLAG_ADVANCED,
3571 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3574 .label = "blocking locks",
3577 .ptr = &sDefault.bBlockingLocks,
3580 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3583 .label = "csc policy",
3586 .ptr = &sDefault.iCSCPolicy,
3588 .enum_list = enum_csc_policy,
3589 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3592 .label = "fake oplocks",
3595 .ptr = &sDefault.bFakeOplocks,
3598 .flags = FLAG_ADVANCED | FLAG_SHARE,
3601 .label = "kernel oplocks",
3603 .p_class = P_GLOBAL,
3604 .ptr = &Globals.bKernelOplocks,
3607 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3613 .ptr = &sDefault.bLocking,
3616 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3619 .label = "lock spin time",
3621 .p_class = P_GLOBAL,
3622 .ptr = &Globals.iLockSpinTime,
3625 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3631 .ptr = &sDefault.bOpLocks,
3634 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3637 .label = "level2 oplocks",
3640 .ptr = &sDefault.bLevel2OpLocks,
3643 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3646 .label = "oplock break wait time",
3648 .p_class = P_GLOBAL,
3649 .ptr = &Globals.oplock_break_wait_time,
3652 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3655 .label = "oplock contention limit",
3658 .ptr = &sDefault.iOplockContentionLimit,
3661 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3664 .label = "posix locking",
3667 .ptr = &sDefault.bPosixLocking,
3670 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3673 .label = "strict locking",
3676 .ptr = &sDefault.iStrictLocking,
3678 .enum_list = enum_bool_auto,
3679 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3682 .label = "share modes",
3685 .ptr = &sDefault.bShareModes,
3688 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3691 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3694 .label = "ldap admin dn",
3696 .p_class = P_GLOBAL,
3697 .ptr = &Globals.szLdapAdminDn,
3700 .flags = FLAG_ADVANCED,
3703 .label = "ldap delete dn",
3705 .p_class = P_GLOBAL,
3706 .ptr = &Globals.ldap_delete_dn,
3709 .flags = FLAG_ADVANCED,
3712 .label = "ldap group suffix",
3714 .p_class = P_GLOBAL,
3715 .ptr = &Globals.szLdapGroupSuffix,
3718 .flags = FLAG_ADVANCED,
3721 .label = "ldap idmap suffix",
3723 .p_class = P_GLOBAL,
3724 .ptr = &Globals.szLdapIdmapSuffix,
3727 .flags = FLAG_ADVANCED,
3730 .label = "ldap machine suffix",
3732 .p_class = P_GLOBAL,
3733 .ptr = &Globals.szLdapMachineSuffix,
3736 .flags = FLAG_ADVANCED,
3739 .label = "ldap passwd sync",
3741 .p_class = P_GLOBAL,
3742 .ptr = &Globals.ldap_passwd_sync,
3744 .enum_list = enum_ldap_passwd_sync,
3745 .flags = FLAG_ADVANCED,
3748 .label = "ldap password sync",
3750 .p_class = P_GLOBAL,
3751 .ptr = &Globals.ldap_passwd_sync,
3753 .enum_list = enum_ldap_passwd_sync,
3757 .label = "ldap replication sleep",
3759 .p_class = P_GLOBAL,
3760 .ptr = &Globals.ldap_replication_sleep,
3763 .flags = FLAG_ADVANCED,
3766 .label = "ldap suffix",
3768 .p_class = P_GLOBAL,
3769 .ptr = &Globals.szLdapSuffix,
3772 .flags = FLAG_ADVANCED,
3775 .label = "ldap ssl",
3777 .p_class = P_GLOBAL,
3778 .ptr = &Globals.ldap_ssl,
3780 .enum_list = enum_ldap_ssl,
3781 .flags = FLAG_ADVANCED,
3784 .label = "ldap ssl ads",
3786 .p_class = P_GLOBAL,
3787 .ptr = &Globals.ldap_ssl_ads,
3790 .flags = FLAG_ADVANCED,
3793 .label = "ldap deref",
3795 .p_class = P_GLOBAL,
3796 .ptr = &Globals.ldap_deref,
3798 .enum_list = enum_ldap_deref,
3799 .flags = FLAG_ADVANCED,
3802 .label = "ldap follow referral",
3804 .p_class = P_GLOBAL,
3805 .ptr = &Globals.ldap_follow_referral,
3807 .enum_list = enum_bool_auto,
3808 .flags = FLAG_ADVANCED,
3811 .label = "ldap timeout",
3813 .p_class = P_GLOBAL,
3814 .ptr = &Globals.ldap_timeout,
3817 .flags = FLAG_ADVANCED,
3820 .label = "ldap connection timeout",
3822 .p_class = P_GLOBAL,
3823 .ptr = &Globals.ldap_connection_timeout,
3826 .flags = FLAG_ADVANCED,
3829 .label = "ldap page size",
3831 .p_class = P_GLOBAL,
3832 .ptr = &Globals.ldap_page_size,
3835 .flags = FLAG_ADVANCED,
3838 .label = "ldap user suffix",
3840 .p_class = P_GLOBAL,
3841 .ptr = &Globals.szLdapUserSuffix,
3844 .flags = FLAG_ADVANCED,
3847 .label = "ldap debug level",
3849 .p_class = P_GLOBAL,
3850 .ptr = &Globals.ldap_debug_level,
3851 .special = handle_ldap_debug_level,
3853 .flags = FLAG_ADVANCED,
3856 .label = "ldap debug threshold",
3858 .p_class = P_GLOBAL,
3859 .ptr = &Globals.ldap_debug_threshold,
3862 .flags = FLAG_ADVANCED,
3865 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3868 .label = "eventlog list",
3870 .p_class = P_GLOBAL,
3871 .ptr = &Globals.szEventLogs,
3874 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3877 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3880 .label = "add share command",
3882 .p_class = P_GLOBAL,
3883 .ptr = &Globals.szAddShareCommand,
3886 .flags = FLAG_ADVANCED,
3889 .label = "change share command",
3891 .p_class = P_GLOBAL,
3892 .ptr = &Globals.szChangeShareCommand,
3895 .flags = FLAG_ADVANCED,
3898 .label = "delete share command",
3900 .p_class = P_GLOBAL,
3901 .ptr = &Globals.szDeleteShareCommand,
3904 .flags = FLAG_ADVANCED,
3907 .label = "config file",
3909 .p_class = P_GLOBAL,
3910 .ptr = &Globals.szConfigFile,
3913 .flags = FLAG_HIDE|FLAG_META,
3918 .p_class = P_GLOBAL,
3919 .ptr = &Globals.szAutoServices,
3922 .flags = FLAG_ADVANCED,
3925 .label = "auto services",
3927 .p_class = P_GLOBAL,
3928 .ptr = &Globals.szAutoServices,
3931 .flags = FLAG_ADVANCED,
3934 .label = "lock directory",
3936 .p_class = P_GLOBAL,
3937 .ptr = &Globals.szLockDir,
3940 .flags = FLAG_ADVANCED,
3943 .label = "lock dir",
3945 .p_class = P_GLOBAL,
3946 .ptr = &Globals.szLockDir,
3952 .label = "state directory",
3954 .p_class = P_GLOBAL,
3955 .ptr = &Globals.szStateDir,
3958 .flags = FLAG_ADVANCED,
3961 .label = "cache directory",
3963 .p_class = P_GLOBAL,
3964 .ptr = &Globals.szCacheDir,
3967 .flags = FLAG_ADVANCED,
3970 .label = "pid directory",
3972 .p_class = P_GLOBAL,
3973 .ptr = &Globals.szPidDir,
3976 .flags = FLAG_ADVANCED,
3980 .label = "utmp directory",
3982 .p_class = P_GLOBAL,
3983 .ptr = &Globals.szUtmpDir,
3986 .flags = FLAG_ADVANCED,
3989 .label = "wtmp directory",
3991 .p_class = P_GLOBAL,
3992 .ptr = &Globals.szWtmpDir,
3995 .flags = FLAG_ADVANCED,
4000 .p_class = P_GLOBAL,
4001 .ptr = &Globals.bUtmp,
4004 .flags = FLAG_ADVANCED,
4008 .label = "default service",
4010 .p_class = P_GLOBAL,
4011 .ptr = &Globals.szDefaultService,
4014 .flags = FLAG_ADVANCED,
4019 .p_class = P_GLOBAL,
4020 .ptr = &Globals.szDefaultService,
4023 .flags = FLAG_ADVANCED,
4026 .label = "message command",
4028 .p_class = P_GLOBAL,
4029 .ptr = &Globals.szMsgCommand,
4032 .flags = FLAG_ADVANCED,
4035 .label = "dfree cache time",
4038 .ptr = &sDefault.iDfreeCacheTime,
4041 .flags = FLAG_ADVANCED,
4044 .label = "dfree command",
4047 .ptr = &sDefault.szDfree,
4050 .flags = FLAG_ADVANCED,
4053 .label = "get quota command",
4055 .p_class = P_GLOBAL,
4056 .ptr = &Globals.szGetQuota,
4059 .flags = FLAG_ADVANCED,
4062 .label = "set quota command",
4064 .p_class = P_GLOBAL,
4065 .ptr = &Globals.szSetQuota,
4068 .flags = FLAG_ADVANCED,
4071 .label = "remote announce",
4073 .p_class = P_GLOBAL,
4074 .ptr = &Globals.szRemoteAnnounce,
4077 .flags = FLAG_ADVANCED,
4080 .label = "remote browse sync",
4082 .p_class = P_GLOBAL,
4083 .ptr = &Globals.szRemoteBrowseSync,
4086 .flags = FLAG_ADVANCED,
4089 .label = "socket address",
4091 .p_class = P_GLOBAL,
4092 .ptr = &Globals.szSocketAddress,
4095 .flags = FLAG_ADVANCED,
4098 .label = "nmbd bind explicit broadcast",
4100 .p_class = P_GLOBAL,
4101 .ptr = &Globals.bNmbdBindExplicitBroadcast,
4104 .flags = FLAG_ADVANCED,
4107 .label = "homedir map",
4109 .p_class = P_GLOBAL,
4110 .ptr = &Globals.szNISHomeMapName,
4113 .flags = FLAG_ADVANCED,
4116 .label = "afs username map",
4118 .p_class = P_GLOBAL,
4119 .ptr = &Globals.szAfsUsernameMap,
4122 .flags = FLAG_ADVANCED,
4125 .label = "afs token lifetime",
4127 .p_class = P_GLOBAL,
4128 .ptr = &Globals.iAfsTokenLifetime,
4131 .flags = FLAG_ADVANCED,
4134 .label = "log nt token command",
4136 .p_class = P_GLOBAL,
4137 .ptr = &Globals.szLogNtTokenCommand,
4140 .flags = FLAG_ADVANCED,
4143 .label = "time offset",
4145 .p_class = P_GLOBAL,
4146 .ptr = &extra_time_offset,
4149 .flags = FLAG_ADVANCED,
4152 .label = "NIS homedir",
4154 .p_class = P_GLOBAL,
4155 .ptr = &Globals.bNISHomeMap,
4158 .flags = FLAG_ADVANCED,
4164 .ptr = &sDefault.valid,
4173 .ptr = &sDefault.szCopy,
4174 .special = handle_copy,
4182 .ptr = &sDefault.szInclude,
4183 .special = handle_include,
4185 .flags = FLAG_HIDE|FLAG_META,
4191 .ptr = &sDefault.szPreExec,
4194 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4200 .ptr = &sDefault.szPreExec,
4203 .flags = FLAG_ADVANCED,
4206 .label = "preexec close",
4209 .ptr = &sDefault.bPreexecClose,
4212 .flags = FLAG_ADVANCED | FLAG_SHARE,
4215 .label = "postexec",
4218 .ptr = &sDefault.szPostExec,
4221 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4224 .label = "root preexec",
4227 .ptr = &sDefault.szRootPreExec,
4230 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4233 .label = "root preexec close",
4236 .ptr = &sDefault.bRootpreexecClose,
4239 .flags = FLAG_ADVANCED | FLAG_SHARE,
4242 .label = "root postexec",
4245 .ptr = &sDefault.szRootPostExec,
4248 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4251 .label = "available",
4254 .ptr = &sDefault.bAvailable,
4257 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4260 .label = "registry shares",
4262 .p_class = P_GLOBAL,
4263 .ptr = &Globals.bRegistryShares,
4266 .flags = FLAG_ADVANCED,
4269 .label = "usershare allow guests",
4271 .p_class = P_GLOBAL,
4272 .ptr = &Globals.bUsershareAllowGuests,
4275 .flags = FLAG_ADVANCED,
4278 .label = "usershare max shares",
4280 .p_class = P_GLOBAL,
4281 .ptr = &Globals.iUsershareMaxShares,
4284 .flags = FLAG_ADVANCED,
4287 .label = "usershare owner only",
4289 .p_class = P_GLOBAL,
4290 .ptr = &Globals.bUsershareOwnerOnly,
4293 .flags = FLAG_ADVANCED,
4296 .label = "usershare path",
4298 .p_class = P_GLOBAL,
4299 .ptr = &Globals.szUsersharePath,
4302 .flags = FLAG_ADVANCED,
4305 .label = "usershare prefix allow list",
4307 .p_class = P_GLOBAL,
4308 .ptr = &Globals.szUsersharePrefixAllowList,
4311 .flags = FLAG_ADVANCED,
4314 .label = "usershare prefix deny list",
4316 .p_class = P_GLOBAL,
4317 .ptr = &Globals.szUsersharePrefixDenyList,
4320 .flags = FLAG_ADVANCED,
4323 .label = "usershare template share",
4325 .p_class = P_GLOBAL,
4326 .ptr = &Globals.szUsershareTemplateShare,
4329 .flags = FLAG_ADVANCED,
4335 .ptr = &sDefault.volume,
4338 .flags = FLAG_ADVANCED | FLAG_SHARE,
4344 .ptr = &sDefault.fstype,
4347 .flags = FLAG_ADVANCED | FLAG_SHARE,
4350 .label = "set directory",
4353 .ptr = &sDefault.bNo_set_dir,
4356 .flags = FLAG_ADVANCED | FLAG_SHARE,
4359 .label = "wide links",
4362 .ptr = &sDefault.bWidelinks,
4365 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4368 .label = "follow symlinks",
4371 .ptr = &sDefault.bSymlinks,
4374 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4377 .label = "dont descend",
4380 .ptr = &sDefault.szDontdescend,
4383 .flags = FLAG_ADVANCED | FLAG_SHARE,
4386 .label = "magic script",
4389 .ptr = &sDefault.szMagicScript,
4392 .flags = FLAG_ADVANCED | FLAG_SHARE,
4395 .label = "magic output",
4398 .ptr = &sDefault.szMagicOutput,
4401 .flags = FLAG_ADVANCED | FLAG_SHARE,
4404 .label = "delete readonly",
4407 .ptr = &sDefault.bDeleteReadonly,
4410 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4413 .label = "dos filemode",
4416 .ptr = &sDefault.bDosFilemode,
4419 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4422 .label = "dos filetimes",
4425 .ptr = &sDefault.bDosFiletimes,
4428 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4431 .label = "dos filetime resolution",
4434 .ptr = &sDefault.bDosFiletimeResolution,
4437 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4440 .label = "fake directory create times",
4443 .ptr = &sDefault.bFakeDirCreateTimes,
4446 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4449 .label = "async smb echo handler",
4451 .p_class = P_GLOBAL,
4452 .ptr = &Globals.bAsyncSMBEchoHandler,
4455 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4458 .label = "multicast dns register",
4460 .p_class = P_GLOBAL,
4461 .ptr = &Globals.bMulticastDnsRegister,
4464 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4467 .label = "panic action",
4469 .p_class = P_GLOBAL,
4470 .ptr = &Globals.szPanicAction,
4473 .flags = FLAG_ADVANCED,
4476 .label = "perfcount module",
4478 .p_class = P_GLOBAL,
4479 .ptr = &Globals.szSMBPerfcountModule,
4482 .flags = FLAG_ADVANCED,
4485 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4488 .label = "vfs objects",
4491 .ptr = &sDefault.szVfsObjects,
4494 .flags = FLAG_ADVANCED | FLAG_SHARE,
4497 .label = "vfs object",
4500 .ptr = &sDefault.szVfsObjects,
4507 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4510 .label = "msdfs root",
4513 .ptr = &sDefault.bMSDfsRoot,
4516 .flags = FLAG_ADVANCED | FLAG_SHARE,
4519 .label = "msdfs proxy",
4522 .ptr = &sDefault.szMSDfsProxy,
4525 .flags = FLAG_ADVANCED | FLAG_SHARE,
4528 .label = "host msdfs",
4530 .p_class = P_GLOBAL,
4531 .ptr = &Globals.bHostMSDfs,
4534 .flags = FLAG_ADVANCED,
4537 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4540 .label = "passdb expand explicit",
4542 .p_class = P_GLOBAL,
4543 .ptr = &Globals.bPassdbExpandExplicit,
4546 .flags = FLAG_ADVANCED,
4549 .label = "idmap backend",
4551 .p_class = P_GLOBAL,
4552 .ptr = &Globals.szIdmapBackend,
4553 .special = handle_idmap_backend,
4555 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4558 .label = "idmap cache time",
4560 .p_class = P_GLOBAL,
4561 .ptr = &Globals.iIdmapCacheTime,
4564 .flags = FLAG_ADVANCED,
4567 .label = "idmap negative cache time",
4569 .p_class = P_GLOBAL,
4570 .ptr = &Globals.iIdmapNegativeCacheTime,
4573 .flags = FLAG_ADVANCED,
4576 .label = "idmap uid",
4578 .p_class = P_GLOBAL,
4579 .ptr = &Globals.szIdmapUID,
4580 .special = handle_idmap_uid,
4582 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4585 .label = "winbind uid",
4587 .p_class = P_GLOBAL,
4588 .ptr = &Globals.szIdmapUID,
4589 .special = handle_idmap_uid,
4594 .label = "idmap gid",
4596 .p_class = P_GLOBAL,
4597 .ptr = &Globals.szIdmapGID,
4598 .special = handle_idmap_gid,
4600 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4603 .label = "winbind gid",
4605 .p_class = P_GLOBAL,
4606 .ptr = &Globals.szIdmapGID,
4607 .special = handle_idmap_gid,
4612 .label = "template homedir",
4614 .p_class = P_GLOBAL,
4615 .ptr = &Globals.szTemplateHomedir,
4618 .flags = FLAG_ADVANCED,
4621 .label = "template shell",
4623 .p_class = P_GLOBAL,
4624 .ptr = &Globals.szTemplateShell,
4627 .flags = FLAG_ADVANCED,
4630 .label = "winbind separator",
4632 .p_class = P_GLOBAL,
4633 .ptr = &Globals.szWinbindSeparator,
4636 .flags = FLAG_ADVANCED,
4639 .label = "winbind cache time",
4641 .p_class = P_GLOBAL,
4642 .ptr = &Globals.winbind_cache_time,
4645 .flags = FLAG_ADVANCED,
4648 .label = "winbind reconnect delay",
4650 .p_class = P_GLOBAL,
4651 .ptr = &Globals.winbind_reconnect_delay,
4654 .flags = FLAG_ADVANCED,
4657 .label = "winbind max clients",
4659 .p_class = P_GLOBAL,
4660 .ptr = &Globals.winbind_max_clients,
4663 .flags = FLAG_ADVANCED,
4666 .label = "winbind enum users",
4668 .p_class = P_GLOBAL,
4669 .ptr = &Globals.bWinbindEnumUsers,
4672 .flags = FLAG_ADVANCED,
4675 .label = "winbind enum groups",
4677 .p_class = P_GLOBAL,
4678 .ptr = &Globals.bWinbindEnumGroups,
4681 .flags = FLAG_ADVANCED,
4684 .label = "winbind use default domain",
4686 .p_class = P_GLOBAL,
4687 .ptr = &Globals.bWinbindUseDefaultDomain,
4690 .flags = FLAG_ADVANCED,
4693 .label = "winbind trusted domains only",
4695 .p_class = P_GLOBAL,
4696 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4699 .flags = FLAG_ADVANCED,
4702 .label = "winbind nested groups",
4704 .p_class = P_GLOBAL,
4705 .ptr = &Globals.bWinbindNestedGroups,
4708 .flags = FLAG_ADVANCED,
4711 .label = "winbind expand groups",
4713 .p_class = P_GLOBAL,
4714 .ptr = &Globals.winbind_expand_groups,
4717 .flags = FLAG_ADVANCED,
4720 .label = "winbind nss info",
4722 .p_class = P_GLOBAL,
4723 .ptr = &Globals.szWinbindNssInfo,
4726 .flags = FLAG_ADVANCED,
4729 .label = "winbind refresh tickets",
4731 .p_class = P_GLOBAL,
4732 .ptr = &Globals.bWinbindRefreshTickets,
4735 .flags = FLAG_ADVANCED,
4738 .label = "winbind offline logon",
4740 .p_class = P_GLOBAL,
4741 .ptr = &Globals.bWinbindOfflineLogon,
4744 .flags = FLAG_ADVANCED,
4747 .label = "winbind normalize names",
4749 .p_class = P_GLOBAL,
4750 .ptr = &Globals.bWinbindNormalizeNames,
4753 .flags = FLAG_ADVANCED,
4756 .label = "winbind rpc only",
4758 .p_class = P_GLOBAL,
4759 .ptr = &Globals.bWinbindRpcOnly,
4762 .flags = FLAG_ADVANCED,
4765 .label = "create krb5 conf",
4767 .p_class = P_GLOBAL,
4768 .ptr = &Globals.bCreateKrb5Conf,
4771 .flags = FLAG_ADVANCED,
4774 .label = "ncalrpc dir",
4776 .p_class = P_GLOBAL,
4777 .ptr = &Globals.ncalrpc_dir,
4780 .flags = FLAG_ADVANCED,
4783 .label = "winbind max domain connections",
4785 .p_class = P_GLOBAL,
4786 .ptr = &Globals.winbindMaxDomainConnections,
4789 .flags = FLAG_ADVANCED,
4792 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4795 /***************************************************************************
4796 Initialise the sDefault parameter structure for the printer values.
4797 ***************************************************************************/
4799 static void init_printer_values(struct service *pService)
4801 /* choose defaults depending on the type of printing */
4802 switch (pService->iPrinting) {
4807 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4808 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4809 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4814 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4815 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4816 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4817 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4818 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4819 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4820 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4826 /* set the lpq command to contain the destination printer
4827 name only. This is used by cups_queue_get() */
4828 string_set(&pService->szLpqcommand, "%p");
4829 string_set(&pService->szLprmcommand, "");
4830 string_set(&pService->szPrintcommand, "");
4831 string_set(&pService->szLppausecommand, "");
4832 string_set(&pService->szLpresumecommand, "");
4833 string_set(&pService->szQueuepausecommand, "");
4834 string_set(&pService->szQueueresumecommand, "");
4836 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4837 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4838 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4839 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4840 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4841 string_set(&pService->szQueuepausecommand, "disable '%p'");
4842 string_set(&pService->szQueueresumecommand, "enable '%p'");
4843 #endif /* HAVE_CUPS */
4848 string_set(&pService->szLpqcommand, "lpstat -o%p");
4849 string_set(&pService->szLprmcommand, "cancel %p-%j");
4850 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4851 string_set(&pService->szQueuepausecommand, "disable %p");
4852 string_set(&pService->szQueueresumecommand, "enable %p");
4854 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4855 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4860 string_set(&pService->szLpqcommand, "lpq -P%p");
4861 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4862 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4865 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4869 const char *tdbfile;
4872 tdbfile = talloc_asprintf(
4873 talloc_tos(), "tdbfile=%s",
4874 lp_parm_const_string(-1, "vlp", "tdbfile",
4876 if (tdbfile == NULL) {
4877 tdbfile="tdbfile=/tmp/vlp.tdb";
4880 tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
4882 string_set(&pService->szPrintcommand,
4883 tmp ? tmp : "vlp print %p %s");
4886 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
4888 string_set(&pService->szLpqcommand,
4889 tmp ? tmp : "vlp lpq %p");
4892 tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
4894 string_set(&pService->szLprmcommand,
4895 tmp ? tmp : "vlp lprm %p %j");
4898 tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
4900 string_set(&pService->szLppausecommand,
4901 tmp ? tmp : "vlp lppause %p %j");
4904 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
4906 string_set(&pService->szLpresumecommand,
4907 tmp ? tmp : "vlp lpresume %p %j");
4910 tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
4912 string_set(&pService->szQueuepausecommand,
4913 tmp ? tmp : "vlp queuepause %p");
4916 tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
4918 string_set(&pService->szQueueresumecommand,
4919 tmp ? tmp : "vlp queueresume %p");
4924 #endif /* DEVELOPER */
4929 * Function to return the default value for the maximum number of open
4930 * file descriptors permitted. This function tries to consult the
4931 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4932 * the smaller of those.
4934 static int max_open_files(void)
4936 int sysctl_max = MAX_OPEN_FILES;
4937 int rlimit_max = MAX_OPEN_FILES;
4939 #ifdef HAVE_SYSCTLBYNAME
4941 size_t size = sizeof(sysctl_max);
4942 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4947 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4953 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4954 rlimit_max = rl.rlim_cur;
4956 #if defined(RLIM_INFINITY)
4957 if(rl.rlim_cur == RLIM_INFINITY)
4958 rlimit_max = MAX_OPEN_FILES;
4963 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4964 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4965 "minimum Windows limit (%d)\n",
4967 MIN_OPEN_FILES_WINDOWS));
4968 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4971 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4972 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4973 "minimum Windows limit (%d)\n",
4975 MIN_OPEN_FILES_WINDOWS));
4976 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4979 return MIN(sysctl_max, rlimit_max);
4983 * Common part of freeing allocated data for one parameter.
4985 static void free_one_parameter_common(void *parm_ptr,
4986 struct parm_struct parm)
4988 if ((parm.type == P_STRING) ||
4989 (parm.type == P_USTRING))
4991 string_free((char**)parm_ptr);
4992 } else if (parm.type == P_LIST) {
4993 TALLOC_FREE(*((char***)parm_ptr));
4998 * Free the allocated data for one parameter for a share
4999 * given as a service struct.
5001 static void free_one_parameter(struct service *service,
5002 struct parm_struct parm)
5006 if (parm.p_class != P_LOCAL) {
5010 parm_ptr = lp_local_ptr(service, parm.ptr);
5012 free_one_parameter_common(parm_ptr, parm);
5016 * Free the allocated parameter data of a share given
5017 * as a service struct.
5019 static void free_parameters(struct service *service)
5023 for (i=0; parm_table[i].label; i++) {
5024 free_one_parameter(service, parm_table[i]);
5029 * Free the allocated data for one parameter for a given share
5030 * specified by an snum.
5032 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
5036 if (parm.ptr == NULL) {
5041 parm_ptr = parm.ptr;
5042 } else if (parm.p_class != P_LOCAL) {
5045 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
5048 free_one_parameter_common(parm_ptr, parm);
5052 * Free the allocated parameter data for a share specified
5055 static void free_parameters_by_snum(int snum)
5059 for (i=0; parm_table[i].label; i++) {
5060 free_one_parameter_by_snum(snum, parm_table[i]);
5065 * Free the allocated global parameters.
5067 static void free_global_parameters(void)
5069 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
5072 static int map_parameter(const char *pszParmName);
5074 struct lp_stored_option {
5075 struct lp_stored_option *prev, *next;
5080 static struct lp_stored_option *stored_options;
5083 save options set by lp_set_cmdline() into a list. This list is
5084 re-applied when we do a globals reset, so that cmdline set options
5085 are sticky across reloads of smb.conf
5087 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
5089 struct lp_stored_option *entry, *entry_next;
5090 for (entry = stored_options; entry != NULL; entry = entry_next) {
5091 entry_next = entry->next;
5092 if (strcmp(pszParmName, entry->label) == 0) {
5093 DLIST_REMOVE(stored_options, entry);
5099 entry = talloc(NULL, struct lp_stored_option);
5104 entry->label = talloc_strdup(entry, pszParmName);
5105 if (!entry->label) {
5110 entry->value = talloc_strdup(entry, pszParmValue);
5111 if (!entry->value) {
5116 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
5121 static bool apply_lp_set_cmdline(void)
5123 struct lp_stored_option *entry = NULL;
5124 for (entry = stored_options; entry != NULL; entry = entry->next) {
5125 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
5126 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
5127 entry->label, entry->value));
5134 /***************************************************************************
5135 Initialise the global parameter structure.
5136 ***************************************************************************/
5138 static void init_globals(bool reinit_globals)
5140 static bool done_init = False;
5144 /* If requested to initialize only once and we've already done it... */
5145 if (!reinit_globals && done_init) {
5146 /* ... then we have nothing more to do */
5151 /* The logfile can be set before this is invoked. Free it if so. */
5152 if (Globals.szLogFile != NULL) {
5153 string_free(&Globals.szLogFile);
5154 Globals.szLogFile = NULL;
5158 free_global_parameters();
5161 /* This memset and the free_global_parameters() above will
5162 * wipe out smb.conf options set with lp_set_cmdline(). The
5163 * apply_lp_set_cmdline() call puts these values back in the
5164 * table once the defaults are set */
5165 memset((void *)&Globals, '\0', sizeof(Globals));
5167 for (i = 0; parm_table[i].label; i++) {
5168 if ((parm_table[i].type == P_STRING ||
5169 parm_table[i].type == P_USTRING) &&
5172 string_set((char **)parm_table[i].ptr, "");
5176 string_set(&sDefault.fstype, FSTYPE_STRING);
5177 string_set(&sDefault.szPrintjobUsername, "%U");
5179 init_printer_values(&sDefault);
5182 DEBUG(3, ("Initialising global parameters\n"));
5184 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
5185 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
5187 /* use the new 'hash2' method by default, with a prefix of 1 */
5188 string_set(&Globals.szManglingMethod, "hash2");
5189 Globals.mangle_prefix = 1;
5191 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5193 /* using UTF8 by default allows us to support all chars */
5194 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5196 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
5197 /* If the system supports nl_langinfo(), try to grab the value
5198 from the user's locale */
5199 string_set(&Globals.display_charset, "LOCALE");
5201 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
5204 /* Use codepage 850 as a default for the dos character set */
5205 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5208 * Allow the default PASSWD_CHAT to be overridden in local.h.
5210 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5212 set_global_myname(myhostname());
5213 string_set(&Globals.szNetbiosName,global_myname());
5215 string_set(&Globals.szWorkgroup, WORKGROUP);
5217 string_set(&Globals.szPasswdProgram, "");
5218 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5219 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5220 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5221 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5222 string_set(&Globals.szSocketAddress, "0.0.0.0");
5224 * By default support explicit binding to broadcast
5227 Globals.bNmbdBindExplicitBroadcast = true;
5229 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5230 smb_panic("init_globals: ENOMEM");
5232 string_set(&Globals.szServerString, s);
5234 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5235 DEFAULT_MINOR_VERSION) < 0) {
5236 smb_panic("init_globals: ENOMEM");
5238 string_set(&Globals.szAnnounceVersion, s);
5241 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5244 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5246 string_set(&Globals.szLogonDrive, "");
5247 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5248 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5249 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5251 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5252 string_set(&Globals.szPasswordServer, "*");
5254 Globals.AlgorithmicRidBase = BASE_RID;
5256 Globals.bLoadPrinters = True;
5257 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
5259 Globals.ConfigBackend = config_backend;
5261 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5262 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5263 Globals.max_xmit = 0x4104;
5264 Globals.max_mux = 50; /* This is *needed* for profile support. */
5265 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
5266 Globals.bDisableSpoolss = False;
5267 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5268 Globals.pwordlevel = 0;
5269 Globals.unamelevel = 0;
5270 Globals.deadtime = 0;
5271 Globals.getwd_cache = true;
5272 Globals.bLargeReadwrite = True;
5273 Globals.max_log_size = 5000;
5274 Globals.max_open_files = max_open_files();
5275 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5276 Globals.maxprotocol = PROTOCOL_NT1;
5277 Globals.minprotocol = PROTOCOL_CORE;
5278 Globals.security = SEC_USER;
5279 Globals.paranoid_server_security = True;
5280 Globals.bEncryptPasswords = True;
5281 Globals.bUpdateEncrypt = False;
5282 Globals.clientSchannel = Auto;
5283 Globals.serverSchannel = Auto;
5284 Globals.bReadRaw = True;
5285 Globals.bWriteRaw = True;
5286 Globals.bNullPasswords = False;
5287 Globals.bObeyPamRestrictions = False;
5289 Globals.bSyslogOnly = False;
5290 Globals.bTimestampLogs = True;
5291 string_set(&Globals.szLogLevel, "0");
5292 Globals.bDebugPrefixTimestamp = False;
5293 Globals.bDebugHiresTimestamp = true;
5294 Globals.bDebugPid = False;
5295 Globals.bDebugUid = False;
5296 Globals.bDebugClass = False;
5297 Globals.bEnableCoreFiles = True;
5298 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5299 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5300 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5301 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5302 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5303 Globals.lm_interval = 60;
5304 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5305 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5306 Globals.bNISHomeMap = False;
5307 #ifdef WITH_NISPLUS_HOME
5308 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5310 string_set(&Globals.szNISHomeMapName, "auto.home");
5313 Globals.bTimeServer = False;
5314 Globals.bBindInterfacesOnly = False;
5315 Globals.bUnixPasswdSync = False;
5316 Globals.bPamPasswordChange = False;
5317 Globals.bPasswdChatDebug = False;
5318 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5319 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5320 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5321 Globals.bStatCache = True; /* use stat cache by default */
5322 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5323 Globals.restrict_anonymous = 0;
5324 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5325 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5326 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5327 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5328 Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
5329 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
5331 Globals.map_to_guest = 0; /* By Default, "Never" */
5332 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5333 Globals.enhanced_browsing = true;
5334 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5335 #ifdef MMAP_BLACKLIST
5336 Globals.bUseMmap = False;
5338 Globals.bUseMmap = True;
5340 Globals.bUnixExtensions = True;
5341 Globals.bResetOnZeroVC = False;
5342 Globals.bLogWriteableFilesOnExit = False;
5343 Globals.bCreateKrb5Conf = true;
5344 Globals.winbindMaxDomainConnections = 1;
5346 /* hostname lookups can be very expensive and are broken on
5347 a large number of sites (tridge) */
5348 Globals.bHostnameLookups = False;
5350 string_set(&Globals.szPassdbBackend, "tdbsam");
5351 string_set(&Globals.szLdapSuffix, "");
5352 string_set(&Globals.szLdapMachineSuffix, "");
5353 string_set(&Globals.szLdapUserSuffix, "");
5354 string_set(&Globals.szLdapGroupSuffix, "");
5355 string_set(&Globals.szLdapIdmapSuffix, "");
5357 string_set(&Globals.szLdapAdminDn, "");
5358 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5359 Globals.ldap_ssl_ads = False;
5360 Globals.ldap_deref = -1;
5361 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5362 Globals.ldap_delete_dn = False;
5363 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5364 Globals.ldap_follow_referral = Auto;
5365 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5366 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5367 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5369 Globals.ldap_debug_level = 0;
5370 Globals.ldap_debug_threshold = 10;
5372 /* This is what we tell the afs client. in reality we set the token
5373 * to never expire, though, when this runs out the afs client will
5374 * forget the token. Set to 0 to get NEVERDATE.*/
5375 Globals.iAfsTokenLifetime = 604800;
5376 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5378 /* these parameters are set to defaults that are more appropriate
5379 for the increasing samba install base:
5381 as a member of the workgroup, that will possibly become a
5382 _local_ master browser (lm = True). this is opposed to a forced
5383 local master browser startup (pm = True).
5385 doesn't provide WINS server service by default (wsupp = False),
5386 and doesn't provide domain master browser services by default, either.
5390 Globals.bMsAddPrinterWizard = True;
5391 Globals.os_level = 20;
5392 Globals.bLocalMaster = True;
5393 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5394 Globals.bDomainLogons = False;
5395 Globals.bBrowseList = True;
5396 Globals.bWINSsupport = False;
5397 Globals.bWINSproxy = False;
5399 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5400 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5402 Globals.bDNSproxy = True;
5404 /* this just means to use them if they exist */
5405 Globals.bKernelOplocks = True;
5407 Globals.bAllowTrustedDomains = True;
5408 string_set(&Globals.szIdmapBackend, "tdb");
5409 Globals.bIdmapReadOnly = false;
5411 string_set(&Globals.szTemplateShell, "/bin/false");
5412 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5413 string_set(&Globals.szWinbindSeparator, "\\");
5415 string_set(&Globals.szCupsServer, "");
5416 string_set(&Globals.szIPrintServer, "");
5418 string_set(&Globals.ctdbdSocket, "");
5419 Globals.szClusterAddresses = NULL;
5420 Globals.clustering = False;
5421 Globals.ctdb_timeout = 0;
5422 Globals.ctdb_locktime_warn_threshold = 0;
5424 Globals.winbind_cache_time = 300; /* 5 minutes */
5425 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5426 Globals.winbind_max_clients = 200;
5427 Globals.bWinbindEnumUsers = False;
5428 Globals.bWinbindEnumGroups = False;
5429 Globals.bWinbindUseDefaultDomain = False;
5430 Globals.bWinbindTrustedDomainsOnly = False;
5431 Globals.bWinbindNestedGroups = True;
5432 Globals.winbind_expand_groups = 1;
5433 Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
5434 Globals.bWinbindRefreshTickets = False;
5435 Globals.bWinbindOfflineLogon = False;
5437 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5438 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5440 Globals.bPassdbExpandExplicit = False;
5442 Globals.name_cache_timeout = 660; /* In seconds */
5444 Globals.bUseSpnego = True;
5445 Globals.bClientUseSpnego = True;
5447 Globals.client_signing = Auto;
5448 Globals.server_signing = False;
5450 Globals.bDeferSharingViolations = True;
5451 string_set(&Globals.smb_ports, SMB_PORTS);
5453 Globals.bEnablePrivileges = True;
5454 Globals.bHostMSDfs = True;
5455 Globals.bASUSupport = False;
5457 /* User defined shares. */
5458 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5459 smb_panic("init_globals: ENOMEM");
5461 string_set(&Globals.szUsersharePath, s);
5463 string_set(&Globals.szUsershareTemplateShare, "");
5464 Globals.iUsershareMaxShares = 0;
5465 /* By default disallow sharing of directories not owned by the sharer. */
5466 Globals.bUsershareOwnerOnly = True;
5467 /* By default disallow guest access to usershares. */
5468 Globals.bUsershareAllowGuests = False;
5470 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5472 /* By default no shares out of the registry */
5473 Globals.bRegistryShares = False;
5475 Globals.iminreceivefile = 0;
5477 Globals.bMapUntrustedToDomain = false;
5478 Globals.bMulticastDnsRegister = true;
5480 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
5481 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
5482 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
5483 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5485 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5487 /* Now put back the settings that were set with lp_set_cmdline() */
5488 apply_lp_set_cmdline();
5491 /*******************************************************************
5492 Convenience routine to grab string parameters into temporary memory
5493 and run standard_sub_basic on them. The buffers can be written to by
5494 callers without affecting the source string.
5495 ********************************************************************/
5497 static char *lp_string(const char *s)
5500 TALLOC_CTX *ctx = talloc_tos();
5502 /* The follow debug is useful for tracking down memory problems
5503 especially if you have an inner loop that is calling a lp_*()
5504 function that returns a string. Perhaps this debug should be
5505 present all the time? */
5508 DEBUG(10, ("lp_string(%s)\n", s));
5514 ret = talloc_sub_basic(ctx,
5515 get_current_username(),
5516 current_user_info.domain,
5518 if (trim_char(ret, '\"', '\"')) {
5519 if (strchr(ret,'\"') != NULL) {
5521 ret = talloc_sub_basic(ctx,
5522 get_current_username(),
5523 current_user_info.domain,
5531 In this section all the functions that are used to access the
5532 parameters from the rest of the program are defined
5535 #define FN_GLOBAL_STRING(fn_name,ptr) \
5536 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5537 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5538 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5539 #define FN_GLOBAL_LIST(fn_name,ptr) \
5540 const char **fn_name(void) {return(*(const char ***)(ptr));}
5541 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5542 bool fn_name(void) {return(*(bool *)(ptr));}
5543 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5544 char fn_name(void) {return(*(char *)(ptr));}
5545 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5546 int fn_name(void) {return(*(int *)(ptr));}
5548 #define FN_LOCAL_STRING(fn_name,val) \
5549 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5550 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5551 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5552 #define FN_LOCAL_LIST(fn_name,val) \
5553 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5554 #define FN_LOCAL_BOOL(fn_name,val) \
5555 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5556 #define FN_LOCAL_INTEGER(fn_name,val) \
5557 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5559 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5560 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5561 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5562 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5563 #define FN_LOCAL_CHAR(fn_name,val) \
5564 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5566 FN_GLOBAL_CONST_STRING(lp_smb_ports, &Globals.smb_ports)
5567 FN_GLOBAL_CONST_STRING(lp_dos_charset, &Globals.dos_charset)
5568 FN_GLOBAL_CONST_STRING(lp_unix_charset, &Globals.unix_charset)
5569 FN_GLOBAL_CONST_STRING(lp_display_charset, &Globals.display_charset)
5570 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5571 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5572 FN_GLOBAL_CONST_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5573 FN_GLOBAL_CONST_STRING(lp_private_dir, &Globals.szPrivateDir)
5574 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5575 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5576 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5577 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5578 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5579 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5580 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5581 FN_GLOBAL_CONST_STRING(lp_lockdir, &Globals.szLockDir)
5582 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5583 * build process or in smb.conf, we use that value. Otherwise they
5584 * default to the value of lp_lockdir(). */
5585 const char *lp_statedir(void) {
5586 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5587 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5588 return(*(char **)(&Globals.szStateDir) ?
5589 *(char **)(&Globals.szStateDir) : "");
5591 return(*(char **)(&Globals.szLockDir) ?
5592 *(char **)(&Globals.szLockDir) : "");
5594 const char *lp_cachedir(void) {
5595 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5596 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5597 return(*(char **)(&Globals.szCacheDir) ?
5598 *(char **)(&Globals.szCacheDir) : "");
5600 return(*(char **)(&Globals.szLockDir) ?
5601 *(char **)(&Globals.szLockDir) : "");
5603 FN_GLOBAL_CONST_STRING(lp_piddir, &Globals.szPidDir)
5604 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5605 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5606 FN_GLOBAL_CONST_STRING(lp_utmpdir, &Globals.szUtmpDir)
5607 FN_GLOBAL_CONST_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5608 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5609 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5610 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5611 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5612 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5613 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5614 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5615 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5616 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5617 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5618 FN_GLOBAL_CONST_STRING(lp_passwordserver, &Globals.szPasswordServer)
5619 FN_GLOBAL_CONST_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5620 FN_GLOBAL_CONST_STRING(lp_workgroup, &Globals.szWorkgroup)
5621 FN_GLOBAL_CONST_STRING(lp_realm, &Globals.szRealmUpper)
5622 FN_GLOBAL_CONST_STRING(lp_dnsdomain, &Globals.szDnsDomain)
5623 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5624 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5625 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5626 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5627 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5628 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5629 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5630 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5631 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5632 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5633 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5634 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5635 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5636 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5637 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5638 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5639 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5640 * lp_passdb_backend() should be replace by the this macro again after
5643 const char *lp_passdb_backend(void)
5645 char *delim, *quote;
5647 delim = strchr( Globals.szPassdbBackend, ' ');
5648 /* no space at all */
5649 if (delim == NULL) {
5653 quote = strchr(Globals.szPassdbBackend, '"');
5654 /* no quote char or non in the first part */
5655 if (quote == NULL || quote > delim) {
5660 quote = strchr(quote+1, '"');
5661 if (quote == NULL) {
5662 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5664 } else if (*(quote+1) == '\0') {
5665 /* space, fitting quote char, and one backend only */
5668 /* terminate string after the fitting quote char */
5673 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5674 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5675 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5676 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5679 return Globals.szPassdbBackend;
5681 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5682 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5683 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5684 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5685 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5687 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5688 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5689 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5690 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5691 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5692 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5694 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5696 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5697 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5698 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5699 FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
5701 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5703 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5704 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5705 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5706 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5707 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5708 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5709 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5710 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5711 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5712 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5713 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5714 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5715 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5716 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5717 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5718 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5719 static FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections_int,
5720 &Globals.winbindMaxDomainConnections)
5722 int lp_winbind_max_domain_connections(void)
5724 if (lp_winbind_offline_logon() &&
5725 lp_winbind_max_domain_connections_int() > 1) {
5726 DEBUG(1, ("offline logons active, restricting max domain "
5727 "connections to 1\n"));
5730 return MAX(1, lp_winbind_max_domain_connections_int());
5733 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5734 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5735 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5736 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5737 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5739 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5740 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5741 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5742 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5743 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5744 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5745 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5746 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5747 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5748 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5749 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5750 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5751 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5752 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5753 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5754 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5755 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5756 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5757 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5758 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5760 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5762 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5763 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5764 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5765 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5766 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5767 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5768 &Globals.bLogWriteableFilesOnExit)
5769 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5770 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5771 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5772 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5773 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5774 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5775 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5776 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5777 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5778 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5779 FN_GLOBAL_BOOL(_lp_readraw, &Globals.bReadRaw)
5780 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5781 FN_GLOBAL_BOOL(_lp_writeraw, &Globals.bWriteRaw)
5782 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5783 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5784 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5785 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5786 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5787 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5788 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5789 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5790 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5791 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5792 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5793 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5794 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5795 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5796 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5797 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5798 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5799 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5800 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5801 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5802 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5803 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5804 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5805 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5806 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5807 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5808 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5809 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5810 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5811 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5812 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5813 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5814 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5815 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5816 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5817 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5818 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5819 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5820 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5821 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5822 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
5823 FN_GLOBAL_BOOL(lp_send_spnego_principal, &Globals.send_spnego_principal)
5824 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5825 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5826 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5827 FN_GLOBAL_CONST_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5828 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5829 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5830 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5831 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5832 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5833 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5834 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5835 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5836 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5837 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5838 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5839 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5840 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5841 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5842 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5843 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5844 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5845 static FN_GLOBAL_INTEGER(_lp_maxprotocol, &Globals.maxprotocol)
5846 int lp_maxprotocol(void)
5848 int ret = _lp_maxprotocol();
5849 if ((ret == PROTOCOL_SMB2) && (lp_security() == SEC_SHARE)) {
5850 DEBUG(2,("WARNING!!: \"security = share\" is incompatible "
5851 "with the SMB2 protocol. Resetting to SMB1.\n" ));
5852 lp_do_parameter(-1, "max protocol", "NT1");
5853 return PROTOCOL_NT1;
5857 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5858 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5859 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5860 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5861 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5862 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5863 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5864 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5865 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5866 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5867 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5868 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5869 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5870 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5871 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5872 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5873 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5874 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5875 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5876 FN_GLOBAL_INTEGER(lp_smb2_max_read, &Globals.ismb2_max_read)
5877 FN_GLOBAL_INTEGER(lp_smb2_max_write, &Globals.ismb2_max_write)
5878 FN_GLOBAL_INTEGER(lp_smb2_max_trans, &Globals.ismb2_max_trans)
5879 int lp_smb2_max_credits(void)
5881 if (Globals.ismb2_max_credits == 0) {
5882 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5884 return Globals.ismb2_max_credits;
5886 FN_LOCAL_STRING(lp_preexec, szPreExec)
5887 FN_LOCAL_STRING(lp_postexec, szPostExec)
5888 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5889 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5890 FN_LOCAL_STRING(lp_servicename, szService)
5891 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5892 FN_LOCAL_STRING(lp_pathname, szPath)
5893 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5894 FN_LOCAL_STRING(lp_username, szUsername)
5895 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5896 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5897 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5898 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5899 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5900 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5901 int lp_cups_encrypt(void)
5904 #ifdef HAVE_HTTPCONNECTENCRYPT
5905 switch (Globals.CupsEncrypt) {
5907 result = HTTP_ENCRYPT_REQUIRED;
5910 result = HTTP_ENCRYPT_ALWAYS;
5913 result = HTTP_ENCRYPT_NEVER;
5919 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5920 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5921 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5922 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5923 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5924 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5925 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, &Globals.ctdb_locktime_warn_threshold)
5926 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5927 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5928 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5929 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5930 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5931 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5932 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5933 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5934 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5935 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5936 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5937 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5938 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5939 FN_LOCAL_STRING(lp_comment, comment)
5940 FN_LOCAL_STRING(lp_force_user, force_user)
5941 FN_LOCAL_STRING(lp_force_group, force_group)
5942 FN_LOCAL_LIST(lp_readlist, readlist)
5943 FN_LOCAL_LIST(lp_writelist, writelist)
5944 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5945 FN_LOCAL_STRING(lp_fstype, fstype)
5946 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5947 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5948 static FN_LOCAL_STRING(lp_volume, volume)
5949 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5950 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5951 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5952 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5953 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5954 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5955 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5956 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5957 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5958 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5959 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5960 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5961 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5962 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5963 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5964 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5965 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5966 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5967 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5968 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5969 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5970 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5971 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5972 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5973 FN_LOCAL_BOOL(lp_print_notify_backchannel, bPrintNotifyBackchannel)
5974 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5975 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5976 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5977 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5978 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5979 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5980 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5981 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5982 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5983 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5984 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5985 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5986 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5987 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5988 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5989 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5990 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5991 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5992 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5993 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5994 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5995 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5996 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5997 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5998 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5999 FN_GLOBAL_BOOL(lp_multicast_dns_register, &Globals.bMulticastDnsRegister)
6000 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
6001 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
6002 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
6003 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
6004 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
6005 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
6006 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
6007 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
6008 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
6009 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
6010 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
6011 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
6012 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
6013 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
6014 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
6015 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
6016 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
6017 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
6018 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
6019 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
6020 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
6021 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
6022 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
6023 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
6024 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
6025 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
6026 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
6027 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
6028 FN_LOCAL_INTEGER(lp_printing, iPrinting)
6029 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
6030 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
6031 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
6032 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
6033 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
6034 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
6035 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
6036 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
6037 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
6038 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
6039 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
6040 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
6041 FN_LOCAL_CHAR(lp_magicchar, magic_char)
6042 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
6043 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
6044 FN_GLOBAL_INTEGER(lp_winbind_max_clients, &Globals.winbind_max_clients)
6045 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
6046 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
6047 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
6048 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
6049 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
6050 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
6052 FN_GLOBAL_CONST_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
6054 /* local prototypes */
6056 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
6057 static const char *get_boolean(bool bool_value);
6058 static int getservicebyname(const char *pszServiceName,
6059 struct service *pserviceDest);
6060 static void copy_service(struct service *pserviceDest,
6061 struct service *pserviceSource,
6062 struct bitmap *pcopymapDest);
6063 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
6065 static bool do_section(const char *pszSectionName, void *userdata);
6066 static void init_copymap(struct service *pservice);
6067 static bool hash_a_service(const char *name, int number);
6068 static void free_service_byindex(int iService);
6069 static void free_param_opts(struct param_opt_struct **popts);
6070 static void show_parameter(int parmIndex);
6071 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
6074 * This is a helper function for parametrical options support. It returns a
6075 * pointer to parametrical option value if it exists or NULL otherwise. Actual
6076 * parametrical functions are quite simple
6078 static struct param_opt_struct *get_parametrics(int snum, const char *type,
6081 bool global_section = False;
6083 struct param_opt_struct *data;
6085 if (snum >= iNumServices) return NULL;
6088 data = Globals.param_opt;
6089 global_section = True;
6091 data = ServicePtrs[snum]->param_opt;
6094 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
6095 DEBUG(0,("asprintf failed!\n"));
6100 if (strwicmp(data->key, param_key) == 0) {
6101 string_free(¶m_key);
6107 if (!global_section) {
6108 /* Try to fetch the same option but from globals */
6109 /* but only if we are not already working with Globals */
6110 data = Globals.param_opt;
6112 if (strwicmp(data->key, param_key) == 0) {
6113 string_free(¶m_key);
6120 string_free(¶m_key);
6126 #define MISSING_PARAMETER(name) \
6127 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
6129 /*******************************************************************
6130 convenience routine to return int parameters.
6131 ********************************************************************/
6132 static int lp_int(const char *s)
6136 MISSING_PARAMETER(lp_int);
6140 return (int)strtol(s, NULL, 0);
6143 /*******************************************************************
6144 convenience routine to return unsigned long parameters.
6145 ********************************************************************/
6146 static unsigned long lp_ulong(const char *s)
6150 MISSING_PARAMETER(lp_ulong);
6154 return strtoul(s, NULL, 0);
6157 /*******************************************************************
6158 convenience routine to return boolean parameters.
6159 ********************************************************************/
6160 static bool lp_bool(const char *s)
6165 MISSING_PARAMETER(lp_bool);
6169 if (!set_boolean(s, &ret)) {
6170 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
6177 /*******************************************************************
6178 convenience routine to return enum parameters.
6179 ********************************************************************/
6180 static int lp_enum(const char *s,const struct enum_list *_enum)
6184 if (!s || !*s || !_enum) {
6185 MISSING_PARAMETER(lp_enum);
6189 for (i=0; _enum[i].name; i++) {
6190 if (strequal(_enum[i].name,s))
6191 return _enum[i].value;
6194 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
6198 #undef MISSING_PARAMETER
6200 /* DO NOT USE lp_parm_string ANYMORE!!!!
6201 * use lp_parm_const_string or lp_parm_talloc_string
6203 * lp_parm_string is only used to let old modules find this symbol
6205 #undef lp_parm_string
6206 char *lp_parm_string(const char *servicename, const char *type, const char *option);
6207 char *lp_parm_string(const char *servicename, const char *type, const char *option)
6209 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
6212 /* Return parametric option from a given service. Type is a part of option before ':' */
6213 /* Parametric option has following syntax: 'Type: option = value' */
6214 /* the returned value is talloced on the talloc_tos() */
6215 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
6217 struct param_opt_struct *data = get_parametrics(snum, type, option);
6219 if (data == NULL||data->value==NULL) {
6221 return lp_string(def);
6227 return lp_string(data->value);
6230 /* Return parametric option from a given service. Type is a part of option before ':' */
6231 /* Parametric option has following syntax: 'Type: option = value' */
6232 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6234 struct param_opt_struct *data = get_parametrics(snum, type, option);
6236 if (data == NULL||data->value==NULL)
6242 /* Return parametric option from a given service. Type is a part of option before ':' */
6243 /* Parametric option has following syntax: 'Type: option = value' */
6245 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6247 struct param_opt_struct *data = get_parametrics(snum, type, option);
6249 if (data == NULL||data->value==NULL)
6250 return (const char **)def;
6252 if (data->list==NULL) {
6253 data->list = str_list_make_v3(NULL, data->value, NULL);
6256 return (const char **)data->list;
6259 /* Return parametric option from a given service. Type is a part of option before ':' */
6260 /* Parametric option has following syntax: 'Type: option = value' */
6262 int lp_parm_int(int snum, const char *type, const char *option, int def)
6264 struct param_opt_struct *data = get_parametrics(snum, type, option);
6266 if (data && data->value && *data->value)
6267 return lp_int(data->value);
6272 /* Return parametric option from a given service. Type is a part of option before ':' */
6273 /* Parametric option has following syntax: 'Type: option = value' */
6275 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6277 struct param_opt_struct *data = get_parametrics(snum, type, option);
6279 if (data && data->value && *data->value)
6280 return lp_ulong(data->value);
6285 /* Return parametric option from a given service. Type is a part of option before ':' */
6286 /* Parametric option has following syntax: 'Type: option = value' */
6288 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6290 struct param_opt_struct *data = get_parametrics(snum, type, option);
6292 if (data && data->value && *data->value)
6293 return lp_bool(data->value);
6298 /* Return parametric option from a given service. Type is a part of option before ':' */
6299 /* Parametric option has following syntax: 'Type: option = value' */
6301 int lp_parm_enum(int snum, const char *type, const char *option,
6302 const struct enum_list *_enum, int def)
6304 struct param_opt_struct *data = get_parametrics(snum, type, option);
6306 if (data && data->value && *data->value && _enum)
6307 return lp_enum(data->value, _enum);
6313 /***************************************************************************
6314 Initialise a service to the defaults.
6315 ***************************************************************************/
6317 static void init_service(struct service *pservice)
6319 memset((char *)pservice, '\0', sizeof(struct service));
6320 copy_service(pservice, &sDefault, NULL);
6325 * free a param_opts structure.
6326 * param_opts handling should be moved to talloc;
6327 * then this whole functions reduces to a TALLOC_FREE().
6330 static void free_param_opts(struct param_opt_struct **popts)
6332 struct param_opt_struct *opt, *next_opt;
6334 if (popts == NULL) {
6338 if (*popts != NULL) {
6339 DEBUG(5, ("Freeing parametrics:\n"));
6342 while (opt != NULL) {
6343 string_free(&opt->key);
6344 string_free(&opt->value);
6345 TALLOC_FREE(opt->list);
6346 next_opt = opt->next;
6353 /***************************************************************************
6354 Free the dynamically allocated parts of a service struct.
6355 ***************************************************************************/
6357 static void free_service(struct service *pservice)
6362 if (pservice->szService)
6363 DEBUG(5, ("free_service: Freeing service %s\n",
6364 pservice->szService));
6366 free_parameters(pservice);
6368 string_free(&pservice->szService);
6369 TALLOC_FREE(pservice->copymap);
6371 free_param_opts(&pservice->param_opt);
6373 ZERO_STRUCTP(pservice);
6377 /***************************************************************************
6378 remove a service indexed in the ServicePtrs array from the ServiceHash
6379 and free the dynamically allocated parts
6380 ***************************************************************************/
6382 static void free_service_byindex(int idx)
6384 if ( !LP_SNUM_OK(idx) )
6387 ServicePtrs[idx]->valid = False;
6388 invalid_services[num_invalid_services++] = idx;
6390 /* we have to cleanup the hash record */
6392 if (ServicePtrs[idx]->szService) {
6393 char *canon_name = canonicalize_servicename(
6395 ServicePtrs[idx]->szService );
6397 dbwrap_delete_bystring(ServiceHash, canon_name );
6398 TALLOC_FREE(canon_name);
6401 free_service(ServicePtrs[idx]);
6404 /***************************************************************************
6405 Add a new service to the services array initialising it with the given
6407 ***************************************************************************/
6409 static int add_a_service(const struct service *pservice, const char *name)
6412 struct service tservice;
6413 int num_to_alloc = iNumServices + 1;
6415 tservice = *pservice;
6417 /* it might already exist */
6419 i = getservicebyname(name, NULL);
6425 /* find an invalid one */
6427 if (num_invalid_services > 0) {
6428 i = invalid_services[--num_invalid_services];
6431 /* if not, then create one */
6432 if (i == iNumServices) {
6433 struct service **tsp;
6436 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6438 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6442 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6443 if (!ServicePtrs[iNumServices]) {
6444 DEBUG(0,("add_a_service: out of memory!\n"));
6449 /* enlarge invalid_services here for now... */
6450 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6452 if (tinvalid == NULL) {
6453 DEBUG(0,("add_a_service: failed to enlarge "
6454 "invalid_services!\n"));
6457 invalid_services = tinvalid;
6459 free_service_byindex(i);
6462 ServicePtrs[i]->valid = True;
6464 init_service(ServicePtrs[i]);
6465 copy_service(ServicePtrs[i], &tservice, NULL);
6467 string_set(&ServicePtrs[i]->szService, name);
6469 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6470 i, ServicePtrs[i]->szService));
6472 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6479 /***************************************************************************
6480 Convert a string to uppercase and remove whitespaces.
6481 ***************************************************************************/
6483 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6488 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6492 result = talloc_strdup(ctx, src);
6493 SMB_ASSERT(result != NULL);
6499 /***************************************************************************
6500 Add a name/index pair for the services array to the hash table.
6501 ***************************************************************************/
6503 static bool hash_a_service(const char *name, int idx)
6507 if ( !ServiceHash ) {
6508 DEBUG(10,("hash_a_service: creating servicehash\n"));
6509 ServiceHash = db_open_rbt(NULL);
6510 if ( !ServiceHash ) {
6511 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6516 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6519 canon_name = canonicalize_servicename(talloc_tos(), name );
6521 dbwrap_store_bystring(ServiceHash, canon_name,
6522 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6525 TALLOC_FREE(canon_name);
6530 /***************************************************************************
6531 Add a new home service, with the specified home directory, defaults coming
6533 ***************************************************************************/
6535 bool lp_add_home(const char *pszHomename, int iDefaultService,
6536 const char *user, const char *pszHomedir)
6540 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6541 pszHomedir[0] == '\0') {
6545 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6550 if (!(*(ServicePtrs[iDefaultService]->szPath))
6551 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6552 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6555 if (!(*(ServicePtrs[i]->comment))) {
6556 char *comment = NULL;
6557 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6560 string_set(&ServicePtrs[i]->comment, comment);
6564 /* set the browseable flag from the global default */
6566 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6567 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6569 ServicePtrs[i]->autoloaded = True;
6571 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6572 user, ServicePtrs[i]->szPath ));
6577 /***************************************************************************
6578 Add a new service, based on an old one.
6579 ***************************************************************************/
6581 int lp_add_service(const char *pszService, int iDefaultService)
6583 if (iDefaultService < 0) {
6584 return add_a_service(&sDefault, pszService);
6587 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6590 /***************************************************************************
6591 Add the IPC service.
6592 ***************************************************************************/
6594 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6596 char *comment = NULL;
6597 int i = add_a_service(&sDefault, ipc_name);
6602 if (asprintf(&comment, "IPC Service (%s)",
6603 Globals.szServerString) < 0) {
6607 string_set(&ServicePtrs[i]->szPath, tmpdir());
6608 string_set(&ServicePtrs[i]->szUsername, "");
6609 string_set(&ServicePtrs[i]->comment, comment);
6610 string_set(&ServicePtrs[i]->fstype, "IPC");
6611 ServicePtrs[i]->iMaxConnections = 0;
6612 ServicePtrs[i]->bAvailable = True;
6613 ServicePtrs[i]->bRead_only = True;
6614 ServicePtrs[i]->bGuest_only = False;
6615 ServicePtrs[i]->bAdministrative_share = True;
6616 ServicePtrs[i]->bGuest_ok = guest_ok;
6617 ServicePtrs[i]->bPrint_ok = False;
6618 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6620 DEBUG(3, ("adding IPC service\n"));
6626 /***************************************************************************
6627 Add a new printer service, with defaults coming from service iFrom.
6628 ***************************************************************************/
6630 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6632 const char *comment = "From Printcap";
6633 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6638 /* note that we do NOT default the availability flag to True - */
6639 /* we take it from the default service passed. This allows all */
6640 /* dynamic printers to be disabled by disabling the [printers] */
6641 /* entry (if/when the 'available' keyword is implemented!). */
6643 /* the printer name is set to the service name. */
6644 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6645 string_set(&ServicePtrs[i]->comment, comment);
6647 /* set the browseable flag from the gloabl default */
6648 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6650 /* Printers cannot be read_only. */
6651 ServicePtrs[i]->bRead_only = False;
6652 /* No share modes on printer services. */
6653 ServicePtrs[i]->bShareModes = False;
6654 /* No oplocks on printer services. */
6655 ServicePtrs[i]->bOpLocks = False;
6656 /* Printer services must be printable. */
6657 ServicePtrs[i]->bPrint_ok = True;
6659 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6665 /***************************************************************************
6666 Check whether the given parameter name is valid.
6667 Parametric options (names containing a colon) are considered valid.
6668 ***************************************************************************/
6670 bool lp_parameter_is_valid(const char *pszParmName)
6672 return ((map_parameter(pszParmName) != -1) ||
6673 (strchr(pszParmName, ':') != NULL));
6676 /***************************************************************************
6677 Check whether the given name is the name of a global parameter.
6678 Returns True for strings belonging to parameters of class
6679 P_GLOBAL, False for all other strings, also for parametric options
6680 and strings not belonging to any option.
6681 ***************************************************************************/
6683 bool lp_parameter_is_global(const char *pszParmName)
6685 int num = map_parameter(pszParmName);
6688 return (parm_table[num].p_class == P_GLOBAL);
6694 /**************************************************************************
6695 Check whether the given name is the canonical name of a parameter.
6696 Returns False if it is not a valid parameter Name.
6697 For parametric options, True is returned.
6698 **************************************************************************/
6700 bool lp_parameter_is_canonical(const char *parm_name)
6702 if (!lp_parameter_is_valid(parm_name)) {
6706 return (map_parameter(parm_name) ==
6707 map_parameter_canonical(parm_name, NULL));
6710 /**************************************************************************
6711 Determine the canonical name for a parameter.
6712 Indicate when it is an inverse (boolean) synonym instead of a
6714 **************************************************************************/
6716 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6721 if (!lp_parameter_is_valid(parm_name)) {
6726 num = map_parameter_canonical(parm_name, inverse);
6728 /* parametric option */
6729 *canon_parm = parm_name;
6731 *canon_parm = parm_table[num].label;
6738 /**************************************************************************
6739 Determine the canonical name for a parameter.
6740 Turn the value given into the inverse boolean expression when
6741 the synonym is an invers boolean synonym.
6743 Return True if parm_name is a valid parameter name and
6744 in case it is an invers boolean synonym, if the val string could
6745 successfully be converted to the reverse bool.
6746 Return false in all other cases.
6747 **************************************************************************/
6749 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6751 const char **canon_parm,
6752 const char **canon_val)
6757 if (!lp_parameter_is_valid(parm_name)) {
6763 num = map_parameter_canonical(parm_name, &inverse);
6765 /* parametric option */
6766 *canon_parm = parm_name;
6769 *canon_parm = parm_table[num].label;
6771 if (!lp_invert_boolean(val, canon_val)) {
6783 /***************************************************************************
6784 Map a parameter's string representation to something we can use.
6785 Returns False if the parameter string is not recognised, else TRUE.
6786 ***************************************************************************/
6788 static int map_parameter(const char *pszParmName)
6792 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6795 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6796 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6799 /* Warn only if it isn't parametric option */
6800 if (strchr(pszParmName, ':') == NULL)
6801 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6802 /* We do return 'fail' for parametric options as well because they are
6803 stored in different storage
6808 /***************************************************************************
6809 Map a parameter's string representation to the index of the canonical
6810 form of the parameter (it might be a synonym).
6811 Returns -1 if the parameter string is not recognised.
6812 ***************************************************************************/
6814 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6816 int parm_num, canon_num;
6817 bool loc_inverse = False;
6819 parm_num = map_parameter(pszParmName);
6820 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6821 /* invalid, parametric or no canidate for synonyms ... */
6825 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6826 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6827 parm_num = canon_num;
6833 if (inverse != NULL) {
6834 *inverse = loc_inverse;
6839 /***************************************************************************
6840 return true if parameter number parm1 is a synonym of parameter
6841 number parm2 (parm2 being the principal name).
6842 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6844 ***************************************************************************/
6846 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6848 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6849 (parm_table[parm1].flags & FLAG_HIDE) &&
6850 !(parm_table[parm2].flags & FLAG_HIDE))
6852 if (inverse != NULL) {
6853 if ((parm_table[parm1].type == P_BOOLREV) &&
6854 (parm_table[parm2].type == P_BOOL))
6866 /***************************************************************************
6867 Show one parameter's name, type, [values,] and flags.
6868 (helper functions for show_parameter_list)
6869 ***************************************************************************/
6871 static void show_parameter(int parmIndex)
6873 int enumIndex, flagIndex;
6878 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6879 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6881 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6882 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6883 FLAG_HIDE, FLAG_DOS_STRING};
6884 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6885 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6886 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6888 printf("%s=%s", parm_table[parmIndex].label,
6889 type[parm_table[parmIndex].type]);
6890 if (parm_table[parmIndex].type == P_ENUM) {
6893 parm_table[parmIndex].enum_list[enumIndex].name;
6897 enumIndex ? "|" : "",
6898 parm_table[parmIndex].enum_list[enumIndex].name);
6903 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6904 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6907 flag_names[flagIndex]);
6912 /* output synonyms */
6914 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6915 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6916 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6917 parm_table[parmIndex2].label);
6918 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6920 printf(" (synonyms: ");
6925 printf("%s%s", parm_table[parmIndex2].label,
6926 inverse ? "[i]" : "");
6936 /***************************************************************************
6937 Show all parameter's name, type, [values,] and flags.
6938 ***************************************************************************/
6940 void show_parameter_list(void)
6942 int classIndex, parmIndex;
6943 const char *section_names[] = { "local", "global", NULL};
6945 for (classIndex=0; section_names[classIndex]; classIndex++) {
6946 printf("[%s]\n", section_names[classIndex]);
6947 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6948 if (parm_table[parmIndex].p_class == classIndex) {
6949 show_parameter(parmIndex);
6955 /***************************************************************************
6956 Check if a given string correctly represents a boolean value.
6957 ***************************************************************************/
6959 bool lp_string_is_valid_boolean(const char *parm_value)
6961 return set_boolean(parm_value, NULL);
6964 /***************************************************************************
6965 Get the standard string representation of a boolean value ("yes" or "no")
6966 ***************************************************************************/
6968 static const char *get_boolean(bool bool_value)
6970 static const char *yes_str = "yes";
6971 static const char *no_str = "no";
6973 return (bool_value ? yes_str : no_str);
6976 /***************************************************************************
6977 Provide the string of the negated boolean value associated to the boolean
6978 given as a string. Returns False if the passed string does not correctly
6979 represent a boolean.
6980 ***************************************************************************/
6982 bool lp_invert_boolean(const char *str, const char **inverse_str)
6986 if (!set_boolean(str, &val)) {
6990 *inverse_str = get_boolean(!val);
6994 /***************************************************************************
6995 Provide the canonical string representation of a boolean value given
6996 as a string. Return True on success, False if the string given does
6997 not correctly represent a boolean.
6998 ***************************************************************************/
7000 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
7004 if (!set_boolean(str, &val)) {
7008 *canon_str = get_boolean(val);
7012 /***************************************************************************
7013 Find a service by name. Otherwise works like get_service.
7014 ***************************************************************************/
7016 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
7022 if (ServiceHash == NULL) {
7026 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
7028 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
7030 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
7031 iService = *(int *)data.dptr;
7034 TALLOC_FREE(canon_name);
7036 if ((iService != -1) && (LP_SNUM_OK(iService))
7037 && (pserviceDest != NULL)) {
7038 copy_service(pserviceDest, ServicePtrs[iService], NULL);
7044 /***************************************************************************
7045 Copy a service structure to another.
7046 If pcopymapDest is NULL then copy all fields
7047 ***************************************************************************/
7050 * Add a parametric option to a param_opt_struct,
7051 * replacing old value, if already present.
7053 static void set_param_opt(struct param_opt_struct **opt_list,
7054 const char *opt_name,
7055 const char *opt_value,
7058 struct param_opt_struct *new_opt, *opt;
7061 if (opt_list == NULL) {
7068 /* Traverse destination */
7070 /* If we already have same option, override it */
7071 if (strwicmp(opt->key, opt_name) == 0) {
7072 if ((opt->flags & FLAG_CMDLINE) &&
7073 !(flags & FLAG_CMDLINE)) {
7074 /* it's been marked as not to be
7078 string_free(&opt->value);
7079 TALLOC_FREE(opt->list);
7080 opt->value = SMB_STRDUP(opt_value);
7088 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
7089 new_opt->key = SMB_STRDUP(opt_name);
7090 new_opt->value = SMB_STRDUP(opt_value);
7091 new_opt->list = NULL;
7092 new_opt->flags = flags;
7093 DLIST_ADD(*opt_list, new_opt);
7097 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
7098 struct bitmap *pcopymapDest)
7101 bool bcopyall = (pcopymapDest == NULL);
7102 struct param_opt_struct *data;
7104 for (i = 0; parm_table[i].label; i++)
7105 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
7106 (bcopyall || bitmap_query(pcopymapDest,i))) {
7107 void *def_ptr = parm_table[i].ptr;
7109 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
7112 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
7115 switch (parm_table[i].type) {
7118 *(bool *)dest_ptr = *(bool *)src_ptr;
7124 *(int *)dest_ptr = *(int *)src_ptr;
7128 *(char *)dest_ptr = *(char *)src_ptr;
7132 string_set((char **)dest_ptr,
7137 string_set((char **)dest_ptr,
7139 strupper_m(*(char **)dest_ptr);
7142 TALLOC_FREE(*((char ***)dest_ptr));
7143 *((char ***)dest_ptr) = str_list_copy(NULL,
7144 *(const char ***)src_ptr);
7152 init_copymap(pserviceDest);
7153 if (pserviceSource->copymap)
7154 bitmap_copy(pserviceDest->copymap,
7155 pserviceSource->copymap);
7158 data = pserviceSource->param_opt;
7160 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->flags);
7165 /***************************************************************************
7166 Check a service for consistency. Return False if the service is in any way
7167 incomplete or faulty, else True.
7168 ***************************************************************************/
7170 bool service_ok(int iService)
7175 if (ServicePtrs[iService]->szService[0] == '\0') {
7176 DEBUG(0, ("The following message indicates an internal error:\n"));
7177 DEBUG(0, ("No service name in service entry.\n"));
7181 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
7182 /* I can't see why you'd want a non-printable printer service... */
7183 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
7184 if (!ServicePtrs[iService]->bPrint_ok) {
7185 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
7186 ServicePtrs[iService]->szService));
7187 ServicePtrs[iService]->bPrint_ok = True;
7189 /* [printers] service must also be non-browsable. */
7190 if (ServicePtrs[iService]->bBrowseable)
7191 ServicePtrs[iService]->bBrowseable = False;
7194 if (ServicePtrs[iService]->szPath[0] == '\0' &&
7195 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
7196 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
7198 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
7199 ServicePtrs[iService]->szService));
7200 ServicePtrs[iService]->bAvailable = False;
7203 /* If a service is flagged unavailable, log the fact at level 1. */
7204 if (!ServicePtrs[iService]->bAvailable)
7205 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
7206 ServicePtrs[iService]->szService));
7211 static struct smbconf_ctx *lp_smbconf_ctx(void)
7214 static struct smbconf_ctx *conf_ctx = NULL;
7216 if (conf_ctx == NULL) {
7217 err = smbconf_init(NULL, &conf_ctx, "registry:");
7218 if (!SBC_ERROR_IS_OK(err)) {
7219 DEBUG(1, ("error initializing registry configuration: "
7220 "%s\n", sbcErrorString(err)));
7228 static bool process_smbconf_service(struct smbconf_service *service)
7233 if (service == NULL) {
7237 ret = do_section(service->name, NULL);
7241 for (count = 0; count < service->num_params; count++) {
7242 ret = do_parameter(service->param_names[count],
7243 service->param_values[count],
7249 if (iServiceIndex >= 0) {
7250 return service_ok(iServiceIndex);
7256 * load a service from registry and activate it
7258 bool process_registry_service(const char *service_name)
7261 struct smbconf_service *service = NULL;
7262 TALLOC_CTX *mem_ctx = talloc_stackframe();
7263 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7266 if (conf_ctx == NULL) {
7270 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7272 if (!smbconf_share_exists(conf_ctx, service_name)) {
7274 * Registry does not contain data for this service (yet),
7275 * but make sure lp_load doesn't return false.
7281 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7282 if (!SBC_ERROR_IS_OK(err)) {
7286 ret = process_smbconf_service(service);
7292 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7295 TALLOC_FREE(mem_ctx);
7300 * process_registry_globals
7302 static bool process_registry_globals(void)
7306 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7308 ret = do_parameter("registry shares", "yes", NULL);
7313 return process_registry_service(GLOBAL_NAME);
7316 bool process_registry_shares(void)
7320 struct smbconf_service **service = NULL;
7321 uint32_t num_shares = 0;
7322 TALLOC_CTX *mem_ctx = talloc_stackframe();
7323 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7326 if (conf_ctx == NULL) {
7330 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7331 if (!SBC_ERROR_IS_OK(err)) {
7337 for (count = 0; count < num_shares; count++) {
7338 if (strequal(service[count]->name, GLOBAL_NAME)) {
7341 ret = process_smbconf_service(service[count]);
7348 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7351 TALLOC_FREE(mem_ctx);
7355 #define MAX_INCLUDE_DEPTH 100
7357 static uint8_t include_depth;
7359 static struct file_lists {
7360 struct file_lists *next;
7364 } *file_lists = NULL;
7366 /*******************************************************************
7367 Keep a linked list of all config files so we know when one has changed
7368 it's date and needs to be reloaded.
7369 ********************************************************************/
7371 static void add_to_file_list(const char *fname, const char *subfname)
7373 struct file_lists *f = file_lists;
7376 if (f->name && !strcmp(f->name, fname))
7382 f = SMB_MALLOC_P(struct file_lists);
7385 f->next = file_lists;
7386 f->name = SMB_STRDUP(fname);
7391 f->subfname = SMB_STRDUP(subfname);
7398 f->modtime = file_modtime(subfname);
7400 time_t t = file_modtime(subfname);
7408 * Free the file lists
7410 static void free_file_list(void)
7412 struct file_lists *f;
7413 struct file_lists *next;
7418 SAFE_FREE( f->name );
7419 SAFE_FREE( f->subfname );
7428 * Utility function for outsiders to check if we're running on registry.
7430 bool lp_config_backend_is_registry(void)
7432 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7436 * Utility function to check if the config backend is FILE.
7438 bool lp_config_backend_is_file(void)
7440 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7443 /*******************************************************************
7444 Check if a config file has changed date.
7445 ********************************************************************/
7447 bool lp_file_list_changed(void)
7449 struct file_lists *f = file_lists;
7451 DEBUG(6, ("lp_file_list_changed()\n"));
7456 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7457 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7459 if (conf_ctx == NULL) {
7462 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7465 DEBUGADD(6, ("registry config changed\n"));
7470 n2 = talloc_sub_basic(talloc_tos(),
7471 get_current_username(),
7472 current_user_info.domain,
7477 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7478 f->name, n2, ctime(&f->modtime)));
7480 mod_time = file_modtime(n2);
7483 ((f->modtime != mod_time) ||
7484 (f->subfname == NULL) ||
7485 (strcmp(n2, f->subfname) != 0)))
7488 ("file %s modified: %s\n", n2,
7490 f->modtime = mod_time;
7491 SAFE_FREE(f->subfname);
7492 f->subfname = SMB_STRDUP(n2);
7504 /***************************************************************************
7505 Run standard_sub_basic on netbios name... needed because global_myname
7506 is not accessed through any lp_ macro.
7507 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7508 ***************************************************************************/
7510 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7513 char *netbios_name = talloc_sub_basic(
7514 talloc_tos(), get_current_username(), current_user_info.domain,
7517 ret = set_global_myname(netbios_name);
7518 TALLOC_FREE(netbios_name);
7519 string_set(&Globals.szNetbiosName,global_myname());
7521 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7528 * Initialize iconv conversion descriptors.
7530 * This is called the first time it is needed, and also called again
7531 * every time the configuration is reloaded, because the charset or
7532 * codepage might have changed.
7534 static void init_iconv(void)
7536 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
7537 lp_unix_charset(), lp_display_charset(),
7538 true, global_iconv_handle);
7541 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7543 if (strcmp(*ptr, pszParmValue) != 0) {
7544 string_set(ptr, pszParmValue);
7550 static bool handle_dos_charset(int snum, const char *pszParmValue, char **ptr)
7552 bool is_utf8 = false;
7553 size_t len = strlen(pszParmValue);
7555 if (len == 4 || len == 5) {
7556 /* Don't use StrCaseCmp here as we don't want to
7557 initialize iconv. */
7558 if ((toupper_ascii(pszParmValue[0]) == 'U') &&
7559 (toupper_ascii(pszParmValue[1]) == 'T') &&
7560 (toupper_ascii(pszParmValue[2]) == 'F')) {
7562 if (pszParmValue[3] == '8') {
7566 if (pszParmValue[3] == '-' &&
7567 pszParmValue[4] == '8') {
7574 if (strcmp(*ptr, pszParmValue) != 0) {
7576 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
7577 "be UTF8, using (default value) %s instead.\n",
7578 DEFAULT_DOS_CHARSET));
7579 pszParmValue = DEFAULT_DOS_CHARSET;
7581 string_set(ptr, pszParmValue);
7587 static bool handle_realm(int snum, const char *pszParmValue, char **ptr)
7590 char *realm = strupper_talloc(talloc_tos(), pszParmValue);
7591 char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
7593 ret &= string_set(&Globals.szRealm, pszParmValue);
7594 ret &= string_set(&Globals.szRealmUpper, realm);
7595 ret &= string_set(&Globals.szDnsDomain, dnsdomain);
7597 TALLOC_FREE(dnsdomain);
7602 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7606 ret = set_global_scope(pszParmValue);
7607 string_set(&Globals.szNetbiosScope,global_scope());
7612 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7614 TALLOC_FREE(Globals.szNetbiosAliases);
7615 Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
7616 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7619 /***************************************************************************
7620 Handle the include operation.
7621 ***************************************************************************/
7622 static bool bAllowIncludeRegistry = true;
7624 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7628 if (include_depth >= MAX_INCLUDE_DEPTH) {
7629 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7634 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7635 if (!bAllowIncludeRegistry) {
7638 if (bInGlobalSection) {
7641 ret = process_registry_globals();
7645 DEBUG(1, ("\"include = registry\" only effective "
7646 "in %s section\n", GLOBAL_NAME));
7651 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7652 current_user_info.domain,
7655 add_to_file_list(pszParmValue, fname);
7657 string_set(ptr, fname);
7659 if (file_exist(fname)) {
7662 ret = pm_process(fname, do_section, do_parameter, NULL);
7668 DEBUG(2, ("Can't find include file %s\n", fname));
7673 /***************************************************************************
7674 Handle the interpretation of the copy parameter.
7675 ***************************************************************************/
7677 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7681 struct service serviceTemp;
7683 string_set(ptr, pszParmValue);
7685 init_service(&serviceTemp);
7689 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7691 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7692 if (iTemp == iServiceIndex) {
7693 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7695 copy_service(ServicePtrs[iServiceIndex],
7697 ServicePtrs[iServiceIndex]->copymap);
7701 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7705 free_service(&serviceTemp);
7709 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7711 Globals.ldap_debug_level = lp_int(pszParmValue);
7712 init_ldap_debugging();
7716 /***************************************************************************
7717 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7722 idmap uid = 1000-1999
7725 We only do simple parsing checks here. The strings are parsed into useful
7726 structures in the idmap daemon code.
7728 ***************************************************************************/
7730 /* Some lp_ routines to return idmap [ug]id information */
7732 static uid_t idmap_uid_low, idmap_uid_high;
7733 static gid_t idmap_gid_low, idmap_gid_high;
7735 bool lp_idmap_uid(uid_t *low, uid_t *high)
7737 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7741 *low = idmap_uid_low;
7744 *high = idmap_uid_high;
7749 bool lp_idmap_gid(gid_t *low, gid_t *high)
7751 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7755 *low = idmap_gid_low;
7758 *high = idmap_gid_high;
7763 static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr)
7765 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7770 /* Do some simple checks on "idmap [ug]id" parameter values */
7772 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7774 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7779 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7781 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7786 /***************************************************************************
7787 Handle the DEBUG level list.
7788 ***************************************************************************/
7790 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7792 string_set(ptr, pszParmValueIn);
7793 return debug_parse_levels(pszParmValueIn);
7796 /***************************************************************************
7797 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7798 ***************************************************************************/
7800 static const char *append_ldap_suffix( const char *str )
7802 const char *suffix_string;
7805 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7806 Globals.szLdapSuffix );
7807 if ( !suffix_string ) {
7808 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7812 return suffix_string;
7815 const char *lp_ldap_machine_suffix(void)
7817 if (Globals.szLdapMachineSuffix[0])
7818 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7820 return lp_string(Globals.szLdapSuffix);
7823 const char *lp_ldap_user_suffix(void)
7825 if (Globals.szLdapUserSuffix[0])
7826 return append_ldap_suffix(Globals.szLdapUserSuffix);
7828 return lp_string(Globals.szLdapSuffix);
7831 const char *lp_ldap_group_suffix(void)
7833 if (Globals.szLdapGroupSuffix[0])
7834 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7836 return lp_string(Globals.szLdapSuffix);
7839 const char *lp_ldap_idmap_suffix(void)
7841 if (Globals.szLdapIdmapSuffix[0])
7842 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7844 return lp_string(Globals.szLdapSuffix);
7847 /****************************************************************************
7848 set the value for a P_ENUM
7849 ***************************************************************************/
7851 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7856 for (i = 0; parm->enum_list[i].name; i++) {
7857 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7858 *ptr = parm->enum_list[i].value;
7862 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7863 pszParmValue, parm->label));
7866 /***************************************************************************
7867 ***************************************************************************/
7869 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7871 static int parm_num = -1;
7874 if ( parm_num == -1 )
7875 parm_num = map_parameter( "printing" );
7877 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7882 s = ServicePtrs[snum];
7884 init_printer_values( s );
7890 /***************************************************************************
7891 Initialise a copymap.
7892 ***************************************************************************/
7894 static void init_copymap(struct service *pservice)
7898 TALLOC_FREE(pservice->copymap);
7900 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7901 if (!pservice->copymap)
7903 ("Couldn't allocate copymap!! (size %d)\n",
7904 (int)NUMPARAMETERS));
7906 for (i = 0; i < NUMPARAMETERS; i++)
7907 bitmap_set(pservice->copymap, i);
7910 /***************************************************************************
7911 Return the local pointer to a parameter given a service struct and the
7912 pointer into the default structure.
7913 ***************************************************************************/
7915 static void *lp_local_ptr(struct service *service, void *ptr)
7917 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7920 /***************************************************************************
7921 Return the local pointer to a parameter given the service number and the
7922 pointer into the default structure.
7923 ***************************************************************************/
7925 void *lp_local_ptr_by_snum(int snum, void *ptr)
7927 return lp_local_ptr(ServicePtrs[snum], ptr);
7930 /***************************************************************************
7931 Process a parameter for a particular service number. If snum < 0
7932 then assume we are in the globals.
7933 ***************************************************************************/
7935 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7938 void *parm_ptr = NULL; /* where we are going to store the result */
7939 void *def_ptr = NULL;
7940 struct param_opt_struct **opt_list;
7942 parmnum = map_parameter(pszParmName);
7945 if (strchr(pszParmName, ':') == NULL) {
7946 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7952 * We've got a parametric option
7955 opt_list = (snum < 0)
7956 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7957 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7962 /* if it's already been set by the command line, then we don't
7964 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7968 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7969 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7973 def_ptr = parm_table[parmnum].ptr;
7975 /* we might point at a service, the default service or a global */
7979 if (parm_table[parmnum].p_class == P_GLOBAL) {
7981 ("Global parameter %s found in service section!\n",
7985 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7989 if (!ServicePtrs[snum]->copymap)
7990 init_copymap(ServicePtrs[snum]);
7992 /* this handles the aliases - set the copymap for other entries with
7993 the same data pointer */
7994 for (i = 0; parm_table[i].label; i++)
7995 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7996 bitmap_clear(ServicePtrs[snum]->copymap, i);
7999 /* if it is a special case then go ahead */
8000 if (parm_table[parmnum].special) {
8001 return parm_table[parmnum].special(snum, pszParmValue,
8005 /* now switch on the type of variable it is */
8006 switch (parm_table[parmnum].type)
8009 *(bool *)parm_ptr = lp_bool(pszParmValue);
8013 *(bool *)parm_ptr = !lp_bool(pszParmValue);
8017 *(int *)parm_ptr = lp_int(pszParmValue);
8021 *(char *)parm_ptr = *pszParmValue;
8025 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
8027 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
8032 TALLOC_FREE(*((char ***)parm_ptr));
8033 *(char ***)parm_ptr = str_list_make_v3(
8034 NULL, pszParmValue, NULL);
8038 string_set((char **)parm_ptr, pszParmValue);
8042 string_set((char **)parm_ptr, pszParmValue);
8043 strupper_m(*(char **)parm_ptr);
8047 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
8056 /***************************************************************************
8057 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
8058 FLAG_CMDLINE won't be overridden by loads from smb.conf.
8059 ***************************************************************************/
8061 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
8064 parmnum = map_parameter(pszParmName);
8066 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
8067 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
8070 parm_table[parmnum].flags |= FLAG_CMDLINE;
8072 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
8073 * be grouped in the table, so we don't have to search the
8075 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
8076 parm_table[i].flags |= FLAG_CMDLINE;
8078 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
8079 parm_table[i].flags |= FLAG_CMDLINE;
8083 store_lp_set_cmdline(pszParmName, pszParmValue);
8088 /* it might be parametric */
8089 if (strchr(pszParmName, ':') != NULL) {
8090 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
8092 store_lp_set_cmdline(pszParmName, pszParmValue);
8097 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
8101 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
8103 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
8106 /***************************************************************************
8107 Process a parameter.
8108 ***************************************************************************/
8110 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
8113 if (!bInGlobalSection && bGlobalOnly)
8116 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
8118 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
8119 pszParmName, pszParmValue));
8123 set a option from the commandline in 'a=b' format. Use to support --option
8125 bool lp_set_option(const char *option)
8130 s = talloc_strdup(NULL, option);
8143 /* skip white spaces after the = sign */
8146 } while (*p == ' ');
8148 ret = lp_set_cmdline(s, p);
8153 /**************************************************************************
8154 Print a parameter of the specified type.
8155 ***************************************************************************/
8157 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
8163 for (i = 0; p->enum_list[i].name; i++) {
8164 if (*(int *)ptr == p->enum_list[i].value) {
8166 p->enum_list[i].name);
8173 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
8177 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
8181 fprintf(f, "%d", *(int *)ptr);
8185 fprintf(f, "%c", *(char *)ptr);
8189 char *o = octal_string(*(int *)ptr);
8190 fprintf(f, "%s", o);
8196 if ((char ***)ptr && *(char ***)ptr) {
8197 char **list = *(char ***)ptr;
8198 for (; *list; list++) {
8199 /* surround strings with whitespace in double quotes */
8200 if ( strchr_m( *list, ' ' ) )
8201 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
8203 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
8210 if (*(char **)ptr) {
8211 fprintf(f, "%s", *(char **)ptr);
8219 /***************************************************************************
8220 Check if two parameters are equal.
8221 ***************************************************************************/
8223 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8228 return (*((bool *)ptr1) == *((bool *)ptr2));
8233 return (*((int *)ptr1) == *((int *)ptr2));
8236 return (*((char *)ptr1) == *((char *)ptr2));
8239 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8244 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8249 return (p1 == p2 || strequal(p1, p2));
8257 /***************************************************************************
8258 Initialize any local varients in the sDefault table.
8259 ***************************************************************************/
8261 void init_locals(void)
8266 /***************************************************************************
8267 Process a new section (service). At this stage all sections are services.
8268 Later we'll have special sections that permit server parameters to be set.
8269 Returns True on success, False on failure.
8270 ***************************************************************************/
8272 static bool do_section(const char *pszSectionName, void *userdata)
8275 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8276 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8279 /* if we were in a global section then do the local inits */
8280 if (bInGlobalSection && !isglobal)
8283 /* if we've just struck a global section, note the fact. */
8284 bInGlobalSection = isglobal;
8286 /* check for multiple global sections */
8287 if (bInGlobalSection) {
8288 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8292 if (!bInGlobalSection && bGlobalOnly)
8295 /* if we have a current service, tidy it up before moving on */
8298 if (iServiceIndex >= 0)
8299 bRetval = service_ok(iServiceIndex);
8301 /* if all is still well, move to the next record in the services array */
8303 /* We put this here to avoid an odd message order if messages are */
8304 /* issued by the post-processing of a previous section. */
8305 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8307 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8309 DEBUG(0, ("Failed to add a new service\n"));
8312 /* Clean all parametric options for service */
8313 /* They will be added during parsing again */
8314 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
8321 /***************************************************************************
8322 Determine if a partcular base parameter is currentl set to the default value.
8323 ***************************************************************************/
8325 static bool is_default(int i)
8327 if (!defaults_saved)
8329 switch (parm_table[i].type) {
8331 return str_list_equal((const char **)parm_table[i].def.lvalue,
8332 *(const char ***)parm_table[i].ptr);
8335 return strequal(parm_table[i].def.svalue,
8336 *(char **)parm_table[i].ptr);
8339 return parm_table[i].def.bvalue ==
8340 *(bool *)parm_table[i].ptr;
8342 return parm_table[i].def.cvalue ==
8343 *(char *)parm_table[i].ptr;
8347 return parm_table[i].def.ivalue ==
8348 *(int *)parm_table[i].ptr;
8355 /***************************************************************************
8356 Display the contents of the global structure.
8357 ***************************************************************************/
8359 static void dump_globals(FILE *f)
8362 struct param_opt_struct *data;
8364 fprintf(f, "[global]\n");
8366 for (i = 0; parm_table[i].label; i++)
8367 if (parm_table[i].p_class == P_GLOBAL &&
8368 !(parm_table[i].flags & FLAG_META) &&
8369 parm_table[i].ptr &&
8370 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8371 if (defaults_saved && is_default(i))
8373 fprintf(f, "\t%s = ", parm_table[i].label);
8374 print_parameter(&parm_table[i], parm_table[i].ptr, f);
8377 if (Globals.param_opt != NULL) {
8378 data = Globals.param_opt;
8380 fprintf(f, "\t%s = %s\n", data->key, data->value);
8387 /***************************************************************************
8388 Return True if a local parameter is currently set to the global default.
8389 ***************************************************************************/
8391 bool lp_is_default(int snum, struct parm_struct *parm)
8393 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8395 return equal_parameter(parm->type,
8396 ((char *)ServicePtrs[snum]) + pdiff,
8397 ((char *)&sDefault) + pdiff);
8400 /***************************************************************************
8401 Display the contents of a single services record.
8402 ***************************************************************************/
8404 static void dump_a_service(struct service *pService, FILE * f)
8407 struct param_opt_struct *data;
8409 if (pService != &sDefault)
8410 fprintf(f, "[%s]\n", pService->szService);
8412 for (i = 0; parm_table[i].label; i++) {
8414 if (parm_table[i].p_class == P_LOCAL &&
8415 !(parm_table[i].flags & FLAG_META) &&
8416 parm_table[i].ptr &&
8417 (*parm_table[i].label != '-') &&
8418 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8420 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8422 if (pService == &sDefault) {
8423 if (defaults_saved && is_default(i))
8426 if (equal_parameter(parm_table[i].type,
8427 ((char *)pService) +
8429 ((char *)&sDefault) +
8434 fprintf(f, "\t%s = ", parm_table[i].label);
8435 print_parameter(&parm_table[i],
8436 ((char *)pService) + pdiff, f);
8441 if (pService->param_opt != NULL) {
8442 data = pService->param_opt;
8444 fprintf(f, "\t%s = %s\n", data->key, data->value);
8450 /***************************************************************************
8451 Display the contents of a parameter of a single services record.
8452 ***************************************************************************/
8454 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8457 bool result = False;
8460 fstring local_parm_name;
8462 const char *parm_opt_value;
8464 /* check for parametrical option */
8465 fstrcpy( local_parm_name, parm_name);
8466 parm_opt = strchr( local_parm_name, ':');
8471 if (strlen(parm_opt)) {
8472 parm_opt_value = lp_parm_const_string( snum,
8473 local_parm_name, parm_opt, NULL);
8474 if (parm_opt_value) {
8475 printf( "%s\n", parm_opt_value);
8482 /* check for a key and print the value */
8489 for (i = 0; parm_table[i].label; i++) {
8490 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8491 !(parm_table[i].flags & FLAG_META) &&
8492 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8493 parm_table[i].ptr &&
8494 (*parm_table[i].label != '-') &&
8495 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8500 ptr = parm_table[i].ptr;
8502 struct service *pService = ServicePtrs[snum];
8503 ptr = ((char *)pService) +
8504 PTR_DIFF(parm_table[i].ptr, &sDefault);
8507 print_parameter(&parm_table[i],
8518 /***************************************************************************
8519 Return info about the requested parameter (given as a string).
8520 Return NULL when the string is not a valid parameter name.
8521 ***************************************************************************/
8523 struct parm_struct *lp_get_parameter(const char *param_name)
8525 int num = map_parameter(param_name);
8531 return &parm_table[num];
8534 /***************************************************************************
8535 Return info about the next parameter in a service.
8536 snum==GLOBAL_SECTION_SNUM gives the globals.
8537 Return NULL when out of parameters.
8538 ***************************************************************************/
8540 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8543 /* do the globals */
8544 for (; parm_table[*i].label; (*i)++) {
8545 if (parm_table[*i].p_class == P_SEPARATOR)
8546 return &parm_table[(*i)++];
8548 if (!parm_table[*i].ptr
8549 || (*parm_table[*i].label == '-'))
8553 && (parm_table[*i].ptr ==
8554 parm_table[(*i) - 1].ptr))
8557 if (is_default(*i) && !allparameters)
8560 return &parm_table[(*i)++];
8563 struct service *pService = ServicePtrs[snum];
8565 for (; parm_table[*i].label; (*i)++) {
8566 if (parm_table[*i].p_class == P_SEPARATOR)
8567 return &parm_table[(*i)++];
8569 if (parm_table[*i].p_class == P_LOCAL &&
8570 parm_table[*i].ptr &&
8571 (*parm_table[*i].label != '-') &&
8573 (parm_table[*i].ptr !=
8574 parm_table[(*i) - 1].ptr)))
8577 PTR_DIFF(parm_table[*i].ptr,
8580 if (allparameters ||
8581 !equal_parameter(parm_table[*i].type,
8582 ((char *)pService) +
8584 ((char *)&sDefault) +
8587 return &parm_table[(*i)++];
8598 /***************************************************************************
8599 Display the contents of a single copy structure.
8600 ***************************************************************************/
8601 static void dump_copy_map(bool *pcopymap)
8607 printf("\n\tNon-Copied parameters:\n");
8609 for (i = 0; parm_table[i].label; i++)
8610 if (parm_table[i].p_class == P_LOCAL &&
8611 parm_table[i].ptr && !pcopymap[i] &&
8612 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8614 printf("\t\t%s\n", parm_table[i].label);
8619 /***************************************************************************
8620 Return TRUE if the passed service number is within range.
8621 ***************************************************************************/
8623 bool lp_snum_ok(int iService)
8625 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8628 /***************************************************************************
8629 Auto-load some home services.
8630 ***************************************************************************/
8632 static void lp_add_auto_services(char *str)
8642 s = SMB_STRDUP(str);
8646 homes = lp_servicenumber(HOMES_NAME);
8648 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8649 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8652 if (lp_servicenumber(p) >= 0)
8655 home = get_user_home_dir(talloc_tos(), p);
8657 if (home && home[0] && homes >= 0)
8658 lp_add_home(p, homes, p, home);
8665 /***************************************************************************
8666 Auto-load one printer.
8667 ***************************************************************************/
8669 void lp_add_one_printer(const char *name, const char *comment,
8670 const char *location, void *pdata)
8672 int printers = lp_servicenumber(PRINTERS_NAME);
8675 if (lp_servicenumber(name) < 0) {
8676 lp_add_printer(name, printers);
8677 if ((i = lp_servicenumber(name)) >= 0) {
8678 string_set(&ServicePtrs[i]->comment, comment);
8679 ServicePtrs[i]->autoloaded = True;
8684 /***************************************************************************
8685 Have we loaded a services file yet?
8686 ***************************************************************************/
8688 bool lp_loaded(void)
8693 /***************************************************************************
8694 Unload unused services.
8695 ***************************************************************************/
8697 void lp_killunused(struct smbd_server_connection *sconn,
8698 bool (*snumused) (struct smbd_server_connection *, int))
8701 for (i = 0; i < iNumServices; i++) {
8705 /* don't kill autoloaded or usershare services */
8706 if ( ServicePtrs[i]->autoloaded ||
8707 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8711 if (!snumused || !snumused(sconn, i)) {
8712 free_service_byindex(i);
8718 * Kill all except autoloaded and usershare services - convenience wrapper
8720 void lp_kill_all_services(void)
8722 lp_killunused(NULL, NULL);
8725 /***************************************************************************
8727 ***************************************************************************/
8729 void lp_killservice(int iServiceIn)
8731 if (VALID(iServiceIn)) {
8732 free_service_byindex(iServiceIn);
8736 /***************************************************************************
8737 Save the curent values of all global and sDefault parameters into the
8738 defaults union. This allows swat and testparm to show only the
8739 changed (ie. non-default) parameters.
8740 ***************************************************************************/
8742 static void lp_save_defaults(void)
8745 for (i = 0; parm_table[i].label; i++) {
8746 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8748 switch (parm_table[i].type) {
8750 parm_table[i].def.lvalue = str_list_copy(
8751 NULL, *(const char ***)parm_table[i].ptr);
8755 if (parm_table[i].ptr) {
8756 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8758 parm_table[i].def.svalue = NULL;
8763 parm_table[i].def.bvalue =
8764 *(bool *)parm_table[i].ptr;
8767 parm_table[i].def.cvalue =
8768 *(char *)parm_table[i].ptr;
8773 parm_table[i].def.ivalue =
8774 *(int *)parm_table[i].ptr;
8780 defaults_saved = True;
8783 /***********************************************************
8784 If we should send plaintext/LANMAN passwords in the clinet
8785 ************************************************************/
8787 static void set_allowed_client_auth(void)
8789 if (Globals.bClientNTLMv2Auth) {
8790 Globals.bClientLanManAuth = False;
8792 if (!Globals.bClientLanManAuth) {
8793 Globals.bClientPlaintextAuth = False;
8797 /***************************************************************************
8799 The following code allows smbd to read a user defined share file.
8800 Yes, this is my intent. Yes, I'm comfortable with that...
8802 THE FOLLOWING IS SECURITY CRITICAL CODE.
8804 It washes your clothes, it cleans your house, it guards you while you sleep...
8805 Do not f%^k with it....
8806 ***************************************************************************/
8808 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8810 /***************************************************************************
8811 Check allowed stat state of a usershare file.
8812 Ensure we print out who is dicking with us so the admin can
8813 get their sorry ass fired.
8814 ***************************************************************************/
8816 static bool check_usershare_stat(const char *fname,
8817 const SMB_STRUCT_STAT *psbuf)
8819 if (!S_ISREG(psbuf->st_ex_mode)) {
8820 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8821 "not a regular file\n",
8822 fname, (unsigned int)psbuf->st_ex_uid ));
8826 /* Ensure this doesn't have the other write bit set. */
8827 if (psbuf->st_ex_mode & S_IWOTH) {
8828 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8829 "public write. Refusing to allow as a usershare file.\n",
8830 fname, (unsigned int)psbuf->st_ex_uid ));
8834 /* Should be 10k or less. */
8835 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8836 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8837 "too large (%u) to be a user share file.\n",
8838 fname, (unsigned int)psbuf->st_ex_uid,
8839 (unsigned int)psbuf->st_ex_size ));
8846 /***************************************************************************
8847 Parse the contents of a usershare file.
8848 ***************************************************************************/
8850 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8851 SMB_STRUCT_STAT *psbuf,
8852 const char *servicename,
8856 char **pp_sharepath,
8858 char **pp_cp_servicename,
8859 struct security_descriptor **ppsd,
8862 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8863 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8866 SMB_STRUCT_STAT sbuf;
8867 char *sharepath = NULL;
8868 char *comment = NULL;
8870 *pp_sharepath = NULL;
8873 *pallow_guest = False;
8876 return USERSHARE_MALFORMED_FILE;
8879 if (strcmp(lines[0], "#VERSION 1") == 0) {
8881 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8884 return USERSHARE_MALFORMED_FILE;
8887 return USERSHARE_BAD_VERSION;
8890 if (strncmp(lines[1], "path=", 5) != 0) {
8891 return USERSHARE_MALFORMED_PATH;
8894 sharepath = talloc_strdup(ctx, &lines[1][5]);
8896 return USERSHARE_POSIX_ERR;
8898 trim_string(sharepath, " ", " ");
8900 if (strncmp(lines[2], "comment=", 8) != 0) {
8901 return USERSHARE_MALFORMED_COMMENT_DEF;
8904 comment = talloc_strdup(ctx, &lines[2][8]);
8906 return USERSHARE_POSIX_ERR;
8908 trim_string(comment, " ", " ");
8909 trim_char(comment, '"', '"');
8911 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8912 return USERSHARE_MALFORMED_ACL_DEF;
8915 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8916 return USERSHARE_ACL_ERR;
8920 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8921 return USERSHARE_MALFORMED_ACL_DEF;
8923 if (lines[4][9] == 'y') {
8924 *pallow_guest = True;
8927 /* Backwards compatible extension to file version #2. */
8929 if (strncmp(lines[5], "sharename=", 10) != 0) {
8930 return USERSHARE_MALFORMED_SHARENAME_DEF;
8932 if (!strequal(&lines[5][10], servicename)) {
8933 return USERSHARE_BAD_SHARENAME;
8935 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8936 if (!*pp_cp_servicename) {
8937 return USERSHARE_POSIX_ERR;
8942 if (*pp_cp_servicename == NULL) {
8943 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8944 if (!*pp_cp_servicename) {
8945 return USERSHARE_POSIX_ERR;
8949 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8950 /* Path didn't change, no checks needed. */
8951 *pp_sharepath = sharepath;
8952 *pp_comment = comment;
8953 return USERSHARE_OK;
8956 /* The path *must* be absolute. */
8957 if (sharepath[0] != '/') {
8958 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8959 servicename, sharepath));
8960 return USERSHARE_PATH_NOT_ABSOLUTE;
8963 /* If there is a usershare prefix deny list ensure one of these paths
8964 doesn't match the start of the user given path. */
8965 if (prefixdenylist) {
8967 for ( i=0; prefixdenylist[i]; i++ ) {
8968 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8969 servicename, i, prefixdenylist[i], sharepath ));
8970 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8971 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8972 "usershare prefix deny list entries.\n",
8973 servicename, sharepath));
8974 return USERSHARE_PATH_IS_DENIED;
8979 /* If there is a usershare prefix allow list ensure one of these paths
8980 does match the start of the user given path. */
8982 if (prefixallowlist) {
8984 for ( i=0; prefixallowlist[i]; i++ ) {
8985 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8986 servicename, i, prefixallowlist[i], sharepath ));
8987 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8991 if (prefixallowlist[i] == NULL) {
8992 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8993 "usershare prefix allow list entries.\n",
8994 servicename, sharepath));
8995 return USERSHARE_PATH_NOT_ALLOWED;
8999 /* Ensure this is pointing to a directory. */
9000 dp = sys_opendir(sharepath);
9003 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
9004 servicename, sharepath));
9005 return USERSHARE_PATH_NOT_DIRECTORY;
9008 /* Ensure the owner of the usershare file has permission to share
9011 if (sys_stat(sharepath, &sbuf, false) == -1) {
9012 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
9013 servicename, sharepath, strerror(errno) ));
9015 return USERSHARE_POSIX_ERR;
9020 if (!S_ISDIR(sbuf.st_ex_mode)) {
9021 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
9022 servicename, sharepath ));
9023 return USERSHARE_PATH_NOT_DIRECTORY;
9026 /* Check if sharing is restricted to owner-only. */
9027 /* psbuf is the stat of the usershare definition file,
9028 sbuf is the stat of the target directory to be shared. */
9030 if (lp_usershare_owner_only()) {
9031 /* root can share anything. */
9032 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
9033 return USERSHARE_PATH_NOT_ALLOWED;
9037 *pp_sharepath = sharepath;
9038 *pp_comment = comment;
9039 return USERSHARE_OK;
9042 /***************************************************************************
9043 Deal with a usershare file.
9046 -1 - Bad name, invalid contents.
9047 - service name already existed and not a usershare, problem
9048 with permissions to share directory etc.
9049 ***************************************************************************/
9051 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
9053 SMB_STRUCT_STAT sbuf;
9054 SMB_STRUCT_STAT lsbuf;
9056 char *sharepath = NULL;
9057 char *comment = NULL;
9058 char *cp_service_name = NULL;
9059 char **lines = NULL;
9063 TALLOC_CTX *ctx = talloc_stackframe();
9064 struct security_descriptor *psd = NULL;
9065 bool guest_ok = False;
9066 char *canon_name = NULL;
9067 bool added_service = false;
9070 /* Ensure share name doesn't contain invalid characters. */
9071 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
9072 DEBUG(0,("process_usershare_file: share name %s contains "
9073 "invalid characters (any of %s)\n",
9074 file_name, INVALID_SHARENAME_CHARS ));
9078 canon_name = canonicalize_servicename(ctx, file_name);
9083 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
9088 /* Minimize the race condition by doing an lstat before we
9089 open and fstat. Ensure this isn't a symlink link. */
9091 if (sys_lstat(fname, &lsbuf, false) != 0) {
9092 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
9093 fname, strerror(errno) ));
9097 /* This must be a regular file, not a symlink, directory or
9098 other strange filetype. */
9099 if (!check_usershare_stat(fname, &lsbuf)) {
9104 TDB_DATA data = dbwrap_fetch_bystring(
9105 ServiceHash, canon_name, canon_name);
9109 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
9110 iService = *(int *)data.dptr;
9114 if (iService != -1 &&
9115 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9116 &lsbuf.st_ex_mtime) == 0) {
9117 /* Nothing changed - Mark valid and return. */
9118 DEBUG(10,("process_usershare_file: service %s not changed.\n",
9120 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9125 /* Try and open the file read only - no symlinks allowed. */
9127 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
9129 fd = sys_open(fname, O_RDONLY, 0);
9133 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
9134 fname, strerror(errno) ));
9138 /* Now fstat to be *SURE* it's a regular file. */
9139 if (sys_fstat(fd, &sbuf, false) != 0) {
9141 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
9142 fname, strerror(errno) ));
9146 /* Is it the same dev/inode as was lstated ? */
9147 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
9149 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
9150 "Symlink spoofing going on ?\n", fname ));
9154 /* This must be a regular file, not a symlink, directory or
9155 other strange filetype. */
9156 if (!check_usershare_stat(fname, &sbuf)) {
9160 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
9163 if (lines == NULL) {
9164 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
9165 fname, (unsigned int)sbuf.st_ex_uid ));
9169 if (parse_usershare_file(ctx, &sbuf, file_name,
9170 iService, lines, numlines, &sharepath,
9171 &comment, &cp_service_name,
9172 &psd, &guest_ok) != USERSHARE_OK) {
9176 /* Everything ok - add the service possibly using a template. */
9178 const struct service *sp = &sDefault;
9179 if (snum_template != -1) {
9180 sp = ServicePtrs[snum_template];
9183 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
9184 DEBUG(0, ("process_usershare_file: Failed to add "
9185 "new service %s\n", cp_service_name));
9189 added_service = true;
9191 /* Read only is controlled by usershare ACL below. */
9192 ServicePtrs[iService]->bRead_only = False;
9195 /* Write the ACL of the new/modified share. */
9196 if (!set_share_security(canon_name, psd)) {
9197 DEBUG(0, ("process_usershare_file: Failed to set share "
9198 "security for user share %s\n",
9203 /* If from a template it may be marked invalid. */
9204 ServicePtrs[iService]->valid = True;
9206 /* Set the service as a valid usershare. */
9207 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9209 /* Set guest access. */
9210 if (lp_usershare_allow_guests()) {
9211 ServicePtrs[iService]->bGuest_ok = guest_ok;
9214 /* And note when it was loaded. */
9215 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
9216 string_set(&ServicePtrs[iService]->szPath, sharepath);
9217 string_set(&ServicePtrs[iService]->comment, comment);
9223 if (ret == -1 && iService != -1 && added_service) {
9224 lp_remove_service(iService);
9232 /***************************************************************************
9233 Checks if a usershare entry has been modified since last load.
9234 ***************************************************************************/
9236 static bool usershare_exists(int iService, struct timespec *last_mod)
9238 SMB_STRUCT_STAT lsbuf;
9239 const char *usersharepath = Globals.szUsersharePath;
9242 if (asprintf(&fname, "%s/%s",
9244 ServicePtrs[iService]->szService) < 0) {
9248 if (sys_lstat(fname, &lsbuf, false) != 0) {
9253 if (!S_ISREG(lsbuf.st_ex_mode)) {
9259 *last_mod = lsbuf.st_ex_mtime;
9263 /***************************************************************************
9264 Load a usershare service by name. Returns a valid servicenumber or -1.
9265 ***************************************************************************/
9267 int load_usershare_service(const char *servicename)
9269 SMB_STRUCT_STAT sbuf;
9270 const char *usersharepath = Globals.szUsersharePath;
9271 int max_user_shares = Globals.iUsershareMaxShares;
9272 int snum_template = -1;
9274 if (*usersharepath == 0 || max_user_shares == 0) {
9278 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9279 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9280 usersharepath, strerror(errno) ));
9284 if (!S_ISDIR(sbuf.st_ex_mode)) {
9285 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9291 * This directory must be owned by root, and have the 't' bit set.
9292 * It also must not be writable by "other".
9296 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9298 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9300 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9301 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9306 /* Ensure the template share exists if it's set. */
9307 if (Globals.szUsershareTemplateShare[0]) {
9308 /* We can't use lp_servicenumber here as we are recommending that
9309 template shares have -valid=False set. */
9310 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9311 if (ServicePtrs[snum_template]->szService &&
9312 strequal(ServicePtrs[snum_template]->szService,
9313 Globals.szUsershareTemplateShare)) {
9318 if (snum_template == -1) {
9319 DEBUG(0,("load_usershare_service: usershare template share %s "
9320 "does not exist.\n",
9321 Globals.szUsershareTemplateShare ));
9326 return process_usershare_file(usersharepath, servicename, snum_template);
9329 /***************************************************************************
9330 Load all user defined shares from the user share directory.
9331 We only do this if we're enumerating the share list.
9332 This is the function that can delete usershares that have
9334 ***************************************************************************/
9336 int load_usershare_shares(struct smbd_server_connection *sconn)
9339 SMB_STRUCT_STAT sbuf;
9340 SMB_STRUCT_DIRENT *de;
9341 int num_usershares = 0;
9342 int max_user_shares = Globals.iUsershareMaxShares;
9343 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9344 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9345 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9347 int snum_template = -1;
9348 const char *usersharepath = Globals.szUsersharePath;
9349 int ret = lp_numservices();
9351 if (max_user_shares == 0 || *usersharepath == '\0') {
9352 return lp_numservices();
9355 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9356 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9357 usersharepath, strerror(errno) ));
9362 * This directory must be owned by root, and have the 't' bit set.
9363 * It also must not be writable by "other".
9367 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9369 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9371 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9372 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9377 /* Ensure the template share exists if it's set. */
9378 if (Globals.szUsershareTemplateShare[0]) {
9379 /* We can't use lp_servicenumber here as we are recommending that
9380 template shares have -valid=False set. */
9381 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9382 if (ServicePtrs[snum_template]->szService &&
9383 strequal(ServicePtrs[snum_template]->szService,
9384 Globals.szUsershareTemplateShare)) {
9389 if (snum_template == -1) {
9390 DEBUG(0,("load_usershare_shares: usershare template share %s "
9391 "does not exist.\n",
9392 Globals.szUsershareTemplateShare ));
9397 /* Mark all existing usershares as pending delete. */
9398 for (iService = iNumServices - 1; iService >= 0; iService--) {
9399 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9400 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9404 dp = sys_opendir(usersharepath);
9406 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9407 usersharepath, strerror(errno) ));
9411 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9412 (de = sys_readdir(dp));
9413 num_dir_entries++ ) {
9415 const char *n = de->d_name;
9417 /* Ignore . and .. */
9419 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9425 /* Temporary file used when creating a share. */
9426 num_tmp_dir_entries++;
9429 /* Allow 20% tmp entries. */
9430 if (num_tmp_dir_entries > allowed_tmp_entries) {
9431 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9432 "in directory %s\n",
9433 num_tmp_dir_entries, usersharepath));
9437 r = process_usershare_file(usersharepath, n, snum_template);
9439 /* Update the services count. */
9441 if (num_usershares >= max_user_shares) {
9442 DEBUG(0,("load_usershare_shares: max user shares reached "
9443 "on file %s in directory %s\n",
9444 n, usersharepath ));
9447 } else if (r == -1) {
9448 num_bad_dir_entries++;
9451 /* Allow 20% bad entries. */
9452 if (num_bad_dir_entries > allowed_bad_entries) {
9453 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9454 "in directory %s\n",
9455 num_bad_dir_entries, usersharepath));
9459 /* Allow 20% bad entries. */
9460 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9461 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9462 "in directory %s\n",
9463 num_dir_entries, usersharepath));
9470 /* Sweep through and delete any non-refreshed usershares that are
9471 not currently in use. */
9472 for (iService = iNumServices - 1; iService >= 0; iService--) {
9473 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9474 if (conn_snum_used(sconn, iService)) {
9477 /* Remove from the share ACL db. */
9478 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9479 lp_servicename(iService) ));
9480 delete_share_security(lp_servicename(iService));
9481 free_service_byindex(iService);
9485 return lp_numservices();
9488 /********************************************************
9489 Destroy global resources allocated in this file
9490 ********************************************************/
9492 void gfree_loadparm(void)
9498 /* Free resources allocated to services */
9500 for ( i = 0; i < iNumServices; i++ ) {
9502 free_service_byindex(i);
9506 SAFE_FREE( ServicePtrs );
9509 /* Now release all resources allocated to global
9510 parameters and the default service */
9512 free_global_parameters();
9516 /***************************************************************************
9517 Allow client apps to specify that they are a client
9518 ***************************************************************************/
9519 void lp_set_in_client(bool b)
9525 /***************************************************************************
9526 Determine if we're running in a client app
9527 ***************************************************************************/
9528 bool lp_is_in_client(void)
9533 /***************************************************************************
9534 Load the services array from the services file. Return True on success,
9536 ***************************************************************************/
9538 static bool lp_load_ex(const char *pszFname,
9542 bool initialize_globals,
9543 bool allow_include_registry,
9544 bool allow_registry_shares)
9551 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9553 bInGlobalSection = True;
9554 bGlobalOnly = global_only;
9555 bAllowIncludeRegistry = allow_include_registry;
9557 init_globals(initialize_globals);
9561 if (save_defaults) {
9566 free_param_opts(&Globals.param_opt);
9568 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
9570 /* We get sections first, so have to start 'behind' to make up */
9573 if (lp_config_backend_is_file()) {
9574 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9575 current_user_info.domain,
9578 smb_panic("lp_load_ex: out of memory");
9581 add_to_file_list(pszFname, n2);
9583 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9586 /* finish up the last section */
9587 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9589 if (iServiceIndex >= 0) {
9590 bRetval = service_ok(iServiceIndex);
9594 if (lp_config_backend_is_registry()) {
9595 /* config backend changed to registry in config file */
9597 * We need to use this extra global variable here to
9598 * survive restart: init_globals uses this as a default
9599 * for ConfigBackend. Otherwise, init_globals would
9600 * send us into an endless loop here.
9602 config_backend = CONFIG_BACKEND_REGISTRY;
9604 DEBUG(1, ("lp_load_ex: changing to config backend "
9607 lp_kill_all_services();
9608 return lp_load_ex(pszFname, global_only, save_defaults,
9609 add_ipc, initialize_globals,
9610 allow_include_registry,
9611 allow_registry_shares);
9613 } else if (lp_config_backend_is_registry()) {
9614 bRetval = process_registry_globals();
9616 DEBUG(0, ("Illegal config backend given: %d\n",
9617 lp_config_backend()));
9621 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9622 bRetval = process_registry_shares();
9625 lp_add_auto_services(lp_auto_services());
9628 /* When 'restrict anonymous = 2' guest connections to ipc$
9630 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9631 if ( lp_enable_asu_support() ) {
9632 lp_add_ipc("ADMIN$", false);
9637 set_default_server_announce_type();
9638 set_allowed_client_auth();
9640 if (lp_security() == SEC_SHARE) {
9641 DEBUG(1, ("WARNING: The security=share option is deprecated\n"));
9642 } else if (lp_security() == SEC_SERVER) {
9643 DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
9646 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
9647 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
9648 lp_passwordserver()));
9653 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9654 /* if bWINSsupport is true and we are in the client */
9655 if (lp_is_in_client() && Globals.bWINSsupport) {
9656 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9661 fault_configure(smb_panic_s3);
9663 bAllowIncludeRegistry = true;
9668 bool lp_load(const char *pszFname,
9672 bool initialize_globals)
9674 return lp_load_ex(pszFname,
9679 true, /* allow_include_registry */
9680 false); /* allow_registry_shares*/
9683 bool lp_load_initial_only(const char *pszFname)
9685 return lp_load_ex(pszFname,
9686 true, /* global only */
9687 false, /* save_defaults */
9688 false, /* add_ipc */
9689 true, /* initialize_globals */
9690 false, /* allow_include_registry */
9691 false); /* allow_registry_shares*/
9694 bool lp_load_with_registry_shares(const char *pszFname,
9698 bool initialize_globals)
9700 return lp_load_ex(pszFname,
9705 true, /* allow_include_registry */
9706 true); /* allow_registry_shares*/
9709 /***************************************************************************
9710 Return the max number of services.
9711 ***************************************************************************/
9713 int lp_numservices(void)
9715 return (iNumServices);
9718 /***************************************************************************
9719 Display the contents of the services array in human-readable form.
9720 ***************************************************************************/
9722 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9727 defaults_saved = False;
9731 dump_a_service(&sDefault, f);
9733 for (iService = 0; iService < maxtoprint; iService++) {
9735 lp_dump_one(f, show_defaults, iService);
9739 /***************************************************************************
9740 Display the contents of one service in human-readable form.
9741 ***************************************************************************/
9743 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9746 if (ServicePtrs[snum]->szService[0] == '\0')
9748 dump_a_service(ServicePtrs[snum], f);
9752 /***************************************************************************
9753 Return the number of the service with the given name, or -1 if it doesn't
9754 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9755 getservicebyname()! This works ONLY if all services have been loaded, and
9756 does not copy the found service.
9757 ***************************************************************************/
9759 int lp_servicenumber(const char *pszServiceName)
9762 fstring serviceName;
9764 if (!pszServiceName) {
9765 return GLOBAL_SECTION_SNUM;
9768 for (iService = iNumServices - 1; iService >= 0; iService--) {
9769 if (VALID(iService) && ServicePtrs[iService]->szService) {
9771 * The substitution here is used to support %U is
9774 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9775 standard_sub_basic(get_current_username(),
9776 current_user_info.domain,
9777 serviceName,sizeof(serviceName));
9778 if (strequal(serviceName, pszServiceName)) {
9784 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9785 struct timespec last_mod;
9787 if (!usershare_exists(iService, &last_mod)) {
9788 /* Remove the share security tdb entry for it. */
9789 delete_share_security(lp_servicename(iService));
9790 /* Remove it from the array. */
9791 free_service_byindex(iService);
9792 /* Doesn't exist anymore. */
9793 return GLOBAL_SECTION_SNUM;
9796 /* Has it been modified ? If so delete and reload. */
9797 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9799 /* Remove it from the array. */
9800 free_service_byindex(iService);
9801 /* and now reload it. */
9802 iService = load_usershare_service(pszServiceName);
9807 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9808 return GLOBAL_SECTION_SNUM;
9814 bool share_defined(const char *service_name)
9816 return (lp_servicenumber(service_name) != -1);
9819 /*******************************************************************
9820 A useful volume label function.
9821 ********************************************************************/
9823 const char *volume_label(int snum)
9826 const char *label = lp_volume(snum);
9828 label = lp_servicename(snum);
9831 /* This returns a 33 byte guarenteed null terminated string. */
9832 ret = talloc_strndup(talloc_tos(), label, 32);
9839 /*******************************************************************
9840 Set the server type we will announce as via nmbd.
9841 ********************************************************************/
9843 static void set_default_server_announce_type(void)
9845 default_server_announce = 0;
9846 default_server_announce |= SV_TYPE_WORKSTATION;
9847 default_server_announce |= SV_TYPE_SERVER;
9848 default_server_announce |= SV_TYPE_SERVER_UNIX;
9850 /* note that the flag should be set only if we have a
9851 printer service but nmbd doesn't actually load the
9852 services so we can't tell --jerry */
9854 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9856 switch (lp_announce_as()) {
9857 case ANNOUNCE_AS_NT_SERVER:
9858 default_server_announce |= SV_TYPE_SERVER_NT;
9859 /* fall through... */
9860 case ANNOUNCE_AS_NT_WORKSTATION:
9861 default_server_announce |= SV_TYPE_NT;
9863 case ANNOUNCE_AS_WIN95:
9864 default_server_announce |= SV_TYPE_WIN95_PLUS;
9866 case ANNOUNCE_AS_WFW:
9867 default_server_announce |= SV_TYPE_WFW;
9873 switch (lp_server_role()) {
9874 case ROLE_DOMAIN_MEMBER:
9875 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9877 case ROLE_DOMAIN_PDC:
9878 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9880 case ROLE_DOMAIN_BDC:
9881 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9883 case ROLE_STANDALONE:
9887 if (lp_time_server())
9888 default_server_announce |= SV_TYPE_TIME_SOURCE;
9890 if (lp_host_msdfs())
9891 default_server_announce |= SV_TYPE_DFS_SERVER;
9894 /***********************************************************
9895 If we are PDC then prefer us as DMB
9896 ************************************************************/
9898 bool lp_domain_master(void)
9900 if (Globals.iDomainMaster == Auto)
9901 return (lp_server_role() == ROLE_DOMAIN_PDC);
9903 return (bool)Globals.iDomainMaster;
9906 /***********************************************************
9907 If we are PDC then prefer us as DMB
9908 ************************************************************/
9910 bool lp_domain_master_true_or_auto(void)
9912 if (Globals.iDomainMaster) /* auto or yes */
9918 /***********************************************************
9919 If we are DMB then prefer us as LMB
9920 ************************************************************/
9922 bool lp_preferred_master(void)
9924 if (Globals.iPreferredMaster == Auto)
9925 return (lp_local_master() && lp_domain_master());
9927 return (bool)Globals.iPreferredMaster;
9930 /*******************************************************************
9932 ********************************************************************/
9934 void lp_remove_service(int snum)
9936 ServicePtrs[snum]->valid = False;
9937 invalid_services[num_invalid_services++] = snum;
9940 /*******************************************************************
9942 ********************************************************************/
9944 void lp_copy_service(int snum, const char *new_name)
9946 do_section(new_name, NULL);
9948 snum = lp_servicenumber(new_name);
9950 lp_do_parameter(snum, "copy", lp_servicename(snum));
9955 /*******************************************************************
9956 Get the default server type we will announce as via nmbd.
9957 ********************************************************************/
9959 int lp_default_server_announce(void)
9961 return default_server_announce;
9964 /*******************************************************************
9965 Split the announce version into major and minor numbers.
9966 ********************************************************************/
9968 int lp_major_announce_version(void)
9970 static bool got_major = False;
9971 static int major_version = DEFAULT_MAJOR_VERSION;
9976 return major_version;
9979 if ((vers = lp_announce_version()) == NULL)
9980 return major_version;
9982 if ((p = strchr_m(vers, '.')) == 0)
9983 return major_version;
9986 major_version = atoi(vers);
9987 return major_version;
9990 int lp_minor_announce_version(void)
9992 static bool got_minor = False;
9993 static int minor_version = DEFAULT_MINOR_VERSION;
9998 return minor_version;
10001 if ((vers = lp_announce_version()) == NULL)
10002 return minor_version;
10004 if ((p = strchr_m(vers, '.')) == 0)
10005 return minor_version;
10008 minor_version = atoi(p);
10009 return minor_version;
10012 /***********************************************************
10013 Set the global name resolution order (used in smbclient).
10014 ************************************************************/
10016 void lp_set_name_resolve_order(const char *new_order)
10018 string_set(&Globals.szNameResolveOrder, new_order);
10021 const char *lp_printername(int snum)
10023 const char *ret = _lp_printername(snum);
10024 if (ret == NULL || (ret != NULL && *ret == '\0'))
10025 ret = lp_const_servicename(snum);
10031 /***********************************************************
10032 Allow daemons such as winbindd to fix their logfile name.
10033 ************************************************************/
10035 void lp_set_logfile(const char *name)
10037 string_set(&Globals.szLogFile, name);
10038 debug_set_logfile(name);
10041 /*******************************************************************
10042 Return the max print jobs per queue.
10043 ********************************************************************/
10045 int lp_maxprintjobs(int snum)
10047 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
10048 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
10049 maxjobs = PRINT_MAX_JOBID - 1;
10054 const char *lp_printcapname(void)
10056 if ((Globals.szPrintcapname != NULL) &&
10057 (Globals.szPrintcapname[0] != '\0'))
10058 return Globals.szPrintcapname;
10060 if (sDefault.iPrinting == PRINT_CUPS) {
10068 if (sDefault.iPrinting == PRINT_BSD)
10069 return "/etc/printcap";
10071 return PRINTCAP_NAME;
10074 static uint32 spoolss_state;
10076 bool lp_disable_spoolss( void )
10078 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
10079 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
10081 return spoolss_state == SVCCTL_STOPPED ? True : False;
10084 void lp_set_spoolss_state( uint32 state )
10086 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
10088 spoolss_state = state;
10091 uint32 lp_get_spoolss_state( void )
10093 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
10096 /*******************************************************************
10097 Ensure we don't use sendfile if server smb signing is active.
10098 ********************************************************************/
10100 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
10102 bool sign_active = false;
10104 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
10105 if (get_Protocol() < PROTOCOL_NT1) {
10108 if (signing_state) {
10109 sign_active = smb_signing_is_active(signing_state);
10111 return (_lp_use_sendfile(snum) &&
10112 (get_remote_arch() != RA_WIN95) &&
10116 /*******************************************************************
10117 Turn off sendfile if we find the underlying OS doesn't support it.
10118 ********************************************************************/
10120 void set_use_sendfile(int snum, bool val)
10122 if (LP_SNUM_OK(snum))
10123 ServicePtrs[snum]->bUseSendfile = val;
10125 sDefault.bUseSendfile = val;
10128 /*******************************************************************
10129 Turn off storing DOS attributes if this share doesn't support it.
10130 ********************************************************************/
10132 void set_store_dos_attributes(int snum, bool val)
10134 if (!LP_SNUM_OK(snum))
10136 ServicePtrs[(snum)]->bStoreDosAttributes = val;
10139 void lp_set_mangling_method(const char *new_method)
10141 string_set(&Globals.szManglingMethod, new_method);
10144 /*******************************************************************
10145 Global state for POSIX pathname processing.
10146 ********************************************************************/
10148 static bool posix_pathnames;
10150 bool lp_posix_pathnames(void)
10152 return posix_pathnames;
10155 /*******************************************************************
10156 Change everything needed to ensure POSIX pathname processing (currently
10158 ********************************************************************/
10160 void lp_set_posix_pathnames(void)
10162 posix_pathnames = True;
10165 /*******************************************************************
10166 Global state for POSIX lock processing - CIFS unix extensions.
10167 ********************************************************************/
10169 bool posix_default_lock_was_set;
10170 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
10172 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
10174 if (posix_default_lock_was_set) {
10175 return posix_cifsx_locktype;
10177 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
10181 /*******************************************************************
10182 ********************************************************************/
10184 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
10186 posix_default_lock_was_set = True;
10187 posix_cifsx_locktype = val;
10190 int lp_min_receive_file_size(void)
10192 if (Globals.iminreceivefile < 0) {
10195 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
10198 /*******************************************************************
10199 If socket address is an empty character string, it is necessary to
10200 define it as "0.0.0.0".
10201 ********************************************************************/
10203 const char *lp_socket_address(void)
10205 char *sock_addr = Globals.szSocketAddress;
10207 if (sock_addr[0] == '\0'){
10208 string_set(&Globals.szSocketAddress, "0.0.0.0");
10210 return Globals.szSocketAddress;
10213 void lp_set_passdb_backend(const char *backend)
10215 string_set(&Globals.szPassdbBackend, backend);
10218 /*******************************************************************
10219 Safe wide links checks.
10220 This helper function always verify the validity of wide links,
10221 even after a configuration file reload.
10222 ********************************************************************/
10224 static bool lp_widelinks_internal(int snum)
10226 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
10227 sDefault.bWidelinks);
10230 void widelinks_warning(int snum)
10232 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10233 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10234 "These parameters are incompatible. "
10235 "Wide links will be disabled for this share.\n",
10236 lp_servicename(snum) ));
10240 bool lp_widelinks(int snum)
10242 /* wide links is always incompatible with unix extensions */
10243 if (lp_unix_extensions()) {
10247 return lp_widelinks_internal(snum);
10250 bool lp_writeraw(void)
10252 if (lp_async_smb_echo_handler()) {
10255 return _lp_writeraw();
10258 bool lp_readraw(void)
10260 if (lp_async_smb_echo_handler()) {
10263 return _lp_readraw();