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 read only",
4557 .p_class = P_GLOBAL,
4558 .ptr = &Globals.bIdmapReadOnly,
4561 .flags = FLAG_ADVANCED,
4564 .label = "idmap cache time",
4566 .p_class = P_GLOBAL,
4567 .ptr = &Globals.iIdmapCacheTime,
4570 .flags = FLAG_ADVANCED,
4573 .label = "idmap negative cache time",
4575 .p_class = P_GLOBAL,
4576 .ptr = &Globals.iIdmapNegativeCacheTime,
4579 .flags = FLAG_ADVANCED,
4582 .label = "idmap uid",
4584 .p_class = P_GLOBAL,
4585 .ptr = &Globals.szIdmapUID,
4586 .special = handle_idmap_uid,
4588 .flags = FLAG_ADVANCED,
4591 .label = "winbind uid",
4593 .p_class = P_GLOBAL,
4594 .ptr = &Globals.szIdmapUID,
4595 .special = handle_idmap_uid,
4600 .label = "idmap gid",
4602 .p_class = P_GLOBAL,
4603 .ptr = &Globals.szIdmapGID,
4604 .special = handle_idmap_gid,
4606 .flags = FLAG_ADVANCED,
4609 .label = "winbind gid",
4611 .p_class = P_GLOBAL,
4612 .ptr = &Globals.szIdmapGID,
4613 .special = handle_idmap_gid,
4618 .label = "template homedir",
4620 .p_class = P_GLOBAL,
4621 .ptr = &Globals.szTemplateHomedir,
4624 .flags = FLAG_ADVANCED,
4627 .label = "template shell",
4629 .p_class = P_GLOBAL,
4630 .ptr = &Globals.szTemplateShell,
4633 .flags = FLAG_ADVANCED,
4636 .label = "winbind separator",
4638 .p_class = P_GLOBAL,
4639 .ptr = &Globals.szWinbindSeparator,
4642 .flags = FLAG_ADVANCED,
4645 .label = "winbind cache time",
4647 .p_class = P_GLOBAL,
4648 .ptr = &Globals.winbind_cache_time,
4651 .flags = FLAG_ADVANCED,
4654 .label = "winbind reconnect delay",
4656 .p_class = P_GLOBAL,
4657 .ptr = &Globals.winbind_reconnect_delay,
4660 .flags = FLAG_ADVANCED,
4663 .label = "winbind max clients",
4665 .p_class = P_GLOBAL,
4666 .ptr = &Globals.winbind_max_clients,
4669 .flags = FLAG_ADVANCED,
4672 .label = "winbind enum users",
4674 .p_class = P_GLOBAL,
4675 .ptr = &Globals.bWinbindEnumUsers,
4678 .flags = FLAG_ADVANCED,
4681 .label = "winbind enum groups",
4683 .p_class = P_GLOBAL,
4684 .ptr = &Globals.bWinbindEnumGroups,
4687 .flags = FLAG_ADVANCED,
4690 .label = "winbind use default domain",
4692 .p_class = P_GLOBAL,
4693 .ptr = &Globals.bWinbindUseDefaultDomain,
4696 .flags = FLAG_ADVANCED,
4699 .label = "winbind trusted domains only",
4701 .p_class = P_GLOBAL,
4702 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4705 .flags = FLAG_ADVANCED,
4708 .label = "winbind nested groups",
4710 .p_class = P_GLOBAL,
4711 .ptr = &Globals.bWinbindNestedGroups,
4714 .flags = FLAG_ADVANCED,
4717 .label = "winbind expand groups",
4719 .p_class = P_GLOBAL,
4720 .ptr = &Globals.winbind_expand_groups,
4723 .flags = FLAG_ADVANCED,
4726 .label = "winbind nss info",
4728 .p_class = P_GLOBAL,
4729 .ptr = &Globals.szWinbindNssInfo,
4732 .flags = FLAG_ADVANCED,
4735 .label = "winbind refresh tickets",
4737 .p_class = P_GLOBAL,
4738 .ptr = &Globals.bWinbindRefreshTickets,
4741 .flags = FLAG_ADVANCED,
4744 .label = "winbind offline logon",
4746 .p_class = P_GLOBAL,
4747 .ptr = &Globals.bWinbindOfflineLogon,
4750 .flags = FLAG_ADVANCED,
4753 .label = "winbind normalize names",
4755 .p_class = P_GLOBAL,
4756 .ptr = &Globals.bWinbindNormalizeNames,
4759 .flags = FLAG_ADVANCED,
4762 .label = "winbind rpc only",
4764 .p_class = P_GLOBAL,
4765 .ptr = &Globals.bWinbindRpcOnly,
4768 .flags = FLAG_ADVANCED,
4771 .label = "create krb5 conf",
4773 .p_class = P_GLOBAL,
4774 .ptr = &Globals.bCreateKrb5Conf,
4777 .flags = FLAG_ADVANCED,
4780 .label = "ncalrpc dir",
4782 .p_class = P_GLOBAL,
4783 .ptr = &Globals.ncalrpc_dir,
4786 .flags = FLAG_ADVANCED,
4789 .label = "winbind max domain connections",
4791 .p_class = P_GLOBAL,
4792 .ptr = &Globals.winbindMaxDomainConnections,
4795 .flags = FLAG_ADVANCED,
4798 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4801 /***************************************************************************
4802 Initialise the sDefault parameter structure for the printer values.
4803 ***************************************************************************/
4805 static void init_printer_values(struct service *pService)
4807 /* choose defaults depending on the type of printing */
4808 switch (pService->iPrinting) {
4813 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4814 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4815 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4820 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4821 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4822 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4823 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4824 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4825 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4826 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4832 /* set the lpq command to contain the destination printer
4833 name only. This is used by cups_queue_get() */
4834 string_set(&pService->szLpqcommand, "%p");
4835 string_set(&pService->szLprmcommand, "");
4836 string_set(&pService->szPrintcommand, "");
4837 string_set(&pService->szLppausecommand, "");
4838 string_set(&pService->szLpresumecommand, "");
4839 string_set(&pService->szQueuepausecommand, "");
4840 string_set(&pService->szQueueresumecommand, "");
4842 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4843 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4844 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4845 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4846 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4847 string_set(&pService->szQueuepausecommand, "disable '%p'");
4848 string_set(&pService->szQueueresumecommand, "enable '%p'");
4849 #endif /* HAVE_CUPS */
4854 string_set(&pService->szLpqcommand, "lpstat -o%p");
4855 string_set(&pService->szLprmcommand, "cancel %p-%j");
4856 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4857 string_set(&pService->szQueuepausecommand, "disable %p");
4858 string_set(&pService->szQueueresumecommand, "enable %p");
4860 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4861 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4866 string_set(&pService->szLpqcommand, "lpq -P%p");
4867 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4868 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4871 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4875 string_set(&pService->szPrintcommand, "vlp print %p %s");
4876 string_set(&pService->szLpqcommand, "vlp lpq %p");
4877 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4878 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4879 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4880 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4881 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4883 #endif /* DEVELOPER */
4888 * Function to return the default value for the maximum number of open
4889 * file descriptors permitted. This function tries to consult the
4890 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4891 * the smaller of those.
4893 static int max_open_files(void)
4895 int sysctl_max = MAX_OPEN_FILES;
4896 int rlimit_max = MAX_OPEN_FILES;
4898 #ifdef HAVE_SYSCTLBYNAME
4900 size_t size = sizeof(sysctl_max);
4901 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4906 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4912 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4913 rlimit_max = rl.rlim_cur;
4915 #if defined(RLIM_INFINITY)
4916 if(rl.rlim_cur == RLIM_INFINITY)
4917 rlimit_max = MAX_OPEN_FILES;
4922 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4923 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4924 "minimum Windows limit (%d)\n",
4926 MIN_OPEN_FILES_WINDOWS));
4927 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4930 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4931 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4932 "minimum Windows limit (%d)\n",
4934 MIN_OPEN_FILES_WINDOWS));
4935 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4938 return MIN(sysctl_max, rlimit_max);
4942 * Common part of freeing allocated data for one parameter.
4944 static void free_one_parameter_common(void *parm_ptr,
4945 struct parm_struct parm)
4947 if ((parm.type == P_STRING) ||
4948 (parm.type == P_USTRING))
4950 string_free((char**)parm_ptr);
4951 } else if (parm.type == P_LIST) {
4952 TALLOC_FREE(*((char***)parm_ptr));
4957 * Free the allocated data for one parameter for a share
4958 * given as a service struct.
4960 static void free_one_parameter(struct service *service,
4961 struct parm_struct parm)
4965 if (parm.p_class != P_LOCAL) {
4969 parm_ptr = lp_local_ptr(service, parm.ptr);
4971 free_one_parameter_common(parm_ptr, parm);
4975 * Free the allocated parameter data of a share given
4976 * as a service struct.
4978 static void free_parameters(struct service *service)
4982 for (i=0; parm_table[i].label; i++) {
4983 free_one_parameter(service, parm_table[i]);
4988 * Free the allocated data for one parameter for a given share
4989 * specified by an snum.
4991 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4995 if (parm.ptr == NULL) {
5000 parm_ptr = parm.ptr;
5001 } else if (parm.p_class != P_LOCAL) {
5004 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
5007 free_one_parameter_common(parm_ptr, parm);
5011 * Free the allocated parameter data for a share specified
5014 static void free_parameters_by_snum(int snum)
5018 for (i=0; parm_table[i].label; i++) {
5019 free_one_parameter_by_snum(snum, parm_table[i]);
5024 * Free the allocated global parameters.
5026 static void free_global_parameters(void)
5028 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
5031 static int map_parameter(const char *pszParmName);
5033 struct lp_stored_option {
5034 struct lp_stored_option *prev, *next;
5039 static struct lp_stored_option *stored_options;
5042 save options set by lp_set_cmdline() into a list. This list is
5043 re-applied when we do a globals reset, so that cmdline set options
5044 are sticky across reloads of smb.conf
5046 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
5048 struct lp_stored_option *entry, *entry_next;
5049 for (entry = stored_options; entry != NULL; entry = entry_next) {
5050 entry_next = entry->next;
5051 if (strcmp(pszParmName, entry->label) == 0) {
5052 DLIST_REMOVE(stored_options, entry);
5058 entry = talloc(NULL, struct lp_stored_option);
5063 entry->label = talloc_strdup(entry, pszParmName);
5064 if (!entry->label) {
5069 entry->value = talloc_strdup(entry, pszParmValue);
5070 if (!entry->value) {
5075 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
5080 static bool apply_lp_set_cmdline(void)
5082 struct lp_stored_option *entry = NULL;
5083 for (entry = stored_options; entry != NULL; entry = entry->next) {
5084 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
5085 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
5086 entry->label, entry->value));
5093 /***************************************************************************
5094 Initialise the global parameter structure.
5095 ***************************************************************************/
5097 static void init_globals(bool reinit_globals)
5099 static bool done_init = False;
5103 /* If requested to initialize only once and we've already done it... */
5104 if (!reinit_globals && done_init) {
5105 /* ... then we have nothing more to do */
5110 /* The logfile can be set before this is invoked. Free it if so. */
5111 if (Globals.szLogFile != NULL) {
5112 string_free(&Globals.szLogFile);
5113 Globals.szLogFile = NULL;
5117 free_global_parameters();
5120 /* This memset and the free_global_parameters() above will
5121 * wipe out smb.conf options set with lp_set_cmdline(). The
5122 * apply_lp_set_cmdline() call puts these values back in the
5123 * table once the defaults are set */
5124 memset((void *)&Globals, '\0', sizeof(Globals));
5126 for (i = 0; parm_table[i].label; i++) {
5127 if ((parm_table[i].type == P_STRING ||
5128 parm_table[i].type == P_USTRING) &&
5131 string_set((char **)parm_table[i].ptr, "");
5135 string_set(&sDefault.fstype, FSTYPE_STRING);
5136 string_set(&sDefault.szPrintjobUsername, "%U");
5138 init_printer_values(&sDefault);
5141 DEBUG(3, ("Initialising global parameters\n"));
5143 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
5144 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
5146 /* use the new 'hash2' method by default, with a prefix of 1 */
5147 string_set(&Globals.szManglingMethod, "hash2");
5148 Globals.mangle_prefix = 1;
5150 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5152 /* using UTF8 by default allows us to support all chars */
5153 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5155 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
5156 /* If the system supports nl_langinfo(), try to grab the value
5157 from the user's locale */
5158 string_set(&Globals.display_charset, "LOCALE");
5160 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
5163 /* Use codepage 850 as a default for the dos character set */
5164 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5167 * Allow the default PASSWD_CHAT to be overridden in local.h.
5169 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5171 set_global_myname(myhostname());
5172 string_set(&Globals.szNetbiosName,global_myname());
5174 set_global_myworkgroup(WORKGROUP);
5175 string_set(&Globals.szWorkgroup, lp_workgroup());
5177 string_set(&Globals.szPasswdProgram, "");
5178 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5179 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5180 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5181 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5182 string_set(&Globals.szSocketAddress, "0.0.0.0");
5184 * By default support explicit binding to broadcast
5187 Globals.bNmbdBindExplicitBroadcast = true;
5189 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5190 smb_panic("init_globals: ENOMEM");
5192 string_set(&Globals.szServerString, s);
5194 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5195 DEFAULT_MINOR_VERSION) < 0) {
5196 smb_panic("init_globals: ENOMEM");
5198 string_set(&Globals.szAnnounceVersion, s);
5201 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5204 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5206 string_set(&Globals.szLogonDrive, "");
5207 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5208 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5209 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5211 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5212 string_set(&Globals.szPasswordServer, "*");
5214 Globals.AlgorithmicRidBase = BASE_RID;
5216 Globals.bLoadPrinters = True;
5217 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
5219 Globals.ConfigBackend = config_backend;
5221 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5222 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5223 Globals.max_xmit = 0x4104;
5224 Globals.max_mux = 50; /* This is *needed* for profile support. */
5225 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
5226 Globals.bDisableSpoolss = False;
5227 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5228 Globals.pwordlevel = 0;
5229 Globals.unamelevel = 0;
5230 Globals.deadtime = 0;
5231 Globals.getwd_cache = true;
5232 Globals.bLargeReadwrite = True;
5233 Globals.max_log_size = 5000;
5234 Globals.max_open_files = max_open_files();
5235 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5236 Globals.maxprotocol = PROTOCOL_NT1;
5237 Globals.minprotocol = PROTOCOL_CORE;
5238 Globals.security = SEC_USER;
5239 Globals.paranoid_server_security = True;
5240 Globals.bEncryptPasswords = True;
5241 Globals.bUpdateEncrypt = False;
5242 Globals.clientSchannel = Auto;
5243 Globals.serverSchannel = Auto;
5244 Globals.bReadRaw = True;
5245 Globals.bWriteRaw = True;
5246 Globals.bNullPasswords = False;
5247 Globals.bObeyPamRestrictions = False;
5249 Globals.bSyslogOnly = False;
5250 Globals.bTimestampLogs = True;
5251 string_set(&Globals.szLogLevel, "0");
5252 Globals.bDebugPrefixTimestamp = False;
5253 Globals.bDebugHiresTimestamp = true;
5254 Globals.bDebugPid = False;
5255 Globals.bDebugUid = False;
5256 Globals.bDebugClass = False;
5257 Globals.bEnableCoreFiles = True;
5258 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5259 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5260 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5261 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5262 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5263 Globals.lm_interval = 60;
5264 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5265 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5266 Globals.bNISHomeMap = False;
5267 #ifdef WITH_NISPLUS_HOME
5268 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5270 string_set(&Globals.szNISHomeMapName, "auto.home");
5273 Globals.bTimeServer = False;
5274 Globals.bBindInterfacesOnly = False;
5275 Globals.bUnixPasswdSync = False;
5276 Globals.bPamPasswordChange = False;
5277 Globals.bPasswdChatDebug = False;
5278 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5279 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5280 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5281 Globals.bStatCache = True; /* use stat cache by default */
5282 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5283 Globals.restrict_anonymous = 0;
5284 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5285 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5286 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5287 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5288 Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
5289 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
5291 Globals.map_to_guest = 0; /* By Default, "Never" */
5292 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5293 Globals.enhanced_browsing = true;
5294 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5295 #ifdef MMAP_BLACKLIST
5296 Globals.bUseMmap = False;
5298 Globals.bUseMmap = True;
5300 Globals.bUnixExtensions = True;
5301 Globals.bResetOnZeroVC = False;
5302 Globals.bLogWriteableFilesOnExit = False;
5303 Globals.bCreateKrb5Conf = true;
5304 Globals.winbindMaxDomainConnections = 1;
5306 /* hostname lookups can be very expensive and are broken on
5307 a large number of sites (tridge) */
5308 Globals.bHostnameLookups = False;
5310 string_set(&Globals.szPassdbBackend, "tdbsam");
5311 string_set(&Globals.szLdapSuffix, "");
5312 string_set(&Globals.szLdapMachineSuffix, "");
5313 string_set(&Globals.szLdapUserSuffix, "");
5314 string_set(&Globals.szLdapGroupSuffix, "");
5315 string_set(&Globals.szLdapIdmapSuffix, "");
5317 string_set(&Globals.szLdapAdminDn, "");
5318 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5319 Globals.ldap_ssl_ads = False;
5320 Globals.ldap_deref = -1;
5321 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5322 Globals.ldap_delete_dn = False;
5323 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5324 Globals.ldap_follow_referral = Auto;
5325 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5326 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5327 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5329 Globals.ldap_debug_level = 0;
5330 Globals.ldap_debug_threshold = 10;
5332 /* This is what we tell the afs client. in reality we set the token
5333 * to never expire, though, when this runs out the afs client will
5334 * forget the token. Set to 0 to get NEVERDATE.*/
5335 Globals.iAfsTokenLifetime = 604800;
5336 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5338 /* these parameters are set to defaults that are more appropriate
5339 for the increasing samba install base:
5341 as a member of the workgroup, that will possibly become a
5342 _local_ master browser (lm = True). this is opposed to a forced
5343 local master browser startup (pm = True).
5345 doesn't provide WINS server service by default (wsupp = False),
5346 and doesn't provide domain master browser services by default, either.
5350 Globals.bMsAddPrinterWizard = True;
5351 Globals.os_level = 20;
5352 Globals.bLocalMaster = True;
5353 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5354 Globals.bDomainLogons = False;
5355 Globals.bBrowseList = True;
5356 Globals.bWINSsupport = False;
5357 Globals.bWINSproxy = False;
5359 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5360 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5362 Globals.bDNSproxy = True;
5364 /* this just means to use them if they exist */
5365 Globals.bKernelOplocks = True;
5367 Globals.bAllowTrustedDomains = True;
5368 string_set(&Globals.szIdmapBackend, "tdb");
5369 Globals.bIdmapReadOnly = false;
5371 string_set(&Globals.szTemplateShell, "/bin/false");
5372 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5373 string_set(&Globals.szWinbindSeparator, "\\");
5375 string_set(&Globals.szCupsServer, "");
5376 string_set(&Globals.szIPrintServer, "");
5378 string_set(&Globals.ctdbdSocket, "");
5379 Globals.szClusterAddresses = NULL;
5380 Globals.clustering = False;
5381 Globals.ctdb_timeout = 0;
5382 Globals.ctdb_locktime_warn_threshold = 0;
5384 Globals.winbind_cache_time = 300; /* 5 minutes */
5385 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5386 Globals.winbind_max_clients = 200;
5387 Globals.bWinbindEnumUsers = False;
5388 Globals.bWinbindEnumGroups = False;
5389 Globals.bWinbindUseDefaultDomain = False;
5390 Globals.bWinbindTrustedDomainsOnly = False;
5391 Globals.bWinbindNestedGroups = True;
5392 Globals.winbind_expand_groups = 1;
5393 Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
5394 Globals.bWinbindRefreshTickets = False;
5395 Globals.bWinbindOfflineLogon = False;
5397 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5398 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5400 Globals.bPassdbExpandExplicit = False;
5402 Globals.name_cache_timeout = 660; /* In seconds */
5404 Globals.bUseSpnego = True;
5405 Globals.bClientUseSpnego = True;
5407 Globals.client_signing = Auto;
5408 Globals.server_signing = False;
5410 Globals.bDeferSharingViolations = True;
5411 string_set(&Globals.smb_ports, SMB_PORTS);
5413 Globals.bEnablePrivileges = True;
5414 Globals.bHostMSDfs = True;
5415 Globals.bASUSupport = False;
5417 /* User defined shares. */
5418 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5419 smb_panic("init_globals: ENOMEM");
5421 string_set(&Globals.szUsersharePath, s);
5423 string_set(&Globals.szUsershareTemplateShare, "");
5424 Globals.iUsershareMaxShares = 0;
5425 /* By default disallow sharing of directories not owned by the sharer. */
5426 Globals.bUsershareOwnerOnly = True;
5427 /* By default disallow guest access to usershares. */
5428 Globals.bUsershareAllowGuests = False;
5430 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5432 /* By default no shares out of the registry */
5433 Globals.bRegistryShares = False;
5435 Globals.iminreceivefile = 0;
5437 Globals.bMapUntrustedToDomain = false;
5438 Globals.bMulticastDnsRegister = true;
5440 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
5441 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
5442 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
5443 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5445 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5447 /* Now put back the settings that were set with lp_set_cmdline() */
5448 apply_lp_set_cmdline();
5451 /*******************************************************************
5452 Convenience routine to grab string parameters into temporary memory
5453 and run standard_sub_basic on them. The buffers can be written to by
5454 callers without affecting the source string.
5455 ********************************************************************/
5457 static char *lp_string(const char *s)
5460 TALLOC_CTX *ctx = talloc_tos();
5462 /* The follow debug is useful for tracking down memory problems
5463 especially if you have an inner loop that is calling a lp_*()
5464 function that returns a string. Perhaps this debug should be
5465 present all the time? */
5468 DEBUG(10, ("lp_string(%s)\n", s));
5474 ret = talloc_sub_basic(ctx,
5475 get_current_username(),
5476 current_user_info.domain,
5478 if (trim_char(ret, '\"', '\"')) {
5479 if (strchr(ret,'\"') != NULL) {
5481 ret = talloc_sub_basic(ctx,
5482 get_current_username(),
5483 current_user_info.domain,
5491 In this section all the functions that are used to access the
5492 parameters from the rest of the program are defined
5495 #define FN_GLOBAL_STRING(fn_name,ptr) \
5496 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5497 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5498 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5499 #define FN_GLOBAL_LIST(fn_name,ptr) \
5500 const char **fn_name(void) {return(*(const char ***)(ptr));}
5501 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5502 bool fn_name(void) {return(*(bool *)(ptr));}
5503 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5504 char fn_name(void) {return(*(char *)(ptr));}
5505 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5506 int fn_name(void) {return(*(int *)(ptr));}
5508 #define FN_LOCAL_STRING(fn_name,val) \
5509 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5510 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5511 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5512 #define FN_LOCAL_LIST(fn_name,val) \
5513 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5514 #define FN_LOCAL_BOOL(fn_name,val) \
5515 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5516 #define FN_LOCAL_INTEGER(fn_name,val) \
5517 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5519 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5520 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5521 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5522 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5523 #define FN_LOCAL_CHAR(fn_name,val) \
5524 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5526 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5527 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5528 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5529 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5530 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5531 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5532 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5533 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5534 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5535 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5536 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5537 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5538 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5539 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5540 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5541 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5542 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5543 * build process or in smb.conf, we use that value. Otherwise they
5544 * default to the value of lp_lockdir(). */
5545 char *lp_statedir(void) {
5546 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5547 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5548 return(lp_string(*(char **)(&Globals.szStateDir) ?
5549 *(char **)(&Globals.szStateDir) : ""));
5551 return(lp_string(*(char **)(&Globals.szLockDir) ?
5552 *(char **)(&Globals.szLockDir) : ""));
5554 char *lp_cachedir(void) {
5555 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5556 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5557 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5558 *(char **)(&Globals.szCacheDir) : ""));
5560 return(lp_string(*(char **)(&Globals.szLockDir) ?
5561 *(char **)(&Globals.szLockDir) : ""));
5563 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5564 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5565 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5566 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5567 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5568 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5569 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5570 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5571 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5572 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5573 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5574 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5575 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5576 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5577 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5578 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5579 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5580 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5581 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5582 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5583 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5584 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5585 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5586 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5587 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5588 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5589 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5590 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5591 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5592 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5593 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5594 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5595 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5596 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5597 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5598 * lp_passdb_backend() should be replace by the this macro again after
5601 const char *lp_passdb_backend(void)
5603 char *delim, *quote;
5605 delim = strchr( Globals.szPassdbBackend, ' ');
5606 /* no space at all */
5607 if (delim == NULL) {
5611 quote = strchr(Globals.szPassdbBackend, '"');
5612 /* no quote char or non in the first part */
5613 if (quote == NULL || quote > delim) {
5618 quote = strchr(quote+1, '"');
5619 if (quote == NULL) {
5620 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5622 } else if (*(quote+1) == '\0') {
5623 /* space, fitting quote char, and one backend only */
5626 /* terminate string after the fitting quote char */
5631 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5632 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5633 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5634 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5637 return Globals.szPassdbBackend;
5639 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5640 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5641 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5642 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5643 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5645 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5646 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5647 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5648 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5649 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5650 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5652 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5654 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5655 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5656 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5657 FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
5659 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5661 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5662 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5663 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5664 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5665 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5666 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5667 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5668 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5669 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5670 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5671 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5672 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5673 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5674 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5675 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5676 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5677 static FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections_int,
5678 &Globals.winbindMaxDomainConnections)
5680 int lp_winbind_max_domain_connections(void)
5682 if (lp_winbind_offline_logon() &&
5683 lp_winbind_max_domain_connections_int() > 1) {
5684 DEBUG(1, ("offline logons active, restricting max domain "
5685 "connections to 1\n"));
5688 return MAX(1, lp_winbind_max_domain_connections_int());
5691 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5692 FN_GLOBAL_BOOL(lp_idmap_read_only, &Globals.bIdmapReadOnly)
5693 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5694 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5695 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5696 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5698 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5699 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5700 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5701 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5702 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5703 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5704 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5705 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5706 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5707 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5708 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5709 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5710 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5711 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5712 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5713 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5714 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5715 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5716 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5717 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5719 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5721 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5722 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5723 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5724 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5725 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5726 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5727 &Globals.bLogWriteableFilesOnExit)
5728 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5729 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5730 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5731 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5732 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5733 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5734 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5735 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5736 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5737 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5738 FN_GLOBAL_BOOL(_lp_readraw, &Globals.bReadRaw)
5739 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5740 FN_GLOBAL_BOOL(_lp_writeraw, &Globals.bWriteRaw)
5741 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5742 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5743 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5744 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5745 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5746 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5747 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5748 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5749 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5750 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5751 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5752 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5753 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5754 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5755 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5756 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5757 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5758 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5759 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5760 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5761 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5762 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5763 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5764 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5765 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5766 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5767 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5768 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5769 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5770 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5771 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5772 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5773 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5774 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5775 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5776 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5777 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5778 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5779 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5780 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5781 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
5782 FN_GLOBAL_BOOL(lp_send_spnego_principal, &Globals.send_spnego_principal)
5783 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5784 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5785 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5786 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5787 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5788 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5789 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5790 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5791 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5792 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5793 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5794 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5795 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5796 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5797 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5798 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5799 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5800 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5801 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5802 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5803 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5804 static FN_GLOBAL_INTEGER(_lp_maxprotocol, &Globals.maxprotocol)
5805 int lp_maxprotocol(void)
5807 int ret = _lp_maxprotocol();
5808 if ((ret == PROTOCOL_SMB2) && (lp_security() == SEC_SHARE)) {
5809 DEBUG(2,("WARNING!!: \"security = share\" is incompatible "
5810 "with the SMB2 protocol. Resetting to SMB1.\n" ));
5811 lp_do_parameter(-1, "max protocol", "NT1");
5812 return PROTOCOL_NT1;
5816 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5817 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5818 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5819 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5820 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5821 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5822 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5823 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5824 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5825 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5826 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5827 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5828 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5829 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5830 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5831 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5832 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5833 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5834 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5835 FN_GLOBAL_INTEGER(lp_smb2_max_read, &Globals.ismb2_max_read)
5836 FN_GLOBAL_INTEGER(lp_smb2_max_write, &Globals.ismb2_max_write)
5837 FN_GLOBAL_INTEGER(lp_smb2_max_trans, &Globals.ismb2_max_trans)
5838 int lp_smb2_max_credits(void)
5840 if (Globals.ismb2_max_credits == 0) {
5841 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5843 return Globals.ismb2_max_credits;
5845 FN_LOCAL_STRING(lp_preexec, szPreExec)
5846 FN_LOCAL_STRING(lp_postexec, szPostExec)
5847 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5848 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5849 FN_LOCAL_STRING(lp_servicename, szService)
5850 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5851 FN_LOCAL_STRING(lp_pathname, szPath)
5852 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5853 FN_LOCAL_STRING(lp_username, szUsername)
5854 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5855 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5856 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5857 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5858 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5859 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5860 int lp_cups_encrypt(void)
5863 #ifdef HAVE_HTTPCONNECTENCRYPT
5864 switch (Globals.CupsEncrypt) {
5866 result = HTTP_ENCRYPT_REQUIRED;
5869 result = HTTP_ENCRYPT_ALWAYS;
5872 result = HTTP_ENCRYPT_NEVER;
5878 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5879 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5880 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5881 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5882 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5883 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5884 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, &Globals.ctdb_locktime_warn_threshold)
5885 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5886 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5887 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5888 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5889 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5890 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5891 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5892 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5893 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5894 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5895 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5896 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5897 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5898 FN_LOCAL_STRING(lp_comment, comment)
5899 FN_LOCAL_STRING(lp_force_user, force_user)
5900 FN_LOCAL_STRING(lp_force_group, force_group)
5901 FN_LOCAL_LIST(lp_readlist, readlist)
5902 FN_LOCAL_LIST(lp_writelist, writelist)
5903 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5904 FN_LOCAL_STRING(lp_fstype, fstype)
5905 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5906 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5907 static FN_LOCAL_STRING(lp_volume, volume)
5908 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5909 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5910 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5911 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5912 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5913 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5914 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5915 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5916 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5917 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5918 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5919 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5920 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5921 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5922 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5923 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5924 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5925 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5926 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5927 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5928 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5929 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5930 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5931 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5932 FN_LOCAL_BOOL(lp_print_notify_backchannel, bPrintNotifyBackchannel)
5933 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5934 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5935 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5936 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5937 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5938 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5939 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5940 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5941 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5942 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5943 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5944 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5945 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5946 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5947 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5948 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5949 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5950 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5951 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5952 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5953 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5954 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5955 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5956 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5957 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5958 FN_GLOBAL_BOOL(lp_multicast_dns_register, &Globals.bMulticastDnsRegister)
5959 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5960 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5961 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5962 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5963 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5964 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5965 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5966 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5967 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5968 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5969 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5970 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5971 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5972 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5973 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5974 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5975 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5976 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5977 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5978 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5979 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5980 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5981 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5982 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5983 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5984 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5985 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5986 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5987 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5988 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5989 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5990 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5991 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5992 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5993 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5994 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5995 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5996 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5997 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5998 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5999 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
6000 FN_LOCAL_CHAR(lp_magicchar, magic_char)
6001 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
6002 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
6003 FN_GLOBAL_INTEGER(lp_winbind_max_clients, &Globals.winbind_max_clients)
6004 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
6005 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
6006 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
6007 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
6008 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
6009 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
6011 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
6013 /* local prototypes */
6015 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
6016 static const char *get_boolean(bool bool_value);
6017 static int getservicebyname(const char *pszServiceName,
6018 struct service *pserviceDest);
6019 static void copy_service(struct service *pserviceDest,
6020 struct service *pserviceSource,
6021 struct bitmap *pcopymapDest);
6022 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
6024 static bool do_section(const char *pszSectionName, void *userdata);
6025 static void init_copymap(struct service *pservice);
6026 static bool hash_a_service(const char *name, int number);
6027 static void free_service_byindex(int iService);
6028 static void free_param_opts(struct param_opt_struct **popts);
6029 static void show_parameter(int parmIndex);
6030 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
6033 * This is a helper function for parametrical options support. It returns a
6034 * pointer to parametrical option value if it exists or NULL otherwise. Actual
6035 * parametrical functions are quite simple
6037 static struct param_opt_struct *get_parametrics(int snum, const char *type,
6040 bool global_section = False;
6042 struct param_opt_struct *data;
6044 if (snum >= iNumServices) return NULL;
6047 data = Globals.param_opt;
6048 global_section = True;
6050 data = ServicePtrs[snum]->param_opt;
6053 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
6054 DEBUG(0,("asprintf failed!\n"));
6059 if (strwicmp(data->key, param_key) == 0) {
6060 string_free(¶m_key);
6066 if (!global_section) {
6067 /* Try to fetch the same option but from globals */
6068 /* but only if we are not already working with Globals */
6069 data = Globals.param_opt;
6071 if (strwicmp(data->key, param_key) == 0) {
6072 string_free(¶m_key);
6079 string_free(¶m_key);
6085 #define MISSING_PARAMETER(name) \
6086 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
6088 /*******************************************************************
6089 convenience routine to return int parameters.
6090 ********************************************************************/
6091 static int lp_int(const char *s)
6095 MISSING_PARAMETER(lp_int);
6099 return (int)strtol(s, NULL, 0);
6102 /*******************************************************************
6103 convenience routine to return unsigned long parameters.
6104 ********************************************************************/
6105 static unsigned long lp_ulong(const char *s)
6109 MISSING_PARAMETER(lp_ulong);
6113 return strtoul(s, NULL, 0);
6116 /*******************************************************************
6117 convenience routine to return boolean parameters.
6118 ********************************************************************/
6119 static bool lp_bool(const char *s)
6124 MISSING_PARAMETER(lp_bool);
6128 if (!set_boolean(s, &ret)) {
6129 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
6136 /*******************************************************************
6137 convenience routine to return enum parameters.
6138 ********************************************************************/
6139 static int lp_enum(const char *s,const struct enum_list *_enum)
6143 if (!s || !*s || !_enum) {
6144 MISSING_PARAMETER(lp_enum);
6148 for (i=0; _enum[i].name; i++) {
6149 if (strequal(_enum[i].name,s))
6150 return _enum[i].value;
6153 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
6157 #undef MISSING_PARAMETER
6159 /* DO NOT USE lp_parm_string ANYMORE!!!!
6160 * use lp_parm_const_string or lp_parm_talloc_string
6162 * lp_parm_string is only used to let old modules find this symbol
6164 #undef lp_parm_string
6165 char *lp_parm_string(const char *servicename, const char *type, const char *option);
6166 char *lp_parm_string(const char *servicename, const char *type, const char *option)
6168 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
6171 /* Return parametric option from a given service. Type is a part of option before ':' */
6172 /* Parametric option has following syntax: 'Type: option = value' */
6173 /* the returned value is talloced on the talloc_tos() */
6174 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
6176 struct param_opt_struct *data = get_parametrics(snum, type, option);
6178 if (data == NULL||data->value==NULL) {
6180 return lp_string(def);
6186 return lp_string(data->value);
6189 /* Return parametric option from a given service. Type is a part of option before ':' */
6190 /* Parametric option has following syntax: 'Type: option = value' */
6191 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6193 struct param_opt_struct *data = get_parametrics(snum, type, option);
6195 if (data == NULL||data->value==NULL)
6201 /* Return parametric option from a given service. Type is a part of option before ':' */
6202 /* Parametric option has following syntax: 'Type: option = value' */
6204 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6206 struct param_opt_struct *data = get_parametrics(snum, type, option);
6208 if (data == NULL||data->value==NULL)
6209 return (const char **)def;
6211 if (data->list==NULL) {
6212 data->list = str_list_make_v3(NULL, data->value, NULL);
6215 return (const char **)data->list;
6218 /* Return parametric option from a given service. Type is a part of option before ':' */
6219 /* Parametric option has following syntax: 'Type: option = value' */
6221 int lp_parm_int(int snum, const char *type, const char *option, int def)
6223 struct param_opt_struct *data = get_parametrics(snum, type, option);
6225 if (data && data->value && *data->value)
6226 return lp_int(data->value);
6231 /* Return parametric option from a given service. Type is a part of option before ':' */
6232 /* Parametric option has following syntax: 'Type: option = value' */
6234 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6236 struct param_opt_struct *data = get_parametrics(snum, type, option);
6238 if (data && data->value && *data->value)
6239 return lp_ulong(data->value);
6244 /* Return parametric option from a given service. Type is a part of option before ':' */
6245 /* Parametric option has following syntax: 'Type: option = value' */
6247 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6249 struct param_opt_struct *data = get_parametrics(snum, type, option);
6251 if (data && data->value && *data->value)
6252 return lp_bool(data->value);
6257 /* Return parametric option from a given service. Type is a part of option before ':' */
6258 /* Parametric option has following syntax: 'Type: option = value' */
6260 int lp_parm_enum(int snum, const char *type, const char *option,
6261 const struct enum_list *_enum, int def)
6263 struct param_opt_struct *data = get_parametrics(snum, type, option);
6265 if (data && data->value && *data->value && _enum)
6266 return lp_enum(data->value, _enum);
6272 /***************************************************************************
6273 Initialise a service to the defaults.
6274 ***************************************************************************/
6276 static void init_service(struct service *pservice)
6278 memset((char *)pservice, '\0', sizeof(struct service));
6279 copy_service(pservice, &sDefault, NULL);
6284 * free a param_opts structure.
6285 * param_opts handling should be moved to talloc;
6286 * then this whole functions reduces to a TALLOC_FREE().
6289 static void free_param_opts(struct param_opt_struct **popts)
6291 struct param_opt_struct *opt, *next_opt;
6293 if (popts == NULL) {
6297 if (*popts != NULL) {
6298 DEBUG(5, ("Freeing parametrics:\n"));
6301 while (opt != NULL) {
6302 string_free(&opt->key);
6303 string_free(&opt->value);
6304 TALLOC_FREE(opt->list);
6305 next_opt = opt->next;
6312 /***************************************************************************
6313 Free the dynamically allocated parts of a service struct.
6314 ***************************************************************************/
6316 static void free_service(struct service *pservice)
6321 if (pservice->szService)
6322 DEBUG(5, ("free_service: Freeing service %s\n",
6323 pservice->szService));
6325 free_parameters(pservice);
6327 string_free(&pservice->szService);
6328 TALLOC_FREE(pservice->copymap);
6330 free_param_opts(&pservice->param_opt);
6332 ZERO_STRUCTP(pservice);
6336 /***************************************************************************
6337 remove a service indexed in the ServicePtrs array from the ServiceHash
6338 and free the dynamically allocated parts
6339 ***************************************************************************/
6341 static void free_service_byindex(int idx)
6343 if ( !LP_SNUM_OK(idx) )
6346 ServicePtrs[idx]->valid = False;
6347 invalid_services[num_invalid_services++] = idx;
6349 /* we have to cleanup the hash record */
6351 if (ServicePtrs[idx]->szService) {
6352 char *canon_name = canonicalize_servicename(
6354 ServicePtrs[idx]->szService );
6356 dbwrap_delete_bystring(ServiceHash, canon_name );
6357 TALLOC_FREE(canon_name);
6360 free_service(ServicePtrs[idx]);
6363 /***************************************************************************
6364 Add a new service to the services array initialising it with the given
6366 ***************************************************************************/
6368 static int add_a_service(const struct service *pservice, const char *name)
6371 struct service tservice;
6372 int num_to_alloc = iNumServices + 1;
6374 tservice = *pservice;
6376 /* it might already exist */
6378 i = getservicebyname(name, NULL);
6384 /* find an invalid one */
6386 if (num_invalid_services > 0) {
6387 i = invalid_services[--num_invalid_services];
6390 /* if not, then create one */
6391 if (i == iNumServices) {
6392 struct service **tsp;
6395 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6397 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6401 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6402 if (!ServicePtrs[iNumServices]) {
6403 DEBUG(0,("add_a_service: out of memory!\n"));
6408 /* enlarge invalid_services here for now... */
6409 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6411 if (tinvalid == NULL) {
6412 DEBUG(0,("add_a_service: failed to enlarge "
6413 "invalid_services!\n"));
6416 invalid_services = tinvalid;
6418 free_service_byindex(i);
6421 ServicePtrs[i]->valid = True;
6423 init_service(ServicePtrs[i]);
6424 copy_service(ServicePtrs[i], &tservice, NULL);
6426 string_set(&ServicePtrs[i]->szService, name);
6428 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6429 i, ServicePtrs[i]->szService));
6431 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6438 /***************************************************************************
6439 Convert a string to uppercase and remove whitespaces.
6440 ***************************************************************************/
6442 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6447 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6451 result = talloc_strdup(ctx, src);
6452 SMB_ASSERT(result != NULL);
6458 /***************************************************************************
6459 Add a name/index pair for the services array to the hash table.
6460 ***************************************************************************/
6462 static bool hash_a_service(const char *name, int idx)
6466 if ( !ServiceHash ) {
6467 DEBUG(10,("hash_a_service: creating servicehash\n"));
6468 ServiceHash = db_open_rbt(NULL);
6469 if ( !ServiceHash ) {
6470 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6475 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6478 canon_name = canonicalize_servicename(talloc_tos(), name );
6480 dbwrap_store_bystring(ServiceHash, canon_name,
6481 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6484 TALLOC_FREE(canon_name);
6489 /***************************************************************************
6490 Add a new home service, with the specified home directory, defaults coming
6492 ***************************************************************************/
6494 bool lp_add_home(const char *pszHomename, int iDefaultService,
6495 const char *user, const char *pszHomedir)
6499 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6500 pszHomedir[0] == '\0') {
6504 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6509 if (!(*(ServicePtrs[iDefaultService]->szPath))
6510 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6511 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6514 if (!(*(ServicePtrs[i]->comment))) {
6515 char *comment = NULL;
6516 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6519 string_set(&ServicePtrs[i]->comment, comment);
6523 /* set the browseable flag from the global default */
6525 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6526 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6528 ServicePtrs[i]->autoloaded = True;
6530 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6531 user, ServicePtrs[i]->szPath ));
6536 /***************************************************************************
6537 Add a new service, based on an old one.
6538 ***************************************************************************/
6540 int lp_add_service(const char *pszService, int iDefaultService)
6542 if (iDefaultService < 0) {
6543 return add_a_service(&sDefault, pszService);
6546 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6549 /***************************************************************************
6550 Add the IPC service.
6551 ***************************************************************************/
6553 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6555 char *comment = NULL;
6556 int i = add_a_service(&sDefault, ipc_name);
6561 if (asprintf(&comment, "IPC Service (%s)",
6562 Globals.szServerString) < 0) {
6566 string_set(&ServicePtrs[i]->szPath, tmpdir());
6567 string_set(&ServicePtrs[i]->szUsername, "");
6568 string_set(&ServicePtrs[i]->comment, comment);
6569 string_set(&ServicePtrs[i]->fstype, "IPC");
6570 ServicePtrs[i]->iMaxConnections = 0;
6571 ServicePtrs[i]->bAvailable = True;
6572 ServicePtrs[i]->bRead_only = True;
6573 ServicePtrs[i]->bGuest_only = False;
6574 ServicePtrs[i]->bAdministrative_share = True;
6575 ServicePtrs[i]->bGuest_ok = guest_ok;
6576 ServicePtrs[i]->bPrint_ok = False;
6577 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6579 DEBUG(3, ("adding IPC service\n"));
6585 /***************************************************************************
6586 Add a new printer service, with defaults coming from service iFrom.
6587 ***************************************************************************/
6589 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6591 const char *comment = "From Printcap";
6592 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6597 /* note that we do NOT default the availability flag to True - */
6598 /* we take it from the default service passed. This allows all */
6599 /* dynamic printers to be disabled by disabling the [printers] */
6600 /* entry (if/when the 'available' keyword is implemented!). */
6602 /* the printer name is set to the service name. */
6603 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6604 string_set(&ServicePtrs[i]->comment, comment);
6606 /* set the browseable flag from the gloabl default */
6607 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6609 /* Printers cannot be read_only. */
6610 ServicePtrs[i]->bRead_only = False;
6611 /* No share modes on printer services. */
6612 ServicePtrs[i]->bShareModes = False;
6613 /* No oplocks on printer services. */
6614 ServicePtrs[i]->bOpLocks = False;
6615 /* Printer services must be printable. */
6616 ServicePtrs[i]->bPrint_ok = True;
6618 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6624 /***************************************************************************
6625 Check whether the given parameter name is valid.
6626 Parametric options (names containing a colon) are considered valid.
6627 ***************************************************************************/
6629 bool lp_parameter_is_valid(const char *pszParmName)
6631 return ((map_parameter(pszParmName) != -1) ||
6632 (strchr(pszParmName, ':') != NULL));
6635 /***************************************************************************
6636 Check whether the given name is the name of a global parameter.
6637 Returns True for strings belonging to parameters of class
6638 P_GLOBAL, False for all other strings, also for parametric options
6639 and strings not belonging to any option.
6640 ***************************************************************************/
6642 bool lp_parameter_is_global(const char *pszParmName)
6644 int num = map_parameter(pszParmName);
6647 return (parm_table[num].p_class == P_GLOBAL);
6653 /**************************************************************************
6654 Check whether the given name is the canonical name of a parameter.
6655 Returns False if it is not a valid parameter Name.
6656 For parametric options, True is returned.
6657 **************************************************************************/
6659 bool lp_parameter_is_canonical(const char *parm_name)
6661 if (!lp_parameter_is_valid(parm_name)) {
6665 return (map_parameter(parm_name) ==
6666 map_parameter_canonical(parm_name, NULL));
6669 /**************************************************************************
6670 Determine the canonical name for a parameter.
6671 Indicate when it is an inverse (boolean) synonym instead of a
6673 **************************************************************************/
6675 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6680 if (!lp_parameter_is_valid(parm_name)) {
6685 num = map_parameter_canonical(parm_name, inverse);
6687 /* parametric option */
6688 *canon_parm = parm_name;
6690 *canon_parm = parm_table[num].label;
6697 /**************************************************************************
6698 Determine the canonical name for a parameter.
6699 Turn the value given into the inverse boolean expression when
6700 the synonym is an invers boolean synonym.
6702 Return True if parm_name is a valid parameter name and
6703 in case it is an invers boolean synonym, if the val string could
6704 successfully be converted to the reverse bool.
6705 Return false in all other cases.
6706 **************************************************************************/
6708 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6710 const char **canon_parm,
6711 const char **canon_val)
6716 if (!lp_parameter_is_valid(parm_name)) {
6722 num = map_parameter_canonical(parm_name, &inverse);
6724 /* parametric option */
6725 *canon_parm = parm_name;
6728 *canon_parm = parm_table[num].label;
6730 if (!lp_invert_boolean(val, canon_val)) {
6742 /***************************************************************************
6743 Map a parameter's string representation to something we can use.
6744 Returns False if the parameter string is not recognised, else TRUE.
6745 ***************************************************************************/
6747 static int map_parameter(const char *pszParmName)
6751 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6754 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6755 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6758 /* Warn only if it isn't parametric option */
6759 if (strchr(pszParmName, ':') == NULL)
6760 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6761 /* We do return 'fail' for parametric options as well because they are
6762 stored in different storage
6767 /***************************************************************************
6768 Map a parameter's string representation to the index of the canonical
6769 form of the parameter (it might be a synonym).
6770 Returns -1 if the parameter string is not recognised.
6771 ***************************************************************************/
6773 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6775 int parm_num, canon_num;
6776 bool loc_inverse = False;
6778 parm_num = map_parameter(pszParmName);
6779 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6780 /* invalid, parametric or no canidate for synonyms ... */
6784 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6785 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6786 parm_num = canon_num;
6792 if (inverse != NULL) {
6793 *inverse = loc_inverse;
6798 /***************************************************************************
6799 return true if parameter number parm1 is a synonym of parameter
6800 number parm2 (parm2 being the principal name).
6801 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6803 ***************************************************************************/
6805 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6807 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6808 (parm_table[parm1].flags & FLAG_HIDE) &&
6809 !(parm_table[parm2].flags & FLAG_HIDE))
6811 if (inverse != NULL) {
6812 if ((parm_table[parm1].type == P_BOOLREV) &&
6813 (parm_table[parm2].type == P_BOOL))
6825 /***************************************************************************
6826 Show one parameter's name, type, [values,] and flags.
6827 (helper functions for show_parameter_list)
6828 ***************************************************************************/
6830 static void show_parameter(int parmIndex)
6832 int enumIndex, flagIndex;
6837 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6838 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6840 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6841 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6842 FLAG_HIDE, FLAG_DOS_STRING};
6843 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6844 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6845 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6847 printf("%s=%s", parm_table[parmIndex].label,
6848 type[parm_table[parmIndex].type]);
6849 if (parm_table[parmIndex].type == P_ENUM) {
6852 parm_table[parmIndex].enum_list[enumIndex].name;
6856 enumIndex ? "|" : "",
6857 parm_table[parmIndex].enum_list[enumIndex].name);
6862 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6863 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6866 flag_names[flagIndex]);
6871 /* output synonyms */
6873 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6874 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6875 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6876 parm_table[parmIndex2].label);
6877 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6879 printf(" (synonyms: ");
6884 printf("%s%s", parm_table[parmIndex2].label,
6885 inverse ? "[i]" : "");
6895 /***************************************************************************
6896 Show all parameter's name, type, [values,] and flags.
6897 ***************************************************************************/
6899 void show_parameter_list(void)
6901 int classIndex, parmIndex;
6902 const char *section_names[] = { "local", "global", NULL};
6904 for (classIndex=0; section_names[classIndex]; classIndex++) {
6905 printf("[%s]\n", section_names[classIndex]);
6906 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6907 if (parm_table[parmIndex].p_class == classIndex) {
6908 show_parameter(parmIndex);
6914 /***************************************************************************
6915 Check if a given string correctly represents a boolean value.
6916 ***************************************************************************/
6918 bool lp_string_is_valid_boolean(const char *parm_value)
6920 return set_boolean(parm_value, NULL);
6923 /***************************************************************************
6924 Get the standard string representation of a boolean value ("yes" or "no")
6925 ***************************************************************************/
6927 static const char *get_boolean(bool bool_value)
6929 static const char *yes_str = "yes";
6930 static const char *no_str = "no";
6932 return (bool_value ? yes_str : no_str);
6935 /***************************************************************************
6936 Provide the string of the negated boolean value associated to the boolean
6937 given as a string. Returns False if the passed string does not correctly
6938 represent a boolean.
6939 ***************************************************************************/
6941 bool lp_invert_boolean(const char *str, const char **inverse_str)
6945 if (!set_boolean(str, &val)) {
6949 *inverse_str = get_boolean(!val);
6953 /***************************************************************************
6954 Provide the canonical string representation of a boolean value given
6955 as a string. Return True on success, False if the string given does
6956 not correctly represent a boolean.
6957 ***************************************************************************/
6959 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6963 if (!set_boolean(str, &val)) {
6967 *canon_str = get_boolean(val);
6971 /***************************************************************************
6972 Find a service by name. Otherwise works like get_service.
6973 ***************************************************************************/
6975 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6981 if (ServiceHash == NULL) {
6985 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6987 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6989 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6990 iService = *(int *)data.dptr;
6993 TALLOC_FREE(canon_name);
6995 if ((iService != -1) && (LP_SNUM_OK(iService))
6996 && (pserviceDest != NULL)) {
6997 copy_service(pserviceDest, ServicePtrs[iService], NULL);
7003 /***************************************************************************
7004 Copy a service structure to another.
7005 If pcopymapDest is NULL then copy all fields
7006 ***************************************************************************/
7009 * Add a parametric option to a param_opt_struct,
7010 * replacing old value, if already present.
7012 static void set_param_opt(struct param_opt_struct **opt_list,
7013 const char *opt_name,
7014 const char *opt_value,
7017 struct param_opt_struct *new_opt, *opt;
7020 if (opt_list == NULL) {
7027 /* Traverse destination */
7029 /* If we already have same option, override it */
7030 if (strwicmp(opt->key, opt_name) == 0) {
7031 if ((opt->flags & FLAG_CMDLINE) &&
7032 !(flags & FLAG_CMDLINE)) {
7033 /* it's been marked as not to be
7037 string_free(&opt->value);
7038 TALLOC_FREE(opt->list);
7039 opt->value = SMB_STRDUP(opt_value);
7047 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
7048 new_opt->key = SMB_STRDUP(opt_name);
7049 new_opt->value = SMB_STRDUP(opt_value);
7050 new_opt->list = NULL;
7051 new_opt->flags = flags;
7052 DLIST_ADD(*opt_list, new_opt);
7056 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
7057 struct bitmap *pcopymapDest)
7060 bool bcopyall = (pcopymapDest == NULL);
7061 struct param_opt_struct *data;
7063 for (i = 0; parm_table[i].label; i++)
7064 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
7065 (bcopyall || bitmap_query(pcopymapDest,i))) {
7066 void *def_ptr = parm_table[i].ptr;
7068 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
7071 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
7074 switch (parm_table[i].type) {
7077 *(bool *)dest_ptr = *(bool *)src_ptr;
7083 *(int *)dest_ptr = *(int *)src_ptr;
7087 *(char *)dest_ptr = *(char *)src_ptr;
7091 string_set((char **)dest_ptr,
7096 string_set((char **)dest_ptr,
7098 strupper_m(*(char **)dest_ptr);
7101 TALLOC_FREE(*((char ***)dest_ptr));
7102 *((char ***)dest_ptr) = str_list_copy(NULL,
7103 *(const char ***)src_ptr);
7111 init_copymap(pserviceDest);
7112 if (pserviceSource->copymap)
7113 bitmap_copy(pserviceDest->copymap,
7114 pserviceSource->copymap);
7117 data = pserviceSource->param_opt;
7119 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->flags);
7124 /***************************************************************************
7125 Check a service for consistency. Return False if the service is in any way
7126 incomplete or faulty, else True.
7127 ***************************************************************************/
7129 bool service_ok(int iService)
7134 if (ServicePtrs[iService]->szService[0] == '\0') {
7135 DEBUG(0, ("The following message indicates an internal error:\n"));
7136 DEBUG(0, ("No service name in service entry.\n"));
7140 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
7141 /* I can't see why you'd want a non-printable printer service... */
7142 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
7143 if (!ServicePtrs[iService]->bPrint_ok) {
7144 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
7145 ServicePtrs[iService]->szService));
7146 ServicePtrs[iService]->bPrint_ok = True;
7148 /* [printers] service must also be non-browsable. */
7149 if (ServicePtrs[iService]->bBrowseable)
7150 ServicePtrs[iService]->bBrowseable = False;
7153 if (ServicePtrs[iService]->szPath[0] == '\0' &&
7154 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
7155 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
7157 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
7158 ServicePtrs[iService]->szService));
7159 ServicePtrs[iService]->bAvailable = False;
7162 /* If a service is flagged unavailable, log the fact at level 1. */
7163 if (!ServicePtrs[iService]->bAvailable)
7164 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
7165 ServicePtrs[iService]->szService));
7170 static struct smbconf_ctx *lp_smbconf_ctx(void)
7173 static struct smbconf_ctx *conf_ctx = NULL;
7175 if (conf_ctx == NULL) {
7176 werr = smbconf_init(NULL, &conf_ctx, "registry:");
7177 if (!W_ERROR_IS_OK(werr)) {
7178 DEBUG(1, ("error initializing registry configuration: "
7179 "%s\n", win_errstr(werr)));
7187 static bool process_smbconf_service(struct smbconf_service *service)
7192 if (service == NULL) {
7196 ret = do_section(service->name, NULL);
7200 for (count = 0; count < service->num_params; count++) {
7201 ret = do_parameter(service->param_names[count],
7202 service->param_values[count],
7208 if (iServiceIndex >= 0) {
7209 return service_ok(iServiceIndex);
7215 * load a service from registry and activate it
7217 bool process_registry_service(const char *service_name)
7220 struct smbconf_service *service = NULL;
7221 TALLOC_CTX *mem_ctx = talloc_stackframe();
7222 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7225 if (conf_ctx == NULL) {
7229 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7231 if (!smbconf_share_exists(conf_ctx, service_name)) {
7233 * Registry does not contain data for this service (yet),
7234 * but make sure lp_load doesn't return false.
7240 werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7241 if (!W_ERROR_IS_OK(werr)) {
7245 ret = process_smbconf_service(service);
7251 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7254 TALLOC_FREE(mem_ctx);
7259 * process_registry_globals
7261 static bool process_registry_globals(void)
7265 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7267 ret = do_parameter("registry shares", "yes", NULL);
7272 return process_registry_service(GLOBAL_NAME);
7275 bool process_registry_shares(void)
7279 struct smbconf_service **service = NULL;
7280 uint32_t num_shares = 0;
7281 TALLOC_CTX *mem_ctx = talloc_stackframe();
7282 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7285 if (conf_ctx == NULL) {
7289 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7290 if (!W_ERROR_IS_OK(werr)) {
7296 for (count = 0; count < num_shares; count++) {
7297 if (strequal(service[count]->name, GLOBAL_NAME)) {
7300 ret = process_smbconf_service(service[count]);
7307 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7310 TALLOC_FREE(mem_ctx);
7314 #define MAX_INCLUDE_DEPTH 100
7316 static uint8_t include_depth;
7318 static struct file_lists {
7319 struct file_lists *next;
7323 } *file_lists = NULL;
7325 /*******************************************************************
7326 Keep a linked list of all config files so we know when one has changed
7327 it's date and needs to be reloaded.
7328 ********************************************************************/
7330 static void add_to_file_list(const char *fname, const char *subfname)
7332 struct file_lists *f = file_lists;
7335 if (f->name && !strcmp(f->name, fname))
7341 f = SMB_MALLOC_P(struct file_lists);
7344 f->next = file_lists;
7345 f->name = SMB_STRDUP(fname);
7350 f->subfname = SMB_STRDUP(subfname);
7357 f->modtime = file_modtime(subfname);
7359 time_t t = file_modtime(subfname);
7367 * Free the file lists
7369 static void free_file_list(void)
7371 struct file_lists *f;
7372 struct file_lists *next;
7377 SAFE_FREE( f->name );
7378 SAFE_FREE( f->subfname );
7387 * Utility function for outsiders to check if we're running on registry.
7389 bool lp_config_backend_is_registry(void)
7391 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7395 * Utility function to check if the config backend is FILE.
7397 bool lp_config_backend_is_file(void)
7399 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7402 /*******************************************************************
7403 Check if a config file has changed date.
7404 ********************************************************************/
7406 bool lp_file_list_changed(void)
7408 struct file_lists *f = file_lists;
7410 DEBUG(6, ("lp_file_list_changed()\n"));
7415 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7416 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7418 if (conf_ctx == NULL) {
7421 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7424 DEBUGADD(6, ("registry config changed\n"));
7429 n2 = talloc_sub_basic(talloc_tos(),
7430 get_current_username(),
7431 current_user_info.domain,
7436 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7437 f->name, n2, ctime(&f->modtime)));
7439 mod_time = file_modtime(n2);
7442 ((f->modtime != mod_time) ||
7443 (f->subfname == NULL) ||
7444 (strcmp(n2, f->subfname) != 0)))
7447 ("file %s modified: %s\n", n2,
7449 f->modtime = mod_time;
7450 SAFE_FREE(f->subfname);
7451 f->subfname = SMB_STRDUP(n2);
7463 /***************************************************************************
7464 Run standard_sub_basic on netbios name... needed because global_myname
7465 is not accessed through any lp_ macro.
7466 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7467 ***************************************************************************/
7469 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7472 char *netbios_name = talloc_sub_basic(
7473 talloc_tos(), get_current_username(), current_user_info.domain,
7476 ret = set_global_myname(netbios_name);
7477 TALLOC_FREE(netbios_name);
7478 string_set(&Globals.szNetbiosName,global_myname());
7480 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7486 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7488 if (strcmp(*ptr, pszParmValue) != 0) {
7489 string_set(ptr, pszParmValue);
7497 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7501 ret = set_global_myworkgroup(pszParmValue);
7502 string_set(&Globals.szWorkgroup,lp_workgroup());
7507 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7511 ret = set_global_scope(pszParmValue);
7512 string_set(&Globals.szNetbiosScope,global_scope());
7517 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7519 TALLOC_FREE(Globals.szNetbiosAliases);
7520 Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
7521 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7524 /***************************************************************************
7525 Handle the include operation.
7526 ***************************************************************************/
7527 static bool bAllowIncludeRegistry = true;
7529 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7533 if (include_depth >= MAX_INCLUDE_DEPTH) {
7534 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7539 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7540 if (!bAllowIncludeRegistry) {
7543 if (bInGlobalSection) {
7546 ret = process_registry_globals();
7550 DEBUG(1, ("\"include = registry\" only effective "
7551 "in %s section\n", GLOBAL_NAME));
7556 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7557 current_user_info.domain,
7560 add_to_file_list(pszParmValue, fname);
7562 string_set(ptr, fname);
7564 if (file_exist(fname)) {
7567 ret = pm_process(fname, do_section, do_parameter, NULL);
7573 DEBUG(2, ("Can't find include file %s\n", fname));
7578 /***************************************************************************
7579 Handle the interpretation of the copy parameter.
7580 ***************************************************************************/
7582 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7586 struct service serviceTemp;
7588 string_set(ptr, pszParmValue);
7590 init_service(&serviceTemp);
7594 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7596 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7597 if (iTemp == iServiceIndex) {
7598 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7600 copy_service(ServicePtrs[iServiceIndex],
7602 ServicePtrs[iServiceIndex]->copymap);
7606 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7610 free_service(&serviceTemp);
7614 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7616 Globals.ldap_debug_level = lp_int(pszParmValue);
7617 init_ldap_debugging();
7621 /***************************************************************************
7622 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7627 idmap uid = 1000-1999
7630 We only do simple parsing checks here. The strings are parsed into useful
7631 structures in the idmap daemon code.
7633 ***************************************************************************/
7635 /* Some lp_ routines to return idmap [ug]id information */
7637 static uid_t idmap_uid_low, idmap_uid_high;
7638 static gid_t idmap_gid_low, idmap_gid_high;
7640 bool lp_idmap_uid(uid_t *low, uid_t *high)
7642 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7646 *low = idmap_uid_low;
7649 *high = idmap_uid_high;
7654 bool lp_idmap_gid(gid_t *low, gid_t *high)
7656 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7660 *low = idmap_gid_low;
7663 *high = idmap_gid_high;
7668 /* Do some simple checks on "idmap [ug]id" parameter values */
7670 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7674 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7679 string_set(ptr, pszParmValue);
7681 idmap_uid_low = low;
7682 idmap_uid_high = high;
7687 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7691 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7696 string_set(ptr, pszParmValue);
7698 idmap_gid_low = low;
7699 idmap_gid_high = high;
7704 /***************************************************************************
7705 Handle the DEBUG level list.
7706 ***************************************************************************/
7708 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7710 string_set(ptr, pszParmValueIn);
7711 return debug_parse_levels(pszParmValueIn);
7714 /***************************************************************************
7715 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7716 ***************************************************************************/
7718 static const char *append_ldap_suffix( const char *str )
7720 const char *suffix_string;
7723 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7724 Globals.szLdapSuffix );
7725 if ( !suffix_string ) {
7726 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7730 return suffix_string;
7733 const char *lp_ldap_machine_suffix(void)
7735 if (Globals.szLdapMachineSuffix[0])
7736 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7738 return lp_string(Globals.szLdapSuffix);
7741 const char *lp_ldap_user_suffix(void)
7743 if (Globals.szLdapUserSuffix[0])
7744 return append_ldap_suffix(Globals.szLdapUserSuffix);
7746 return lp_string(Globals.szLdapSuffix);
7749 const char *lp_ldap_group_suffix(void)
7751 if (Globals.szLdapGroupSuffix[0])
7752 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7754 return lp_string(Globals.szLdapSuffix);
7757 const char *lp_ldap_idmap_suffix(void)
7759 if (Globals.szLdapIdmapSuffix[0])
7760 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7762 return lp_string(Globals.szLdapSuffix);
7765 /****************************************************************************
7766 set the value for a P_ENUM
7767 ***************************************************************************/
7769 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7774 for (i = 0; parm->enum_list[i].name; i++) {
7775 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7776 *ptr = parm->enum_list[i].value;
7780 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7781 pszParmValue, parm->label));
7784 /***************************************************************************
7785 ***************************************************************************/
7787 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7789 static int parm_num = -1;
7792 if ( parm_num == -1 )
7793 parm_num = map_parameter( "printing" );
7795 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7800 s = ServicePtrs[snum];
7802 init_printer_values( s );
7808 /***************************************************************************
7809 Initialise a copymap.
7810 ***************************************************************************/
7812 static void init_copymap(struct service *pservice)
7816 TALLOC_FREE(pservice->copymap);
7818 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7819 if (!pservice->copymap)
7821 ("Couldn't allocate copymap!! (size %d)\n",
7822 (int)NUMPARAMETERS));
7824 for (i = 0; i < NUMPARAMETERS; i++)
7825 bitmap_set(pservice->copymap, i);
7828 /***************************************************************************
7829 Return the local pointer to a parameter given a service struct and the
7830 pointer into the default structure.
7831 ***************************************************************************/
7833 static void *lp_local_ptr(struct service *service, void *ptr)
7835 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7838 /***************************************************************************
7839 Return the local pointer to a parameter given the service number and the
7840 pointer into the default structure.
7841 ***************************************************************************/
7843 void *lp_local_ptr_by_snum(int snum, void *ptr)
7845 return lp_local_ptr(ServicePtrs[snum], ptr);
7848 /***************************************************************************
7849 Process a parameter for a particular service number. If snum < 0
7850 then assume we are in the globals.
7851 ***************************************************************************/
7853 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7856 void *parm_ptr = NULL; /* where we are going to store the result */
7857 void *def_ptr = NULL;
7858 struct param_opt_struct **opt_list;
7860 parmnum = map_parameter(pszParmName);
7863 if (strchr(pszParmName, ':') == NULL) {
7864 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7870 * We've got a parametric option
7873 opt_list = (snum < 0)
7874 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7875 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7880 /* if it's already been set by the command line, then we don't
7882 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7886 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7887 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7891 def_ptr = parm_table[parmnum].ptr;
7893 /* we might point at a service, the default service or a global */
7897 if (parm_table[parmnum].p_class == P_GLOBAL) {
7899 ("Global parameter %s found in service section!\n",
7903 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7907 if (!ServicePtrs[snum]->copymap)
7908 init_copymap(ServicePtrs[snum]);
7910 /* this handles the aliases - set the copymap for other entries with
7911 the same data pointer */
7912 for (i = 0; parm_table[i].label; i++)
7913 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7914 bitmap_clear(ServicePtrs[snum]->copymap, i);
7917 /* if it is a special case then go ahead */
7918 if (parm_table[parmnum].special) {
7919 return parm_table[parmnum].special(snum, pszParmValue,
7923 /* now switch on the type of variable it is */
7924 switch (parm_table[parmnum].type)
7927 *(bool *)parm_ptr = lp_bool(pszParmValue);
7931 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7935 *(int *)parm_ptr = lp_int(pszParmValue);
7939 *(char *)parm_ptr = *pszParmValue;
7943 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7945 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7950 TALLOC_FREE(*((char ***)parm_ptr));
7951 *(char ***)parm_ptr = str_list_make_v3(
7952 NULL, pszParmValue, NULL);
7956 string_set((char **)parm_ptr, pszParmValue);
7960 string_set((char **)parm_ptr, pszParmValue);
7961 strupper_m(*(char **)parm_ptr);
7965 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7974 /***************************************************************************
7975 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7976 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7977 ***************************************************************************/
7979 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7982 parmnum = map_parameter(pszParmName);
7984 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7985 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7988 parm_table[parmnum].flags |= FLAG_CMDLINE;
7990 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7991 * be grouped in the table, so we don't have to search the
7993 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
7994 parm_table[i].flags |= FLAG_CMDLINE;
7996 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
7997 parm_table[i].flags |= FLAG_CMDLINE;
8001 store_lp_set_cmdline(pszParmName, pszParmValue);
8006 /* it might be parametric */
8007 if (strchr(pszParmName, ':') != NULL) {
8008 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
8010 store_lp_set_cmdline(pszParmName, pszParmValue);
8015 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
8019 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
8021 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
8024 /***************************************************************************
8025 Process a parameter.
8026 ***************************************************************************/
8028 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
8031 if (!bInGlobalSection && bGlobalOnly)
8034 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
8036 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
8037 pszParmName, pszParmValue));
8041 set a option from the commandline in 'a=b' format. Use to support --option
8043 bool lp_set_option(const char *option)
8048 s = talloc_strdup(NULL, option);
8061 /* skip white spaces after the = sign */
8064 } while (*p == ' ');
8066 ret = lp_set_cmdline(s, p);
8071 /**************************************************************************
8072 Print a parameter of the specified type.
8073 ***************************************************************************/
8075 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
8081 for (i = 0; p->enum_list[i].name; i++) {
8082 if (*(int *)ptr == p->enum_list[i].value) {
8084 p->enum_list[i].name);
8091 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
8095 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
8099 fprintf(f, "%d", *(int *)ptr);
8103 fprintf(f, "%c", *(char *)ptr);
8107 char *o = octal_string(*(int *)ptr);
8108 fprintf(f, "%s", o);
8114 if ((char ***)ptr && *(char ***)ptr) {
8115 char **list = *(char ***)ptr;
8116 for (; *list; list++) {
8117 /* surround strings with whitespace in double quotes */
8118 if ( strchr_m( *list, ' ' ) )
8119 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
8121 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
8128 if (*(char **)ptr) {
8129 fprintf(f, "%s", *(char **)ptr);
8137 /***************************************************************************
8138 Check if two parameters are equal.
8139 ***************************************************************************/
8141 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8146 return (*((bool *)ptr1) == *((bool *)ptr2));
8151 return (*((int *)ptr1) == *((int *)ptr2));
8154 return (*((char *)ptr1) == *((char *)ptr2));
8157 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8162 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8167 return (p1 == p2 || strequal(p1, p2));
8175 /***************************************************************************
8176 Initialize any local varients in the sDefault table.
8177 ***************************************************************************/
8179 void init_locals(void)
8184 /***************************************************************************
8185 Process a new section (service). At this stage all sections are services.
8186 Later we'll have special sections that permit server parameters to be set.
8187 Returns True on success, False on failure.
8188 ***************************************************************************/
8190 static bool do_section(const char *pszSectionName, void *userdata)
8193 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8194 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8197 /* if we were in a global section then do the local inits */
8198 if (bInGlobalSection && !isglobal)
8201 /* if we've just struck a global section, note the fact. */
8202 bInGlobalSection = isglobal;
8204 /* check for multiple global sections */
8205 if (bInGlobalSection) {
8206 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8210 if (!bInGlobalSection && bGlobalOnly)
8213 /* if we have a current service, tidy it up before moving on */
8216 if (iServiceIndex >= 0)
8217 bRetval = service_ok(iServiceIndex);
8219 /* if all is still well, move to the next record in the services array */
8221 /* We put this here to avoid an odd message order if messages are */
8222 /* issued by the post-processing of a previous section. */
8223 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8225 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8227 DEBUG(0, ("Failed to add a new service\n"));
8230 /* Clean all parametric options for service */
8231 /* They will be added during parsing again */
8232 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
8239 /***************************************************************************
8240 Determine if a partcular base parameter is currentl set to the default value.
8241 ***************************************************************************/
8243 static bool is_default(int i)
8245 if (!defaults_saved)
8247 switch (parm_table[i].type) {
8249 return str_list_equal((const char **)parm_table[i].def.lvalue,
8250 *(const char ***)parm_table[i].ptr);
8253 return strequal(parm_table[i].def.svalue,
8254 *(char **)parm_table[i].ptr);
8257 return parm_table[i].def.bvalue ==
8258 *(bool *)parm_table[i].ptr;
8260 return parm_table[i].def.cvalue ==
8261 *(char *)parm_table[i].ptr;
8265 return parm_table[i].def.ivalue ==
8266 *(int *)parm_table[i].ptr;
8273 /***************************************************************************
8274 Display the contents of the global structure.
8275 ***************************************************************************/
8277 static void dump_globals(FILE *f)
8280 struct param_opt_struct *data;
8282 fprintf(f, "[global]\n");
8284 for (i = 0; parm_table[i].label; i++)
8285 if (parm_table[i].p_class == P_GLOBAL &&
8286 !(parm_table[i].flags & FLAG_META) &&
8287 parm_table[i].ptr &&
8288 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8289 if (defaults_saved && is_default(i))
8291 fprintf(f, "\t%s = ", parm_table[i].label);
8292 print_parameter(&parm_table[i], parm_table[i].ptr, f);
8295 if (Globals.param_opt != NULL) {
8296 data = Globals.param_opt;
8298 fprintf(f, "\t%s = %s\n", data->key, data->value);
8305 /***************************************************************************
8306 Return True if a local parameter is currently set to the global default.
8307 ***************************************************************************/
8309 bool lp_is_default(int snum, struct parm_struct *parm)
8311 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8313 return equal_parameter(parm->type,
8314 ((char *)ServicePtrs[snum]) + pdiff,
8315 ((char *)&sDefault) + pdiff);
8318 /***************************************************************************
8319 Display the contents of a single services record.
8320 ***************************************************************************/
8322 static void dump_a_service(struct service *pService, FILE * f)
8325 struct param_opt_struct *data;
8327 if (pService != &sDefault)
8328 fprintf(f, "[%s]\n", pService->szService);
8330 for (i = 0; parm_table[i].label; i++) {
8332 if (parm_table[i].p_class == P_LOCAL &&
8333 !(parm_table[i].flags & FLAG_META) &&
8334 parm_table[i].ptr &&
8335 (*parm_table[i].label != '-') &&
8336 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8338 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8340 if (pService == &sDefault) {
8341 if (defaults_saved && is_default(i))
8344 if (equal_parameter(parm_table[i].type,
8345 ((char *)pService) +
8347 ((char *)&sDefault) +
8352 fprintf(f, "\t%s = ", parm_table[i].label);
8353 print_parameter(&parm_table[i],
8354 ((char *)pService) + pdiff, f);
8359 if (pService->param_opt != NULL) {
8360 data = pService->param_opt;
8362 fprintf(f, "\t%s = %s\n", data->key, data->value);
8368 /***************************************************************************
8369 Display the contents of a parameter of a single services record.
8370 ***************************************************************************/
8372 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8375 bool result = False;
8378 fstring local_parm_name;
8380 const char *parm_opt_value;
8382 /* check for parametrical option */
8383 fstrcpy( local_parm_name, parm_name);
8384 parm_opt = strchr( local_parm_name, ':');
8389 if (strlen(parm_opt)) {
8390 parm_opt_value = lp_parm_const_string( snum,
8391 local_parm_name, parm_opt, NULL);
8392 if (parm_opt_value) {
8393 printf( "%s\n", parm_opt_value);
8400 /* check for a key and print the value */
8407 for (i = 0; parm_table[i].label; i++) {
8408 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8409 !(parm_table[i].flags & FLAG_META) &&
8410 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8411 parm_table[i].ptr &&
8412 (*parm_table[i].label != '-') &&
8413 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8418 ptr = parm_table[i].ptr;
8420 struct service *pService = ServicePtrs[snum];
8421 ptr = ((char *)pService) +
8422 PTR_DIFF(parm_table[i].ptr, &sDefault);
8425 print_parameter(&parm_table[i],
8436 /***************************************************************************
8437 Return info about the requested parameter (given as a string).
8438 Return NULL when the string is not a valid parameter name.
8439 ***************************************************************************/
8441 struct parm_struct *lp_get_parameter(const char *param_name)
8443 int num = map_parameter(param_name);
8449 return &parm_table[num];
8452 /***************************************************************************
8453 Return info about the next parameter in a service.
8454 snum==GLOBAL_SECTION_SNUM gives the globals.
8455 Return NULL when out of parameters.
8456 ***************************************************************************/
8458 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8461 /* do the globals */
8462 for (; parm_table[*i].label; (*i)++) {
8463 if (parm_table[*i].p_class == P_SEPARATOR)
8464 return &parm_table[(*i)++];
8466 if (!parm_table[*i].ptr
8467 || (*parm_table[*i].label == '-'))
8471 && (parm_table[*i].ptr ==
8472 parm_table[(*i) - 1].ptr))
8475 if (is_default(*i) && !allparameters)
8478 return &parm_table[(*i)++];
8481 struct service *pService = ServicePtrs[snum];
8483 for (; parm_table[*i].label; (*i)++) {
8484 if (parm_table[*i].p_class == P_SEPARATOR)
8485 return &parm_table[(*i)++];
8487 if (parm_table[*i].p_class == P_LOCAL &&
8488 parm_table[*i].ptr &&
8489 (*parm_table[*i].label != '-') &&
8491 (parm_table[*i].ptr !=
8492 parm_table[(*i) - 1].ptr)))
8495 PTR_DIFF(parm_table[*i].ptr,
8498 if (allparameters ||
8499 !equal_parameter(parm_table[*i].type,
8500 ((char *)pService) +
8502 ((char *)&sDefault) +
8505 return &parm_table[(*i)++];
8516 /***************************************************************************
8517 Display the contents of a single copy structure.
8518 ***************************************************************************/
8519 static void dump_copy_map(bool *pcopymap)
8525 printf("\n\tNon-Copied parameters:\n");
8527 for (i = 0; parm_table[i].label; i++)
8528 if (parm_table[i].p_class == P_LOCAL &&
8529 parm_table[i].ptr && !pcopymap[i] &&
8530 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8532 printf("\t\t%s\n", parm_table[i].label);
8537 /***************************************************************************
8538 Return TRUE if the passed service number is within range.
8539 ***************************************************************************/
8541 bool lp_snum_ok(int iService)
8543 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8546 /***************************************************************************
8547 Auto-load some home services.
8548 ***************************************************************************/
8550 static void lp_add_auto_services(char *str)
8560 s = SMB_STRDUP(str);
8564 homes = lp_servicenumber(HOMES_NAME);
8566 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8567 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8570 if (lp_servicenumber(p) >= 0)
8573 home = get_user_home_dir(talloc_tos(), p);
8575 if (home && home[0] && homes >= 0)
8576 lp_add_home(p, homes, p, home);
8583 /***************************************************************************
8584 Auto-load one printer.
8585 ***************************************************************************/
8587 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8589 int printers = lp_servicenumber(PRINTERS_NAME);
8592 if (lp_servicenumber(name) < 0) {
8593 lp_add_printer(name, printers);
8594 if ((i = lp_servicenumber(name)) >= 0) {
8595 string_set(&ServicePtrs[i]->comment, comment);
8596 ServicePtrs[i]->autoloaded = True;
8601 /***************************************************************************
8602 Have we loaded a services file yet?
8603 ***************************************************************************/
8605 bool lp_loaded(void)
8610 /***************************************************************************
8611 Unload unused services.
8612 ***************************************************************************/
8614 void lp_killunused(bool (*snumused) (int))
8617 for (i = 0; i < iNumServices; i++) {
8621 /* don't kill autoloaded or usershare services */
8622 if ( ServicePtrs[i]->autoloaded ||
8623 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8627 if (!snumused || !snumused(i)) {
8628 free_service_byindex(i);
8634 * Kill all except autoloaded and usershare services - convenience wrapper
8636 void lp_kill_all_services(void)
8638 lp_killunused(NULL);
8641 /***************************************************************************
8643 ***************************************************************************/
8645 void lp_killservice(int iServiceIn)
8647 if (VALID(iServiceIn)) {
8648 free_service_byindex(iServiceIn);
8652 /***************************************************************************
8653 Save the curent values of all global and sDefault parameters into the
8654 defaults union. This allows swat and testparm to show only the
8655 changed (ie. non-default) parameters.
8656 ***************************************************************************/
8658 static void lp_save_defaults(void)
8661 for (i = 0; parm_table[i].label; i++) {
8662 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8664 switch (parm_table[i].type) {
8666 parm_table[i].def.lvalue = str_list_copy(
8667 NULL, *(const char ***)parm_table[i].ptr);
8671 if (parm_table[i].ptr) {
8672 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8674 parm_table[i].def.svalue = NULL;
8679 parm_table[i].def.bvalue =
8680 *(bool *)parm_table[i].ptr;
8683 parm_table[i].def.cvalue =
8684 *(char *)parm_table[i].ptr;
8689 parm_table[i].def.ivalue =
8690 *(int *)parm_table[i].ptr;
8696 defaults_saved = True;
8699 /***********************************************************
8700 If we should send plaintext/LANMAN passwords in the clinet
8701 ************************************************************/
8703 static void set_allowed_client_auth(void)
8705 if (Globals.bClientNTLMv2Auth) {
8706 Globals.bClientLanManAuth = False;
8708 if (!Globals.bClientLanManAuth) {
8709 Globals.bClientPlaintextAuth = False;
8713 /***************************************************************************
8715 The following code allows smbd to read a user defined share file.
8716 Yes, this is my intent. Yes, I'm comfortable with that...
8718 THE FOLLOWING IS SECURITY CRITICAL CODE.
8720 It washes your clothes, it cleans your house, it guards you while you sleep...
8721 Do not f%^k with it....
8722 ***************************************************************************/
8724 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8726 /***************************************************************************
8727 Check allowed stat state of a usershare file.
8728 Ensure we print out who is dicking with us so the admin can
8729 get their sorry ass fired.
8730 ***************************************************************************/
8732 static bool check_usershare_stat(const char *fname,
8733 const SMB_STRUCT_STAT *psbuf)
8735 if (!S_ISREG(psbuf->st_ex_mode)) {
8736 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8737 "not a regular file\n",
8738 fname, (unsigned int)psbuf->st_ex_uid ));
8742 /* Ensure this doesn't have the other write bit set. */
8743 if (psbuf->st_ex_mode & S_IWOTH) {
8744 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8745 "public write. Refusing to allow as a usershare file.\n",
8746 fname, (unsigned int)psbuf->st_ex_uid ));
8750 /* Should be 10k or less. */
8751 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8752 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8753 "too large (%u) to be a user share file.\n",
8754 fname, (unsigned int)psbuf->st_ex_uid,
8755 (unsigned int)psbuf->st_ex_size ));
8762 /***************************************************************************
8763 Parse the contents of a usershare file.
8764 ***************************************************************************/
8766 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8767 SMB_STRUCT_STAT *psbuf,
8768 const char *servicename,
8772 char **pp_sharepath,
8774 char **pp_cp_servicename,
8775 struct security_descriptor **ppsd,
8778 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8779 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8782 SMB_STRUCT_STAT sbuf;
8783 char *sharepath = NULL;
8784 char *comment = NULL;
8786 *pp_sharepath = NULL;
8789 *pallow_guest = False;
8792 return USERSHARE_MALFORMED_FILE;
8795 if (strcmp(lines[0], "#VERSION 1") == 0) {
8797 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8800 return USERSHARE_MALFORMED_FILE;
8803 return USERSHARE_BAD_VERSION;
8806 if (strncmp(lines[1], "path=", 5) != 0) {
8807 return USERSHARE_MALFORMED_PATH;
8810 sharepath = talloc_strdup(ctx, &lines[1][5]);
8812 return USERSHARE_POSIX_ERR;
8814 trim_string(sharepath, " ", " ");
8816 if (strncmp(lines[2], "comment=", 8) != 0) {
8817 return USERSHARE_MALFORMED_COMMENT_DEF;
8820 comment = talloc_strdup(ctx, &lines[2][8]);
8822 return USERSHARE_POSIX_ERR;
8824 trim_string(comment, " ", " ");
8825 trim_char(comment, '"', '"');
8827 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8828 return USERSHARE_MALFORMED_ACL_DEF;
8831 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8832 return USERSHARE_ACL_ERR;
8836 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8837 return USERSHARE_MALFORMED_ACL_DEF;
8839 if (lines[4][9] == 'y') {
8840 *pallow_guest = True;
8843 /* Backwards compatible extension to file version #2. */
8845 if (strncmp(lines[5], "sharename=", 10) != 0) {
8846 return USERSHARE_MALFORMED_SHARENAME_DEF;
8848 if (!strequal(&lines[5][10], servicename)) {
8849 return USERSHARE_BAD_SHARENAME;
8851 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8852 if (!*pp_cp_servicename) {
8853 return USERSHARE_POSIX_ERR;
8858 if (*pp_cp_servicename == NULL) {
8859 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8860 if (!*pp_cp_servicename) {
8861 return USERSHARE_POSIX_ERR;
8865 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8866 /* Path didn't change, no checks needed. */
8867 *pp_sharepath = sharepath;
8868 *pp_comment = comment;
8869 return USERSHARE_OK;
8872 /* The path *must* be absolute. */
8873 if (sharepath[0] != '/') {
8874 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8875 servicename, sharepath));
8876 return USERSHARE_PATH_NOT_ABSOLUTE;
8879 /* If there is a usershare prefix deny list ensure one of these paths
8880 doesn't match the start of the user given path. */
8881 if (prefixdenylist) {
8883 for ( i=0; prefixdenylist[i]; i++ ) {
8884 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8885 servicename, i, prefixdenylist[i], sharepath ));
8886 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8887 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8888 "usershare prefix deny list entries.\n",
8889 servicename, sharepath));
8890 return USERSHARE_PATH_IS_DENIED;
8895 /* If there is a usershare prefix allow list ensure one of these paths
8896 does match the start of the user given path. */
8898 if (prefixallowlist) {
8900 for ( i=0; prefixallowlist[i]; i++ ) {
8901 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8902 servicename, i, prefixallowlist[i], sharepath ));
8903 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8907 if (prefixallowlist[i] == NULL) {
8908 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8909 "usershare prefix allow list entries.\n",
8910 servicename, sharepath));
8911 return USERSHARE_PATH_NOT_ALLOWED;
8915 /* Ensure this is pointing to a directory. */
8916 dp = sys_opendir(sharepath);
8919 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8920 servicename, sharepath));
8921 return USERSHARE_PATH_NOT_DIRECTORY;
8924 /* Ensure the owner of the usershare file has permission to share
8927 if (sys_stat(sharepath, &sbuf, false) == -1) {
8928 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8929 servicename, sharepath, strerror(errno) ));
8931 return USERSHARE_POSIX_ERR;
8936 if (!S_ISDIR(sbuf.st_ex_mode)) {
8937 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8938 servicename, sharepath ));
8939 return USERSHARE_PATH_NOT_DIRECTORY;
8942 /* Check if sharing is restricted to owner-only. */
8943 /* psbuf is the stat of the usershare definition file,
8944 sbuf is the stat of the target directory to be shared. */
8946 if (lp_usershare_owner_only()) {
8947 /* root can share anything. */
8948 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8949 return USERSHARE_PATH_NOT_ALLOWED;
8953 *pp_sharepath = sharepath;
8954 *pp_comment = comment;
8955 return USERSHARE_OK;
8958 /***************************************************************************
8959 Deal with a usershare file.
8962 -1 - Bad name, invalid contents.
8963 - service name already existed and not a usershare, problem
8964 with permissions to share directory etc.
8965 ***************************************************************************/
8967 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8969 SMB_STRUCT_STAT sbuf;
8970 SMB_STRUCT_STAT lsbuf;
8972 char *sharepath = NULL;
8973 char *comment = NULL;
8974 char *cp_service_name = NULL;
8975 char **lines = NULL;
8979 TALLOC_CTX *ctx = talloc_stackframe();
8980 struct security_descriptor *psd = NULL;
8981 bool guest_ok = False;
8982 char *canon_name = NULL;
8983 bool added_service = false;
8986 /* Ensure share name doesn't contain invalid characters. */
8987 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8988 DEBUG(0,("process_usershare_file: share name %s contains "
8989 "invalid characters (any of %s)\n",
8990 file_name, INVALID_SHARENAME_CHARS ));
8994 canon_name = canonicalize_servicename(ctx, file_name);
8999 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
9004 /* Minimize the race condition by doing an lstat before we
9005 open and fstat. Ensure this isn't a symlink link. */
9007 if (sys_lstat(fname, &lsbuf, false) != 0) {
9008 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
9009 fname, strerror(errno) ));
9013 /* This must be a regular file, not a symlink, directory or
9014 other strange filetype. */
9015 if (!check_usershare_stat(fname, &lsbuf)) {
9020 TDB_DATA data = dbwrap_fetch_bystring(
9021 ServiceHash, canon_name, canon_name);
9025 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
9026 iService = *(int *)data.dptr;
9030 if (iService != -1 &&
9031 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9032 &lsbuf.st_ex_mtime) == 0) {
9033 /* Nothing changed - Mark valid and return. */
9034 DEBUG(10,("process_usershare_file: service %s not changed.\n",
9036 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9041 /* Try and open the file read only - no symlinks allowed. */
9043 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
9045 fd = sys_open(fname, O_RDONLY, 0);
9049 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
9050 fname, strerror(errno) ));
9054 /* Now fstat to be *SURE* it's a regular file. */
9055 if (sys_fstat(fd, &sbuf, false) != 0) {
9057 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
9058 fname, strerror(errno) ));
9062 /* Is it the same dev/inode as was lstated ? */
9063 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
9065 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
9066 "Symlink spoofing going on ?\n", fname ));
9070 /* This must be a regular file, not a symlink, directory or
9071 other strange filetype. */
9072 if (!check_usershare_stat(fname, &sbuf)) {
9076 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
9079 if (lines == NULL) {
9080 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
9081 fname, (unsigned int)sbuf.st_ex_uid ));
9085 if (parse_usershare_file(ctx, &sbuf, file_name,
9086 iService, lines, numlines, &sharepath,
9087 &comment, &cp_service_name,
9088 &psd, &guest_ok) != USERSHARE_OK) {
9092 /* Everything ok - add the service possibly using a template. */
9094 const struct service *sp = &sDefault;
9095 if (snum_template != -1) {
9096 sp = ServicePtrs[snum_template];
9099 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
9100 DEBUG(0, ("process_usershare_file: Failed to add "
9101 "new service %s\n", cp_service_name));
9105 added_service = true;
9107 /* Read only is controlled by usershare ACL below. */
9108 ServicePtrs[iService]->bRead_only = False;
9111 /* Write the ACL of the new/modified share. */
9112 if (!set_share_security(canon_name, psd)) {
9113 DEBUG(0, ("process_usershare_file: Failed to set share "
9114 "security for user share %s\n",
9119 /* If from a template it may be marked invalid. */
9120 ServicePtrs[iService]->valid = True;
9122 /* Set the service as a valid usershare. */
9123 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9125 /* Set guest access. */
9126 if (lp_usershare_allow_guests()) {
9127 ServicePtrs[iService]->bGuest_ok = guest_ok;
9130 /* And note when it was loaded. */
9131 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
9132 string_set(&ServicePtrs[iService]->szPath, sharepath);
9133 string_set(&ServicePtrs[iService]->comment, comment);
9139 if (ret == -1 && iService != -1 && added_service) {
9140 lp_remove_service(iService);
9148 /***************************************************************************
9149 Checks if a usershare entry has been modified since last load.
9150 ***************************************************************************/
9152 static bool usershare_exists(int iService, struct timespec *last_mod)
9154 SMB_STRUCT_STAT lsbuf;
9155 const char *usersharepath = Globals.szUsersharePath;
9158 if (asprintf(&fname, "%s/%s",
9160 ServicePtrs[iService]->szService) < 0) {
9164 if (sys_lstat(fname, &lsbuf, false) != 0) {
9169 if (!S_ISREG(lsbuf.st_ex_mode)) {
9175 *last_mod = lsbuf.st_ex_mtime;
9179 /***************************************************************************
9180 Load a usershare service by name. Returns a valid servicenumber or -1.
9181 ***************************************************************************/
9183 int load_usershare_service(const char *servicename)
9185 SMB_STRUCT_STAT sbuf;
9186 const char *usersharepath = Globals.szUsersharePath;
9187 int max_user_shares = Globals.iUsershareMaxShares;
9188 int snum_template = -1;
9190 if (*usersharepath == 0 || max_user_shares == 0) {
9194 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9195 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9196 usersharepath, strerror(errno) ));
9200 if (!S_ISDIR(sbuf.st_ex_mode)) {
9201 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9207 * This directory must be owned by root, and have the 't' bit set.
9208 * It also must not be writable by "other".
9212 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9214 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9216 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9217 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9222 /* Ensure the template share exists if it's set. */
9223 if (Globals.szUsershareTemplateShare[0]) {
9224 /* We can't use lp_servicenumber here as we are recommending that
9225 template shares have -valid=False set. */
9226 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9227 if (ServicePtrs[snum_template]->szService &&
9228 strequal(ServicePtrs[snum_template]->szService,
9229 Globals.szUsershareTemplateShare)) {
9234 if (snum_template == -1) {
9235 DEBUG(0,("load_usershare_service: usershare template share %s "
9236 "does not exist.\n",
9237 Globals.szUsershareTemplateShare ));
9242 return process_usershare_file(usersharepath, servicename, snum_template);
9245 /***************************************************************************
9246 Load all user defined shares from the user share directory.
9247 We only do this if we're enumerating the share list.
9248 This is the function that can delete usershares that have
9250 ***************************************************************************/
9252 int load_usershare_shares(void)
9255 SMB_STRUCT_STAT sbuf;
9256 SMB_STRUCT_DIRENT *de;
9257 int num_usershares = 0;
9258 int max_user_shares = Globals.iUsershareMaxShares;
9259 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9260 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9261 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9263 int snum_template = -1;
9264 const char *usersharepath = Globals.szUsersharePath;
9265 int ret = lp_numservices();
9267 if (max_user_shares == 0 || *usersharepath == '\0') {
9268 return lp_numservices();
9271 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9272 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9273 usersharepath, strerror(errno) ));
9278 * This directory must be owned by root, and have the 't' bit set.
9279 * It also must not be writable by "other".
9283 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9285 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9287 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9288 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9293 /* Ensure the template share exists if it's set. */
9294 if (Globals.szUsershareTemplateShare[0]) {
9295 /* We can't use lp_servicenumber here as we are recommending that
9296 template shares have -valid=False set. */
9297 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9298 if (ServicePtrs[snum_template]->szService &&
9299 strequal(ServicePtrs[snum_template]->szService,
9300 Globals.szUsershareTemplateShare)) {
9305 if (snum_template == -1) {
9306 DEBUG(0,("load_usershare_shares: usershare template share %s "
9307 "does not exist.\n",
9308 Globals.szUsershareTemplateShare ));
9313 /* Mark all existing usershares as pending delete. */
9314 for (iService = iNumServices - 1; iService >= 0; iService--) {
9315 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9316 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9320 dp = sys_opendir(usersharepath);
9322 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9323 usersharepath, strerror(errno) ));
9327 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9328 (de = sys_readdir(dp));
9329 num_dir_entries++ ) {
9331 const char *n = de->d_name;
9333 /* Ignore . and .. */
9335 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9341 /* Temporary file used when creating a share. */
9342 num_tmp_dir_entries++;
9345 /* Allow 20% tmp entries. */
9346 if (num_tmp_dir_entries > allowed_tmp_entries) {
9347 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9348 "in directory %s\n",
9349 num_tmp_dir_entries, usersharepath));
9353 r = process_usershare_file(usersharepath, n, snum_template);
9355 /* Update the services count. */
9357 if (num_usershares >= max_user_shares) {
9358 DEBUG(0,("load_usershare_shares: max user shares reached "
9359 "on file %s in directory %s\n",
9360 n, usersharepath ));
9363 } else if (r == -1) {
9364 num_bad_dir_entries++;
9367 /* Allow 20% bad entries. */
9368 if (num_bad_dir_entries > allowed_bad_entries) {
9369 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9370 "in directory %s\n",
9371 num_bad_dir_entries, usersharepath));
9375 /* Allow 20% bad entries. */
9376 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9377 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9378 "in directory %s\n",
9379 num_dir_entries, usersharepath));
9386 /* Sweep through and delete any non-refreshed usershares that are
9387 not currently in use. */
9388 for (iService = iNumServices - 1; iService >= 0; iService--) {
9389 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9390 if (conn_snum_used(iService)) {
9393 /* Remove from the share ACL db. */
9394 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9395 lp_servicename(iService) ));
9396 delete_share_security(lp_servicename(iService));
9397 free_service_byindex(iService);
9401 return lp_numservices();
9404 /********************************************************
9405 Destroy global resources allocated in this file
9406 ********************************************************/
9408 void gfree_loadparm(void)
9414 /* Free resources allocated to services */
9416 for ( i = 0; i < iNumServices; i++ ) {
9418 free_service_byindex(i);
9422 SAFE_FREE( ServicePtrs );
9425 /* Now release all resources allocated to global
9426 parameters and the default service */
9428 free_global_parameters();
9432 /***************************************************************************
9433 Allow client apps to specify that they are a client
9434 ***************************************************************************/
9435 void lp_set_in_client(bool b)
9441 /***************************************************************************
9442 Determine if we're running in a client app
9443 ***************************************************************************/
9444 bool lp_is_in_client(void)
9449 /***************************************************************************
9450 Load the services array from the services file. Return True on success,
9452 ***************************************************************************/
9454 static bool lp_load_ex(const char *pszFname,
9458 bool initialize_globals,
9459 bool allow_include_registry,
9460 bool allow_registry_shares)
9467 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9469 bInGlobalSection = True;
9470 bGlobalOnly = global_only;
9471 bAllowIncludeRegistry = allow_include_registry;
9473 init_globals(initialize_globals);
9477 if (save_defaults) {
9482 free_param_opts(&Globals.param_opt);
9484 /* We get sections first, so have to start 'behind' to make up */
9487 if (lp_config_backend_is_file()) {
9488 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9489 current_user_info.domain,
9492 smb_panic("lp_load_ex: out of memory");
9495 add_to_file_list(pszFname, n2);
9497 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9500 /* finish up the last section */
9501 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9503 if (iServiceIndex >= 0) {
9504 bRetval = service_ok(iServiceIndex);
9508 if (lp_config_backend_is_registry()) {
9509 /* config backend changed to registry in config file */
9511 * We need to use this extra global variable here to
9512 * survive restart: init_globals uses this as a default
9513 * for ConfigBackend. Otherwise, init_globals would
9514 * send us into an endless loop here.
9516 config_backend = CONFIG_BACKEND_REGISTRY;
9518 DEBUG(1, ("lp_load_ex: changing to config backend "
9521 lp_kill_all_services();
9522 return lp_load_ex(pszFname, global_only, save_defaults,
9523 add_ipc, initialize_globals,
9524 allow_include_registry,
9525 allow_registry_shares);
9527 } else if (lp_config_backend_is_registry()) {
9528 bRetval = process_registry_globals();
9530 DEBUG(0, ("Illegal config backend given: %d\n",
9531 lp_config_backend()));
9535 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9536 bRetval = process_registry_shares();
9539 lp_add_auto_services(lp_auto_services());
9542 /* When 'restrict anonymous = 2' guest connections to ipc$
9544 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9545 if ( lp_enable_asu_support() ) {
9546 lp_add_ipc("ADMIN$", false);
9551 set_default_server_announce_type();
9552 set_allowed_client_auth();
9556 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9557 /* if bWINSsupport is true and we are in the client */
9558 if (lp_is_in_client() && Globals.bWINSsupport) {
9559 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9564 bAllowIncludeRegistry = true;
9569 bool lp_load(const char *pszFname,
9573 bool initialize_globals)
9575 return lp_load_ex(pszFname,
9580 true, /* allow_include_registry */
9581 false); /* allow_registry_shares*/
9584 bool lp_load_initial_only(const char *pszFname)
9586 return lp_load_ex(pszFname,
9587 true, /* global only */
9588 false, /* save_defaults */
9589 false, /* add_ipc */
9590 true, /* initialize_globals */
9591 false, /* allow_include_registry */
9592 false); /* allow_registry_shares*/
9595 bool lp_load_with_registry_shares(const char *pszFname,
9599 bool initialize_globals)
9601 return lp_load_ex(pszFname,
9606 true, /* allow_include_registry */
9607 true); /* allow_registry_shares*/
9610 /***************************************************************************
9611 Return the max number of services.
9612 ***************************************************************************/
9614 int lp_numservices(void)
9616 return (iNumServices);
9619 /***************************************************************************
9620 Display the contents of the services array in human-readable form.
9621 ***************************************************************************/
9623 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9628 defaults_saved = False;
9632 dump_a_service(&sDefault, f);
9634 for (iService = 0; iService < maxtoprint; iService++) {
9636 lp_dump_one(f, show_defaults, iService);
9640 /***************************************************************************
9641 Display the contents of one service in human-readable form.
9642 ***************************************************************************/
9644 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9647 if (ServicePtrs[snum]->szService[0] == '\0')
9649 dump_a_service(ServicePtrs[snum], f);
9653 /***************************************************************************
9654 Return the number of the service with the given name, or -1 if it doesn't
9655 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9656 getservicebyname()! This works ONLY if all services have been loaded, and
9657 does not copy the found service.
9658 ***************************************************************************/
9660 int lp_servicenumber(const char *pszServiceName)
9663 fstring serviceName;
9665 if (!pszServiceName) {
9666 return GLOBAL_SECTION_SNUM;
9669 for (iService = iNumServices - 1; iService >= 0; iService--) {
9670 if (VALID(iService) && ServicePtrs[iService]->szService) {
9672 * The substitution here is used to support %U is
9675 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9676 standard_sub_basic(get_current_username(),
9677 current_user_info.domain,
9678 serviceName,sizeof(serviceName));
9679 if (strequal(serviceName, pszServiceName)) {
9685 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9686 struct timespec last_mod;
9688 if (!usershare_exists(iService, &last_mod)) {
9689 /* Remove the share security tdb entry for it. */
9690 delete_share_security(lp_servicename(iService));
9691 /* Remove it from the array. */
9692 free_service_byindex(iService);
9693 /* Doesn't exist anymore. */
9694 return GLOBAL_SECTION_SNUM;
9697 /* Has it been modified ? If so delete and reload. */
9698 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9700 /* Remove it from the array. */
9701 free_service_byindex(iService);
9702 /* and now reload it. */
9703 iService = load_usershare_service(pszServiceName);
9708 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9709 return GLOBAL_SECTION_SNUM;
9715 bool share_defined(const char *service_name)
9717 return (lp_servicenumber(service_name) != -1);
9720 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9721 const char *sharename)
9723 struct share_params *result;
9727 snum = find_service(mem_ctx, sharename, &sname);
9728 if (snum < 0 || sname == NULL) {
9732 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9733 DEBUG(0, ("talloc failed\n"));
9737 result->service = snum;
9741 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9743 struct share_iterator *result;
9745 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9746 DEBUG(0, ("talloc failed\n"));
9750 result->next_id = 0;
9754 struct share_params *next_share(struct share_iterator *list)
9756 struct share_params *result;
9758 while (!lp_snum_ok(list->next_id) &&
9759 (list->next_id < lp_numservices())) {
9763 if (list->next_id >= lp_numservices()) {
9767 if (!(result = TALLOC_P(list, struct share_params))) {
9768 DEBUG(0, ("talloc failed\n"));
9772 result->service = list->next_id;
9777 struct share_params *next_printer(struct share_iterator *list)
9779 struct share_params *result;
9781 while ((result = next_share(list)) != NULL) {
9782 if (lp_print_ok(result->service)) {
9790 * This is a hack for a transition period until we transformed all code from
9791 * service numbers to struct share_params.
9794 struct share_params *snum2params_static(int snum)
9796 static struct share_params result;
9797 result.service = snum;
9801 /*******************************************************************
9802 A useful volume label function.
9803 ********************************************************************/
9805 const char *volume_label(int snum)
9808 const char *label = lp_volume(snum);
9810 label = lp_servicename(snum);
9813 /* This returns a 33 byte guarenteed null terminated string. */
9814 ret = talloc_strndup(talloc_tos(), label, 32);
9821 /*******************************************************************
9822 Set the server type we will announce as via nmbd.
9823 ********************************************************************/
9825 static void set_default_server_announce_type(void)
9827 default_server_announce = 0;
9828 default_server_announce |= SV_TYPE_WORKSTATION;
9829 default_server_announce |= SV_TYPE_SERVER;
9830 default_server_announce |= SV_TYPE_SERVER_UNIX;
9832 /* note that the flag should be set only if we have a
9833 printer service but nmbd doesn't actually load the
9834 services so we can't tell --jerry */
9836 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9838 switch (lp_announce_as()) {
9839 case ANNOUNCE_AS_NT_SERVER:
9840 default_server_announce |= SV_TYPE_SERVER_NT;
9841 /* fall through... */
9842 case ANNOUNCE_AS_NT_WORKSTATION:
9843 default_server_announce |= SV_TYPE_NT;
9845 case ANNOUNCE_AS_WIN95:
9846 default_server_announce |= SV_TYPE_WIN95_PLUS;
9848 case ANNOUNCE_AS_WFW:
9849 default_server_announce |= SV_TYPE_WFW;
9855 switch (lp_server_role()) {
9856 case ROLE_DOMAIN_MEMBER:
9857 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9859 case ROLE_DOMAIN_PDC:
9860 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9862 case ROLE_DOMAIN_BDC:
9863 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9865 case ROLE_STANDALONE:
9869 if (lp_time_server())
9870 default_server_announce |= SV_TYPE_TIME_SOURCE;
9872 if (lp_host_msdfs())
9873 default_server_announce |= SV_TYPE_DFS_SERVER;
9876 /***********************************************************
9877 If we are PDC then prefer us as DMB
9878 ************************************************************/
9880 bool lp_domain_master(void)
9882 if (Globals.iDomainMaster == Auto)
9883 return (lp_server_role() == ROLE_DOMAIN_PDC);
9885 return (bool)Globals.iDomainMaster;
9888 /***********************************************************
9889 If we are PDC then prefer us as DMB
9890 ************************************************************/
9892 bool lp_domain_master_true_or_auto(void)
9894 if (Globals.iDomainMaster) /* auto or yes */
9900 /***********************************************************
9901 If we are DMB then prefer us as LMB
9902 ************************************************************/
9904 bool lp_preferred_master(void)
9906 if (Globals.iPreferredMaster == Auto)
9907 return (lp_local_master() && lp_domain_master());
9909 return (bool)Globals.iPreferredMaster;
9912 /*******************************************************************
9914 ********************************************************************/
9916 void lp_remove_service(int snum)
9918 ServicePtrs[snum]->valid = False;
9919 invalid_services[num_invalid_services++] = snum;
9922 /*******************************************************************
9924 ********************************************************************/
9926 void lp_copy_service(int snum, const char *new_name)
9928 do_section(new_name, NULL);
9930 snum = lp_servicenumber(new_name);
9932 lp_do_parameter(snum, "copy", lp_servicename(snum));
9937 /*******************************************************************
9938 Get the default server type we will announce as via nmbd.
9939 ********************************************************************/
9941 int lp_default_server_announce(void)
9943 return default_server_announce;
9946 /*******************************************************************
9947 Split the announce version into major and minor numbers.
9948 ********************************************************************/
9950 int lp_major_announce_version(void)
9952 static bool got_major = False;
9953 static int major_version = DEFAULT_MAJOR_VERSION;
9958 return major_version;
9961 if ((vers = lp_announce_version()) == NULL)
9962 return major_version;
9964 if ((p = strchr_m(vers, '.')) == 0)
9965 return major_version;
9968 major_version = atoi(vers);
9969 return major_version;
9972 int lp_minor_announce_version(void)
9974 static bool got_minor = False;
9975 static int minor_version = DEFAULT_MINOR_VERSION;
9980 return minor_version;
9983 if ((vers = lp_announce_version()) == NULL)
9984 return minor_version;
9986 if ((p = strchr_m(vers, '.')) == 0)
9987 return minor_version;
9990 minor_version = atoi(p);
9991 return minor_version;
9994 /***********************************************************
9995 Set the global name resolution order (used in smbclient).
9996 ************************************************************/
9998 void lp_set_name_resolve_order(const char *new_order)
10000 string_set(&Globals.szNameResolveOrder, new_order);
10003 const char *lp_printername(int snum)
10005 const char *ret = _lp_printername(snum);
10006 if (ret == NULL || (ret != NULL && *ret == '\0'))
10007 ret = lp_const_servicename(snum);
10013 /***********************************************************
10014 Allow daemons such as winbindd to fix their logfile name.
10015 ************************************************************/
10017 void lp_set_logfile(const char *name)
10019 string_set(&Globals.szLogFile, name);
10020 debug_set_logfile(name);
10023 /*******************************************************************
10024 Return the max print jobs per queue.
10025 ********************************************************************/
10027 int lp_maxprintjobs(int snum)
10029 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
10030 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
10031 maxjobs = PRINT_MAX_JOBID - 1;
10036 const char *lp_printcapname(void)
10038 if ((Globals.szPrintcapname != NULL) &&
10039 (Globals.szPrintcapname[0] != '\0'))
10040 return Globals.szPrintcapname;
10042 if (sDefault.iPrinting == PRINT_CUPS) {
10050 if (sDefault.iPrinting == PRINT_BSD)
10051 return "/etc/printcap";
10053 return PRINTCAP_NAME;
10056 static uint32 spoolss_state;
10058 bool lp_disable_spoolss( void )
10060 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
10061 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
10063 return spoolss_state == SVCCTL_STOPPED ? True : False;
10066 void lp_set_spoolss_state( uint32 state )
10068 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
10070 spoolss_state = state;
10073 uint32 lp_get_spoolss_state( void )
10075 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
10078 /*******************************************************************
10079 Ensure we don't use sendfile if server smb signing is active.
10080 ********************************************************************/
10082 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
10084 bool sign_active = false;
10086 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
10087 if (get_Protocol() < PROTOCOL_NT1) {
10090 if (signing_state) {
10091 sign_active = smb_signing_is_active(signing_state);
10093 return (_lp_use_sendfile(snum) &&
10094 (get_remote_arch() != RA_WIN95) &&
10098 /*******************************************************************
10099 Turn off sendfile if we find the underlying OS doesn't support it.
10100 ********************************************************************/
10102 void set_use_sendfile(int snum, bool val)
10104 if (LP_SNUM_OK(snum))
10105 ServicePtrs[snum]->bUseSendfile = val;
10107 sDefault.bUseSendfile = val;
10110 /*******************************************************************
10111 Turn off storing DOS attributes if this share doesn't support it.
10112 ********************************************************************/
10114 void set_store_dos_attributes(int snum, bool val)
10116 if (!LP_SNUM_OK(snum))
10118 ServicePtrs[(snum)]->bStoreDosAttributes = val;
10121 void lp_set_mangling_method(const char *new_method)
10123 string_set(&Globals.szManglingMethod, new_method);
10126 /*******************************************************************
10127 Global state for POSIX pathname processing.
10128 ********************************************************************/
10130 static bool posix_pathnames;
10132 bool lp_posix_pathnames(void)
10134 return posix_pathnames;
10137 /*******************************************************************
10138 Change everything needed to ensure POSIX pathname processing (currently
10140 ********************************************************************/
10142 void lp_set_posix_pathnames(void)
10144 posix_pathnames = True;
10147 /*******************************************************************
10148 Global state for POSIX lock processing - CIFS unix extensions.
10149 ********************************************************************/
10151 bool posix_default_lock_was_set;
10152 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
10154 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
10156 if (posix_default_lock_was_set) {
10157 return posix_cifsx_locktype;
10159 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
10163 /*******************************************************************
10164 ********************************************************************/
10166 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
10168 posix_default_lock_was_set = True;
10169 posix_cifsx_locktype = val;
10172 int lp_min_receive_file_size(void)
10174 if (Globals.iminreceivefile < 0) {
10177 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
10180 /*******************************************************************
10181 If socket address is an empty character string, it is necessary to
10182 define it as "0.0.0.0".
10183 ********************************************************************/
10185 const char *lp_socket_address(void)
10187 char *sock_addr = Globals.szSocketAddress;
10189 if (sock_addr[0] == '\0'){
10190 string_set(&Globals.szSocketAddress, "0.0.0.0");
10192 return Globals.szSocketAddress;
10195 void lp_set_passdb_backend(const char *backend)
10197 string_set(&Globals.szPassdbBackend, backend);
10200 /*******************************************************************
10201 Safe wide links checks.
10202 This helper function always verify the validity of wide links,
10203 even after a configuration file reload.
10204 ********************************************************************/
10206 static bool lp_widelinks_internal(int snum)
10208 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
10209 sDefault.bWidelinks);
10212 void widelinks_warning(int snum)
10214 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10215 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10216 "These parameters are incompatible. "
10217 "Wide links will be disabled for this share.\n",
10218 lp_servicename(snum) ));
10222 bool lp_widelinks(int snum)
10224 /* wide links is always incompatible with unix extensions */
10225 if (lp_unix_extensions()) {
10229 return lp_widelinks_internal(snum);
10232 bool lp_writeraw(void)
10234 if (lp_async_smb_echo_handler()) {
10237 return _lp_writeraw();
10240 bool lp_readraw(void)
10242 if (lp_async_smb_echo_handler()) {
10245 return _lp_readraw();