2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12 Copyright (C) Michael Adam 2008
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 3 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
31 * This module provides suitable callback functions for the params
32 * module. It builds the internal table of service details which is
33 * then used by the rest of the server.
37 * 1) add it to the global or service structure definition
38 * 2) add it to the parm_table
39 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40 * 4) If it's a global then initialise it in init_globals. If a local
41 * (ie. service) parameter then initialise it in the sDefault structure
45 * The configuration file is processed sequentially for speed. It is NOT
46 * accessed randomly as happens in 'real' Windows. For this reason, there
47 * is a fair bit of sequence-dependent code here - ie., code which assumes
48 * that certain things happen before others. In particular, the code which
49 * happens at the boundary between sections is delicately poised, so be
56 #include "lib/smbconf/smbconf.h"
57 #include "lib/smbconf/smbconf_init.h"
58 #include "lib/smbconf/smbconf_reg.h"
61 #include "../librpc/gen_ndr/svcctl.h"
63 #include "smb_signing.h"
67 #ifdef HAVE_SYS_SYSCTL_H
68 #include <sys/sysctl.h>
71 #ifdef HAVE_HTTPCONNECTENCRYPT
72 #include <cups/http.h>
77 extern userdom_struct current_user_info;
80 #define GLOBAL_NAME "global"
84 #define PRINTERS_NAME "printers"
88 #define HOMES_NAME "homes"
91 /* the special value for the include parameter
92 * to be interpreted not as a file name but to
93 * trigger loading of the global smb.conf options
95 #ifndef INCLUDE_REGISTRY_NAME
96 #define INCLUDE_REGISTRY_NAME "registry"
99 static bool in_client = False; /* Not in the client by default */
100 static struct smbconf_csn conf_last_csn;
102 #define CONFIG_BACKEND_FILE 0
103 #define CONFIG_BACKEND_REGISTRY 1
105 static int config_backend = CONFIG_BACKEND_FILE;
107 /* some helpful bits */
108 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
109 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
111 #define USERSHARE_VALID 1
112 #define USERSHARE_PENDING_DELETE 2
114 static bool defaults_saved = False;
116 struct param_opt_struct {
117 struct param_opt_struct *prev, *next;
125 * This structure describes global (ie., server-wide) parameters.
132 char *display_charset;
133 char *szPrintcapname;
134 char *szAddPortCommand;
135 char *szEnumPortsCommand;
136 char *szAddPrinterCommand;
137 char *szDeletePrinterCommand;
138 char *szOs2DriverMap;
144 char *szDefaultService;
148 char *szServerString;
149 char *szAutoServices;
150 char *szPasswdProgram;
154 char *szSMBPasswdFile;
156 char *szPassdbBackend;
157 char **szPreloadModules;
158 char *szPasswordServer;
159 char *szSocketOptions;
161 char *szAfsUsernameMap;
162 int iAfsTokenLifetime;
163 char *szLogNtTokenCommand;
169 char **szWINSservers;
171 char *szRemoteAnnounce;
172 char *szRemoteBrowseSync;
173 char *szSocketAddress;
174 bool bNmbdBindExplicitBroadcast;
175 char *szNISHomeMapName;
176 char *szAnnounceVersion; /* This is initialised in init_globals */
179 char **szNetbiosAliases;
180 char *szNetbiosScope;
181 char *szNameResolveOrder;
183 char *szAddUserScript;
184 char *szRenameUserScript;
185 char *szDelUserScript;
186 char *szAddGroupScript;
187 char *szDelGroupScript;
188 char *szAddUserToGroupScript;
189 char *szDelUserFromGroupScript;
190 char *szSetPrimaryGroupScript;
191 char *szAddMachineScript;
192 char *szShutdownScript;
193 char *szAbortShutdownScript;
194 char *szUsernameMapScript;
195 int iUsernameMapCacheTime;
196 char *szCheckPasswordScript;
203 bool bPassdbExpandExplicit;
204 int AlgorithmicRidBase;
205 char *szTemplateHomedir;
206 char *szTemplateShell;
207 char *szWinbindSeparator;
208 bool bWinbindEnumUsers;
209 bool bWinbindEnumGroups;
210 bool bWinbindUseDefaultDomain;
211 bool bWinbindTrustedDomainsOnly;
212 bool bWinbindNestedGroups;
213 int winbind_expand_groups;
214 bool bWinbindRefreshTickets;
215 bool bWinbindOfflineLogon;
216 bool bWinbindNormalizeNames;
217 bool bWinbindRpcOnly;
218 bool bCreateKrb5Conf;
219 int winbindMaxDomainConnections;
220 char *szIdmapBackend;
222 char *szAddShareCommand;
223 char *szChangeShareCommand;
224 char *szDeleteShareCommand;
226 char *szGuestaccount;
227 char *szManglingMethod;
228 char **szServicesList;
229 char *szUsersharePath;
230 char *szUsershareTemplateShare;
231 char **szUsersharePrefixAllowList;
232 char **szUsersharePrefixDenyList;
239 int open_files_db_hash_size;
248 bool paranoid_server_security;
251 int iMaxSmbdProcesses;
252 bool bDisableSpoolss;
255 bool enhanced_browsing;
261 int announce_as; /* This is initialised in init_globals */
262 int machine_password_timeout;
264 int oplock_break_wait_time;
265 int winbind_cache_time;
266 int winbind_reconnect_delay;
267 int winbind_max_clients;
268 char **szWinbindNssInfo;
270 char *szLdapMachineSuffix;
271 char *szLdapUserSuffix;
272 char *szLdapIdmapSuffix;
273 char *szLdapGroupSuffix;
277 int ldap_follow_referral;
280 int ldap_debug_level;
281 int ldap_debug_threshold;
285 char *szIPrintServer;
287 char **szClusterAddresses;
290 int ctdb_locktime_warn_threshold;
291 int ldap_passwd_sync;
292 int ldap_replication_sleep;
293 int ldap_timeout; /* This is initialised in init_globals */
294 int ldap_connection_timeout;
297 bool bMsAddPrinterWizard;
302 int iPreferredMaster;
305 char **szInitLogonDelayedHosts;
307 bool bEncryptPasswords;
312 bool bObeyPamRestrictions;
314 int PrintcapCacheTime;
315 bool bLargeReadwrite;
322 bool bBindInterfacesOnly;
323 bool bPamPasswordChange;
324 bool bUnixPasswdSync;
325 bool bPasswdChatDebug;
326 int iPasswdChatTimeout;
330 bool bNTStatusSupport;
332 int iMaxStatCacheSize;
334 bool bAllowTrustedDomains;
338 bool bClientLanManAuth;
339 bool bClientNTLMv2Auth;
340 bool bClientPlaintextAuth;
341 bool bClientUseSpnego;
342 bool client_use_spnego_principal;
343 bool send_spnego_principal;
344 bool bDebugPrefixTimestamp;
345 bool bDebugHiresTimestamp;
349 bool bEnableCoreFiles;
352 bool bHostnameLookups;
353 bool bUnixExtensions;
354 bool bDisableNetbios;
355 char * szDedicatedKeytabFile;
357 bool bDeferSharingViolations;
358 bool bEnablePrivileges;
360 bool bUsershareOwnerOnly;
361 bool bUsershareAllowGuests;
362 bool bRegistryShares;
363 int restrict_anonymous;
364 int name_cache_timeout;
367 int client_ldap_sasl_wrapping;
368 int iUsershareMaxShares;
370 int iIdmapNegativeCacheTime;
372 bool bLogWriteableFilesOnExit;
375 struct param_opt_struct *param_opt;
376 int cups_connection_timeout;
377 char *szSMBPerfcountModule;
378 bool bMapUntrustedToDomain;
379 bool bAsyncSMBEchoHandler;
380 bool bMulticastDnsRegister;
384 int ismb2_max_credits;
388 static struct global Globals;
391 * This structure describes a single service.
397 struct timespec usershare_last_mod;
401 char **szInvalidUsers;
409 char *szRootPostExec;
411 char *szPrintcommand;
414 char *szLppausecommand;
415 char *szLpresumecommand;
416 char *szQueuepausecommand;
417 char *szQueueresumecommand;
419 char *szPrintjobUsername;
427 char *szVetoOplockFiles;
433 char **printer_admin;
438 char *szAioWriteBehind;
442 int iMaxReportedPrintJobs;
445 int iCreate_force_mode;
447 int iSecurity_force_mode;
450 int iDir_Security_mask;
451 int iDir_Security_force_mode;
455 int iOplockContentionLimit;
460 bool bRootpreexecClose;
463 bool bShortCasePreserve;
465 bool bHideSpecialFiles;
466 bool bHideUnReadable;
467 bool bHideUnWriteableFiles;
469 bool bAccessBasedShareEnum;
474 bool bAdministrative_share;
477 bool bPrintNotifyBackchannel;
481 bool bStoreDosAttributes;
494 bool bStrictAllocate;
497 struct bitmap *copymap;
498 bool bDeleteReadonly;
500 bool bDeleteVetoFiles;
503 bool bDosFiletimeResolution;
504 bool bFakeDirCreateTimes;
510 bool bUseClientDriver;
511 bool bDefaultDevmode;
512 bool bForcePrintername;
514 bool bForceUnknownAclUser;
517 bool bMap_acl_inherit;
520 bool bAclCheckPermissions;
521 bool bAclMapFullControl;
522 bool bAclGroupControl;
524 bool bKernelChangeNotify;
525 int iallocation_roundup_size;
529 int iDirectoryNameCacheSize;
531 struct param_opt_struct *param_opt;
533 char dummy[3]; /* for alignment */
537 /* This is a default service used to prime a services structure */
538 static struct service sDefault = {
540 False, /* not autoloaded */
541 0, /* not a usershare */
542 {0, }, /* No last mod time */
543 NULL, /* szService */
545 NULL, /* szUsername */
546 NULL, /* szInvalidUsers */
547 NULL, /* szValidUsers */
548 NULL, /* szAdminUsers */
550 NULL, /* szInclude */
551 NULL, /* szPreExec */
552 NULL, /* szPostExec */
553 NULL, /* szRootPreExec */
554 NULL, /* szRootPostExec */
555 NULL, /* szCupsOptions */
556 NULL, /* szPrintcommand */
557 NULL, /* szLpqcommand */
558 NULL, /* szLprmcommand */
559 NULL, /* szLppausecommand */
560 NULL, /* szLpresumecommand */
561 NULL, /* szQueuepausecommand */
562 NULL, /* szQueueresumecommand */
563 NULL, /* szPrintername */
564 NULL, /* szPrintjobUsername */
565 NULL, /* szDontdescend */
566 NULL, /* szHostsallow */
567 NULL, /* szHostsdeny */
568 NULL, /* szMagicScript */
569 NULL, /* szMagicOutput */
570 NULL, /* szVetoFiles */
571 NULL, /* szHideFiles */
572 NULL, /* szVetoOplockFiles */
574 NULL, /* force user */
575 NULL, /* force group */
577 NULL, /* writelist */
578 NULL, /* printer admin */
581 NULL, /* vfs objects */
582 NULL, /* szMSDfsProxy */
583 NULL, /* szAioWriteBehind */
585 0, /* iMinPrintSpace */
586 1000, /* iMaxPrintJobs */
587 0, /* iMaxReportedPrintJobs */
588 0, /* iWriteCacheSize */
589 0744, /* iCreate_mask */
590 0000, /* iCreate_force_mode */
591 0777, /* iSecurity_mask */
592 0, /* iSecurity_force_mode */
593 0755, /* iDir_mask */
594 0000, /* iDir_force_mode */
595 0777, /* iDir_Security_mask */
596 0, /* iDir_Security_force_mode */
597 0, /* iMaxConnections */
598 CASE_LOWER, /* iDefaultCase */
599 DEFAULT_PRINTING, /* iPrinting */
600 2, /* iOplockContentionLimit */
602 1024, /* iBlock_size */
603 0, /* iDfreeCacheTime */
604 False, /* bPreexecClose */
605 False, /* bRootpreexecClose */
606 Auto, /* case sensitive */
607 True, /* case preserve */
608 True, /* short case preserve */
609 True, /* bHideDotFiles */
610 False, /* bHideSpecialFiles */
611 False, /* bHideUnReadable */
612 False, /* bHideUnWriteableFiles */
613 True, /* bBrowseable */
614 False, /* bAccessBasedShareEnum */
615 True, /* bAvailable */
616 True, /* bRead_only */
617 True, /* bNo_set_dir */
618 False, /* bGuest_only */
619 False, /* bAdministrative_share */
620 False, /* bGuest_ok */
621 False, /* bPrint_ok */
622 True, /* bPrintNotifyBackchannel */
623 False, /* bMap_system */
624 False, /* bMap_hidden */
625 True, /* bMap_archive */
626 False, /* bStoreDosAttributes */
627 False, /* bDmapiSupport */
629 Auto, /* iStrictLocking */
630 True, /* bPosixLocking */
631 True, /* bShareModes */
633 True, /* bLevel2OpLocks */
634 False, /* bOnlyUser */
635 True, /* bMangledNames */
636 false, /* bWidelinks */
637 True, /* bSymlinks */
638 False, /* bSyncAlways */
639 True, /* bStrictAllocate */
640 False, /* bStrictSync */
641 '~', /* magic char */
643 False, /* bDeleteReadonly */
644 False, /* bFakeOplocks */
645 False, /* bDeleteVetoFiles */
646 False, /* bDosFilemode */
647 True, /* bDosFiletimes */
648 False, /* bDosFiletimeResolution */
649 False, /* bFakeDirCreateTimes */
650 True, /* bBlockingLocks */
651 False, /* bInheritPerms */
652 False, /* bInheritACLS */
653 False, /* bInheritOwner */
654 False, /* bMSDfsRoot */
655 False, /* bUseClientDriver */
656 True, /* bDefaultDevmode */
657 False, /* bForcePrintername */
658 True, /* bNTAclSupport */
659 False, /* bForceUnknownAclUser */
660 False, /* bUseSendfile */
661 False, /* bProfileAcls */
662 False, /* bMap_acl_inherit */
663 False, /* bAfs_Share */
664 False, /* bEASupport */
665 True, /* bAclCheckPermissions */
666 True, /* bAclMapFullControl */
667 False, /* bAclGroupControl */
668 True, /* bChangeNotify */
669 True, /* bKernelChangeNotify */
670 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
671 0, /* iAioReadSize */
672 0, /* iAioWriteSize */
673 MAP_READONLY_YES, /* iMap_readonly */
674 #ifdef BROKEN_DIRECTORY_HANDLING
675 0, /* iDirectoryNameCacheSize */
677 100, /* iDirectoryNameCacheSize */
679 Auto, /* ismb_encrypt */
680 NULL, /* Parametric options */
685 /* local variables */
686 static struct service **ServicePtrs = NULL;
687 static int iNumServices = 0;
688 static int iServiceIndex = 0;
689 static struct db_context *ServiceHash;
690 static int *invalid_services = NULL;
691 static int num_invalid_services = 0;
692 static bool bInGlobalSection = True;
693 static bool bGlobalOnly = False;
694 static int default_server_announce;
696 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
698 /* prototypes for the special type handlers */
699 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
700 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
701 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
702 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
703 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
704 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
705 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
706 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
707 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
708 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
709 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
710 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
712 static void set_default_server_announce_type(void);
713 static void set_allowed_client_auth(void);
715 static void *lp_local_ptr(struct service *service, void *ptr);
717 static void add_to_file_list(const char *fname, const char *subfname);
718 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
720 static const struct enum_list enum_protocol[] = {
721 {PROTOCOL_SMB2, "SMB2"},
722 {PROTOCOL_NT1, "NT1"},
723 {PROTOCOL_LANMAN2, "LANMAN2"},
724 {PROTOCOL_LANMAN1, "LANMAN1"},
725 {PROTOCOL_CORE, "CORE"},
726 {PROTOCOL_COREPLUS, "COREPLUS"},
727 {PROTOCOL_COREPLUS, "CORE+"},
731 static const struct enum_list enum_security[] = {
732 {SEC_SHARE, "SHARE"},
734 {SEC_SERVER, "SERVER"},
735 {SEC_DOMAIN, "DOMAIN"},
742 static const struct enum_list enum_printing[] = {
743 {PRINT_SYSV, "sysv"},
745 {PRINT_HPUX, "hpux"},
749 {PRINT_LPRNG, "lprng"},
750 {PRINT_CUPS, "cups"},
751 {PRINT_IPRINT, "iprint"},
753 {PRINT_LPROS2, "os2"},
754 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
755 {PRINT_TEST, "test"},
757 #endif /* DEVELOPER */
761 static const struct enum_list enum_ldap_sasl_wrapping[] = {
763 {ADS_AUTH_SASL_SIGN, "sign"},
764 {ADS_AUTH_SASL_SEAL, "seal"},
768 static const struct enum_list enum_ldap_ssl[] = {
769 {LDAP_SSL_OFF, "no"},
770 {LDAP_SSL_OFF, "off"},
771 {LDAP_SSL_START_TLS, "start tls"},
772 {LDAP_SSL_START_TLS, "start_tls"},
776 /* LDAP Dereferencing Alias types */
777 #define SAMBA_LDAP_DEREF_NEVER 0
778 #define SAMBA_LDAP_DEREF_SEARCHING 1
779 #define SAMBA_LDAP_DEREF_FINDING 2
780 #define SAMBA_LDAP_DEREF_ALWAYS 3
782 static const struct enum_list enum_ldap_deref[] = {
783 {SAMBA_LDAP_DEREF_NEVER, "never"},
784 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
785 {SAMBA_LDAP_DEREF_FINDING, "finding"},
786 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
790 static const struct enum_list enum_ldap_passwd_sync[] = {
791 {LDAP_PASSWD_SYNC_OFF, "no"},
792 {LDAP_PASSWD_SYNC_OFF, "off"},
793 {LDAP_PASSWD_SYNC_ON, "yes"},
794 {LDAP_PASSWD_SYNC_ON, "on"},
795 {LDAP_PASSWD_SYNC_ONLY, "only"},
799 /* Types of machine we can announce as. */
800 #define ANNOUNCE_AS_NT_SERVER 1
801 #define ANNOUNCE_AS_WIN95 2
802 #define ANNOUNCE_AS_WFW 3
803 #define ANNOUNCE_AS_NT_WORKSTATION 4
805 static const struct enum_list enum_announce_as[] = {
806 {ANNOUNCE_AS_NT_SERVER, "NT"},
807 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
808 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
809 {ANNOUNCE_AS_WIN95, "win95"},
810 {ANNOUNCE_AS_WFW, "WfW"},
814 static const struct enum_list enum_map_readonly[] = {
815 {MAP_READONLY_NO, "no"},
816 {MAP_READONLY_NO, "false"},
817 {MAP_READONLY_NO, "0"},
818 {MAP_READONLY_YES, "yes"},
819 {MAP_READONLY_YES, "true"},
820 {MAP_READONLY_YES, "1"},
821 {MAP_READONLY_PERMISSIONS, "permissions"},
822 {MAP_READONLY_PERMISSIONS, "perms"},
826 static const struct enum_list enum_case[] = {
827 {CASE_LOWER, "lower"},
828 {CASE_UPPER, "upper"},
834 static const struct enum_list enum_bool_auto[] = {
845 static const struct enum_list enum_csc_policy[] = {
846 {CSC_POLICY_MANUAL, "manual"},
847 {CSC_POLICY_DOCUMENTS, "documents"},
848 {CSC_POLICY_PROGRAMS, "programs"},
849 {CSC_POLICY_DISABLE, "disable"},
853 /* SMB signing types. */
854 static const struct enum_list enum_smb_signing_vals[] = {
866 {Required, "required"},
867 {Required, "mandatory"},
869 {Required, "forced"},
870 {Required, "enforced"},
874 /* ACL compatibility options. */
875 static const struct enum_list enum_acl_compat_vals[] = {
876 { ACL_COMPAT_AUTO, "auto" },
877 { ACL_COMPAT_WINNT, "winnt" },
878 { ACL_COMPAT_WIN2K, "win2k" },
883 Do you want session setups at user level security with a invalid
884 password to be rejected or allowed in as guest? WinNT rejects them
885 but it can be a pain as it means "net view" needs to use a password
887 You have 3 choices in the setting of map_to_guest:
889 "Never" means session setups with an invalid password
890 are rejected. This is the default.
892 "Bad User" means session setups with an invalid password
893 are rejected, unless the username does not exist, in which case it
894 is treated as a guest login
896 "Bad Password" means session setups with an invalid password
897 are treated as a guest login
899 Note that map_to_guest only has an effect in user or server
903 static const struct enum_list enum_map_to_guest[] = {
904 {NEVER_MAP_TO_GUEST, "Never"},
905 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
906 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
907 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
911 /* Config backend options */
913 static const struct enum_list enum_config_backend[] = {
914 {CONFIG_BACKEND_FILE, "file"},
915 {CONFIG_BACKEND_REGISTRY, "registry"},
919 /* ADS kerberos ticket verification options */
921 static const struct enum_list enum_kerberos_method[] = {
922 {KERBEROS_VERIFY_SECRETS, "default"},
923 {KERBEROS_VERIFY_SECRETS, "secrets only"},
924 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
925 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
926 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
930 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
932 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
933 * screen in SWAT. This is used to exclude parameters as well as to squash all
934 * parameters that have been duplicated by pseudonyms.
936 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
937 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
938 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
941 * NOTE2: Handling of duplicated (synonym) parameters:
942 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
943 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
944 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
945 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
948 static struct parm_struct parm_table[] = {
949 {N_("Base Options"), P_SEP, P_SEPARATOR},
952 .label = "dos charset",
955 .ptr = &Globals.dos_charset,
956 .special = handle_charset,
958 .flags = FLAG_ADVANCED
961 .label = "unix charset",
964 .ptr = &Globals.unix_charset,
965 .special = handle_charset,
967 .flags = FLAG_ADVANCED
970 .label = "display charset",
973 .ptr = &Globals.display_charset,
974 .special = handle_charset,
976 .flags = FLAG_ADVANCED
982 .ptr = &sDefault.comment,
985 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
991 .ptr = &sDefault.szPath,
994 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
997 .label = "directory",
1000 .ptr = &sDefault.szPath,
1006 .label = "workgroup",
1008 .p_class = P_GLOBAL,
1009 .ptr = &Globals.szWorkgroup,
1010 .special = handle_workgroup,
1012 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1018 .p_class = P_GLOBAL,
1019 .ptr = &Globals.szRealm,
1022 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1026 .label = "netbios name",
1028 .p_class = P_GLOBAL,
1029 .ptr = &Globals.szNetbiosName,
1030 .special = handle_netbios_name,
1032 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1035 .label = "netbios aliases",
1037 .p_class = P_GLOBAL,
1038 .ptr = &Globals.szNetbiosAliases,
1039 .special = handle_netbios_aliases,
1041 .flags = FLAG_ADVANCED,
1044 .label = "netbios scope",
1046 .p_class = P_GLOBAL,
1047 .ptr = &Globals.szNetbiosScope,
1048 .special = handle_netbios_scope,
1050 .flags = FLAG_ADVANCED,
1053 .label = "server string",
1055 .p_class = P_GLOBAL,
1056 .ptr = &Globals.szServerString,
1059 .flags = FLAG_BASIC | FLAG_ADVANCED,
1062 .label = "interfaces",
1064 .p_class = P_GLOBAL,
1065 .ptr = &Globals.szInterfaces,
1068 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1071 .label = "bind interfaces only",
1073 .p_class = P_GLOBAL,
1074 .ptr = &Globals.bBindInterfacesOnly,
1077 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1080 .label = "config backend",
1082 .p_class = P_GLOBAL,
1083 .ptr = &Globals.ConfigBackend,
1085 .enum_list = enum_config_backend,
1086 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1089 {N_("Security Options"), P_SEP, P_SEPARATOR},
1092 .label = "security",
1094 .p_class = P_GLOBAL,
1095 .ptr = &Globals.security,
1097 .enum_list = enum_security,
1098 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1101 .label = "auth methods",
1103 .p_class = P_GLOBAL,
1104 .ptr = &Globals.AuthMethods,
1107 .flags = FLAG_ADVANCED,
1110 .label = "encrypt passwords",
1112 .p_class = P_GLOBAL,
1113 .ptr = &Globals.bEncryptPasswords,
1116 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1119 .label = "client schannel",
1121 .p_class = P_GLOBAL,
1122 .ptr = &Globals.clientSchannel,
1124 .enum_list = enum_bool_auto,
1125 .flags = FLAG_BASIC | FLAG_ADVANCED,
1128 .label = "server schannel",
1130 .p_class = P_GLOBAL,
1131 .ptr = &Globals.serverSchannel,
1133 .enum_list = enum_bool_auto,
1134 .flags = FLAG_BASIC | FLAG_ADVANCED,
1137 .label = "allow trusted domains",
1139 .p_class = P_GLOBAL,
1140 .ptr = &Globals.bAllowTrustedDomains,
1143 .flags = FLAG_ADVANCED,
1146 .label = "map to guest",
1148 .p_class = P_GLOBAL,
1149 .ptr = &Globals.map_to_guest,
1151 .enum_list = enum_map_to_guest,
1152 .flags = FLAG_ADVANCED,
1155 .label = "null passwords",
1157 .p_class = P_GLOBAL,
1158 .ptr = &Globals.bNullPasswords,
1161 .flags = FLAG_ADVANCED,
1164 .label = "obey pam restrictions",
1166 .p_class = P_GLOBAL,
1167 .ptr = &Globals.bObeyPamRestrictions,
1170 .flags = FLAG_ADVANCED,
1173 .label = "password server",
1175 .p_class = P_GLOBAL,
1176 .ptr = &Globals.szPasswordServer,
1179 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1182 .label = "smb passwd file",
1184 .p_class = P_GLOBAL,
1185 .ptr = &Globals.szSMBPasswdFile,
1188 .flags = FLAG_ADVANCED,
1191 .label = "private dir",
1193 .p_class = P_GLOBAL,
1194 .ptr = &Globals.szPrivateDir,
1197 .flags = FLAG_ADVANCED,
1200 .label = "passdb backend",
1202 .p_class = P_GLOBAL,
1203 .ptr = &Globals.szPassdbBackend,
1206 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1209 .label = "algorithmic rid base",
1211 .p_class = P_GLOBAL,
1212 .ptr = &Globals.AlgorithmicRidBase,
1215 .flags = FLAG_ADVANCED,
1218 .label = "root directory",
1220 .p_class = P_GLOBAL,
1221 .ptr = &Globals.szRootdir,
1224 .flags = FLAG_ADVANCED,
1227 .label = "root dir",
1229 .p_class = P_GLOBAL,
1230 .ptr = &Globals.szRootdir,
1238 .p_class = P_GLOBAL,
1239 .ptr = &Globals.szRootdir,
1245 .label = "guest account",
1247 .p_class = P_GLOBAL,
1248 .ptr = &Globals.szGuestaccount,
1251 .flags = FLAG_BASIC | FLAG_ADVANCED,
1254 .label = "enable privileges",
1256 .p_class = P_GLOBAL,
1257 .ptr = &Globals.bEnablePrivileges,
1260 .flags = FLAG_ADVANCED,
1264 .label = "pam password change",
1266 .p_class = P_GLOBAL,
1267 .ptr = &Globals.bPamPasswordChange,
1270 .flags = FLAG_ADVANCED,
1273 .label = "passwd program",
1275 .p_class = P_GLOBAL,
1276 .ptr = &Globals.szPasswdProgram,
1279 .flags = FLAG_ADVANCED,
1282 .label = "passwd chat",
1284 .p_class = P_GLOBAL,
1285 .ptr = &Globals.szPasswdChat,
1288 .flags = FLAG_ADVANCED,
1291 .label = "passwd chat debug",
1293 .p_class = P_GLOBAL,
1294 .ptr = &Globals.bPasswdChatDebug,
1297 .flags = FLAG_ADVANCED,
1300 .label = "passwd chat timeout",
1302 .p_class = P_GLOBAL,
1303 .ptr = &Globals.iPasswdChatTimeout,
1306 .flags = FLAG_ADVANCED,
1309 .label = "check password script",
1311 .p_class = P_GLOBAL,
1312 .ptr = &Globals.szCheckPasswordScript,
1315 .flags = FLAG_ADVANCED,
1318 .label = "username map",
1320 .p_class = P_GLOBAL,
1321 .ptr = &Globals.szUsernameMap,
1324 .flags = FLAG_ADVANCED,
1327 .label = "password level",
1329 .p_class = P_GLOBAL,
1330 .ptr = &Globals.pwordlevel,
1333 .flags = FLAG_ADVANCED,
1336 .label = "username level",
1338 .p_class = P_GLOBAL,
1339 .ptr = &Globals.unamelevel,
1342 .flags = FLAG_ADVANCED,
1345 .label = "unix password sync",
1347 .p_class = P_GLOBAL,
1348 .ptr = &Globals.bUnixPasswdSync,
1351 .flags = FLAG_ADVANCED,
1354 .label = "restrict anonymous",
1356 .p_class = P_GLOBAL,
1357 .ptr = &Globals.restrict_anonymous,
1360 .flags = FLAG_ADVANCED,
1363 .label = "lanman auth",
1365 .p_class = P_GLOBAL,
1366 .ptr = &Globals.bLanmanAuth,
1369 .flags = FLAG_ADVANCED,
1372 .label = "ntlm auth",
1374 .p_class = P_GLOBAL,
1375 .ptr = &Globals.bNTLMAuth,
1378 .flags = FLAG_ADVANCED,
1381 .label = "client NTLMv2 auth",
1383 .p_class = P_GLOBAL,
1384 .ptr = &Globals.bClientNTLMv2Auth,
1387 .flags = FLAG_ADVANCED,
1390 .label = "client lanman auth",
1392 .p_class = P_GLOBAL,
1393 .ptr = &Globals.bClientLanManAuth,
1396 .flags = FLAG_ADVANCED,
1399 .label = "client plaintext auth",
1401 .p_class = P_GLOBAL,
1402 .ptr = &Globals.bClientPlaintextAuth,
1405 .flags = FLAG_ADVANCED,
1408 .label = "client use spnego principal",
1410 .p_class = P_GLOBAL,
1411 .ptr = &Globals.client_use_spnego_principal,
1414 .flags = FLAG_ADVANCED,
1417 .label = "send spnego principal",
1419 .p_class = P_GLOBAL,
1420 .ptr = &Globals.send_spnego_principal,
1423 .flags = FLAG_ADVANCED,
1426 .label = "username",
1429 .ptr = &sDefault.szUsername,
1432 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1438 .ptr = &sDefault.szUsername,
1447 .ptr = &sDefault.szUsername,
1453 .label = "invalid users",
1456 .ptr = &sDefault.szInvalidUsers,
1459 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1462 .label = "valid users",
1465 .ptr = &sDefault.szValidUsers,
1468 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1471 .label = "admin users",
1474 .ptr = &sDefault.szAdminUsers,
1477 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1480 .label = "read list",
1483 .ptr = &sDefault.readlist,
1486 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1489 .label = "write list",
1492 .ptr = &sDefault.writelist,
1495 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1498 .label = "printer admin",
1501 .ptr = &sDefault.printer_admin,
1504 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1507 .label = "force user",
1510 .ptr = &sDefault.force_user,
1513 .flags = FLAG_ADVANCED | FLAG_SHARE,
1516 .label = "force group",
1519 .ptr = &sDefault.force_group,
1522 .flags = FLAG_ADVANCED | FLAG_SHARE,
1528 .ptr = &sDefault.force_group,
1531 .flags = FLAG_ADVANCED,
1534 .label = "read only",
1537 .ptr = &sDefault.bRead_only,
1540 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1543 .label = "write ok",
1546 .ptr = &sDefault.bRead_only,
1552 .label = "writeable",
1555 .ptr = &sDefault.bRead_only,
1561 .label = "writable",
1564 .ptr = &sDefault.bRead_only,
1570 .label = "acl check permissions",
1573 .ptr = &sDefault.bAclCheckPermissions,
1576 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1579 .label = "acl group control",
1582 .ptr = &sDefault.bAclGroupControl,
1585 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1588 .label = "acl map full control",
1591 .ptr = &sDefault.bAclMapFullControl,
1594 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1597 .label = "create mask",
1600 .ptr = &sDefault.iCreate_mask,
1603 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1606 .label = "create mode",
1609 .ptr = &sDefault.iCreate_mask,
1615 .label = "force create mode",
1618 .ptr = &sDefault.iCreate_force_mode,
1621 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1624 .label = "security mask",
1627 .ptr = &sDefault.iSecurity_mask,
1630 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1633 .label = "force security mode",
1636 .ptr = &sDefault.iSecurity_force_mode,
1639 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1642 .label = "directory mask",
1645 .ptr = &sDefault.iDir_mask,
1648 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1651 .label = "directory mode",
1654 .ptr = &sDefault.iDir_mask,
1657 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1660 .label = "force directory mode",
1663 .ptr = &sDefault.iDir_force_mode,
1666 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1669 .label = "directory security mask",
1672 .ptr = &sDefault.iDir_Security_mask,
1675 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1678 .label = "force directory security mode",
1681 .ptr = &sDefault.iDir_Security_force_mode,
1684 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1687 .label = "force unknown acl user",
1690 .ptr = &sDefault.bForceUnknownAclUser,
1693 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1696 .label = "inherit permissions",
1699 .ptr = &sDefault.bInheritPerms,
1702 .flags = FLAG_ADVANCED | FLAG_SHARE,
1705 .label = "inherit acls",
1708 .ptr = &sDefault.bInheritACLS,
1711 .flags = FLAG_ADVANCED | FLAG_SHARE,
1714 .label = "inherit owner",
1717 .ptr = &sDefault.bInheritOwner,
1720 .flags = FLAG_ADVANCED | FLAG_SHARE,
1723 .label = "guest only",
1726 .ptr = &sDefault.bGuest_only,
1729 .flags = FLAG_ADVANCED | FLAG_SHARE,
1732 .label = "only guest",
1735 .ptr = &sDefault.bGuest_only,
1741 .label = "administrative share",
1744 .ptr = &sDefault.bAdministrative_share,
1747 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1751 .label = "guest ok",
1754 .ptr = &sDefault.bGuest_ok,
1757 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1763 .ptr = &sDefault.bGuest_ok,
1769 .label = "only user",
1772 .ptr = &sDefault.bOnlyUser,
1775 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1778 .label = "hosts allow",
1781 .ptr = &sDefault.szHostsallow,
1784 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1787 .label = "allow hosts",
1790 .ptr = &sDefault.szHostsallow,
1796 .label = "hosts deny",
1799 .ptr = &sDefault.szHostsdeny,
1802 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1805 .label = "deny hosts",
1808 .ptr = &sDefault.szHostsdeny,
1814 .label = "preload modules",
1816 .p_class = P_GLOBAL,
1817 .ptr = &Globals.szPreloadModules,
1820 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1823 .label = "dedicated keytab file",
1825 .p_class = P_GLOBAL,
1826 .ptr = &Globals.szDedicatedKeytabFile,
1829 .flags = FLAG_ADVANCED,
1832 .label = "kerberos method",
1834 .p_class = P_GLOBAL,
1835 .ptr = &Globals.iKerberosMethod,
1837 .enum_list = enum_kerberos_method,
1838 .flags = FLAG_ADVANCED,
1841 .label = "map untrusted to domain",
1843 .p_class = P_GLOBAL,
1844 .ptr = &Globals.bMapUntrustedToDomain,
1847 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1851 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1854 .label = "log level",
1856 .p_class = P_GLOBAL,
1857 .ptr = &Globals.szLogLevel,
1858 .special = handle_debug_list,
1860 .flags = FLAG_ADVANCED,
1863 .label = "debuglevel",
1865 .p_class = P_GLOBAL,
1866 .ptr = &Globals.szLogLevel,
1867 .special = handle_debug_list,
1874 .p_class = P_GLOBAL,
1875 .ptr = &Globals.syslog,
1878 .flags = FLAG_ADVANCED,
1881 .label = "syslog only",
1883 .p_class = P_GLOBAL,
1884 .ptr = &Globals.bSyslogOnly,
1887 .flags = FLAG_ADVANCED,
1890 .label = "log file",
1892 .p_class = P_GLOBAL,
1893 .ptr = &Globals.szLogFile,
1896 .flags = FLAG_ADVANCED,
1899 .label = "max log size",
1901 .p_class = P_GLOBAL,
1902 .ptr = &Globals.max_log_size,
1905 .flags = FLAG_ADVANCED,
1908 .label = "debug timestamp",
1910 .p_class = P_GLOBAL,
1911 .ptr = &Globals.bTimestampLogs,
1914 .flags = FLAG_ADVANCED,
1917 .label = "timestamp logs",
1919 .p_class = P_GLOBAL,
1920 .ptr = &Globals.bTimestampLogs,
1923 .flags = FLAG_ADVANCED,
1926 .label = "debug prefix timestamp",
1928 .p_class = P_GLOBAL,
1929 .ptr = &Globals.bDebugPrefixTimestamp,
1932 .flags = FLAG_ADVANCED,
1935 .label = "debug hires timestamp",
1937 .p_class = P_GLOBAL,
1938 .ptr = &Globals.bDebugHiresTimestamp,
1941 .flags = FLAG_ADVANCED,
1944 .label = "debug pid",
1946 .p_class = P_GLOBAL,
1947 .ptr = &Globals.bDebugPid,
1950 .flags = FLAG_ADVANCED,
1953 .label = "debug uid",
1955 .p_class = P_GLOBAL,
1956 .ptr = &Globals.bDebugUid,
1959 .flags = FLAG_ADVANCED,
1962 .label = "debug class",
1964 .p_class = P_GLOBAL,
1965 .ptr = &Globals.bDebugClass,
1968 .flags = FLAG_ADVANCED,
1971 .label = "enable core files",
1973 .p_class = P_GLOBAL,
1974 .ptr = &Globals.bEnableCoreFiles,
1977 .flags = FLAG_ADVANCED,
1980 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1983 .label = "allocation roundup size",
1986 .ptr = &sDefault.iallocation_roundup_size,
1989 .flags = FLAG_ADVANCED,
1992 .label = "aio read size",
1995 .ptr = &sDefault.iAioReadSize,
1998 .flags = FLAG_ADVANCED,
2001 .label = "aio write size",
2004 .ptr = &sDefault.iAioWriteSize,
2007 .flags = FLAG_ADVANCED,
2010 .label = "aio write behind",
2013 .ptr = &sDefault.szAioWriteBehind,
2016 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2019 .label = "smb ports",
2021 .p_class = P_GLOBAL,
2022 .ptr = &Globals.smb_ports,
2025 .flags = FLAG_ADVANCED,
2028 .label = "large readwrite",
2030 .p_class = P_GLOBAL,
2031 .ptr = &Globals.bLargeReadwrite,
2034 .flags = FLAG_ADVANCED,
2037 .label = "max protocol",
2039 .p_class = P_GLOBAL,
2040 .ptr = &Globals.maxprotocol,
2042 .enum_list = enum_protocol,
2043 .flags = FLAG_ADVANCED,
2046 .label = "protocol",
2048 .p_class = P_GLOBAL,
2049 .ptr = &Globals.maxprotocol,
2051 .enum_list = enum_protocol,
2052 .flags = FLAG_ADVANCED,
2055 .label = "min protocol",
2057 .p_class = P_GLOBAL,
2058 .ptr = &Globals.minprotocol,
2060 .enum_list = enum_protocol,
2061 .flags = FLAG_ADVANCED,
2064 .label = "min receivefile size",
2066 .p_class = P_GLOBAL,
2067 .ptr = &Globals.iminreceivefile,
2070 .flags = FLAG_ADVANCED,
2073 .label = "read raw",
2075 .p_class = P_GLOBAL,
2076 .ptr = &Globals.bReadRaw,
2079 .flags = FLAG_ADVANCED,
2082 .label = "write raw",
2084 .p_class = P_GLOBAL,
2085 .ptr = &Globals.bWriteRaw,
2088 .flags = FLAG_ADVANCED,
2091 .label = "disable netbios",
2093 .p_class = P_GLOBAL,
2094 .ptr = &Globals.bDisableNetbios,
2097 .flags = FLAG_ADVANCED,
2100 .label = "reset on zero vc",
2102 .p_class = P_GLOBAL,
2103 .ptr = &Globals.bResetOnZeroVC,
2106 .flags = FLAG_ADVANCED,
2109 .label = "log writeable files on exit",
2111 .p_class = P_GLOBAL,
2112 .ptr = &Globals.bLogWriteableFilesOnExit,
2115 .flags = FLAG_ADVANCED,
2118 .label = "acl compatibility",
2120 .p_class = P_GLOBAL,
2121 .ptr = &Globals.iAclCompat,
2123 .enum_list = enum_acl_compat_vals,
2124 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2127 .label = "defer sharing violations",
2129 .p_class = P_GLOBAL,
2130 .ptr = &Globals.bDeferSharingViolations,
2133 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2136 .label = "ea support",
2139 .ptr = &sDefault.bEASupport,
2142 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2145 .label = "nt acl support",
2148 .ptr = &sDefault.bNTAclSupport,
2151 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2154 .label = "nt pipe support",
2156 .p_class = P_GLOBAL,
2157 .ptr = &Globals.bNTPipeSupport,
2160 .flags = FLAG_ADVANCED,
2163 .label = "nt status support",
2165 .p_class = P_GLOBAL,
2166 .ptr = &Globals.bNTStatusSupport,
2169 .flags = FLAG_ADVANCED,
2172 .label = "profile acls",
2175 .ptr = &sDefault.bProfileAcls,
2178 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2181 .label = "announce version",
2183 .p_class = P_GLOBAL,
2184 .ptr = &Globals.szAnnounceVersion,
2187 .flags = FLAG_ADVANCED,
2190 .label = "announce as",
2192 .p_class = P_GLOBAL,
2193 .ptr = &Globals.announce_as,
2195 .enum_list = enum_announce_as,
2196 .flags = FLAG_ADVANCED,
2199 .label = "map acl inherit",
2202 .ptr = &sDefault.bMap_acl_inherit,
2205 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2208 .label = "afs share",
2211 .ptr = &sDefault.bAfs_Share,
2214 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2219 .p_class = P_GLOBAL,
2220 .ptr = &Globals.max_mux,
2223 .flags = FLAG_ADVANCED,
2226 .label = "max xmit",
2228 .p_class = P_GLOBAL,
2229 .ptr = &Globals.max_xmit,
2232 .flags = FLAG_ADVANCED,
2235 .label = "name resolve order",
2237 .p_class = P_GLOBAL,
2238 .ptr = &Globals.szNameResolveOrder,
2241 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2246 .p_class = P_GLOBAL,
2247 .ptr = &Globals.max_ttl,
2250 .flags = FLAG_ADVANCED,
2253 .label = "max wins ttl",
2255 .p_class = P_GLOBAL,
2256 .ptr = &Globals.max_wins_ttl,
2259 .flags = FLAG_ADVANCED,
2262 .label = "min wins ttl",
2264 .p_class = P_GLOBAL,
2265 .ptr = &Globals.min_wins_ttl,
2268 .flags = FLAG_ADVANCED,
2271 .label = "time server",
2273 .p_class = P_GLOBAL,
2274 .ptr = &Globals.bTimeServer,
2277 .flags = FLAG_ADVANCED,
2280 .label = "unix extensions",
2282 .p_class = P_GLOBAL,
2283 .ptr = &Globals.bUnixExtensions,
2286 .flags = FLAG_ADVANCED,
2289 .label = "use spnego",
2291 .p_class = P_GLOBAL,
2292 .ptr = &Globals.bUseSpnego,
2295 .flags = FLAG_ADVANCED,
2298 .label = "client signing",
2300 .p_class = P_GLOBAL,
2301 .ptr = &Globals.client_signing,
2303 .enum_list = enum_smb_signing_vals,
2304 .flags = FLAG_ADVANCED,
2307 .label = "server signing",
2309 .p_class = P_GLOBAL,
2310 .ptr = &Globals.server_signing,
2312 .enum_list = enum_smb_signing_vals,
2313 .flags = FLAG_ADVANCED,
2316 .label = "smb encrypt",
2319 .ptr = &sDefault.ismb_encrypt,
2321 .enum_list = enum_smb_signing_vals,
2322 .flags = FLAG_ADVANCED,
2325 .label = "client use spnego",
2327 .p_class = P_GLOBAL,
2328 .ptr = &Globals.bClientUseSpnego,
2331 .flags = FLAG_ADVANCED,
2334 .label = "client ldap sasl wrapping",
2336 .p_class = P_GLOBAL,
2337 .ptr = &Globals.client_ldap_sasl_wrapping,
2339 .enum_list = enum_ldap_sasl_wrapping,
2340 .flags = FLAG_ADVANCED,
2343 .label = "enable asu support",
2345 .p_class = P_GLOBAL,
2346 .ptr = &Globals.bASUSupport,
2349 .flags = FLAG_ADVANCED,
2352 .label = "svcctl list",
2354 .p_class = P_GLOBAL,
2355 .ptr = &Globals.szServicesList,
2358 .flags = FLAG_ADVANCED,
2361 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2364 .label = "block size",
2367 .ptr = &sDefault.iBlock_size,
2370 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2373 .label = "deadtime",
2375 .p_class = P_GLOBAL,
2376 .ptr = &Globals.deadtime,
2379 .flags = FLAG_ADVANCED,
2382 .label = "getwd cache",
2384 .p_class = P_GLOBAL,
2385 .ptr = &Globals.getwd_cache,
2388 .flags = FLAG_ADVANCED,
2391 .label = "keepalive",
2393 .p_class = P_GLOBAL,
2394 .ptr = &Globals.iKeepalive,
2397 .flags = FLAG_ADVANCED,
2400 .label = "change notify",
2403 .ptr = &sDefault.bChangeNotify,
2406 .flags = FLAG_ADVANCED | FLAG_SHARE,
2409 .label = "directory name cache size",
2412 .ptr = &sDefault.iDirectoryNameCacheSize,
2415 .flags = FLAG_ADVANCED | FLAG_SHARE,
2418 .label = "kernel change notify",
2421 .ptr = &sDefault.bKernelChangeNotify,
2424 .flags = FLAG_ADVANCED | FLAG_SHARE,
2427 .label = "lpq cache time",
2429 .p_class = P_GLOBAL,
2430 .ptr = &Globals.lpqcachetime,
2433 .flags = FLAG_ADVANCED,
2436 .label = "max smbd processes",
2438 .p_class = P_GLOBAL,
2439 .ptr = &Globals.iMaxSmbdProcesses,
2442 .flags = FLAG_ADVANCED,
2445 .label = "max connections",
2448 .ptr = &sDefault.iMaxConnections,
2451 .flags = FLAG_ADVANCED | FLAG_SHARE,
2454 .label = "paranoid server security",
2456 .p_class = P_GLOBAL,
2457 .ptr = &Globals.paranoid_server_security,
2460 .flags = FLAG_ADVANCED,
2463 .label = "max disk size",
2465 .p_class = P_GLOBAL,
2466 .ptr = &Globals.maxdisksize,
2469 .flags = FLAG_ADVANCED,
2472 .label = "max open files",
2474 .p_class = P_GLOBAL,
2475 .ptr = &Globals.max_open_files,
2478 .flags = FLAG_ADVANCED,
2481 .label = "min print space",
2484 .ptr = &sDefault.iMinPrintSpace,
2487 .flags = FLAG_ADVANCED | FLAG_PRINT,
2490 .label = "socket options",
2492 .p_class = P_GLOBAL,
2493 .ptr = &Globals.szSocketOptions,
2496 .flags = FLAG_ADVANCED,
2499 .label = "strict allocate",
2502 .ptr = &sDefault.bStrictAllocate,
2505 .flags = FLAG_ADVANCED | FLAG_SHARE,
2508 .label = "strict sync",
2511 .ptr = &sDefault.bStrictSync,
2514 .flags = FLAG_ADVANCED | FLAG_SHARE,
2517 .label = "sync always",
2520 .ptr = &sDefault.bSyncAlways,
2523 .flags = FLAG_ADVANCED | FLAG_SHARE,
2526 .label = "use mmap",
2528 .p_class = P_GLOBAL,
2529 .ptr = &Globals.bUseMmap,
2532 .flags = FLAG_ADVANCED,
2535 .label = "use sendfile",
2538 .ptr = &sDefault.bUseSendfile,
2541 .flags = FLAG_ADVANCED | FLAG_SHARE,
2544 .label = "hostname lookups",
2546 .p_class = P_GLOBAL,
2547 .ptr = &Globals.bHostnameLookups,
2550 .flags = FLAG_ADVANCED,
2553 .label = "write cache size",
2556 .ptr = &sDefault.iWriteCacheSize,
2559 .flags = FLAG_ADVANCED | FLAG_SHARE,
2562 .label = "name cache timeout",
2564 .p_class = P_GLOBAL,
2565 .ptr = &Globals.name_cache_timeout,
2568 .flags = FLAG_ADVANCED,
2571 .label = "ctdbd socket",
2573 .p_class = P_GLOBAL,
2574 .ptr = &Globals.ctdbdSocket,
2577 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2580 .label = "cluster addresses",
2582 .p_class = P_GLOBAL,
2583 .ptr = &Globals.szClusterAddresses,
2586 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2589 .label = "clustering",
2591 .p_class = P_GLOBAL,
2592 .ptr = &Globals.clustering,
2595 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2598 .label = "ctdb timeout",
2600 .p_class = P_GLOBAL,
2601 .ptr = &Globals.ctdb_timeout,
2604 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2607 .label = "ctdb locktime warn threshold",
2609 .p_class = P_GLOBAL,
2610 .ptr = &Globals.ctdb_locktime_warn_threshold,
2613 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2616 .label = "smb2 max read",
2618 .p_class = P_GLOBAL,
2619 .ptr = &Globals.ismb2_max_read,
2622 .flags = FLAG_ADVANCED,
2625 .label = "smb2 max write",
2627 .p_class = P_GLOBAL,
2628 .ptr = &Globals.ismb2_max_write,
2631 .flags = FLAG_ADVANCED,
2634 .label = "smb2 max trans",
2636 .p_class = P_GLOBAL,
2637 .ptr = &Globals.ismb2_max_trans,
2640 .flags = FLAG_ADVANCED,
2643 .label = "smb2 max credits",
2645 .p_class = P_GLOBAL,
2646 .ptr = &Globals.ismb2_max_credits,
2649 .flags = FLAG_ADVANCED,
2652 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2655 .label = "max reported print jobs",
2658 .ptr = &sDefault.iMaxReportedPrintJobs,
2661 .flags = FLAG_ADVANCED | FLAG_PRINT,
2664 .label = "max print jobs",
2667 .ptr = &sDefault.iMaxPrintJobs,
2670 .flags = FLAG_ADVANCED | FLAG_PRINT,
2673 .label = "load printers",
2675 .p_class = P_GLOBAL,
2676 .ptr = &Globals.bLoadPrinters,
2679 .flags = FLAG_ADVANCED | FLAG_PRINT,
2682 .label = "printcap cache time",
2684 .p_class = P_GLOBAL,
2685 .ptr = &Globals.PrintcapCacheTime,
2688 .flags = FLAG_ADVANCED | FLAG_PRINT,
2691 .label = "printcap name",
2693 .p_class = P_GLOBAL,
2694 .ptr = &Globals.szPrintcapname,
2697 .flags = FLAG_ADVANCED | FLAG_PRINT,
2700 .label = "printcap",
2702 .p_class = P_GLOBAL,
2703 .ptr = &Globals.szPrintcapname,
2709 .label = "printable",
2712 .ptr = &sDefault.bPrint_ok,
2715 .flags = FLAG_ADVANCED | FLAG_PRINT,
2718 .label = "print notify backchannel",
2721 .ptr = &sDefault.bPrintNotifyBackchannel,
2724 .flags = FLAG_ADVANCED,
2727 .label = "print ok",
2730 .ptr = &sDefault.bPrint_ok,
2736 .label = "printing",
2739 .ptr = &sDefault.iPrinting,
2740 .special = handle_printing,
2741 .enum_list = enum_printing,
2742 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2745 .label = "cups options",
2748 .ptr = &sDefault.szCupsOptions,
2751 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2754 .label = "cups server",
2756 .p_class = P_GLOBAL,
2757 .ptr = &Globals.szCupsServer,
2760 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2763 .label = "cups encrypt",
2765 .p_class = P_GLOBAL,
2766 .ptr = &Globals.CupsEncrypt,
2768 .enum_list = enum_bool_auto,
2769 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2773 .label = "cups connection timeout",
2775 .p_class = P_GLOBAL,
2776 .ptr = &Globals.cups_connection_timeout,
2779 .flags = FLAG_ADVANCED,
2782 .label = "iprint server",
2784 .p_class = P_GLOBAL,
2785 .ptr = &Globals.szIPrintServer,
2788 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2791 .label = "print command",
2794 .ptr = &sDefault.szPrintcommand,
2797 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2800 .label = "disable spoolss",
2802 .p_class = P_GLOBAL,
2803 .ptr = &Globals.bDisableSpoolss,
2806 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2809 .label = "enable spoolss",
2811 .p_class = P_GLOBAL,
2812 .ptr = &Globals.bDisableSpoolss,
2818 .label = "lpq command",
2821 .ptr = &sDefault.szLpqcommand,
2824 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2827 .label = "lprm command",
2830 .ptr = &sDefault.szLprmcommand,
2833 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2836 .label = "lppause command",
2839 .ptr = &sDefault.szLppausecommand,
2842 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2845 .label = "lpresume command",
2848 .ptr = &sDefault.szLpresumecommand,
2851 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2854 .label = "queuepause command",
2857 .ptr = &sDefault.szQueuepausecommand,
2860 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2863 .label = "queueresume command",
2866 .ptr = &sDefault.szQueueresumecommand,
2869 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2872 .label = "addport command",
2874 .p_class = P_GLOBAL,
2875 .ptr = &Globals.szAddPortCommand,
2878 .flags = FLAG_ADVANCED,
2881 .label = "enumports command",
2883 .p_class = P_GLOBAL,
2884 .ptr = &Globals.szEnumPortsCommand,
2887 .flags = FLAG_ADVANCED,
2890 .label = "addprinter command",
2892 .p_class = P_GLOBAL,
2893 .ptr = &Globals.szAddPrinterCommand,
2896 .flags = FLAG_ADVANCED,
2899 .label = "deleteprinter command",
2901 .p_class = P_GLOBAL,
2902 .ptr = &Globals.szDeletePrinterCommand,
2905 .flags = FLAG_ADVANCED,
2908 .label = "show add printer wizard",
2910 .p_class = P_GLOBAL,
2911 .ptr = &Globals.bMsAddPrinterWizard,
2914 .flags = FLAG_ADVANCED,
2917 .label = "os2 driver map",
2919 .p_class = P_GLOBAL,
2920 .ptr = &Globals.szOs2DriverMap,
2923 .flags = FLAG_ADVANCED,
2927 .label = "printer name",
2930 .ptr = &sDefault.szPrintername,
2933 .flags = FLAG_ADVANCED | FLAG_PRINT,
2939 .ptr = &sDefault.szPrintername,
2945 .label = "use client driver",
2948 .ptr = &sDefault.bUseClientDriver,
2951 .flags = FLAG_ADVANCED | FLAG_PRINT,
2954 .label = "default devmode",
2957 .ptr = &sDefault.bDefaultDevmode,
2960 .flags = FLAG_ADVANCED | FLAG_PRINT,
2963 .label = "force printername",
2966 .ptr = &sDefault.bForcePrintername,
2969 .flags = FLAG_ADVANCED | FLAG_PRINT,
2972 .label = "printjob username",
2975 .ptr = &sDefault.szPrintjobUsername,
2978 .flags = FLAG_ADVANCED | FLAG_PRINT,
2981 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2984 .label = "mangling method",
2986 .p_class = P_GLOBAL,
2987 .ptr = &Globals.szManglingMethod,
2990 .flags = FLAG_ADVANCED,
2993 .label = "mangle prefix",
2995 .p_class = P_GLOBAL,
2996 .ptr = &Globals.mangle_prefix,
2999 .flags = FLAG_ADVANCED,
3003 .label = "default case",
3006 .ptr = &sDefault.iDefaultCase,
3008 .enum_list = enum_case,
3009 .flags = FLAG_ADVANCED | FLAG_SHARE,
3012 .label = "case sensitive",
3015 .ptr = &sDefault.iCaseSensitive,
3017 .enum_list = enum_bool_auto,
3018 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3021 .label = "casesignames",
3024 .ptr = &sDefault.iCaseSensitive,
3026 .enum_list = enum_bool_auto,
3027 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
3030 .label = "preserve case",
3033 .ptr = &sDefault.bCasePreserve,
3036 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3039 .label = "short preserve case",
3042 .ptr = &sDefault.bShortCasePreserve,
3045 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3048 .label = "mangling char",
3051 .ptr = &sDefault.magic_char,
3054 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3057 .label = "hide dot files",
3060 .ptr = &sDefault.bHideDotFiles,
3063 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3066 .label = "hide special files",
3069 .ptr = &sDefault.bHideSpecialFiles,
3072 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3075 .label = "hide unreadable",
3078 .ptr = &sDefault.bHideUnReadable,
3081 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3084 .label = "hide unwriteable files",
3087 .ptr = &sDefault.bHideUnWriteableFiles,
3090 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3093 .label = "delete veto files",
3096 .ptr = &sDefault.bDeleteVetoFiles,
3099 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3102 .label = "veto files",
3105 .ptr = &sDefault.szVetoFiles,
3108 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3111 .label = "hide files",
3114 .ptr = &sDefault.szHideFiles,
3117 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3120 .label = "veto oplock files",
3123 .ptr = &sDefault.szVetoOplockFiles,
3126 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3129 .label = "map archive",
3132 .ptr = &sDefault.bMap_archive,
3135 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3138 .label = "map hidden",
3141 .ptr = &sDefault.bMap_hidden,
3144 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3147 .label = "map system",
3150 .ptr = &sDefault.bMap_system,
3153 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3156 .label = "map readonly",
3159 .ptr = &sDefault.iMap_readonly,
3161 .enum_list = enum_map_readonly,
3162 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3165 .label = "mangled names",
3168 .ptr = &sDefault.bMangledNames,
3171 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3174 .label = "max stat cache size",
3176 .p_class = P_GLOBAL,
3177 .ptr = &Globals.iMaxStatCacheSize,
3180 .flags = FLAG_ADVANCED,
3183 .label = "stat cache",
3185 .p_class = P_GLOBAL,
3186 .ptr = &Globals.bStatCache,
3189 .flags = FLAG_ADVANCED,
3192 .label = "store dos attributes",
3195 .ptr = &sDefault.bStoreDosAttributes,
3198 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3201 .label = "dmapi support",
3204 .ptr = &sDefault.bDmapiSupport,
3207 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3211 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3214 .label = "machine password timeout",
3216 .p_class = P_GLOBAL,
3217 .ptr = &Globals.machine_password_timeout,
3220 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3223 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3226 .label = "add user script",
3228 .p_class = P_GLOBAL,
3229 .ptr = &Globals.szAddUserScript,
3232 .flags = FLAG_ADVANCED,
3235 .label = "rename user script",
3237 .p_class = P_GLOBAL,
3238 .ptr = &Globals.szRenameUserScript,
3241 .flags = FLAG_ADVANCED,
3244 .label = "delete user script",
3246 .p_class = P_GLOBAL,
3247 .ptr = &Globals.szDelUserScript,
3250 .flags = FLAG_ADVANCED,
3253 .label = "add group script",
3255 .p_class = P_GLOBAL,
3256 .ptr = &Globals.szAddGroupScript,
3259 .flags = FLAG_ADVANCED,
3262 .label = "delete group script",
3264 .p_class = P_GLOBAL,
3265 .ptr = &Globals.szDelGroupScript,
3268 .flags = FLAG_ADVANCED,
3271 .label = "add user to group script",
3273 .p_class = P_GLOBAL,
3274 .ptr = &Globals.szAddUserToGroupScript,
3277 .flags = FLAG_ADVANCED,
3280 .label = "delete user from group script",
3282 .p_class = P_GLOBAL,
3283 .ptr = &Globals.szDelUserFromGroupScript,
3286 .flags = FLAG_ADVANCED,
3289 .label = "set primary group script",
3291 .p_class = P_GLOBAL,
3292 .ptr = &Globals.szSetPrimaryGroupScript,
3295 .flags = FLAG_ADVANCED,
3298 .label = "add machine script",
3300 .p_class = P_GLOBAL,
3301 .ptr = &Globals.szAddMachineScript,
3304 .flags = FLAG_ADVANCED,
3307 .label = "shutdown script",
3309 .p_class = P_GLOBAL,
3310 .ptr = &Globals.szShutdownScript,
3313 .flags = FLAG_ADVANCED,
3316 .label = "abort shutdown script",
3318 .p_class = P_GLOBAL,
3319 .ptr = &Globals.szAbortShutdownScript,
3322 .flags = FLAG_ADVANCED,
3325 .label = "username map script",
3327 .p_class = P_GLOBAL,
3328 .ptr = &Globals.szUsernameMapScript,
3331 .flags = FLAG_ADVANCED,
3334 .label = "username map cache time",
3336 .p_class = P_GLOBAL,
3337 .ptr = &Globals.iUsernameMapCacheTime,
3340 .flags = FLAG_ADVANCED,
3343 .label = "logon script",
3345 .p_class = P_GLOBAL,
3346 .ptr = &Globals.szLogonScript,
3349 .flags = FLAG_ADVANCED,
3352 .label = "logon path",
3354 .p_class = P_GLOBAL,
3355 .ptr = &Globals.szLogonPath,
3358 .flags = FLAG_ADVANCED,
3361 .label = "logon drive",
3363 .p_class = P_GLOBAL,
3364 .ptr = &Globals.szLogonDrive,
3367 .flags = FLAG_ADVANCED,
3370 .label = "logon home",
3372 .p_class = P_GLOBAL,
3373 .ptr = &Globals.szLogonHome,
3376 .flags = FLAG_ADVANCED,
3379 .label = "domain logons",
3381 .p_class = P_GLOBAL,
3382 .ptr = &Globals.bDomainLogons,
3385 .flags = FLAG_ADVANCED,
3389 .label = "init logon delayed hosts",
3391 .p_class = P_GLOBAL,
3392 .ptr = &Globals.szInitLogonDelayedHosts,
3395 .flags = FLAG_ADVANCED,
3399 .label = "init logon delay",
3401 .p_class = P_GLOBAL,
3402 .ptr = &Globals.InitLogonDelay,
3405 .flags = FLAG_ADVANCED,
3409 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3412 .label = "os level",
3414 .p_class = P_GLOBAL,
3415 .ptr = &Globals.os_level,
3418 .flags = FLAG_BASIC | FLAG_ADVANCED,
3421 .label = "lm announce",
3423 .p_class = P_GLOBAL,
3424 .ptr = &Globals.lm_announce,
3426 .enum_list = enum_bool_auto,
3427 .flags = FLAG_ADVANCED,
3430 .label = "lm interval",
3432 .p_class = P_GLOBAL,
3433 .ptr = &Globals.lm_interval,
3436 .flags = FLAG_ADVANCED,
3439 .label = "preferred master",
3441 .p_class = P_GLOBAL,
3442 .ptr = &Globals.iPreferredMaster,
3444 .enum_list = enum_bool_auto,
3445 .flags = FLAG_BASIC | FLAG_ADVANCED,
3448 .label = "prefered master",
3450 .p_class = P_GLOBAL,
3451 .ptr = &Globals.iPreferredMaster,
3453 .enum_list = enum_bool_auto,
3457 .label = "local master",
3459 .p_class = P_GLOBAL,
3460 .ptr = &Globals.bLocalMaster,
3463 .flags = FLAG_BASIC | FLAG_ADVANCED,
3466 .label = "domain master",
3468 .p_class = P_GLOBAL,
3469 .ptr = &Globals.iDomainMaster,
3471 .enum_list = enum_bool_auto,
3472 .flags = FLAG_BASIC | FLAG_ADVANCED,
3475 .label = "browse list",
3477 .p_class = P_GLOBAL,
3478 .ptr = &Globals.bBrowseList,
3481 .flags = FLAG_ADVANCED,
3484 .label = "browseable",
3487 .ptr = &sDefault.bBrowseable,
3490 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3493 .label = "browsable",
3496 .ptr = &sDefault.bBrowseable,
3502 .label = "access based share enum",
3505 .ptr = &sDefault.bAccessBasedShareEnum,
3508 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3511 .label = "enhanced browsing",
3513 .p_class = P_GLOBAL,
3514 .ptr = &Globals.enhanced_browsing,
3517 .flags = FLAG_ADVANCED,
3520 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3523 .label = "dns proxy",
3525 .p_class = P_GLOBAL,
3526 .ptr = &Globals.bDNSproxy,
3529 .flags = FLAG_ADVANCED,
3532 .label = "wins proxy",
3534 .p_class = P_GLOBAL,
3535 .ptr = &Globals.bWINSproxy,
3538 .flags = FLAG_ADVANCED,
3541 .label = "wins server",
3543 .p_class = P_GLOBAL,
3544 .ptr = &Globals.szWINSservers,
3547 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3550 .label = "wins support",
3552 .p_class = P_GLOBAL,
3553 .ptr = &Globals.bWINSsupport,
3556 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3559 .label = "wins hook",
3561 .p_class = P_GLOBAL,
3562 .ptr = &Globals.szWINSHook,
3565 .flags = FLAG_ADVANCED,
3568 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3571 .label = "blocking locks",
3574 .ptr = &sDefault.bBlockingLocks,
3577 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3580 .label = "csc policy",
3583 .ptr = &sDefault.iCSCPolicy,
3585 .enum_list = enum_csc_policy,
3586 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3589 .label = "fake oplocks",
3592 .ptr = &sDefault.bFakeOplocks,
3595 .flags = FLAG_ADVANCED | FLAG_SHARE,
3598 .label = "kernel oplocks",
3600 .p_class = P_GLOBAL,
3601 .ptr = &Globals.bKernelOplocks,
3604 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3610 .ptr = &sDefault.bLocking,
3613 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3616 .label = "lock spin time",
3618 .p_class = P_GLOBAL,
3619 .ptr = &Globals.iLockSpinTime,
3622 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3628 .ptr = &sDefault.bOpLocks,
3631 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3634 .label = "level2 oplocks",
3637 .ptr = &sDefault.bLevel2OpLocks,
3640 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3643 .label = "oplock break wait time",
3645 .p_class = P_GLOBAL,
3646 .ptr = &Globals.oplock_break_wait_time,
3649 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3652 .label = "oplock contention limit",
3655 .ptr = &sDefault.iOplockContentionLimit,
3658 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3661 .label = "posix locking",
3664 .ptr = &sDefault.bPosixLocking,
3667 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3670 .label = "strict locking",
3673 .ptr = &sDefault.iStrictLocking,
3675 .enum_list = enum_bool_auto,
3676 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3679 .label = "share modes",
3682 .ptr = &sDefault.bShareModes,
3685 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3688 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3691 .label = "ldap admin dn",
3693 .p_class = P_GLOBAL,
3694 .ptr = &Globals.szLdapAdminDn,
3697 .flags = FLAG_ADVANCED,
3700 .label = "ldap delete dn",
3702 .p_class = P_GLOBAL,
3703 .ptr = &Globals.ldap_delete_dn,
3706 .flags = FLAG_ADVANCED,
3709 .label = "ldap group suffix",
3711 .p_class = P_GLOBAL,
3712 .ptr = &Globals.szLdapGroupSuffix,
3715 .flags = FLAG_ADVANCED,
3718 .label = "ldap idmap suffix",
3720 .p_class = P_GLOBAL,
3721 .ptr = &Globals.szLdapIdmapSuffix,
3724 .flags = FLAG_ADVANCED,
3727 .label = "ldap machine suffix",
3729 .p_class = P_GLOBAL,
3730 .ptr = &Globals.szLdapMachineSuffix,
3733 .flags = FLAG_ADVANCED,
3736 .label = "ldap passwd sync",
3738 .p_class = P_GLOBAL,
3739 .ptr = &Globals.ldap_passwd_sync,
3741 .enum_list = enum_ldap_passwd_sync,
3742 .flags = FLAG_ADVANCED,
3745 .label = "ldap password sync",
3747 .p_class = P_GLOBAL,
3748 .ptr = &Globals.ldap_passwd_sync,
3750 .enum_list = enum_ldap_passwd_sync,
3754 .label = "ldap replication sleep",
3756 .p_class = P_GLOBAL,
3757 .ptr = &Globals.ldap_replication_sleep,
3760 .flags = FLAG_ADVANCED,
3763 .label = "ldap suffix",
3765 .p_class = P_GLOBAL,
3766 .ptr = &Globals.szLdapSuffix,
3769 .flags = FLAG_ADVANCED,
3772 .label = "ldap ssl",
3774 .p_class = P_GLOBAL,
3775 .ptr = &Globals.ldap_ssl,
3777 .enum_list = enum_ldap_ssl,
3778 .flags = FLAG_ADVANCED,
3781 .label = "ldap ssl ads",
3783 .p_class = P_GLOBAL,
3784 .ptr = &Globals.ldap_ssl_ads,
3787 .flags = FLAG_ADVANCED,
3790 .label = "ldap deref",
3792 .p_class = P_GLOBAL,
3793 .ptr = &Globals.ldap_deref,
3795 .enum_list = enum_ldap_deref,
3796 .flags = FLAG_ADVANCED,
3799 .label = "ldap follow referral",
3801 .p_class = P_GLOBAL,
3802 .ptr = &Globals.ldap_follow_referral,
3804 .enum_list = enum_bool_auto,
3805 .flags = FLAG_ADVANCED,
3808 .label = "ldap timeout",
3810 .p_class = P_GLOBAL,
3811 .ptr = &Globals.ldap_timeout,
3814 .flags = FLAG_ADVANCED,
3817 .label = "ldap connection timeout",
3819 .p_class = P_GLOBAL,
3820 .ptr = &Globals.ldap_connection_timeout,
3823 .flags = FLAG_ADVANCED,
3826 .label = "ldap page size",
3828 .p_class = P_GLOBAL,
3829 .ptr = &Globals.ldap_page_size,
3832 .flags = FLAG_ADVANCED,
3835 .label = "ldap user suffix",
3837 .p_class = P_GLOBAL,
3838 .ptr = &Globals.szLdapUserSuffix,
3841 .flags = FLAG_ADVANCED,
3844 .label = "ldap debug level",
3846 .p_class = P_GLOBAL,
3847 .ptr = &Globals.ldap_debug_level,
3848 .special = handle_ldap_debug_level,
3850 .flags = FLAG_ADVANCED,
3853 .label = "ldap debug threshold",
3855 .p_class = P_GLOBAL,
3856 .ptr = &Globals.ldap_debug_threshold,
3859 .flags = FLAG_ADVANCED,
3862 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3865 .label = "eventlog list",
3867 .p_class = P_GLOBAL,
3868 .ptr = &Globals.szEventLogs,
3871 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3874 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3877 .label = "add share command",
3879 .p_class = P_GLOBAL,
3880 .ptr = &Globals.szAddShareCommand,
3883 .flags = FLAG_ADVANCED,
3886 .label = "change share command",
3888 .p_class = P_GLOBAL,
3889 .ptr = &Globals.szChangeShareCommand,
3892 .flags = FLAG_ADVANCED,
3895 .label = "delete share command",
3897 .p_class = P_GLOBAL,
3898 .ptr = &Globals.szDeleteShareCommand,
3901 .flags = FLAG_ADVANCED,
3904 .label = "config file",
3906 .p_class = P_GLOBAL,
3907 .ptr = &Globals.szConfigFile,
3910 .flags = FLAG_HIDE|FLAG_META,
3915 .p_class = P_GLOBAL,
3916 .ptr = &Globals.szAutoServices,
3919 .flags = FLAG_ADVANCED,
3922 .label = "auto services",
3924 .p_class = P_GLOBAL,
3925 .ptr = &Globals.szAutoServices,
3928 .flags = FLAG_ADVANCED,
3931 .label = "lock directory",
3933 .p_class = P_GLOBAL,
3934 .ptr = &Globals.szLockDir,
3937 .flags = FLAG_ADVANCED,
3940 .label = "lock dir",
3942 .p_class = P_GLOBAL,
3943 .ptr = &Globals.szLockDir,
3949 .label = "state directory",
3951 .p_class = P_GLOBAL,
3952 .ptr = &Globals.szStateDir,
3955 .flags = FLAG_ADVANCED,
3958 .label = "cache directory",
3960 .p_class = P_GLOBAL,
3961 .ptr = &Globals.szCacheDir,
3964 .flags = FLAG_ADVANCED,
3967 .label = "pid directory",
3969 .p_class = P_GLOBAL,
3970 .ptr = &Globals.szPidDir,
3973 .flags = FLAG_ADVANCED,
3977 .label = "utmp directory",
3979 .p_class = P_GLOBAL,
3980 .ptr = &Globals.szUtmpDir,
3983 .flags = FLAG_ADVANCED,
3986 .label = "wtmp directory",
3988 .p_class = P_GLOBAL,
3989 .ptr = &Globals.szWtmpDir,
3992 .flags = FLAG_ADVANCED,
3997 .p_class = P_GLOBAL,
3998 .ptr = &Globals.bUtmp,
4001 .flags = FLAG_ADVANCED,
4005 .label = "default service",
4007 .p_class = P_GLOBAL,
4008 .ptr = &Globals.szDefaultService,
4011 .flags = FLAG_ADVANCED,
4016 .p_class = P_GLOBAL,
4017 .ptr = &Globals.szDefaultService,
4020 .flags = FLAG_ADVANCED,
4023 .label = "message command",
4025 .p_class = P_GLOBAL,
4026 .ptr = &Globals.szMsgCommand,
4029 .flags = FLAG_ADVANCED,
4032 .label = "dfree cache time",
4035 .ptr = &sDefault.iDfreeCacheTime,
4038 .flags = FLAG_ADVANCED,
4041 .label = "dfree command",
4044 .ptr = &sDefault.szDfree,
4047 .flags = FLAG_ADVANCED,
4050 .label = "get quota command",
4052 .p_class = P_GLOBAL,
4053 .ptr = &Globals.szGetQuota,
4056 .flags = FLAG_ADVANCED,
4059 .label = "set quota command",
4061 .p_class = P_GLOBAL,
4062 .ptr = &Globals.szSetQuota,
4065 .flags = FLAG_ADVANCED,
4068 .label = "remote announce",
4070 .p_class = P_GLOBAL,
4071 .ptr = &Globals.szRemoteAnnounce,
4074 .flags = FLAG_ADVANCED,
4077 .label = "remote browse sync",
4079 .p_class = P_GLOBAL,
4080 .ptr = &Globals.szRemoteBrowseSync,
4083 .flags = FLAG_ADVANCED,
4086 .label = "socket address",
4088 .p_class = P_GLOBAL,
4089 .ptr = &Globals.szSocketAddress,
4092 .flags = FLAG_ADVANCED,
4095 .label = "nmbd bind explicit broadcast",
4097 .p_class = P_GLOBAL,
4098 .ptr = &Globals.bNmbdBindExplicitBroadcast,
4101 .flags = FLAG_ADVANCED,
4104 .label = "homedir map",
4106 .p_class = P_GLOBAL,
4107 .ptr = &Globals.szNISHomeMapName,
4110 .flags = FLAG_ADVANCED,
4113 .label = "afs username map",
4115 .p_class = P_GLOBAL,
4116 .ptr = &Globals.szAfsUsernameMap,
4119 .flags = FLAG_ADVANCED,
4122 .label = "afs token lifetime",
4124 .p_class = P_GLOBAL,
4125 .ptr = &Globals.iAfsTokenLifetime,
4128 .flags = FLAG_ADVANCED,
4131 .label = "log nt token command",
4133 .p_class = P_GLOBAL,
4134 .ptr = &Globals.szLogNtTokenCommand,
4137 .flags = FLAG_ADVANCED,
4140 .label = "time offset",
4142 .p_class = P_GLOBAL,
4143 .ptr = &extra_time_offset,
4146 .flags = FLAG_ADVANCED,
4149 .label = "NIS homedir",
4151 .p_class = P_GLOBAL,
4152 .ptr = &Globals.bNISHomeMap,
4155 .flags = FLAG_ADVANCED,
4161 .ptr = &sDefault.valid,
4170 .ptr = &sDefault.szCopy,
4171 .special = handle_copy,
4179 .ptr = &sDefault.szInclude,
4180 .special = handle_include,
4182 .flags = FLAG_HIDE|FLAG_META,
4188 .ptr = &sDefault.szPreExec,
4191 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4197 .ptr = &sDefault.szPreExec,
4200 .flags = FLAG_ADVANCED,
4203 .label = "preexec close",
4206 .ptr = &sDefault.bPreexecClose,
4209 .flags = FLAG_ADVANCED | FLAG_SHARE,
4212 .label = "postexec",
4215 .ptr = &sDefault.szPostExec,
4218 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4221 .label = "root preexec",
4224 .ptr = &sDefault.szRootPreExec,
4227 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4230 .label = "root preexec close",
4233 .ptr = &sDefault.bRootpreexecClose,
4236 .flags = FLAG_ADVANCED | FLAG_SHARE,
4239 .label = "root postexec",
4242 .ptr = &sDefault.szRootPostExec,
4245 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4248 .label = "available",
4251 .ptr = &sDefault.bAvailable,
4254 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4257 .label = "registry shares",
4259 .p_class = P_GLOBAL,
4260 .ptr = &Globals.bRegistryShares,
4263 .flags = FLAG_ADVANCED,
4266 .label = "usershare allow guests",
4268 .p_class = P_GLOBAL,
4269 .ptr = &Globals.bUsershareAllowGuests,
4272 .flags = FLAG_ADVANCED,
4275 .label = "usershare max shares",
4277 .p_class = P_GLOBAL,
4278 .ptr = &Globals.iUsershareMaxShares,
4281 .flags = FLAG_ADVANCED,
4284 .label = "usershare owner only",
4286 .p_class = P_GLOBAL,
4287 .ptr = &Globals.bUsershareOwnerOnly,
4290 .flags = FLAG_ADVANCED,
4293 .label = "usershare path",
4295 .p_class = P_GLOBAL,
4296 .ptr = &Globals.szUsersharePath,
4299 .flags = FLAG_ADVANCED,
4302 .label = "usershare prefix allow list",
4304 .p_class = P_GLOBAL,
4305 .ptr = &Globals.szUsersharePrefixAllowList,
4308 .flags = FLAG_ADVANCED,
4311 .label = "usershare prefix deny list",
4313 .p_class = P_GLOBAL,
4314 .ptr = &Globals.szUsersharePrefixDenyList,
4317 .flags = FLAG_ADVANCED,
4320 .label = "usershare template share",
4322 .p_class = P_GLOBAL,
4323 .ptr = &Globals.szUsershareTemplateShare,
4326 .flags = FLAG_ADVANCED,
4332 .ptr = &sDefault.volume,
4335 .flags = FLAG_ADVANCED | FLAG_SHARE,
4341 .ptr = &sDefault.fstype,
4344 .flags = FLAG_ADVANCED | FLAG_SHARE,
4347 .label = "set directory",
4350 .ptr = &sDefault.bNo_set_dir,
4353 .flags = FLAG_ADVANCED | FLAG_SHARE,
4356 .label = "wide links",
4359 .ptr = &sDefault.bWidelinks,
4362 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4365 .label = "follow symlinks",
4368 .ptr = &sDefault.bSymlinks,
4371 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4374 .label = "dont descend",
4377 .ptr = &sDefault.szDontdescend,
4380 .flags = FLAG_ADVANCED | FLAG_SHARE,
4383 .label = "magic script",
4386 .ptr = &sDefault.szMagicScript,
4389 .flags = FLAG_ADVANCED | FLAG_SHARE,
4392 .label = "magic output",
4395 .ptr = &sDefault.szMagicOutput,
4398 .flags = FLAG_ADVANCED | FLAG_SHARE,
4401 .label = "delete readonly",
4404 .ptr = &sDefault.bDeleteReadonly,
4407 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4410 .label = "dos filemode",
4413 .ptr = &sDefault.bDosFilemode,
4416 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4419 .label = "dos filetimes",
4422 .ptr = &sDefault.bDosFiletimes,
4425 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4428 .label = "dos filetime resolution",
4431 .ptr = &sDefault.bDosFiletimeResolution,
4434 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4437 .label = "fake directory create times",
4440 .ptr = &sDefault.bFakeDirCreateTimes,
4443 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4446 .label = "async smb echo handler",
4448 .p_class = P_GLOBAL,
4449 .ptr = &Globals.bAsyncSMBEchoHandler,
4452 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4455 .label = "multicast dns register",
4457 .p_class = P_GLOBAL,
4458 .ptr = &Globals.bMulticastDnsRegister,
4461 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4464 .label = "panic action",
4466 .p_class = P_GLOBAL,
4467 .ptr = &Globals.szPanicAction,
4470 .flags = FLAG_ADVANCED,
4473 .label = "perfcount module",
4475 .p_class = P_GLOBAL,
4476 .ptr = &Globals.szSMBPerfcountModule,
4479 .flags = FLAG_ADVANCED,
4482 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4485 .label = "vfs objects",
4488 .ptr = &sDefault.szVfsObjects,
4491 .flags = FLAG_ADVANCED | FLAG_SHARE,
4494 .label = "vfs object",
4497 .ptr = &sDefault.szVfsObjects,
4504 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4507 .label = "msdfs root",
4510 .ptr = &sDefault.bMSDfsRoot,
4513 .flags = FLAG_ADVANCED | FLAG_SHARE,
4516 .label = "msdfs proxy",
4519 .ptr = &sDefault.szMSDfsProxy,
4522 .flags = FLAG_ADVANCED | FLAG_SHARE,
4525 .label = "host msdfs",
4527 .p_class = P_GLOBAL,
4528 .ptr = &Globals.bHostMSDfs,
4531 .flags = FLAG_ADVANCED,
4534 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4537 .label = "passdb expand explicit",
4539 .p_class = P_GLOBAL,
4540 .ptr = &Globals.bPassdbExpandExplicit,
4543 .flags = FLAG_ADVANCED,
4546 .label = "idmap backend",
4548 .p_class = P_GLOBAL,
4549 .ptr = &Globals.szIdmapBackend,
4552 .flags = FLAG_ADVANCED,
4555 .label = "idmap cache time",
4557 .p_class = P_GLOBAL,
4558 .ptr = &Globals.iIdmapCacheTime,
4561 .flags = FLAG_ADVANCED,
4564 .label = "idmap negative cache time",
4566 .p_class = P_GLOBAL,
4567 .ptr = &Globals.iIdmapNegativeCacheTime,
4570 .flags = FLAG_ADVANCED,
4573 .label = "idmap uid",
4575 .p_class = P_GLOBAL,
4576 .ptr = &Globals.szIdmapUID,
4577 .special = handle_idmap_uid,
4579 .flags = FLAG_ADVANCED,
4582 .label = "winbind uid",
4584 .p_class = P_GLOBAL,
4585 .ptr = &Globals.szIdmapUID,
4586 .special = handle_idmap_uid,
4591 .label = "idmap gid",
4593 .p_class = P_GLOBAL,
4594 .ptr = &Globals.szIdmapGID,
4595 .special = handle_idmap_gid,
4597 .flags = FLAG_ADVANCED,
4600 .label = "winbind gid",
4602 .p_class = P_GLOBAL,
4603 .ptr = &Globals.szIdmapGID,
4604 .special = handle_idmap_gid,
4609 .label = "template homedir",
4611 .p_class = P_GLOBAL,
4612 .ptr = &Globals.szTemplateHomedir,
4615 .flags = FLAG_ADVANCED,
4618 .label = "template shell",
4620 .p_class = P_GLOBAL,
4621 .ptr = &Globals.szTemplateShell,
4624 .flags = FLAG_ADVANCED,
4627 .label = "winbind separator",
4629 .p_class = P_GLOBAL,
4630 .ptr = &Globals.szWinbindSeparator,
4633 .flags = FLAG_ADVANCED,
4636 .label = "winbind cache time",
4638 .p_class = P_GLOBAL,
4639 .ptr = &Globals.winbind_cache_time,
4642 .flags = FLAG_ADVANCED,
4645 .label = "winbind reconnect delay",
4647 .p_class = P_GLOBAL,
4648 .ptr = &Globals.winbind_reconnect_delay,
4651 .flags = FLAG_ADVANCED,
4654 .label = "winbind max clients",
4656 .p_class = P_GLOBAL,
4657 .ptr = &Globals.winbind_max_clients,
4660 .flags = FLAG_ADVANCED,
4663 .label = "winbind enum users",
4665 .p_class = P_GLOBAL,
4666 .ptr = &Globals.bWinbindEnumUsers,
4669 .flags = FLAG_ADVANCED,
4672 .label = "winbind enum groups",
4674 .p_class = P_GLOBAL,
4675 .ptr = &Globals.bWinbindEnumGroups,
4678 .flags = FLAG_ADVANCED,
4681 .label = "winbind use default domain",
4683 .p_class = P_GLOBAL,
4684 .ptr = &Globals.bWinbindUseDefaultDomain,
4687 .flags = FLAG_ADVANCED,
4690 .label = "winbind trusted domains only",
4692 .p_class = P_GLOBAL,
4693 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4696 .flags = FLAG_ADVANCED,
4699 .label = "winbind nested groups",
4701 .p_class = P_GLOBAL,
4702 .ptr = &Globals.bWinbindNestedGroups,
4705 .flags = FLAG_ADVANCED,
4708 .label = "winbind expand groups",
4710 .p_class = P_GLOBAL,
4711 .ptr = &Globals.winbind_expand_groups,
4714 .flags = FLAG_ADVANCED,
4717 .label = "winbind nss info",
4719 .p_class = P_GLOBAL,
4720 .ptr = &Globals.szWinbindNssInfo,
4723 .flags = FLAG_ADVANCED,
4726 .label = "winbind refresh tickets",
4728 .p_class = P_GLOBAL,
4729 .ptr = &Globals.bWinbindRefreshTickets,
4732 .flags = FLAG_ADVANCED,
4735 .label = "winbind offline logon",
4737 .p_class = P_GLOBAL,
4738 .ptr = &Globals.bWinbindOfflineLogon,
4741 .flags = FLAG_ADVANCED,
4744 .label = "winbind normalize names",
4746 .p_class = P_GLOBAL,
4747 .ptr = &Globals.bWinbindNormalizeNames,
4750 .flags = FLAG_ADVANCED,
4753 .label = "winbind rpc only",
4755 .p_class = P_GLOBAL,
4756 .ptr = &Globals.bWinbindRpcOnly,
4759 .flags = FLAG_ADVANCED,
4762 .label = "create krb5 conf",
4764 .p_class = P_GLOBAL,
4765 .ptr = &Globals.bCreateKrb5Conf,
4768 .flags = FLAG_ADVANCED,
4771 .label = "ncalrpc dir",
4773 .p_class = P_GLOBAL,
4774 .ptr = &Globals.ncalrpc_dir,
4777 .flags = FLAG_ADVANCED,
4780 .label = "winbind max domain connections",
4782 .p_class = P_GLOBAL,
4783 .ptr = &Globals.winbindMaxDomainConnections,
4786 .flags = FLAG_ADVANCED,
4789 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4792 /***************************************************************************
4793 Initialise the sDefault parameter structure for the printer values.
4794 ***************************************************************************/
4796 static void init_printer_values(struct service *pService)
4798 /* choose defaults depending on the type of printing */
4799 switch (pService->iPrinting) {
4804 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4805 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4806 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4811 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4812 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4813 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4814 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4815 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4816 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4817 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4823 /* set the lpq command to contain the destination printer
4824 name only. This is used by cups_queue_get() */
4825 string_set(&pService->szLpqcommand, "%p");
4826 string_set(&pService->szLprmcommand, "");
4827 string_set(&pService->szPrintcommand, "");
4828 string_set(&pService->szLppausecommand, "");
4829 string_set(&pService->szLpresumecommand, "");
4830 string_set(&pService->szQueuepausecommand, "");
4831 string_set(&pService->szQueueresumecommand, "");
4833 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4834 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4835 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4836 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4837 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4838 string_set(&pService->szQueuepausecommand, "disable '%p'");
4839 string_set(&pService->szQueueresumecommand, "enable '%p'");
4840 #endif /* HAVE_CUPS */
4845 string_set(&pService->szLpqcommand, "lpstat -o%p");
4846 string_set(&pService->szLprmcommand, "cancel %p-%j");
4847 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4848 string_set(&pService->szQueuepausecommand, "disable %p");
4849 string_set(&pService->szQueueresumecommand, "enable %p");
4851 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4852 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4857 string_set(&pService->szLpqcommand, "lpq -P%p");
4858 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4859 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4862 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4866 string_set(&pService->szPrintcommand, "vlp print %p %s");
4867 string_set(&pService->szLpqcommand, "vlp lpq %p");
4868 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4869 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4870 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4871 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4872 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4874 #endif /* DEVELOPER */
4879 * Function to return the default value for the maximum number of open
4880 * file descriptors permitted. This function tries to consult the
4881 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4882 * the smaller of those.
4884 static int max_open_files(void)
4886 int sysctl_max = MAX_OPEN_FILES;
4887 int rlimit_max = MAX_OPEN_FILES;
4889 #ifdef HAVE_SYSCTLBYNAME
4891 size_t size = sizeof(sysctl_max);
4892 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4897 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4903 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4904 rlimit_max = rl.rlim_cur;
4906 #if defined(RLIM_INFINITY)
4907 if(rl.rlim_cur == RLIM_INFINITY)
4908 rlimit_max = MAX_OPEN_FILES;
4913 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4914 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4915 "minimum Windows limit (%d)\n",
4917 MIN_OPEN_FILES_WINDOWS));
4918 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4921 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4922 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4923 "minimum Windows limit (%d)\n",
4925 MIN_OPEN_FILES_WINDOWS));
4926 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4929 return MIN(sysctl_max, rlimit_max);
4933 * Common part of freeing allocated data for one parameter.
4935 static void free_one_parameter_common(void *parm_ptr,
4936 struct parm_struct parm)
4938 if ((parm.type == P_STRING) ||
4939 (parm.type == P_USTRING))
4941 string_free((char**)parm_ptr);
4942 } else if (parm.type == P_LIST) {
4943 TALLOC_FREE(*((char***)parm_ptr));
4948 * Free the allocated data for one parameter for a share
4949 * given as a service struct.
4951 static void free_one_parameter(struct service *service,
4952 struct parm_struct parm)
4956 if (parm.p_class != P_LOCAL) {
4960 parm_ptr = lp_local_ptr(service, parm.ptr);
4962 free_one_parameter_common(parm_ptr, parm);
4966 * Free the allocated parameter data of a share given
4967 * as a service struct.
4969 static void free_parameters(struct service *service)
4973 for (i=0; parm_table[i].label; i++) {
4974 free_one_parameter(service, parm_table[i]);
4979 * Free the allocated data for one parameter for a given share
4980 * specified by an snum.
4982 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4986 if (parm.ptr == NULL) {
4991 parm_ptr = parm.ptr;
4992 } else if (parm.p_class != P_LOCAL) {
4995 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4998 free_one_parameter_common(parm_ptr, parm);
5002 * Free the allocated parameter data for a share specified
5005 static void free_parameters_by_snum(int snum)
5009 for (i=0; parm_table[i].label; i++) {
5010 free_one_parameter_by_snum(snum, parm_table[i]);
5015 * Free the allocated global parameters.
5017 static void free_global_parameters(void)
5019 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
5022 static int map_parameter(const char *pszParmName);
5024 struct lp_stored_option {
5025 struct lp_stored_option *prev, *next;
5030 static struct lp_stored_option *stored_options;
5033 save options set by lp_set_cmdline() into a list. This list is
5034 re-applied when we do a globals reset, so that cmdline set options
5035 are sticky across reloads of smb.conf
5037 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
5039 struct lp_stored_option *entry, *entry_next;
5040 for (entry = stored_options; entry != NULL; entry = entry_next) {
5041 entry_next = entry->next;
5042 if (strcmp(pszParmName, entry->label) == 0) {
5043 DLIST_REMOVE(stored_options, entry);
5049 entry = talloc(NULL, struct lp_stored_option);
5054 entry->label = talloc_strdup(entry, pszParmName);
5055 if (!entry->label) {
5060 entry->value = talloc_strdup(entry, pszParmValue);
5061 if (!entry->value) {
5066 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
5071 static bool apply_lp_set_cmdline(void)
5073 struct lp_stored_option *entry = NULL;
5074 for (entry = stored_options; entry != NULL; entry = entry->next) {
5075 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
5076 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
5077 entry->label, entry->value));
5084 /***************************************************************************
5085 Initialise the global parameter structure.
5086 ***************************************************************************/
5088 static void init_globals(bool reinit_globals)
5090 static bool done_init = False;
5094 /* If requested to initialize only once and we've already done it... */
5095 if (!reinit_globals && done_init) {
5096 /* ... then we have nothing more to do */
5101 /* The logfile can be set before this is invoked. Free it if so. */
5102 if (Globals.szLogFile != NULL) {
5103 string_free(&Globals.szLogFile);
5104 Globals.szLogFile = NULL;
5108 free_global_parameters();
5111 /* This memset and the free_global_parameters() above will
5112 * wipe out smb.conf options set with lp_set_cmdline(). The
5113 * apply_lp_set_cmdline() call puts these values back in the
5114 * table once the defaults are set */
5115 memset((void *)&Globals, '\0', sizeof(Globals));
5117 for (i = 0; parm_table[i].label; i++) {
5118 if ((parm_table[i].type == P_STRING ||
5119 parm_table[i].type == P_USTRING) &&
5122 string_set((char **)parm_table[i].ptr, "");
5126 string_set(&sDefault.fstype, FSTYPE_STRING);
5127 string_set(&sDefault.szPrintjobUsername, "%U");
5129 init_printer_values(&sDefault);
5132 DEBUG(3, ("Initialising global parameters\n"));
5134 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
5135 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
5137 /* use the new 'hash2' method by default, with a prefix of 1 */
5138 string_set(&Globals.szManglingMethod, "hash2");
5139 Globals.mangle_prefix = 1;
5141 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5143 /* using UTF8 by default allows us to support all chars */
5144 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5146 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
5147 /* If the system supports nl_langinfo(), try to grab the value
5148 from the user's locale */
5149 string_set(&Globals.display_charset, "LOCALE");
5151 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
5154 /* Use codepage 850 as a default for the dos character set */
5155 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5158 * Allow the default PASSWD_CHAT to be overridden in local.h.
5160 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5162 set_global_myname(myhostname());
5163 string_set(&Globals.szNetbiosName,global_myname());
5165 set_global_myworkgroup(WORKGROUP);
5166 string_set(&Globals.szWorkgroup, lp_workgroup());
5168 string_set(&Globals.szPasswdProgram, "");
5169 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5170 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5171 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5172 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5173 string_set(&Globals.szSocketAddress, "0.0.0.0");
5175 * By default support explicit binding to broadcast
5178 Globals.bNmbdBindExplicitBroadcast = true;
5180 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5181 smb_panic("init_globals: ENOMEM");
5183 string_set(&Globals.szServerString, s);
5185 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5186 DEFAULT_MINOR_VERSION) < 0) {
5187 smb_panic("init_globals: ENOMEM");
5189 string_set(&Globals.szAnnounceVersion, s);
5192 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5195 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5197 string_set(&Globals.szLogonDrive, "");
5198 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5199 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5200 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5202 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5203 string_set(&Globals.szPasswordServer, "*");
5205 Globals.AlgorithmicRidBase = BASE_RID;
5207 Globals.bLoadPrinters = True;
5208 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
5210 Globals.ConfigBackend = config_backend;
5212 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5213 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5214 Globals.max_xmit = 0x4104;
5215 Globals.max_mux = 50; /* This is *needed* for profile support. */
5216 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
5217 Globals.bDisableSpoolss = False;
5218 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5219 Globals.pwordlevel = 0;
5220 Globals.unamelevel = 0;
5221 Globals.deadtime = 0;
5222 Globals.getwd_cache = true;
5223 Globals.bLargeReadwrite = True;
5224 Globals.max_log_size = 5000;
5225 Globals.max_open_files = max_open_files();
5226 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5227 Globals.maxprotocol = PROTOCOL_NT1;
5228 Globals.minprotocol = PROTOCOL_CORE;
5229 Globals.security = SEC_USER;
5230 Globals.paranoid_server_security = True;
5231 Globals.bEncryptPasswords = True;
5232 Globals.bUpdateEncrypt = False;
5233 Globals.clientSchannel = Auto;
5234 Globals.serverSchannel = Auto;
5235 Globals.bReadRaw = True;
5236 Globals.bWriteRaw = True;
5237 Globals.bNullPasswords = False;
5238 Globals.bObeyPamRestrictions = False;
5240 Globals.bSyslogOnly = False;
5241 Globals.bTimestampLogs = True;
5242 string_set(&Globals.szLogLevel, "0");
5243 Globals.bDebugPrefixTimestamp = False;
5244 Globals.bDebugHiresTimestamp = true;
5245 Globals.bDebugPid = False;
5246 Globals.bDebugUid = False;
5247 Globals.bDebugClass = False;
5248 Globals.bEnableCoreFiles = True;
5249 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5250 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5251 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5252 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5253 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5254 Globals.lm_interval = 60;
5255 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5256 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5257 Globals.bNISHomeMap = False;
5258 #ifdef WITH_NISPLUS_HOME
5259 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5261 string_set(&Globals.szNISHomeMapName, "auto.home");
5264 Globals.bTimeServer = False;
5265 Globals.bBindInterfacesOnly = False;
5266 Globals.bUnixPasswdSync = False;
5267 Globals.bPamPasswordChange = False;
5268 Globals.bPasswdChatDebug = False;
5269 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5270 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5271 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5272 Globals.bStatCache = True; /* use stat cache by default */
5273 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5274 Globals.restrict_anonymous = 0;
5275 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5276 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5277 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5278 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5279 Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
5280 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
5282 Globals.map_to_guest = 0; /* By Default, "Never" */
5283 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5284 Globals.enhanced_browsing = true;
5285 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5286 #ifdef MMAP_BLACKLIST
5287 Globals.bUseMmap = False;
5289 Globals.bUseMmap = True;
5291 Globals.bUnixExtensions = True;
5292 Globals.bResetOnZeroVC = False;
5293 Globals.bLogWriteableFilesOnExit = False;
5294 Globals.bCreateKrb5Conf = true;
5295 Globals.winbindMaxDomainConnections = 1;
5297 /* hostname lookups can be very expensive and are broken on
5298 a large number of sites (tridge) */
5299 Globals.bHostnameLookups = False;
5301 string_set(&Globals.szPassdbBackend, "tdbsam");
5302 string_set(&Globals.szLdapSuffix, "");
5303 string_set(&Globals.szLdapMachineSuffix, "");
5304 string_set(&Globals.szLdapUserSuffix, "");
5305 string_set(&Globals.szLdapGroupSuffix, "");
5306 string_set(&Globals.szLdapIdmapSuffix, "");
5308 string_set(&Globals.szLdapAdminDn, "");
5309 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5310 Globals.ldap_ssl_ads = False;
5311 Globals.ldap_deref = -1;
5312 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5313 Globals.ldap_delete_dn = False;
5314 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5315 Globals.ldap_follow_referral = Auto;
5316 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5317 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5318 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5320 Globals.ldap_debug_level = 0;
5321 Globals.ldap_debug_threshold = 10;
5323 /* This is what we tell the afs client. in reality we set the token
5324 * to never expire, though, when this runs out the afs client will
5325 * forget the token. Set to 0 to get NEVERDATE.*/
5326 Globals.iAfsTokenLifetime = 604800;
5327 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5329 /* these parameters are set to defaults that are more appropriate
5330 for the increasing samba install base:
5332 as a member of the workgroup, that will possibly become a
5333 _local_ master browser (lm = True). this is opposed to a forced
5334 local master browser startup (pm = True).
5336 doesn't provide WINS server service by default (wsupp = False),
5337 and doesn't provide domain master browser services by default, either.
5341 Globals.bMsAddPrinterWizard = True;
5342 Globals.os_level = 20;
5343 Globals.bLocalMaster = True;
5344 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5345 Globals.bDomainLogons = False;
5346 Globals.bBrowseList = True;
5347 Globals.bWINSsupport = False;
5348 Globals.bWINSproxy = False;
5350 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5351 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5353 Globals.bDNSproxy = True;
5355 /* this just means to use them if they exist */
5356 Globals.bKernelOplocks = True;
5358 Globals.bAllowTrustedDomains = True;
5359 string_set(&Globals.szIdmapBackend, "tdb");
5360 Globals.bIdmapReadOnly = false;
5362 string_set(&Globals.szTemplateShell, "/bin/false");
5363 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5364 string_set(&Globals.szWinbindSeparator, "\\");
5366 string_set(&Globals.szCupsServer, "");
5367 string_set(&Globals.szIPrintServer, "");
5369 string_set(&Globals.ctdbdSocket, "");
5370 Globals.szClusterAddresses = NULL;
5371 Globals.clustering = False;
5372 Globals.ctdb_timeout = 0;
5373 Globals.ctdb_locktime_warn_threshold = 0;
5375 Globals.winbind_cache_time = 300; /* 5 minutes */
5376 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5377 Globals.winbind_max_clients = 200;
5378 Globals.bWinbindEnumUsers = False;
5379 Globals.bWinbindEnumGroups = False;
5380 Globals.bWinbindUseDefaultDomain = False;
5381 Globals.bWinbindTrustedDomainsOnly = False;
5382 Globals.bWinbindNestedGroups = True;
5383 Globals.winbind_expand_groups = 1;
5384 Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
5385 Globals.bWinbindRefreshTickets = False;
5386 Globals.bWinbindOfflineLogon = False;
5388 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5389 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5391 Globals.bPassdbExpandExplicit = False;
5393 Globals.name_cache_timeout = 660; /* In seconds */
5395 Globals.bUseSpnego = True;
5396 Globals.bClientUseSpnego = True;
5398 Globals.client_signing = Auto;
5399 Globals.server_signing = False;
5401 Globals.bDeferSharingViolations = True;
5402 string_set(&Globals.smb_ports, SMB_PORTS);
5404 Globals.bEnablePrivileges = True;
5405 Globals.bHostMSDfs = True;
5406 Globals.bASUSupport = False;
5408 /* User defined shares. */
5409 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5410 smb_panic("init_globals: ENOMEM");
5412 string_set(&Globals.szUsersharePath, s);
5414 string_set(&Globals.szUsershareTemplateShare, "");
5415 Globals.iUsershareMaxShares = 0;
5416 /* By default disallow sharing of directories not owned by the sharer. */
5417 Globals.bUsershareOwnerOnly = True;
5418 /* By default disallow guest access to usershares. */
5419 Globals.bUsershareAllowGuests = False;
5421 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5423 /* By default no shares out of the registry */
5424 Globals.bRegistryShares = False;
5426 Globals.iminreceivefile = 0;
5428 Globals.bMapUntrustedToDomain = false;
5429 Globals.bMulticastDnsRegister = true;
5431 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
5432 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
5433 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
5434 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5436 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5438 /* Now put back the settings that were set with lp_set_cmdline() */
5439 apply_lp_set_cmdline();
5442 /*******************************************************************
5443 Convenience routine to grab string parameters into temporary memory
5444 and run standard_sub_basic on them. The buffers can be written to by
5445 callers without affecting the source string.
5446 ********************************************************************/
5448 static char *lp_string(const char *s)
5451 TALLOC_CTX *ctx = talloc_tos();
5453 /* The follow debug is useful for tracking down memory problems
5454 especially if you have an inner loop that is calling a lp_*()
5455 function that returns a string. Perhaps this debug should be
5456 present all the time? */
5459 DEBUG(10, ("lp_string(%s)\n", s));
5465 ret = talloc_sub_basic(ctx,
5466 get_current_username(),
5467 current_user_info.domain,
5469 if (trim_char(ret, '\"', '\"')) {
5470 if (strchr(ret,'\"') != NULL) {
5472 ret = talloc_sub_basic(ctx,
5473 get_current_username(),
5474 current_user_info.domain,
5482 In this section all the functions that are used to access the
5483 parameters from the rest of the program are defined
5486 #define FN_GLOBAL_STRING(fn_name,ptr) \
5487 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5488 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5489 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5490 #define FN_GLOBAL_LIST(fn_name,ptr) \
5491 const char **fn_name(void) {return(*(const char ***)(ptr));}
5492 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5493 bool fn_name(void) {return(*(bool *)(ptr));}
5494 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5495 char fn_name(void) {return(*(char *)(ptr));}
5496 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5497 int fn_name(void) {return(*(int *)(ptr));}
5499 #define FN_LOCAL_STRING(fn_name,val) \
5500 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5501 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5502 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5503 #define FN_LOCAL_LIST(fn_name,val) \
5504 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5505 #define FN_LOCAL_BOOL(fn_name,val) \
5506 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5507 #define FN_LOCAL_INTEGER(fn_name,val) \
5508 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5510 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5511 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5512 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5513 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5514 #define FN_LOCAL_CHAR(fn_name,val) \
5515 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5517 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5518 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5519 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5520 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5521 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5522 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5523 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5524 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5525 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5526 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5527 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5528 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5529 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5530 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5531 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5532 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5533 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5534 * build process or in smb.conf, we use that value. Otherwise they
5535 * default to the value of lp_lockdir(). */
5536 char *lp_statedir(void) {
5537 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5538 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5539 return(lp_string(*(char **)(&Globals.szStateDir) ?
5540 *(char **)(&Globals.szStateDir) : ""));
5542 return(lp_string(*(char **)(&Globals.szLockDir) ?
5543 *(char **)(&Globals.szLockDir) : ""));
5545 char *lp_cachedir(void) {
5546 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5547 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5548 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5549 *(char **)(&Globals.szCacheDir) : ""));
5551 return(lp_string(*(char **)(&Globals.szLockDir) ?
5552 *(char **)(&Globals.szLockDir) : ""));
5554 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5555 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5556 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5557 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5558 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5559 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5560 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5561 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5562 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5563 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5564 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5565 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5566 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5567 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5568 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5569 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5570 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5571 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5572 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5573 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5574 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5575 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5576 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5577 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5578 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5579 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5580 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5581 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5582 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5583 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5584 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5585 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5586 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5587 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5588 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5589 * lp_passdb_backend() should be replace by the this macro again after
5592 const char *lp_passdb_backend(void)
5594 char *delim, *quote;
5596 delim = strchr( Globals.szPassdbBackend, ' ');
5597 /* no space at all */
5598 if (delim == NULL) {
5602 quote = strchr(Globals.szPassdbBackend, '"');
5603 /* no quote char or non in the first part */
5604 if (quote == NULL || quote > delim) {
5609 quote = strchr(quote+1, '"');
5610 if (quote == NULL) {
5611 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5613 } else if (*(quote+1) == '\0') {
5614 /* space, fitting quote char, and one backend only */
5617 /* terminate string after the fitting quote char */
5622 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5623 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5624 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5625 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5628 return Globals.szPassdbBackend;
5630 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5631 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5632 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5633 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5634 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5636 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5637 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5638 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5639 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5640 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5641 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5643 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5645 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5646 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5647 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5648 FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
5650 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5652 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5653 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5654 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5655 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5656 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5657 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5658 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5659 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5660 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5661 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5662 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5663 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5664 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5665 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5666 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5667 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5668 static FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections_int,
5669 &Globals.winbindMaxDomainConnections)
5671 int lp_winbind_max_domain_connections(void)
5673 if (lp_winbind_offline_logon() &&
5674 lp_winbind_max_domain_connections_int() > 1) {
5675 DEBUG(1, ("offline logons active, restricting max domain "
5676 "connections to 1\n"));
5679 return MAX(1, lp_winbind_max_domain_connections_int());
5682 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5683 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5684 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5685 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5686 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5688 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5689 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5690 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5691 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5692 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5693 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5694 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5695 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5696 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5697 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5698 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5699 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5700 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5701 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5702 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5703 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5704 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5705 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5706 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5707 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5709 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5711 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5712 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5713 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5714 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5715 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5716 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5717 &Globals.bLogWriteableFilesOnExit)
5718 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5719 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5720 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5721 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5722 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5723 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5724 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5725 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5726 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5727 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5728 FN_GLOBAL_BOOL(_lp_readraw, &Globals.bReadRaw)
5729 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5730 FN_GLOBAL_BOOL(_lp_writeraw, &Globals.bWriteRaw)
5731 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5732 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5733 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5734 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5735 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5736 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5737 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5738 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5739 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5740 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5741 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5742 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5743 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5744 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5745 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5746 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5747 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5748 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5749 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5750 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5751 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5752 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5753 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5754 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5755 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5756 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5757 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5758 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5759 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5760 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5761 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5762 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5763 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5764 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5765 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5766 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5767 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5768 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5769 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5770 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5771 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
5772 FN_GLOBAL_BOOL(lp_send_spnego_principal, &Globals.send_spnego_principal)
5773 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5774 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5775 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5776 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5777 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5778 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5779 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5780 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5781 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5782 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5783 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5784 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5785 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5786 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5787 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5788 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5789 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5790 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5791 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5792 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5793 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5794 static FN_GLOBAL_INTEGER(_lp_maxprotocol, &Globals.maxprotocol)
5795 int lp_maxprotocol(void)
5797 int ret = _lp_maxprotocol();
5798 if ((ret == PROTOCOL_SMB2) && (lp_security() == SEC_SHARE)) {
5799 DEBUG(2,("WARNING!!: \"security = share\" is incompatible "
5800 "with the SMB2 protocol. Resetting to SMB1.\n" ));
5801 lp_do_parameter(-1, "max protocol", "NT1");
5802 return PROTOCOL_NT1;
5806 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5807 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5808 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5809 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5810 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5811 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5812 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5813 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5814 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5815 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5816 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5817 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5818 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5819 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5820 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5821 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5822 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5823 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5824 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5825 FN_GLOBAL_INTEGER(lp_smb2_max_read, &Globals.ismb2_max_read)
5826 FN_GLOBAL_INTEGER(lp_smb2_max_write, &Globals.ismb2_max_write)
5827 FN_GLOBAL_INTEGER(lp_smb2_max_trans, &Globals.ismb2_max_trans)
5828 int lp_smb2_max_credits(void)
5830 if (Globals.ismb2_max_credits == 0) {
5831 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5833 return Globals.ismb2_max_credits;
5835 FN_LOCAL_STRING(lp_preexec, szPreExec)
5836 FN_LOCAL_STRING(lp_postexec, szPostExec)
5837 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5838 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5839 FN_LOCAL_STRING(lp_servicename, szService)
5840 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5841 FN_LOCAL_STRING(lp_pathname, szPath)
5842 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5843 FN_LOCAL_STRING(lp_username, szUsername)
5844 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5845 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5846 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5847 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5848 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5849 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5850 int lp_cups_encrypt(void)
5853 #ifdef HAVE_HTTPCONNECTENCRYPT
5854 switch (Globals.CupsEncrypt) {
5856 result = HTTP_ENCRYPT_REQUIRED;
5859 result = HTTP_ENCRYPT_ALWAYS;
5862 result = HTTP_ENCRYPT_NEVER;
5868 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5869 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5870 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5871 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5872 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5873 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5874 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, &Globals.ctdb_locktime_warn_threshold)
5875 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5876 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5877 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5878 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5879 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5880 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5881 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5882 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5883 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5884 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5885 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5886 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5887 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5888 FN_LOCAL_STRING(lp_comment, comment)
5889 FN_LOCAL_STRING(lp_force_user, force_user)
5890 FN_LOCAL_STRING(lp_force_group, force_group)
5891 FN_LOCAL_LIST(lp_readlist, readlist)
5892 FN_LOCAL_LIST(lp_writelist, writelist)
5893 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5894 FN_LOCAL_STRING(lp_fstype, fstype)
5895 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5896 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5897 static FN_LOCAL_STRING(lp_volume, volume)
5898 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5899 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5900 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5901 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5902 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5903 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5904 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5905 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5906 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5907 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5908 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5909 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5910 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5911 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5912 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5913 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5914 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5915 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5916 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5917 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5918 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5919 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5920 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5921 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5922 FN_LOCAL_BOOL(lp_print_notify_backchannel, bPrintNotifyBackchannel)
5923 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5924 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5925 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5926 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5927 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5928 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5929 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5930 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5931 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5932 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5933 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5934 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5935 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5936 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5937 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5938 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5939 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5940 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5941 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5942 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5943 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5944 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5945 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5946 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5947 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5948 FN_GLOBAL_BOOL(lp_multicast_dns_register, &Globals.bMulticastDnsRegister)
5949 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5950 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5951 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5952 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5953 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5954 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5955 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5956 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5957 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5958 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5959 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5960 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5961 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5962 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5963 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5964 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5965 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5966 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5967 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5968 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5969 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5970 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5971 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5972 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5973 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5974 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5975 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5976 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5977 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5978 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5979 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5980 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5981 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5982 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5983 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5984 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5985 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5986 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5987 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5988 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5989 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5990 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5991 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5992 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5993 FN_GLOBAL_INTEGER(lp_winbind_max_clients, &Globals.winbind_max_clients)
5994 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5995 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5996 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5997 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5998 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5999 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
6001 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
6003 /* local prototypes */
6005 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
6006 static const char *get_boolean(bool bool_value);
6007 static int getservicebyname(const char *pszServiceName,
6008 struct service *pserviceDest);
6009 static void copy_service(struct service *pserviceDest,
6010 struct service *pserviceSource,
6011 struct bitmap *pcopymapDest);
6012 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
6014 static bool do_section(const char *pszSectionName, void *userdata);
6015 static void init_copymap(struct service *pservice);
6016 static bool hash_a_service(const char *name, int number);
6017 static void free_service_byindex(int iService);
6018 static void free_param_opts(struct param_opt_struct **popts);
6019 static void show_parameter(int parmIndex);
6020 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
6023 * This is a helper function for parametrical options support. It returns a
6024 * pointer to parametrical option value if it exists or NULL otherwise. Actual
6025 * parametrical functions are quite simple
6027 static struct param_opt_struct *get_parametrics(int snum, const char *type,
6030 bool global_section = False;
6032 struct param_opt_struct *data;
6034 if (snum >= iNumServices) return NULL;
6037 data = Globals.param_opt;
6038 global_section = True;
6040 data = ServicePtrs[snum]->param_opt;
6043 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
6044 DEBUG(0,("asprintf failed!\n"));
6049 if (strwicmp(data->key, param_key) == 0) {
6050 string_free(¶m_key);
6056 if (!global_section) {
6057 /* Try to fetch the same option but from globals */
6058 /* but only if we are not already working with Globals */
6059 data = Globals.param_opt;
6061 if (strwicmp(data->key, param_key) == 0) {
6062 string_free(¶m_key);
6069 string_free(¶m_key);
6075 #define MISSING_PARAMETER(name) \
6076 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
6078 /*******************************************************************
6079 convenience routine to return int parameters.
6080 ********************************************************************/
6081 static int lp_int(const char *s)
6085 MISSING_PARAMETER(lp_int);
6089 return (int)strtol(s, NULL, 0);
6092 /*******************************************************************
6093 convenience routine to return unsigned long parameters.
6094 ********************************************************************/
6095 static unsigned long lp_ulong(const char *s)
6099 MISSING_PARAMETER(lp_ulong);
6103 return strtoul(s, NULL, 0);
6106 /*******************************************************************
6107 convenience routine to return boolean parameters.
6108 ********************************************************************/
6109 static bool lp_bool(const char *s)
6114 MISSING_PARAMETER(lp_bool);
6118 if (!set_boolean(s, &ret)) {
6119 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
6126 /*******************************************************************
6127 convenience routine to return enum parameters.
6128 ********************************************************************/
6129 static int lp_enum(const char *s,const struct enum_list *_enum)
6133 if (!s || !*s || !_enum) {
6134 MISSING_PARAMETER(lp_enum);
6138 for (i=0; _enum[i].name; i++) {
6139 if (strequal(_enum[i].name,s))
6140 return _enum[i].value;
6143 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
6147 #undef MISSING_PARAMETER
6149 /* DO NOT USE lp_parm_string ANYMORE!!!!
6150 * use lp_parm_const_string or lp_parm_talloc_string
6152 * lp_parm_string is only used to let old modules find this symbol
6154 #undef lp_parm_string
6155 char *lp_parm_string(const char *servicename, const char *type, const char *option);
6156 char *lp_parm_string(const char *servicename, const char *type, const char *option)
6158 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
6161 /* Return parametric option from a given service. Type is a part of option before ':' */
6162 /* Parametric option has following syntax: 'Type: option = value' */
6163 /* the returned value is talloced on the talloc_tos() */
6164 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
6166 struct param_opt_struct *data = get_parametrics(snum, type, option);
6168 if (data == NULL||data->value==NULL) {
6170 return lp_string(def);
6176 return lp_string(data->value);
6179 /* Return parametric option from a given service. Type is a part of option before ':' */
6180 /* Parametric option has following syntax: 'Type: option = value' */
6181 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6183 struct param_opt_struct *data = get_parametrics(snum, type, option);
6185 if (data == NULL||data->value==NULL)
6191 /* Return parametric option from a given service. Type is a part of option before ':' */
6192 /* Parametric option has following syntax: 'Type: option = value' */
6194 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6196 struct param_opt_struct *data = get_parametrics(snum, type, option);
6198 if (data == NULL||data->value==NULL)
6199 return (const char **)def;
6201 if (data->list==NULL) {
6202 data->list = str_list_make_v3(NULL, data->value, NULL);
6205 return (const char **)data->list;
6208 /* Return parametric option from a given service. Type is a part of option before ':' */
6209 /* Parametric option has following syntax: 'Type: option = value' */
6211 int lp_parm_int(int snum, const char *type, const char *option, int def)
6213 struct param_opt_struct *data = get_parametrics(snum, type, option);
6215 if (data && data->value && *data->value)
6216 return lp_int(data->value);
6221 /* Return parametric option from a given service. Type is a part of option before ':' */
6222 /* Parametric option has following syntax: 'Type: option = value' */
6224 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6226 struct param_opt_struct *data = get_parametrics(snum, type, option);
6228 if (data && data->value && *data->value)
6229 return lp_ulong(data->value);
6234 /* Return parametric option from a given service. Type is a part of option before ':' */
6235 /* Parametric option has following syntax: 'Type: option = value' */
6237 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6239 struct param_opt_struct *data = get_parametrics(snum, type, option);
6241 if (data && data->value && *data->value)
6242 return lp_bool(data->value);
6247 /* Return parametric option from a given service. Type is a part of option before ':' */
6248 /* Parametric option has following syntax: 'Type: option = value' */
6250 int lp_parm_enum(int snum, const char *type, const char *option,
6251 const struct enum_list *_enum, int def)
6253 struct param_opt_struct *data = get_parametrics(snum, type, option);
6255 if (data && data->value && *data->value && _enum)
6256 return lp_enum(data->value, _enum);
6262 /***************************************************************************
6263 Initialise a service to the defaults.
6264 ***************************************************************************/
6266 static void init_service(struct service *pservice)
6268 memset((char *)pservice, '\0', sizeof(struct service));
6269 copy_service(pservice, &sDefault, NULL);
6274 * free a param_opts structure.
6275 * param_opts handling should be moved to talloc;
6276 * then this whole functions reduces to a TALLOC_FREE().
6279 static void free_param_opts(struct param_opt_struct **popts)
6281 struct param_opt_struct *opt, *next_opt;
6283 if (popts == NULL) {
6287 if (*popts != NULL) {
6288 DEBUG(5, ("Freeing parametrics:\n"));
6291 while (opt != NULL) {
6292 string_free(&opt->key);
6293 string_free(&opt->value);
6294 TALLOC_FREE(opt->list);
6295 next_opt = opt->next;
6302 /***************************************************************************
6303 Free the dynamically allocated parts of a service struct.
6304 ***************************************************************************/
6306 static void free_service(struct service *pservice)
6311 if (pservice->szService)
6312 DEBUG(5, ("free_service: Freeing service %s\n",
6313 pservice->szService));
6315 free_parameters(pservice);
6317 string_free(&pservice->szService);
6318 TALLOC_FREE(pservice->copymap);
6320 free_param_opts(&pservice->param_opt);
6322 ZERO_STRUCTP(pservice);
6326 /***************************************************************************
6327 remove a service indexed in the ServicePtrs array from the ServiceHash
6328 and free the dynamically allocated parts
6329 ***************************************************************************/
6331 static void free_service_byindex(int idx)
6333 if ( !LP_SNUM_OK(idx) )
6336 ServicePtrs[idx]->valid = False;
6337 invalid_services[num_invalid_services++] = idx;
6339 /* we have to cleanup the hash record */
6341 if (ServicePtrs[idx]->szService) {
6342 char *canon_name = canonicalize_servicename(
6344 ServicePtrs[idx]->szService );
6346 dbwrap_delete_bystring(ServiceHash, canon_name );
6347 TALLOC_FREE(canon_name);
6350 free_service(ServicePtrs[idx]);
6353 /***************************************************************************
6354 Add a new service to the services array initialising it with the given
6356 ***************************************************************************/
6358 static int add_a_service(const struct service *pservice, const char *name)
6361 struct service tservice;
6362 int num_to_alloc = iNumServices + 1;
6364 tservice = *pservice;
6366 /* it might already exist */
6368 i = getservicebyname(name, NULL);
6374 /* find an invalid one */
6376 if (num_invalid_services > 0) {
6377 i = invalid_services[--num_invalid_services];
6380 /* if not, then create one */
6381 if (i == iNumServices) {
6382 struct service **tsp;
6385 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6387 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6391 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6392 if (!ServicePtrs[iNumServices]) {
6393 DEBUG(0,("add_a_service: out of memory!\n"));
6398 /* enlarge invalid_services here for now... */
6399 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6401 if (tinvalid == NULL) {
6402 DEBUG(0,("add_a_service: failed to enlarge "
6403 "invalid_services!\n"));
6406 invalid_services = tinvalid;
6408 free_service_byindex(i);
6411 ServicePtrs[i]->valid = True;
6413 init_service(ServicePtrs[i]);
6414 copy_service(ServicePtrs[i], &tservice, NULL);
6416 string_set(&ServicePtrs[i]->szService, name);
6418 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6419 i, ServicePtrs[i]->szService));
6421 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6428 /***************************************************************************
6429 Convert a string to uppercase and remove whitespaces.
6430 ***************************************************************************/
6432 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6437 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6441 result = talloc_strdup(ctx, src);
6442 SMB_ASSERT(result != NULL);
6448 /***************************************************************************
6449 Add a name/index pair for the services array to the hash table.
6450 ***************************************************************************/
6452 static bool hash_a_service(const char *name, int idx)
6456 if ( !ServiceHash ) {
6457 DEBUG(10,("hash_a_service: creating servicehash\n"));
6458 ServiceHash = db_open_rbt(NULL);
6459 if ( !ServiceHash ) {
6460 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6465 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6468 canon_name = canonicalize_servicename(talloc_tos(), name );
6470 dbwrap_store_bystring(ServiceHash, canon_name,
6471 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6474 TALLOC_FREE(canon_name);
6479 /***************************************************************************
6480 Add a new home service, with the specified home directory, defaults coming
6482 ***************************************************************************/
6484 bool lp_add_home(const char *pszHomename, int iDefaultService,
6485 const char *user, const char *pszHomedir)
6489 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6490 pszHomedir[0] == '\0') {
6494 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6499 if (!(*(ServicePtrs[iDefaultService]->szPath))
6500 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6501 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6504 if (!(*(ServicePtrs[i]->comment))) {
6505 char *comment = NULL;
6506 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6509 string_set(&ServicePtrs[i]->comment, comment);
6513 /* set the browseable flag from the global default */
6515 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6516 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6518 ServicePtrs[i]->autoloaded = True;
6520 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6521 user, ServicePtrs[i]->szPath ));
6526 /***************************************************************************
6527 Add a new service, based on an old one.
6528 ***************************************************************************/
6530 int lp_add_service(const char *pszService, int iDefaultService)
6532 if (iDefaultService < 0) {
6533 return add_a_service(&sDefault, pszService);
6536 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6539 /***************************************************************************
6540 Add the IPC service.
6541 ***************************************************************************/
6543 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6545 char *comment = NULL;
6546 int i = add_a_service(&sDefault, ipc_name);
6551 if (asprintf(&comment, "IPC Service (%s)",
6552 Globals.szServerString) < 0) {
6556 string_set(&ServicePtrs[i]->szPath, tmpdir());
6557 string_set(&ServicePtrs[i]->szUsername, "");
6558 string_set(&ServicePtrs[i]->comment, comment);
6559 string_set(&ServicePtrs[i]->fstype, "IPC");
6560 ServicePtrs[i]->iMaxConnections = 0;
6561 ServicePtrs[i]->bAvailable = True;
6562 ServicePtrs[i]->bRead_only = True;
6563 ServicePtrs[i]->bGuest_only = False;
6564 ServicePtrs[i]->bAdministrative_share = True;
6565 ServicePtrs[i]->bGuest_ok = guest_ok;
6566 ServicePtrs[i]->bPrint_ok = False;
6567 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6569 DEBUG(3, ("adding IPC service\n"));
6575 /***************************************************************************
6576 Add a new printer service, with defaults coming from service iFrom.
6577 ***************************************************************************/
6579 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6581 const char *comment = "From Printcap";
6582 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6587 /* note that we do NOT default the availability flag to True - */
6588 /* we take it from the default service passed. This allows all */
6589 /* dynamic printers to be disabled by disabling the [printers] */
6590 /* entry (if/when the 'available' keyword is implemented!). */
6592 /* the printer name is set to the service name. */
6593 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6594 string_set(&ServicePtrs[i]->comment, comment);
6596 /* set the browseable flag from the gloabl default */
6597 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6599 /* Printers cannot be read_only. */
6600 ServicePtrs[i]->bRead_only = False;
6601 /* No share modes on printer services. */
6602 ServicePtrs[i]->bShareModes = False;
6603 /* No oplocks on printer services. */
6604 ServicePtrs[i]->bOpLocks = False;
6605 /* Printer services must be printable. */
6606 ServicePtrs[i]->bPrint_ok = True;
6608 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6614 /***************************************************************************
6615 Check whether the given parameter name is valid.
6616 Parametric options (names containing a colon) are considered valid.
6617 ***************************************************************************/
6619 bool lp_parameter_is_valid(const char *pszParmName)
6621 return ((map_parameter(pszParmName) != -1) ||
6622 (strchr(pszParmName, ':') != NULL));
6625 /***************************************************************************
6626 Check whether the given name is the name of a global parameter.
6627 Returns True for strings belonging to parameters of class
6628 P_GLOBAL, False for all other strings, also for parametric options
6629 and strings not belonging to any option.
6630 ***************************************************************************/
6632 bool lp_parameter_is_global(const char *pszParmName)
6634 int num = map_parameter(pszParmName);
6637 return (parm_table[num].p_class == P_GLOBAL);
6643 /**************************************************************************
6644 Check whether the given name is the canonical name of a parameter.
6645 Returns False if it is not a valid parameter Name.
6646 For parametric options, True is returned.
6647 **************************************************************************/
6649 bool lp_parameter_is_canonical(const char *parm_name)
6651 if (!lp_parameter_is_valid(parm_name)) {
6655 return (map_parameter(parm_name) ==
6656 map_parameter_canonical(parm_name, NULL));
6659 /**************************************************************************
6660 Determine the canonical name for a parameter.
6661 Indicate when it is an inverse (boolean) synonym instead of a
6663 **************************************************************************/
6665 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6670 if (!lp_parameter_is_valid(parm_name)) {
6675 num = map_parameter_canonical(parm_name, inverse);
6677 /* parametric option */
6678 *canon_parm = parm_name;
6680 *canon_parm = parm_table[num].label;
6687 /**************************************************************************
6688 Determine the canonical name for a parameter.
6689 Turn the value given into the inverse boolean expression when
6690 the synonym is an invers boolean synonym.
6692 Return True if parm_name is a valid parameter name and
6693 in case it is an invers boolean synonym, if the val string could
6694 successfully be converted to the reverse bool.
6695 Return false in all other cases.
6696 **************************************************************************/
6698 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6700 const char **canon_parm,
6701 const char **canon_val)
6706 if (!lp_parameter_is_valid(parm_name)) {
6712 num = map_parameter_canonical(parm_name, &inverse);
6714 /* parametric option */
6715 *canon_parm = parm_name;
6718 *canon_parm = parm_table[num].label;
6720 if (!lp_invert_boolean(val, canon_val)) {
6732 /***************************************************************************
6733 Map a parameter's string representation to something we can use.
6734 Returns False if the parameter string is not recognised, else TRUE.
6735 ***************************************************************************/
6737 static int map_parameter(const char *pszParmName)
6741 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6744 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6745 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6748 /* Warn only if it isn't parametric option */
6749 if (strchr(pszParmName, ':') == NULL)
6750 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6751 /* We do return 'fail' for parametric options as well because they are
6752 stored in different storage
6757 /***************************************************************************
6758 Map a parameter's string representation to the index of the canonical
6759 form of the parameter (it might be a synonym).
6760 Returns -1 if the parameter string is not recognised.
6761 ***************************************************************************/
6763 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6765 int parm_num, canon_num;
6766 bool loc_inverse = False;
6768 parm_num = map_parameter(pszParmName);
6769 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6770 /* invalid, parametric or no canidate for synonyms ... */
6774 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6775 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6776 parm_num = canon_num;
6782 if (inverse != NULL) {
6783 *inverse = loc_inverse;
6788 /***************************************************************************
6789 return true if parameter number parm1 is a synonym of parameter
6790 number parm2 (parm2 being the principal name).
6791 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6793 ***************************************************************************/
6795 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6797 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6798 (parm_table[parm1].flags & FLAG_HIDE) &&
6799 !(parm_table[parm2].flags & FLAG_HIDE))
6801 if (inverse != NULL) {
6802 if ((parm_table[parm1].type == P_BOOLREV) &&
6803 (parm_table[parm2].type == P_BOOL))
6815 /***************************************************************************
6816 Show one parameter's name, type, [values,] and flags.
6817 (helper functions for show_parameter_list)
6818 ***************************************************************************/
6820 static void show_parameter(int parmIndex)
6822 int enumIndex, flagIndex;
6827 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6828 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6830 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6831 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6832 FLAG_HIDE, FLAG_DOS_STRING};
6833 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6834 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6835 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6837 printf("%s=%s", parm_table[parmIndex].label,
6838 type[parm_table[parmIndex].type]);
6839 if (parm_table[parmIndex].type == P_ENUM) {
6842 parm_table[parmIndex].enum_list[enumIndex].name;
6846 enumIndex ? "|" : "",
6847 parm_table[parmIndex].enum_list[enumIndex].name);
6852 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6853 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6856 flag_names[flagIndex]);
6861 /* output synonyms */
6863 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6864 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6865 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6866 parm_table[parmIndex2].label);
6867 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6869 printf(" (synonyms: ");
6874 printf("%s%s", parm_table[parmIndex2].label,
6875 inverse ? "[i]" : "");
6885 /***************************************************************************
6886 Show all parameter's name, type, [values,] and flags.
6887 ***************************************************************************/
6889 void show_parameter_list(void)
6891 int classIndex, parmIndex;
6892 const char *section_names[] = { "local", "global", NULL};
6894 for (classIndex=0; section_names[classIndex]; classIndex++) {
6895 printf("[%s]\n", section_names[classIndex]);
6896 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6897 if (parm_table[parmIndex].p_class == classIndex) {
6898 show_parameter(parmIndex);
6904 /***************************************************************************
6905 Check if a given string correctly represents a boolean value.
6906 ***************************************************************************/
6908 bool lp_string_is_valid_boolean(const char *parm_value)
6910 return set_boolean(parm_value, NULL);
6913 /***************************************************************************
6914 Get the standard string representation of a boolean value ("yes" or "no")
6915 ***************************************************************************/
6917 static const char *get_boolean(bool bool_value)
6919 static const char *yes_str = "yes";
6920 static const char *no_str = "no";
6922 return (bool_value ? yes_str : no_str);
6925 /***************************************************************************
6926 Provide the string of the negated boolean value associated to the boolean
6927 given as a string. Returns False if the passed string does not correctly
6928 represent a boolean.
6929 ***************************************************************************/
6931 bool lp_invert_boolean(const char *str, const char **inverse_str)
6935 if (!set_boolean(str, &val)) {
6939 *inverse_str = get_boolean(!val);
6943 /***************************************************************************
6944 Provide the canonical string representation of a boolean value given
6945 as a string. Return True on success, False if the string given does
6946 not correctly represent a boolean.
6947 ***************************************************************************/
6949 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6953 if (!set_boolean(str, &val)) {
6957 *canon_str = get_boolean(val);
6961 /***************************************************************************
6962 Find a service by name. Otherwise works like get_service.
6963 ***************************************************************************/
6965 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6971 if (ServiceHash == NULL) {
6975 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6977 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6979 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6980 iService = *(int *)data.dptr;
6983 TALLOC_FREE(canon_name);
6985 if ((iService != -1) && (LP_SNUM_OK(iService))
6986 && (pserviceDest != NULL)) {
6987 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6993 /***************************************************************************
6994 Copy a service structure to another.
6995 If pcopymapDest is NULL then copy all fields
6996 ***************************************************************************/
6999 * Add a parametric option to a param_opt_struct,
7000 * replacing old value, if already present.
7002 static void set_param_opt(struct param_opt_struct **opt_list,
7003 const char *opt_name,
7004 const char *opt_value,
7007 struct param_opt_struct *new_opt, *opt;
7010 if (opt_list == NULL) {
7017 /* Traverse destination */
7019 /* If we already have same option, override it */
7020 if (strwicmp(opt->key, opt_name) == 0) {
7021 if ((opt->flags & FLAG_CMDLINE) &&
7022 !(flags & FLAG_CMDLINE)) {
7023 /* it's been marked as not to be
7027 string_free(&opt->value);
7028 TALLOC_FREE(opt->list);
7029 opt->value = SMB_STRDUP(opt_value);
7037 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
7038 new_opt->key = SMB_STRDUP(opt_name);
7039 new_opt->value = SMB_STRDUP(opt_value);
7040 new_opt->list = NULL;
7041 new_opt->flags = flags;
7042 DLIST_ADD(*opt_list, new_opt);
7046 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
7047 struct bitmap *pcopymapDest)
7050 bool bcopyall = (pcopymapDest == NULL);
7051 struct param_opt_struct *data;
7053 for (i = 0; parm_table[i].label; i++)
7054 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
7055 (bcopyall || bitmap_query(pcopymapDest,i))) {
7056 void *def_ptr = parm_table[i].ptr;
7058 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
7061 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
7064 switch (parm_table[i].type) {
7067 *(bool *)dest_ptr = *(bool *)src_ptr;
7073 *(int *)dest_ptr = *(int *)src_ptr;
7077 *(char *)dest_ptr = *(char *)src_ptr;
7081 string_set((char **)dest_ptr,
7086 string_set((char **)dest_ptr,
7088 strupper_m(*(char **)dest_ptr);
7091 TALLOC_FREE(*((char ***)dest_ptr));
7092 *((char ***)dest_ptr) = str_list_copy(NULL,
7093 *(const char ***)src_ptr);
7101 init_copymap(pserviceDest);
7102 if (pserviceSource->copymap)
7103 bitmap_copy(pserviceDest->copymap,
7104 pserviceSource->copymap);
7107 data = pserviceSource->param_opt;
7109 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->flags);
7114 /***************************************************************************
7115 Check a service for consistency. Return False if the service is in any way
7116 incomplete or faulty, else True.
7117 ***************************************************************************/
7119 bool service_ok(int iService)
7124 if (ServicePtrs[iService]->szService[0] == '\0') {
7125 DEBUG(0, ("The following message indicates an internal error:\n"));
7126 DEBUG(0, ("No service name in service entry.\n"));
7130 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
7131 /* I can't see why you'd want a non-printable printer service... */
7132 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
7133 if (!ServicePtrs[iService]->bPrint_ok) {
7134 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
7135 ServicePtrs[iService]->szService));
7136 ServicePtrs[iService]->bPrint_ok = True;
7138 /* [printers] service must also be non-browsable. */
7139 if (ServicePtrs[iService]->bBrowseable)
7140 ServicePtrs[iService]->bBrowseable = False;
7143 if (ServicePtrs[iService]->szPath[0] == '\0' &&
7144 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
7145 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
7147 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
7148 ServicePtrs[iService]->szService));
7149 ServicePtrs[iService]->bAvailable = False;
7152 /* If a service is flagged unavailable, log the fact at level 1. */
7153 if (!ServicePtrs[iService]->bAvailable)
7154 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
7155 ServicePtrs[iService]->szService));
7160 static struct smbconf_ctx *lp_smbconf_ctx(void)
7163 static struct smbconf_ctx *conf_ctx = NULL;
7165 if (conf_ctx == NULL) {
7166 werr = smbconf_init(NULL, &conf_ctx, "registry:");
7167 if (!W_ERROR_IS_OK(werr)) {
7168 DEBUG(1, ("error initializing registry configuration: "
7169 "%s\n", win_errstr(werr)));
7177 static bool process_smbconf_service(struct smbconf_service *service)
7182 if (service == NULL) {
7186 ret = do_section(service->name, NULL);
7190 for (count = 0; count < service->num_params; count++) {
7191 ret = do_parameter(service->param_names[count],
7192 service->param_values[count],
7198 if (iServiceIndex >= 0) {
7199 return service_ok(iServiceIndex);
7205 * load a service from registry and activate it
7207 bool process_registry_service(const char *service_name)
7210 struct smbconf_service *service = NULL;
7211 TALLOC_CTX *mem_ctx = talloc_stackframe();
7212 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7215 if (conf_ctx == NULL) {
7219 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7221 if (!smbconf_share_exists(conf_ctx, service_name)) {
7223 * Registry does not contain data for this service (yet),
7224 * but make sure lp_load doesn't return false.
7230 werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7231 if (!W_ERROR_IS_OK(werr)) {
7235 ret = process_smbconf_service(service);
7241 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7244 TALLOC_FREE(mem_ctx);
7249 * process_registry_globals
7251 static bool process_registry_globals(void)
7255 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7257 ret = do_parameter("registry shares", "yes", NULL);
7262 return process_registry_service(GLOBAL_NAME);
7265 bool process_registry_shares(void)
7269 struct smbconf_service **service = NULL;
7270 uint32_t num_shares = 0;
7271 TALLOC_CTX *mem_ctx = talloc_stackframe();
7272 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7275 if (conf_ctx == NULL) {
7279 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7280 if (!W_ERROR_IS_OK(werr)) {
7286 for (count = 0; count < num_shares; count++) {
7287 if (strequal(service[count]->name, GLOBAL_NAME)) {
7290 ret = process_smbconf_service(service[count]);
7297 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7300 TALLOC_FREE(mem_ctx);
7304 #define MAX_INCLUDE_DEPTH 100
7306 static uint8_t include_depth;
7308 static struct file_lists {
7309 struct file_lists *next;
7313 } *file_lists = NULL;
7315 /*******************************************************************
7316 Keep a linked list of all config files so we know when one has changed
7317 it's date and needs to be reloaded.
7318 ********************************************************************/
7320 static void add_to_file_list(const char *fname, const char *subfname)
7322 struct file_lists *f = file_lists;
7325 if (f->name && !strcmp(f->name, fname))
7331 f = SMB_MALLOC_P(struct file_lists);
7334 f->next = file_lists;
7335 f->name = SMB_STRDUP(fname);
7340 f->subfname = SMB_STRDUP(subfname);
7347 f->modtime = file_modtime(subfname);
7349 time_t t = file_modtime(subfname);
7357 * Free the file lists
7359 static void free_file_list(void)
7361 struct file_lists *f;
7362 struct file_lists *next;
7367 SAFE_FREE( f->name );
7368 SAFE_FREE( f->subfname );
7377 * Utility function for outsiders to check if we're running on registry.
7379 bool lp_config_backend_is_registry(void)
7381 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7385 * Utility function to check if the config backend is FILE.
7387 bool lp_config_backend_is_file(void)
7389 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7392 /*******************************************************************
7393 Check if a config file has changed date.
7394 ********************************************************************/
7396 bool lp_file_list_changed(void)
7398 struct file_lists *f = file_lists;
7400 DEBUG(6, ("lp_file_list_changed()\n"));
7405 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7406 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7408 if (conf_ctx == NULL) {
7411 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7414 DEBUGADD(6, ("registry config changed\n"));
7419 n2 = talloc_sub_basic(talloc_tos(),
7420 get_current_username(),
7421 current_user_info.domain,
7426 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7427 f->name, n2, ctime(&f->modtime)));
7429 mod_time = file_modtime(n2);
7432 ((f->modtime != mod_time) ||
7433 (f->subfname == NULL) ||
7434 (strcmp(n2, f->subfname) != 0)))
7437 ("file %s modified: %s\n", n2,
7439 f->modtime = mod_time;
7440 SAFE_FREE(f->subfname);
7441 f->subfname = SMB_STRDUP(n2);
7453 /***************************************************************************
7454 Run standard_sub_basic on netbios name... needed because global_myname
7455 is not accessed through any lp_ macro.
7456 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7457 ***************************************************************************/
7459 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7462 char *netbios_name = talloc_sub_basic(
7463 talloc_tos(), get_current_username(), current_user_info.domain,
7466 ret = set_global_myname(netbios_name);
7467 TALLOC_FREE(netbios_name);
7468 string_set(&Globals.szNetbiosName,global_myname());
7470 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7476 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7478 if (strcmp(*ptr, pszParmValue) != 0) {
7479 string_set(ptr, pszParmValue);
7487 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7491 ret = set_global_myworkgroup(pszParmValue);
7492 string_set(&Globals.szWorkgroup,lp_workgroup());
7497 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7501 ret = set_global_scope(pszParmValue);
7502 string_set(&Globals.szNetbiosScope,global_scope());
7507 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7509 TALLOC_FREE(Globals.szNetbiosAliases);
7510 Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
7511 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7514 /***************************************************************************
7515 Handle the include operation.
7516 ***************************************************************************/
7517 static bool bAllowIncludeRegistry = true;
7519 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7523 if (include_depth >= MAX_INCLUDE_DEPTH) {
7524 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7529 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7530 if (!bAllowIncludeRegistry) {
7533 if (bInGlobalSection) {
7536 ret = process_registry_globals();
7540 DEBUG(1, ("\"include = registry\" only effective "
7541 "in %s section\n", GLOBAL_NAME));
7546 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7547 current_user_info.domain,
7550 add_to_file_list(pszParmValue, fname);
7552 string_set(ptr, fname);
7554 if (file_exist(fname)) {
7557 ret = pm_process(fname, do_section, do_parameter, NULL);
7563 DEBUG(2, ("Can't find include file %s\n", fname));
7568 /***************************************************************************
7569 Handle the interpretation of the copy parameter.
7570 ***************************************************************************/
7572 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7576 struct service serviceTemp;
7578 string_set(ptr, pszParmValue);
7580 init_service(&serviceTemp);
7584 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7586 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7587 if (iTemp == iServiceIndex) {
7588 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7590 copy_service(ServicePtrs[iServiceIndex],
7592 ServicePtrs[iServiceIndex]->copymap);
7596 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7600 free_service(&serviceTemp);
7604 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7606 Globals.ldap_debug_level = lp_int(pszParmValue);
7607 init_ldap_debugging();
7611 /***************************************************************************
7612 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7617 idmap uid = 1000-1999
7620 We only do simple parsing checks here. The strings are parsed into useful
7621 structures in the idmap daemon code.
7623 ***************************************************************************/
7625 /* Some lp_ routines to return idmap [ug]id information */
7627 static uid_t idmap_uid_low, idmap_uid_high;
7628 static gid_t idmap_gid_low, idmap_gid_high;
7630 bool lp_idmap_uid(uid_t *low, uid_t *high)
7632 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7636 *low = idmap_uid_low;
7639 *high = idmap_uid_high;
7644 bool lp_idmap_gid(gid_t *low, gid_t *high)
7646 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7650 *low = idmap_gid_low;
7653 *high = idmap_gid_high;
7658 /* Do some simple checks on "idmap [ug]id" parameter values */
7660 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7664 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7669 string_set(ptr, pszParmValue);
7671 idmap_uid_low = low;
7672 idmap_uid_high = high;
7677 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7681 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7686 string_set(ptr, pszParmValue);
7688 idmap_gid_low = low;
7689 idmap_gid_high = high;
7694 /***************************************************************************
7695 Handle the DEBUG level list.
7696 ***************************************************************************/
7698 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7700 string_set(ptr, pszParmValueIn);
7701 return debug_parse_levels(pszParmValueIn);
7704 /***************************************************************************
7705 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7706 ***************************************************************************/
7708 static const char *append_ldap_suffix( const char *str )
7710 const char *suffix_string;
7713 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7714 Globals.szLdapSuffix );
7715 if ( !suffix_string ) {
7716 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7720 return suffix_string;
7723 const char *lp_ldap_machine_suffix(void)
7725 if (Globals.szLdapMachineSuffix[0])
7726 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7728 return lp_string(Globals.szLdapSuffix);
7731 const char *lp_ldap_user_suffix(void)
7733 if (Globals.szLdapUserSuffix[0])
7734 return append_ldap_suffix(Globals.szLdapUserSuffix);
7736 return lp_string(Globals.szLdapSuffix);
7739 const char *lp_ldap_group_suffix(void)
7741 if (Globals.szLdapGroupSuffix[0])
7742 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7744 return lp_string(Globals.szLdapSuffix);
7747 const char *lp_ldap_idmap_suffix(void)
7749 if (Globals.szLdapIdmapSuffix[0])
7750 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7752 return lp_string(Globals.szLdapSuffix);
7755 /****************************************************************************
7756 set the value for a P_ENUM
7757 ***************************************************************************/
7759 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7764 for (i = 0; parm->enum_list[i].name; i++) {
7765 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7766 *ptr = parm->enum_list[i].value;
7770 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7771 pszParmValue, parm->label));
7774 /***************************************************************************
7775 ***************************************************************************/
7777 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7779 static int parm_num = -1;
7782 if ( parm_num == -1 )
7783 parm_num = map_parameter( "printing" );
7785 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7790 s = ServicePtrs[snum];
7792 init_printer_values( s );
7798 /***************************************************************************
7799 Initialise a copymap.
7800 ***************************************************************************/
7802 static void init_copymap(struct service *pservice)
7806 TALLOC_FREE(pservice->copymap);
7808 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7809 if (!pservice->copymap)
7811 ("Couldn't allocate copymap!! (size %d)\n",
7812 (int)NUMPARAMETERS));
7814 for (i = 0; i < NUMPARAMETERS; i++)
7815 bitmap_set(pservice->copymap, i);
7818 /***************************************************************************
7819 Return the local pointer to a parameter given a service struct and the
7820 pointer into the default structure.
7821 ***************************************************************************/
7823 static void *lp_local_ptr(struct service *service, void *ptr)
7825 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7828 /***************************************************************************
7829 Return the local pointer to a parameter given the service number and the
7830 pointer into the default structure.
7831 ***************************************************************************/
7833 void *lp_local_ptr_by_snum(int snum, void *ptr)
7835 return lp_local_ptr(ServicePtrs[snum], ptr);
7838 /***************************************************************************
7839 Process a parameter for a particular service number. If snum < 0
7840 then assume we are in the globals.
7841 ***************************************************************************/
7843 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7846 void *parm_ptr = NULL; /* where we are going to store the result */
7847 void *def_ptr = NULL;
7848 struct param_opt_struct **opt_list;
7850 parmnum = map_parameter(pszParmName);
7853 if (strchr(pszParmName, ':') == NULL) {
7854 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7860 * We've got a parametric option
7863 opt_list = (snum < 0)
7864 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7865 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7870 /* if it's already been set by the command line, then we don't
7872 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7876 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7877 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7881 def_ptr = parm_table[parmnum].ptr;
7883 /* we might point at a service, the default service or a global */
7887 if (parm_table[parmnum].p_class == P_GLOBAL) {
7889 ("Global parameter %s found in service section!\n",
7893 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7897 if (!ServicePtrs[snum]->copymap)
7898 init_copymap(ServicePtrs[snum]);
7900 /* this handles the aliases - set the copymap for other entries with
7901 the same data pointer */
7902 for (i = 0; parm_table[i].label; i++)
7903 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7904 bitmap_clear(ServicePtrs[snum]->copymap, i);
7907 /* if it is a special case then go ahead */
7908 if (parm_table[parmnum].special) {
7909 return parm_table[parmnum].special(snum, pszParmValue,
7913 /* now switch on the type of variable it is */
7914 switch (parm_table[parmnum].type)
7917 *(bool *)parm_ptr = lp_bool(pszParmValue);
7921 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7925 *(int *)parm_ptr = lp_int(pszParmValue);
7929 *(char *)parm_ptr = *pszParmValue;
7933 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7935 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7940 TALLOC_FREE(*((char ***)parm_ptr));
7941 *(char ***)parm_ptr = str_list_make_v3(
7942 NULL, pszParmValue, NULL);
7946 string_set((char **)parm_ptr, pszParmValue);
7950 string_set((char **)parm_ptr, pszParmValue);
7951 strupper_m(*(char **)parm_ptr);
7955 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7964 /***************************************************************************
7965 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7966 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7967 ***************************************************************************/
7969 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7972 parmnum = map_parameter(pszParmName);
7974 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7975 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7978 parm_table[parmnum].flags |= FLAG_CMDLINE;
7980 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7981 * be grouped in the table, so we don't have to search the
7983 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
7984 parm_table[i].flags |= FLAG_CMDLINE;
7986 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
7987 parm_table[i].flags |= FLAG_CMDLINE;
7991 store_lp_set_cmdline(pszParmName, pszParmValue);
7996 /* it might be parametric */
7997 if (strchr(pszParmName, ':') != NULL) {
7998 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
8000 store_lp_set_cmdline(pszParmName, pszParmValue);
8005 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
8009 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
8011 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
8014 /***************************************************************************
8015 Process a parameter.
8016 ***************************************************************************/
8018 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
8021 if (!bInGlobalSection && bGlobalOnly)
8024 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
8026 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
8027 pszParmName, pszParmValue));
8031 set a option from the commandline in 'a=b' format. Use to support --option
8033 bool lp_set_option(const char *option)
8038 s = talloc_strdup(NULL, option);
8051 /* skip white spaces after the = sign */
8054 } while (*p == ' ');
8056 ret = lp_set_cmdline(s, p);
8061 /**************************************************************************
8062 Print a parameter of the specified type.
8063 ***************************************************************************/
8065 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
8071 for (i = 0; p->enum_list[i].name; i++) {
8072 if (*(int *)ptr == p->enum_list[i].value) {
8074 p->enum_list[i].name);
8081 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
8085 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
8089 fprintf(f, "%d", *(int *)ptr);
8093 fprintf(f, "%c", *(char *)ptr);
8097 char *o = octal_string(*(int *)ptr);
8098 fprintf(f, "%s", o);
8104 if ((char ***)ptr && *(char ***)ptr) {
8105 char **list = *(char ***)ptr;
8106 for (; *list; list++) {
8107 /* surround strings with whitespace in double quotes */
8108 if ( strchr_m( *list, ' ' ) )
8109 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
8111 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
8118 if (*(char **)ptr) {
8119 fprintf(f, "%s", *(char **)ptr);
8127 /***************************************************************************
8128 Check if two parameters are equal.
8129 ***************************************************************************/
8131 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8136 return (*((bool *)ptr1) == *((bool *)ptr2));
8141 return (*((int *)ptr1) == *((int *)ptr2));
8144 return (*((char *)ptr1) == *((char *)ptr2));
8147 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8152 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8157 return (p1 == p2 || strequal(p1, p2));
8165 /***************************************************************************
8166 Initialize any local varients in the sDefault table.
8167 ***************************************************************************/
8169 void init_locals(void)
8174 /***************************************************************************
8175 Process a new section (service). At this stage all sections are services.
8176 Later we'll have special sections that permit server parameters to be set.
8177 Returns True on success, False on failure.
8178 ***************************************************************************/
8180 static bool do_section(const char *pszSectionName, void *userdata)
8183 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8184 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8187 /* if we were in a global section then do the local inits */
8188 if (bInGlobalSection && !isglobal)
8191 /* if we've just struck a global section, note the fact. */
8192 bInGlobalSection = isglobal;
8194 /* check for multiple global sections */
8195 if (bInGlobalSection) {
8196 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8200 if (!bInGlobalSection && bGlobalOnly)
8203 /* if we have a current service, tidy it up before moving on */
8206 if (iServiceIndex >= 0)
8207 bRetval = service_ok(iServiceIndex);
8209 /* if all is still well, move to the next record in the services array */
8211 /* We put this here to avoid an odd message order if messages are */
8212 /* issued by the post-processing of a previous section. */
8213 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8215 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8217 DEBUG(0, ("Failed to add a new service\n"));
8220 /* Clean all parametric options for service */
8221 /* They will be added during parsing again */
8222 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
8229 /***************************************************************************
8230 Determine if a partcular base parameter is currentl set to the default value.
8231 ***************************************************************************/
8233 static bool is_default(int i)
8235 if (!defaults_saved)
8237 switch (parm_table[i].type) {
8239 return str_list_equal((const char **)parm_table[i].def.lvalue,
8240 *(const char ***)parm_table[i].ptr);
8243 return strequal(parm_table[i].def.svalue,
8244 *(char **)parm_table[i].ptr);
8247 return parm_table[i].def.bvalue ==
8248 *(bool *)parm_table[i].ptr;
8250 return parm_table[i].def.cvalue ==
8251 *(char *)parm_table[i].ptr;
8255 return parm_table[i].def.ivalue ==
8256 *(int *)parm_table[i].ptr;
8263 /***************************************************************************
8264 Display the contents of the global structure.
8265 ***************************************************************************/
8267 static void dump_globals(FILE *f)
8270 struct param_opt_struct *data;
8272 fprintf(f, "[global]\n");
8274 for (i = 0; parm_table[i].label; i++)
8275 if (parm_table[i].p_class == P_GLOBAL &&
8276 !(parm_table[i].flags & FLAG_META) &&
8277 parm_table[i].ptr &&
8278 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8279 if (defaults_saved && is_default(i))
8281 fprintf(f, "\t%s = ", parm_table[i].label);
8282 print_parameter(&parm_table[i], parm_table[i].ptr, f);
8285 if (Globals.param_opt != NULL) {
8286 data = Globals.param_opt;
8288 fprintf(f, "\t%s = %s\n", data->key, data->value);
8295 /***************************************************************************
8296 Return True if a local parameter is currently set to the global default.
8297 ***************************************************************************/
8299 bool lp_is_default(int snum, struct parm_struct *parm)
8301 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8303 return equal_parameter(parm->type,
8304 ((char *)ServicePtrs[snum]) + pdiff,
8305 ((char *)&sDefault) + pdiff);
8308 /***************************************************************************
8309 Display the contents of a single services record.
8310 ***************************************************************************/
8312 static void dump_a_service(struct service *pService, FILE * f)
8315 struct param_opt_struct *data;
8317 if (pService != &sDefault)
8318 fprintf(f, "[%s]\n", pService->szService);
8320 for (i = 0; parm_table[i].label; i++) {
8322 if (parm_table[i].p_class == P_LOCAL &&
8323 !(parm_table[i].flags & FLAG_META) &&
8324 parm_table[i].ptr &&
8325 (*parm_table[i].label != '-') &&
8326 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8328 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8330 if (pService == &sDefault) {
8331 if (defaults_saved && is_default(i))
8334 if (equal_parameter(parm_table[i].type,
8335 ((char *)pService) +
8337 ((char *)&sDefault) +
8342 fprintf(f, "\t%s = ", parm_table[i].label);
8343 print_parameter(&parm_table[i],
8344 ((char *)pService) + pdiff, f);
8349 if (pService->param_opt != NULL) {
8350 data = pService->param_opt;
8352 fprintf(f, "\t%s = %s\n", data->key, data->value);
8358 /***************************************************************************
8359 Display the contents of a parameter of a single services record.
8360 ***************************************************************************/
8362 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8365 bool result = False;
8368 fstring local_parm_name;
8370 const char *parm_opt_value;
8372 /* check for parametrical option */
8373 fstrcpy( local_parm_name, parm_name);
8374 parm_opt = strchr( local_parm_name, ':');
8379 if (strlen(parm_opt)) {
8380 parm_opt_value = lp_parm_const_string( snum,
8381 local_parm_name, parm_opt, NULL);
8382 if (parm_opt_value) {
8383 printf( "%s\n", parm_opt_value);
8390 /* check for a key and print the value */
8397 for (i = 0; parm_table[i].label; i++) {
8398 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8399 !(parm_table[i].flags & FLAG_META) &&
8400 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8401 parm_table[i].ptr &&
8402 (*parm_table[i].label != '-') &&
8403 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8408 ptr = parm_table[i].ptr;
8410 struct service *pService = ServicePtrs[snum];
8411 ptr = ((char *)pService) +
8412 PTR_DIFF(parm_table[i].ptr, &sDefault);
8415 print_parameter(&parm_table[i],
8426 /***************************************************************************
8427 Return info about the requested parameter (given as a string).
8428 Return NULL when the string is not a valid parameter name.
8429 ***************************************************************************/
8431 struct parm_struct *lp_get_parameter(const char *param_name)
8433 int num = map_parameter(param_name);
8439 return &parm_table[num];
8442 /***************************************************************************
8443 Return info about the next parameter in a service.
8444 snum==GLOBAL_SECTION_SNUM gives the globals.
8445 Return NULL when out of parameters.
8446 ***************************************************************************/
8448 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8451 /* do the globals */
8452 for (; parm_table[*i].label; (*i)++) {
8453 if (parm_table[*i].p_class == P_SEPARATOR)
8454 return &parm_table[(*i)++];
8456 if (!parm_table[*i].ptr
8457 || (*parm_table[*i].label == '-'))
8461 && (parm_table[*i].ptr ==
8462 parm_table[(*i) - 1].ptr))
8465 if (is_default(*i) && !allparameters)
8468 return &parm_table[(*i)++];
8471 struct service *pService = ServicePtrs[snum];
8473 for (; parm_table[*i].label; (*i)++) {
8474 if (parm_table[*i].p_class == P_SEPARATOR)
8475 return &parm_table[(*i)++];
8477 if (parm_table[*i].p_class == P_LOCAL &&
8478 parm_table[*i].ptr &&
8479 (*parm_table[*i].label != '-') &&
8481 (parm_table[*i].ptr !=
8482 parm_table[(*i) - 1].ptr)))
8485 PTR_DIFF(parm_table[*i].ptr,
8488 if (allparameters ||
8489 !equal_parameter(parm_table[*i].type,
8490 ((char *)pService) +
8492 ((char *)&sDefault) +
8495 return &parm_table[(*i)++];
8506 /***************************************************************************
8507 Display the contents of a single copy structure.
8508 ***************************************************************************/
8509 static void dump_copy_map(bool *pcopymap)
8515 printf("\n\tNon-Copied parameters:\n");
8517 for (i = 0; parm_table[i].label; i++)
8518 if (parm_table[i].p_class == P_LOCAL &&
8519 parm_table[i].ptr && !pcopymap[i] &&
8520 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8522 printf("\t\t%s\n", parm_table[i].label);
8527 /***************************************************************************
8528 Return TRUE if the passed service number is within range.
8529 ***************************************************************************/
8531 bool lp_snum_ok(int iService)
8533 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8536 /***************************************************************************
8537 Auto-load some home services.
8538 ***************************************************************************/
8540 static void lp_add_auto_services(char *str)
8550 s = SMB_STRDUP(str);
8554 homes = lp_servicenumber(HOMES_NAME);
8556 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8557 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8560 if (lp_servicenumber(p) >= 0)
8563 home = get_user_home_dir(talloc_tos(), p);
8565 if (home && home[0] && homes >= 0)
8566 lp_add_home(p, homes, p, home);
8573 /***************************************************************************
8574 Auto-load one printer.
8575 ***************************************************************************/
8577 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8579 int printers = lp_servicenumber(PRINTERS_NAME);
8582 if (lp_servicenumber(name) < 0) {
8583 lp_add_printer(name, printers);
8584 if ((i = lp_servicenumber(name)) >= 0) {
8585 string_set(&ServicePtrs[i]->comment, comment);
8586 ServicePtrs[i]->autoloaded = True;
8591 /***************************************************************************
8592 Have we loaded a services file yet?
8593 ***************************************************************************/
8595 bool lp_loaded(void)
8600 /***************************************************************************
8601 Unload unused services.
8602 ***************************************************************************/
8604 void lp_killunused(bool (*snumused) (int))
8607 for (i = 0; i < iNumServices; i++) {
8611 /* don't kill autoloaded or usershare services */
8612 if ( ServicePtrs[i]->autoloaded ||
8613 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8617 if (!snumused || !snumused(i)) {
8618 free_service_byindex(i);
8624 * Kill all except autoloaded and usershare services - convenience wrapper
8626 void lp_kill_all_services(void)
8628 lp_killunused(NULL);
8631 /***************************************************************************
8633 ***************************************************************************/
8635 void lp_killservice(int iServiceIn)
8637 if (VALID(iServiceIn)) {
8638 free_service_byindex(iServiceIn);
8642 /***************************************************************************
8643 Save the curent values of all global and sDefault parameters into the
8644 defaults union. This allows swat and testparm to show only the
8645 changed (ie. non-default) parameters.
8646 ***************************************************************************/
8648 static void lp_save_defaults(void)
8651 for (i = 0; parm_table[i].label; i++) {
8652 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8654 switch (parm_table[i].type) {
8656 parm_table[i].def.lvalue = str_list_copy(
8657 NULL, *(const char ***)parm_table[i].ptr);
8661 if (parm_table[i].ptr) {
8662 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8664 parm_table[i].def.svalue = NULL;
8669 parm_table[i].def.bvalue =
8670 *(bool *)parm_table[i].ptr;
8673 parm_table[i].def.cvalue =
8674 *(char *)parm_table[i].ptr;
8679 parm_table[i].def.ivalue =
8680 *(int *)parm_table[i].ptr;
8686 defaults_saved = True;
8689 /***********************************************************
8690 If we should send plaintext/LANMAN passwords in the clinet
8691 ************************************************************/
8693 static void set_allowed_client_auth(void)
8695 if (Globals.bClientNTLMv2Auth) {
8696 Globals.bClientLanManAuth = False;
8698 if (!Globals.bClientLanManAuth) {
8699 Globals.bClientPlaintextAuth = False;
8703 /***************************************************************************
8705 The following code allows smbd to read a user defined share file.
8706 Yes, this is my intent. Yes, I'm comfortable with that...
8708 THE FOLLOWING IS SECURITY CRITICAL CODE.
8710 It washes your clothes, it cleans your house, it guards you while you sleep...
8711 Do not f%^k with it....
8712 ***************************************************************************/
8714 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8716 /***************************************************************************
8717 Check allowed stat state of a usershare file.
8718 Ensure we print out who is dicking with us so the admin can
8719 get their sorry ass fired.
8720 ***************************************************************************/
8722 static bool check_usershare_stat(const char *fname,
8723 const SMB_STRUCT_STAT *psbuf)
8725 if (!S_ISREG(psbuf->st_ex_mode)) {
8726 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8727 "not a regular file\n",
8728 fname, (unsigned int)psbuf->st_ex_uid ));
8732 /* Ensure this doesn't have the other write bit set. */
8733 if (psbuf->st_ex_mode & S_IWOTH) {
8734 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8735 "public write. Refusing to allow as a usershare file.\n",
8736 fname, (unsigned int)psbuf->st_ex_uid ));
8740 /* Should be 10k or less. */
8741 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8742 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8743 "too large (%u) to be a user share file.\n",
8744 fname, (unsigned int)psbuf->st_ex_uid,
8745 (unsigned int)psbuf->st_ex_size ));
8752 /***************************************************************************
8753 Parse the contents of a usershare file.
8754 ***************************************************************************/
8756 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8757 SMB_STRUCT_STAT *psbuf,
8758 const char *servicename,
8762 char **pp_sharepath,
8764 char **pp_cp_servicename,
8765 struct security_descriptor **ppsd,
8768 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8769 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8772 SMB_STRUCT_STAT sbuf;
8773 char *sharepath = NULL;
8774 char *comment = NULL;
8776 *pp_sharepath = NULL;
8779 *pallow_guest = False;
8782 return USERSHARE_MALFORMED_FILE;
8785 if (strcmp(lines[0], "#VERSION 1") == 0) {
8787 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8790 return USERSHARE_MALFORMED_FILE;
8793 return USERSHARE_BAD_VERSION;
8796 if (strncmp(lines[1], "path=", 5) != 0) {
8797 return USERSHARE_MALFORMED_PATH;
8800 sharepath = talloc_strdup(ctx, &lines[1][5]);
8802 return USERSHARE_POSIX_ERR;
8804 trim_string(sharepath, " ", " ");
8806 if (strncmp(lines[2], "comment=", 8) != 0) {
8807 return USERSHARE_MALFORMED_COMMENT_DEF;
8810 comment = talloc_strdup(ctx, &lines[2][8]);
8812 return USERSHARE_POSIX_ERR;
8814 trim_string(comment, " ", " ");
8815 trim_char(comment, '"', '"');
8817 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8818 return USERSHARE_MALFORMED_ACL_DEF;
8821 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8822 return USERSHARE_ACL_ERR;
8826 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8827 return USERSHARE_MALFORMED_ACL_DEF;
8829 if (lines[4][9] == 'y') {
8830 *pallow_guest = True;
8833 /* Backwards compatible extension to file version #2. */
8835 if (strncmp(lines[5], "sharename=", 10) != 0) {
8836 return USERSHARE_MALFORMED_SHARENAME_DEF;
8838 if (!strequal(&lines[5][10], servicename)) {
8839 return USERSHARE_BAD_SHARENAME;
8841 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8842 if (!*pp_cp_servicename) {
8843 return USERSHARE_POSIX_ERR;
8848 if (*pp_cp_servicename == NULL) {
8849 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8850 if (!*pp_cp_servicename) {
8851 return USERSHARE_POSIX_ERR;
8855 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8856 /* Path didn't change, no checks needed. */
8857 *pp_sharepath = sharepath;
8858 *pp_comment = comment;
8859 return USERSHARE_OK;
8862 /* The path *must* be absolute. */
8863 if (sharepath[0] != '/') {
8864 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8865 servicename, sharepath));
8866 return USERSHARE_PATH_NOT_ABSOLUTE;
8869 /* If there is a usershare prefix deny list ensure one of these paths
8870 doesn't match the start of the user given path. */
8871 if (prefixdenylist) {
8873 for ( i=0; prefixdenylist[i]; i++ ) {
8874 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8875 servicename, i, prefixdenylist[i], sharepath ));
8876 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8877 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8878 "usershare prefix deny list entries.\n",
8879 servicename, sharepath));
8880 return USERSHARE_PATH_IS_DENIED;
8885 /* If there is a usershare prefix allow list ensure one of these paths
8886 does match the start of the user given path. */
8888 if (prefixallowlist) {
8890 for ( i=0; prefixallowlist[i]; i++ ) {
8891 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8892 servicename, i, prefixallowlist[i], sharepath ));
8893 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8897 if (prefixallowlist[i] == NULL) {
8898 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8899 "usershare prefix allow list entries.\n",
8900 servicename, sharepath));
8901 return USERSHARE_PATH_NOT_ALLOWED;
8905 /* Ensure this is pointing to a directory. */
8906 dp = sys_opendir(sharepath);
8909 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8910 servicename, sharepath));
8911 return USERSHARE_PATH_NOT_DIRECTORY;
8914 /* Ensure the owner of the usershare file has permission to share
8917 if (sys_stat(sharepath, &sbuf, false) == -1) {
8918 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8919 servicename, sharepath, strerror(errno) ));
8921 return USERSHARE_POSIX_ERR;
8926 if (!S_ISDIR(sbuf.st_ex_mode)) {
8927 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8928 servicename, sharepath ));
8929 return USERSHARE_PATH_NOT_DIRECTORY;
8932 /* Check if sharing is restricted to owner-only. */
8933 /* psbuf is the stat of the usershare definition file,
8934 sbuf is the stat of the target directory to be shared. */
8936 if (lp_usershare_owner_only()) {
8937 /* root can share anything. */
8938 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8939 return USERSHARE_PATH_NOT_ALLOWED;
8943 *pp_sharepath = sharepath;
8944 *pp_comment = comment;
8945 return USERSHARE_OK;
8948 /***************************************************************************
8949 Deal with a usershare file.
8952 -1 - Bad name, invalid contents.
8953 - service name already existed and not a usershare, problem
8954 with permissions to share directory etc.
8955 ***************************************************************************/
8957 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8959 SMB_STRUCT_STAT sbuf;
8960 SMB_STRUCT_STAT lsbuf;
8962 char *sharepath = NULL;
8963 char *comment = NULL;
8964 char *cp_service_name = NULL;
8965 char **lines = NULL;
8969 TALLOC_CTX *ctx = talloc_stackframe();
8970 struct security_descriptor *psd = NULL;
8971 bool guest_ok = False;
8972 char *canon_name = NULL;
8973 bool added_service = false;
8976 /* Ensure share name doesn't contain invalid characters. */
8977 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8978 DEBUG(0,("process_usershare_file: share name %s contains "
8979 "invalid characters (any of %s)\n",
8980 file_name, INVALID_SHARENAME_CHARS ));
8984 canon_name = canonicalize_servicename(ctx, file_name);
8989 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8994 /* Minimize the race condition by doing an lstat before we
8995 open and fstat. Ensure this isn't a symlink link. */
8997 if (sys_lstat(fname, &lsbuf, false) != 0) {
8998 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8999 fname, strerror(errno) ));
9003 /* This must be a regular file, not a symlink, directory or
9004 other strange filetype. */
9005 if (!check_usershare_stat(fname, &lsbuf)) {
9010 TDB_DATA data = dbwrap_fetch_bystring(
9011 ServiceHash, canon_name, canon_name);
9015 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
9016 iService = *(int *)data.dptr;
9020 if (iService != -1 &&
9021 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9022 &lsbuf.st_ex_mtime) == 0) {
9023 /* Nothing changed - Mark valid and return. */
9024 DEBUG(10,("process_usershare_file: service %s not changed.\n",
9026 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9031 /* Try and open the file read only - no symlinks allowed. */
9033 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
9035 fd = sys_open(fname, O_RDONLY, 0);
9039 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
9040 fname, strerror(errno) ));
9044 /* Now fstat to be *SURE* it's a regular file. */
9045 if (sys_fstat(fd, &sbuf, false) != 0) {
9047 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
9048 fname, strerror(errno) ));
9052 /* Is it the same dev/inode as was lstated ? */
9053 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
9055 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
9056 "Symlink spoofing going on ?\n", fname ));
9060 /* This must be a regular file, not a symlink, directory or
9061 other strange filetype. */
9062 if (!check_usershare_stat(fname, &sbuf)) {
9066 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
9069 if (lines == NULL) {
9070 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
9071 fname, (unsigned int)sbuf.st_ex_uid ));
9075 if (parse_usershare_file(ctx, &sbuf, file_name,
9076 iService, lines, numlines, &sharepath,
9077 &comment, &cp_service_name,
9078 &psd, &guest_ok) != USERSHARE_OK) {
9082 /* Everything ok - add the service possibly using a template. */
9084 const struct service *sp = &sDefault;
9085 if (snum_template != -1) {
9086 sp = ServicePtrs[snum_template];
9089 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
9090 DEBUG(0, ("process_usershare_file: Failed to add "
9091 "new service %s\n", cp_service_name));
9095 added_service = true;
9097 /* Read only is controlled by usershare ACL below. */
9098 ServicePtrs[iService]->bRead_only = False;
9101 /* Write the ACL of the new/modified share. */
9102 if (!set_share_security(canon_name, psd)) {
9103 DEBUG(0, ("process_usershare_file: Failed to set share "
9104 "security for user share %s\n",
9109 /* If from a template it may be marked invalid. */
9110 ServicePtrs[iService]->valid = True;
9112 /* Set the service as a valid usershare. */
9113 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9115 /* Set guest access. */
9116 if (lp_usershare_allow_guests()) {
9117 ServicePtrs[iService]->bGuest_ok = guest_ok;
9120 /* And note when it was loaded. */
9121 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
9122 string_set(&ServicePtrs[iService]->szPath, sharepath);
9123 string_set(&ServicePtrs[iService]->comment, comment);
9129 if (ret == -1 && iService != -1 && added_service) {
9130 lp_remove_service(iService);
9138 /***************************************************************************
9139 Checks if a usershare entry has been modified since last load.
9140 ***************************************************************************/
9142 static bool usershare_exists(int iService, struct timespec *last_mod)
9144 SMB_STRUCT_STAT lsbuf;
9145 const char *usersharepath = Globals.szUsersharePath;
9148 if (asprintf(&fname, "%s/%s",
9150 ServicePtrs[iService]->szService) < 0) {
9154 if (sys_lstat(fname, &lsbuf, false) != 0) {
9159 if (!S_ISREG(lsbuf.st_ex_mode)) {
9165 *last_mod = lsbuf.st_ex_mtime;
9169 /***************************************************************************
9170 Load a usershare service by name. Returns a valid servicenumber or -1.
9171 ***************************************************************************/
9173 int load_usershare_service(const char *servicename)
9175 SMB_STRUCT_STAT sbuf;
9176 const char *usersharepath = Globals.szUsersharePath;
9177 int max_user_shares = Globals.iUsershareMaxShares;
9178 int snum_template = -1;
9180 if (*usersharepath == 0 || max_user_shares == 0) {
9184 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9185 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9186 usersharepath, strerror(errno) ));
9190 if (!S_ISDIR(sbuf.st_ex_mode)) {
9191 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9197 * This directory must be owned by root, and have the 't' bit set.
9198 * It also must not be writable by "other".
9202 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9204 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9206 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9207 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9212 /* Ensure the template share exists if it's set. */
9213 if (Globals.szUsershareTemplateShare[0]) {
9214 /* We can't use lp_servicenumber here as we are recommending that
9215 template shares have -valid=False set. */
9216 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9217 if (ServicePtrs[snum_template]->szService &&
9218 strequal(ServicePtrs[snum_template]->szService,
9219 Globals.szUsershareTemplateShare)) {
9224 if (snum_template == -1) {
9225 DEBUG(0,("load_usershare_service: usershare template share %s "
9226 "does not exist.\n",
9227 Globals.szUsershareTemplateShare ));
9232 return process_usershare_file(usersharepath, servicename, snum_template);
9235 /***************************************************************************
9236 Load all user defined shares from the user share directory.
9237 We only do this if we're enumerating the share list.
9238 This is the function that can delete usershares that have
9240 ***************************************************************************/
9242 int load_usershare_shares(void)
9245 SMB_STRUCT_STAT sbuf;
9246 SMB_STRUCT_DIRENT *de;
9247 int num_usershares = 0;
9248 int max_user_shares = Globals.iUsershareMaxShares;
9249 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9250 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9251 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9253 int snum_template = -1;
9254 const char *usersharepath = Globals.szUsersharePath;
9255 int ret = lp_numservices();
9257 if (max_user_shares == 0 || *usersharepath == '\0') {
9258 return lp_numservices();
9261 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9262 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9263 usersharepath, strerror(errno) ));
9268 * This directory must be owned by root, and have the 't' bit set.
9269 * It also must not be writable by "other".
9273 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9275 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9277 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9278 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9283 /* Ensure the template share exists if it's set. */
9284 if (Globals.szUsershareTemplateShare[0]) {
9285 /* We can't use lp_servicenumber here as we are recommending that
9286 template shares have -valid=False set. */
9287 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9288 if (ServicePtrs[snum_template]->szService &&
9289 strequal(ServicePtrs[snum_template]->szService,
9290 Globals.szUsershareTemplateShare)) {
9295 if (snum_template == -1) {
9296 DEBUG(0,("load_usershare_shares: usershare template share %s "
9297 "does not exist.\n",
9298 Globals.szUsershareTemplateShare ));
9303 /* Mark all existing usershares as pending delete. */
9304 for (iService = iNumServices - 1; iService >= 0; iService--) {
9305 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9306 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9310 dp = sys_opendir(usersharepath);
9312 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9313 usersharepath, strerror(errno) ));
9317 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9318 (de = sys_readdir(dp));
9319 num_dir_entries++ ) {
9321 const char *n = de->d_name;
9323 /* Ignore . and .. */
9325 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9331 /* Temporary file used when creating a share. */
9332 num_tmp_dir_entries++;
9335 /* Allow 20% tmp entries. */
9336 if (num_tmp_dir_entries > allowed_tmp_entries) {
9337 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9338 "in directory %s\n",
9339 num_tmp_dir_entries, usersharepath));
9343 r = process_usershare_file(usersharepath, n, snum_template);
9345 /* Update the services count. */
9347 if (num_usershares >= max_user_shares) {
9348 DEBUG(0,("load_usershare_shares: max user shares reached "
9349 "on file %s in directory %s\n",
9350 n, usersharepath ));
9353 } else if (r == -1) {
9354 num_bad_dir_entries++;
9357 /* Allow 20% bad entries. */
9358 if (num_bad_dir_entries > allowed_bad_entries) {
9359 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9360 "in directory %s\n",
9361 num_bad_dir_entries, usersharepath));
9365 /* Allow 20% bad entries. */
9366 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9367 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9368 "in directory %s\n",
9369 num_dir_entries, usersharepath));
9376 /* Sweep through and delete any non-refreshed usershares that are
9377 not currently in use. */
9378 for (iService = iNumServices - 1; iService >= 0; iService--) {
9379 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9380 if (conn_snum_used(iService)) {
9383 /* Remove from the share ACL db. */
9384 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9385 lp_servicename(iService) ));
9386 delete_share_security(lp_servicename(iService));
9387 free_service_byindex(iService);
9391 return lp_numservices();
9394 /********************************************************
9395 Destroy global resources allocated in this file
9396 ********************************************************/
9398 void gfree_loadparm(void)
9404 /* Free resources allocated to services */
9406 for ( i = 0; i < iNumServices; i++ ) {
9408 free_service_byindex(i);
9412 SAFE_FREE( ServicePtrs );
9415 /* Now release all resources allocated to global
9416 parameters and the default service */
9418 free_global_parameters();
9422 /***************************************************************************
9423 Allow client apps to specify that they are a client
9424 ***************************************************************************/
9425 void lp_set_in_client(bool b)
9431 /***************************************************************************
9432 Determine if we're running in a client app
9433 ***************************************************************************/
9434 bool lp_is_in_client(void)
9439 /***************************************************************************
9440 Load the services array from the services file. Return True on success,
9442 ***************************************************************************/
9444 static bool lp_load_ex(const char *pszFname,
9448 bool initialize_globals,
9449 bool allow_include_registry,
9450 bool allow_registry_shares)
9457 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9459 bInGlobalSection = True;
9460 bGlobalOnly = global_only;
9461 bAllowIncludeRegistry = allow_include_registry;
9463 init_globals(initialize_globals);
9467 if (save_defaults) {
9472 free_param_opts(&Globals.param_opt);
9474 /* We get sections first, so have to start 'behind' to make up */
9477 if (lp_config_backend_is_file()) {
9478 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9479 current_user_info.domain,
9482 smb_panic("lp_load_ex: out of memory");
9485 add_to_file_list(pszFname, n2);
9487 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9490 /* finish up the last section */
9491 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9493 if (iServiceIndex >= 0) {
9494 bRetval = service_ok(iServiceIndex);
9498 if (lp_config_backend_is_registry()) {
9499 /* config backend changed to registry in config file */
9501 * We need to use this extra global variable here to
9502 * survive restart: init_globals uses this as a default
9503 * for ConfigBackend. Otherwise, init_globals would
9504 * send us into an endless loop here.
9506 config_backend = CONFIG_BACKEND_REGISTRY;
9508 DEBUG(1, ("lp_load_ex: changing to config backend "
9511 lp_kill_all_services();
9512 return lp_load_ex(pszFname, global_only, save_defaults,
9513 add_ipc, initialize_globals,
9514 allow_include_registry,
9515 allow_registry_shares);
9517 } else if (lp_config_backend_is_registry()) {
9518 bRetval = process_registry_globals();
9520 DEBUG(0, ("Illegal config backend given: %d\n",
9521 lp_config_backend()));
9525 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9526 bRetval = process_registry_shares();
9529 lp_add_auto_services(lp_auto_services());
9532 /* When 'restrict anonymous = 2' guest connections to ipc$
9534 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9535 if ( lp_enable_asu_support() ) {
9536 lp_add_ipc("ADMIN$", false);
9541 set_default_server_announce_type();
9542 set_allowed_client_auth();
9546 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9547 /* if bWINSsupport is true and we are in the client */
9548 if (lp_is_in_client() && Globals.bWINSsupport) {
9549 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9554 bAllowIncludeRegistry = true;
9559 bool lp_load(const char *pszFname,
9563 bool initialize_globals)
9565 return lp_load_ex(pszFname,
9570 true, /* allow_include_registry */
9571 false); /* allow_registry_shares*/
9574 bool lp_load_initial_only(const char *pszFname)
9576 return lp_load_ex(pszFname,
9577 true, /* global only */
9578 false, /* save_defaults */
9579 false, /* add_ipc */
9580 true, /* initialize_globals */
9581 false, /* allow_include_registry */
9582 false); /* allow_registry_shares*/
9585 bool lp_load_with_registry_shares(const char *pszFname,
9589 bool initialize_globals)
9591 return lp_load_ex(pszFname,
9596 true, /* allow_include_registry */
9597 true); /* allow_registry_shares*/
9600 /***************************************************************************
9601 Return the max number of services.
9602 ***************************************************************************/
9604 int lp_numservices(void)
9606 return (iNumServices);
9609 /***************************************************************************
9610 Display the contents of the services array in human-readable form.
9611 ***************************************************************************/
9613 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9618 defaults_saved = False;
9622 dump_a_service(&sDefault, f);
9624 for (iService = 0; iService < maxtoprint; iService++) {
9626 lp_dump_one(f, show_defaults, iService);
9630 /***************************************************************************
9631 Display the contents of one service in human-readable form.
9632 ***************************************************************************/
9634 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9637 if (ServicePtrs[snum]->szService[0] == '\0')
9639 dump_a_service(ServicePtrs[snum], f);
9643 /***************************************************************************
9644 Return the number of the service with the given name, or -1 if it doesn't
9645 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9646 getservicebyname()! This works ONLY if all services have been loaded, and
9647 does not copy the found service.
9648 ***************************************************************************/
9650 int lp_servicenumber(const char *pszServiceName)
9653 fstring serviceName;
9655 if (!pszServiceName) {
9656 return GLOBAL_SECTION_SNUM;
9659 for (iService = iNumServices - 1; iService >= 0; iService--) {
9660 if (VALID(iService) && ServicePtrs[iService]->szService) {
9662 * The substitution here is used to support %U is
9665 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9666 standard_sub_basic(get_current_username(),
9667 current_user_info.domain,
9668 serviceName,sizeof(serviceName));
9669 if (strequal(serviceName, pszServiceName)) {
9675 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9676 struct timespec last_mod;
9678 if (!usershare_exists(iService, &last_mod)) {
9679 /* Remove the share security tdb entry for it. */
9680 delete_share_security(lp_servicename(iService));
9681 /* Remove it from the array. */
9682 free_service_byindex(iService);
9683 /* Doesn't exist anymore. */
9684 return GLOBAL_SECTION_SNUM;
9687 /* Has it been modified ? If so delete and reload. */
9688 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9690 /* Remove it from the array. */
9691 free_service_byindex(iService);
9692 /* and now reload it. */
9693 iService = load_usershare_service(pszServiceName);
9698 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9699 return GLOBAL_SECTION_SNUM;
9705 bool share_defined(const char *service_name)
9707 return (lp_servicenumber(service_name) != -1);
9710 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9711 const char *sharename)
9713 struct share_params *result;
9717 snum = find_service(mem_ctx, sharename, &sname);
9718 if (snum < 0 || sname == NULL) {
9722 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9723 DEBUG(0, ("talloc failed\n"));
9727 result->service = snum;
9731 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9733 struct share_iterator *result;
9735 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9736 DEBUG(0, ("talloc failed\n"));
9740 result->next_id = 0;
9744 struct share_params *next_share(struct share_iterator *list)
9746 struct share_params *result;
9748 while (!lp_snum_ok(list->next_id) &&
9749 (list->next_id < lp_numservices())) {
9753 if (list->next_id >= lp_numservices()) {
9757 if (!(result = TALLOC_P(list, struct share_params))) {
9758 DEBUG(0, ("talloc failed\n"));
9762 result->service = list->next_id;
9767 struct share_params *next_printer(struct share_iterator *list)
9769 struct share_params *result;
9771 while ((result = next_share(list)) != NULL) {
9772 if (lp_print_ok(result->service)) {
9780 * This is a hack for a transition period until we transformed all code from
9781 * service numbers to struct share_params.
9784 struct share_params *snum2params_static(int snum)
9786 static struct share_params result;
9787 result.service = snum;
9791 /*******************************************************************
9792 A useful volume label function.
9793 ********************************************************************/
9795 const char *volume_label(int snum)
9798 const char *label = lp_volume(snum);
9800 label = lp_servicename(snum);
9803 /* This returns a 33 byte guarenteed null terminated string. */
9804 ret = talloc_strndup(talloc_tos(), label, 32);
9811 /*******************************************************************
9812 Set the server type we will announce as via nmbd.
9813 ********************************************************************/
9815 static void set_default_server_announce_type(void)
9817 default_server_announce = 0;
9818 default_server_announce |= SV_TYPE_WORKSTATION;
9819 default_server_announce |= SV_TYPE_SERVER;
9820 default_server_announce |= SV_TYPE_SERVER_UNIX;
9822 /* note that the flag should be set only if we have a
9823 printer service but nmbd doesn't actually load the
9824 services so we can't tell --jerry */
9826 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9828 switch (lp_announce_as()) {
9829 case ANNOUNCE_AS_NT_SERVER:
9830 default_server_announce |= SV_TYPE_SERVER_NT;
9831 /* fall through... */
9832 case ANNOUNCE_AS_NT_WORKSTATION:
9833 default_server_announce |= SV_TYPE_NT;
9835 case ANNOUNCE_AS_WIN95:
9836 default_server_announce |= SV_TYPE_WIN95_PLUS;
9838 case ANNOUNCE_AS_WFW:
9839 default_server_announce |= SV_TYPE_WFW;
9845 switch (lp_server_role()) {
9846 case ROLE_DOMAIN_MEMBER:
9847 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9849 case ROLE_DOMAIN_PDC:
9850 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9852 case ROLE_DOMAIN_BDC:
9853 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9855 case ROLE_STANDALONE:
9859 if (lp_time_server())
9860 default_server_announce |= SV_TYPE_TIME_SOURCE;
9862 if (lp_host_msdfs())
9863 default_server_announce |= SV_TYPE_DFS_SERVER;
9866 /***********************************************************
9867 If we are PDC then prefer us as DMB
9868 ************************************************************/
9870 bool lp_domain_master(void)
9872 if (Globals.iDomainMaster == Auto)
9873 return (lp_server_role() == ROLE_DOMAIN_PDC);
9875 return (bool)Globals.iDomainMaster;
9878 /***********************************************************
9879 If we are PDC then prefer us as DMB
9880 ************************************************************/
9882 bool lp_domain_master_true_or_auto(void)
9884 if (Globals.iDomainMaster) /* auto or yes */
9890 /***********************************************************
9891 If we are DMB then prefer us as LMB
9892 ************************************************************/
9894 bool lp_preferred_master(void)
9896 if (Globals.iPreferredMaster == Auto)
9897 return (lp_local_master() && lp_domain_master());
9899 return (bool)Globals.iPreferredMaster;
9902 /*******************************************************************
9904 ********************************************************************/
9906 void lp_remove_service(int snum)
9908 ServicePtrs[snum]->valid = False;
9909 invalid_services[num_invalid_services++] = snum;
9912 /*******************************************************************
9914 ********************************************************************/
9916 void lp_copy_service(int snum, const char *new_name)
9918 do_section(new_name, NULL);
9920 snum = lp_servicenumber(new_name);
9922 lp_do_parameter(snum, "copy", lp_servicename(snum));
9927 /*******************************************************************
9928 Get the default server type we will announce as via nmbd.
9929 ********************************************************************/
9931 int lp_default_server_announce(void)
9933 return default_server_announce;
9936 /*******************************************************************
9937 Split the announce version into major and minor numbers.
9938 ********************************************************************/
9940 int lp_major_announce_version(void)
9942 static bool got_major = False;
9943 static int major_version = DEFAULT_MAJOR_VERSION;
9948 return major_version;
9951 if ((vers = lp_announce_version()) == NULL)
9952 return major_version;
9954 if ((p = strchr_m(vers, '.')) == 0)
9955 return major_version;
9958 major_version = atoi(vers);
9959 return major_version;
9962 int lp_minor_announce_version(void)
9964 static bool got_minor = False;
9965 static int minor_version = DEFAULT_MINOR_VERSION;
9970 return minor_version;
9973 if ((vers = lp_announce_version()) == NULL)
9974 return minor_version;
9976 if ((p = strchr_m(vers, '.')) == 0)
9977 return minor_version;
9980 minor_version = atoi(p);
9981 return minor_version;
9984 /***********************************************************
9985 Set the global name resolution order (used in smbclient).
9986 ************************************************************/
9988 void lp_set_name_resolve_order(const char *new_order)
9990 string_set(&Globals.szNameResolveOrder, new_order);
9993 const char *lp_printername(int snum)
9995 const char *ret = _lp_printername(snum);
9996 if (ret == NULL || (ret != NULL && *ret == '\0'))
9997 ret = lp_const_servicename(snum);
10003 /***********************************************************
10004 Allow daemons such as winbindd to fix their logfile name.
10005 ************************************************************/
10007 void lp_set_logfile(const char *name)
10009 string_set(&Globals.szLogFile, name);
10010 debug_set_logfile(name);
10013 /*******************************************************************
10014 Return the max print jobs per queue.
10015 ********************************************************************/
10017 int lp_maxprintjobs(int snum)
10019 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
10020 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
10021 maxjobs = PRINT_MAX_JOBID - 1;
10026 const char *lp_printcapname(void)
10028 if ((Globals.szPrintcapname != NULL) &&
10029 (Globals.szPrintcapname[0] != '\0'))
10030 return Globals.szPrintcapname;
10032 if (sDefault.iPrinting == PRINT_CUPS) {
10040 if (sDefault.iPrinting == PRINT_BSD)
10041 return "/etc/printcap";
10043 return PRINTCAP_NAME;
10046 static uint32 spoolss_state;
10048 bool lp_disable_spoolss( void )
10050 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
10051 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
10053 return spoolss_state == SVCCTL_STOPPED ? True : False;
10056 void lp_set_spoolss_state( uint32 state )
10058 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
10060 spoolss_state = state;
10063 uint32 lp_get_spoolss_state( void )
10065 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
10068 /*******************************************************************
10069 Ensure we don't use sendfile if server smb signing is active.
10070 ********************************************************************/
10072 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
10074 bool sign_active = false;
10076 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
10077 if (get_Protocol() < PROTOCOL_NT1) {
10080 if (signing_state) {
10081 sign_active = smb_signing_is_active(signing_state);
10083 return (_lp_use_sendfile(snum) &&
10084 (get_remote_arch() != RA_WIN95) &&
10088 /*******************************************************************
10089 Turn off sendfile if we find the underlying OS doesn't support it.
10090 ********************************************************************/
10092 void set_use_sendfile(int snum, bool val)
10094 if (LP_SNUM_OK(snum))
10095 ServicePtrs[snum]->bUseSendfile = val;
10097 sDefault.bUseSendfile = val;
10100 /*******************************************************************
10101 Turn off storing DOS attributes if this share doesn't support it.
10102 ********************************************************************/
10104 void set_store_dos_attributes(int snum, bool val)
10106 if (!LP_SNUM_OK(snum))
10108 ServicePtrs[(snum)]->bStoreDosAttributes = val;
10111 void lp_set_mangling_method(const char *new_method)
10113 string_set(&Globals.szManglingMethod, new_method);
10116 /*******************************************************************
10117 Global state for POSIX pathname processing.
10118 ********************************************************************/
10120 static bool posix_pathnames;
10122 bool lp_posix_pathnames(void)
10124 return posix_pathnames;
10127 /*******************************************************************
10128 Change everything needed to ensure POSIX pathname processing (currently
10130 ********************************************************************/
10132 void lp_set_posix_pathnames(void)
10134 posix_pathnames = True;
10137 /*******************************************************************
10138 Global state for POSIX lock processing - CIFS unix extensions.
10139 ********************************************************************/
10141 bool posix_default_lock_was_set;
10142 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
10144 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
10146 if (posix_default_lock_was_set) {
10147 return posix_cifsx_locktype;
10149 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
10153 /*******************************************************************
10154 ********************************************************************/
10156 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
10158 posix_default_lock_was_set = True;
10159 posix_cifsx_locktype = val;
10162 int lp_min_receive_file_size(void)
10164 if (Globals.iminreceivefile < 0) {
10167 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
10170 /*******************************************************************
10171 If socket address is an empty character string, it is necessary to
10172 define it as "0.0.0.0".
10173 ********************************************************************/
10175 const char *lp_socket_address(void)
10177 char *sock_addr = Globals.szSocketAddress;
10179 if (sock_addr[0] == '\0'){
10180 string_set(&Globals.szSocketAddress, "0.0.0.0");
10182 return Globals.szSocketAddress;
10185 void lp_set_passdb_backend(const char *backend)
10187 string_set(&Globals.szPassdbBackend, backend);
10190 /*******************************************************************
10191 Safe wide links checks.
10192 This helper function always verify the validity of wide links,
10193 even after a configuration file reload.
10194 ********************************************************************/
10196 static bool lp_widelinks_internal(int snum)
10198 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
10199 sDefault.bWidelinks);
10202 void widelinks_warning(int snum)
10204 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10205 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10206 "These parameters are incompatible. "
10207 "Wide links will be disabled for this share.\n",
10208 lp_servicename(snum) ));
10212 bool lp_widelinks(int snum)
10214 /* wide links is always incompatible with unix extensions */
10215 if (lp_unix_extensions()) {
10219 return lp_widelinks_internal(snum);
10222 bool lp_writeraw(void)
10224 if (lp_async_smb_echo_handler()) {
10227 return _lp_writeraw();
10230 bool lp_readraw(void)
10232 if (lp_async_smb_echo_handler()) {
10235 return _lp_readraw();