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 char *szIdmapBackend;
221 char *szAddShareCommand;
222 char *szChangeShareCommand;
223 char *szDeleteShareCommand;
225 char *szGuestaccount;
226 char *szManglingMethod;
227 char **szServicesList;
228 char *szUsersharePath;
229 char *szUsershareTemplateShare;
230 char **szUsersharePrefixAllowList;
231 char **szUsersharePrefixDenyList;
238 int open_files_db_hash_size;
247 bool paranoid_server_security;
250 int iMaxSmbdProcesses;
251 bool bDisableSpoolss;
254 bool enhanced_browsing;
260 int announce_as; /* This is initialised in init_globals */
261 int machine_password_timeout;
263 int oplock_break_wait_time;
264 int winbind_cache_time;
265 int winbind_reconnect_delay;
266 int winbind_max_clients;
267 char **szWinbindNssInfo;
269 char *szLdapMachineSuffix;
270 char *szLdapUserSuffix;
271 char *szLdapIdmapSuffix;
272 char *szLdapGroupSuffix;
276 int ldap_follow_referral;
279 int ldap_debug_level;
280 int ldap_debug_threshold;
284 char *szIPrintServer;
286 char **szClusterAddresses;
289 int ctdb_locktime_warn_threshold;
290 int ldap_passwd_sync;
291 int ldap_replication_sleep;
292 int ldap_timeout; /* This is initialised in init_globals */
293 int ldap_connection_timeout;
296 bool bMsAddPrinterWizard;
301 int iPreferredMaster;
304 char **szInitLogonDelayedHosts;
306 bool bEncryptPasswords;
311 bool bObeyPamRestrictions;
313 int PrintcapCacheTime;
314 bool bLargeReadwrite;
321 bool bBindInterfacesOnly;
322 bool bPamPasswordChange;
323 bool bUnixPasswdSync;
324 bool bPasswdChatDebug;
325 int iPasswdChatTimeout;
329 bool bNTStatusSupport;
331 int iMaxStatCacheSize;
333 bool bAllowTrustedDomains;
337 bool bClientLanManAuth;
338 bool bClientNTLMv2Auth;
339 bool bClientPlaintextAuth;
340 bool bClientUseSpnego;
341 bool client_use_spnego_principal;
342 bool send_spnego_principal;
343 bool bDebugPrefixTimestamp;
344 bool bDebugHiresTimestamp;
348 bool bEnableCoreFiles;
351 bool bHostnameLookups;
352 bool bUnixExtensions;
353 bool bDisableNetbios;
354 char * szDedicatedKeytabFile;
356 bool bDeferSharingViolations;
357 bool bEnablePrivileges;
359 bool bUsershareOwnerOnly;
360 bool bUsershareAllowGuests;
361 bool bRegistryShares;
362 int restrict_anonymous;
363 int name_cache_timeout;
366 int client_ldap_sasl_wrapping;
367 int iUsershareMaxShares;
369 int iIdmapNegativeCacheTime;
371 bool bLogWriteableFilesOnExit;
374 struct param_opt_struct *param_opt;
375 int cups_connection_timeout;
376 char *szSMBPerfcountModule;
377 bool bMapUntrustedToDomain;
378 bool bAsyncSMBEchoHandler;
379 bool bMulticastDnsRegister;
386 static struct global Globals;
389 * This structure describes a single service.
395 struct timespec usershare_last_mod;
399 char **szInvalidUsers;
407 char *szRootPostExec;
409 char *szPrintcommand;
412 char *szLppausecommand;
413 char *szLpresumecommand;
414 char *szQueuepausecommand;
415 char *szQueueresumecommand;
417 char *szPrintjobUsername;
425 char *szVetoOplockFiles;
431 char **printer_admin;
436 char *szAioWriteBehind;
440 int iMaxReportedPrintJobs;
443 int iCreate_force_mode;
445 int iSecurity_force_mode;
448 int iDir_Security_mask;
449 int iDir_Security_force_mode;
453 int iOplockContentionLimit;
458 bool bRootpreexecClose;
461 bool bShortCasePreserve;
463 bool bHideSpecialFiles;
464 bool bHideUnReadable;
465 bool bHideUnWriteableFiles;
467 bool bAccessBasedShareEnum;
472 bool bAdministrative_share;
478 bool bStoreDosAttributes;
491 bool bStrictAllocate;
494 struct bitmap *copymap;
495 bool bDeleteReadonly;
497 bool bDeleteVetoFiles;
500 bool bDosFiletimeResolution;
501 bool bFakeDirCreateTimes;
507 bool bUseClientDriver;
508 bool bDefaultDevmode;
509 bool bForcePrintername;
511 bool bForceUnknownAclUser;
514 bool bMap_acl_inherit;
517 bool bAclCheckPermissions;
518 bool bAclMapFullControl;
519 bool bAclGroupControl;
521 bool bKernelChangeNotify;
522 int iallocation_roundup_size;
526 int iDirectoryNameCacheSize;
528 struct param_opt_struct *param_opt;
530 char dummy[3]; /* for alignment */
534 /* This is a default service used to prime a services structure */
535 static struct service sDefault = {
537 False, /* not autoloaded */
538 0, /* not a usershare */
539 {0, }, /* No last mod time */
540 NULL, /* szService */
542 NULL, /* szUsername */
543 NULL, /* szInvalidUsers */
544 NULL, /* szValidUsers */
545 NULL, /* szAdminUsers */
547 NULL, /* szInclude */
548 NULL, /* szPreExec */
549 NULL, /* szPostExec */
550 NULL, /* szRootPreExec */
551 NULL, /* szRootPostExec */
552 NULL, /* szCupsOptions */
553 NULL, /* szPrintcommand */
554 NULL, /* szLpqcommand */
555 NULL, /* szLprmcommand */
556 NULL, /* szLppausecommand */
557 NULL, /* szLpresumecommand */
558 NULL, /* szQueuepausecommand */
559 NULL, /* szQueueresumecommand */
560 NULL, /* szPrintername */
561 NULL, /* szPrintjobUsername */
562 NULL, /* szDontdescend */
563 NULL, /* szHostsallow */
564 NULL, /* szHostsdeny */
565 NULL, /* szMagicScript */
566 NULL, /* szMagicOutput */
567 NULL, /* szVetoFiles */
568 NULL, /* szHideFiles */
569 NULL, /* szVetoOplockFiles */
571 NULL, /* force user */
572 NULL, /* force group */
574 NULL, /* writelist */
575 NULL, /* printer admin */
578 NULL, /* vfs objects */
579 NULL, /* szMSDfsProxy */
580 NULL, /* szAioWriteBehind */
582 0, /* iMinPrintSpace */
583 1000, /* iMaxPrintJobs */
584 0, /* iMaxReportedPrintJobs */
585 0, /* iWriteCacheSize */
586 0744, /* iCreate_mask */
587 0000, /* iCreate_force_mode */
588 0777, /* iSecurity_mask */
589 0, /* iSecurity_force_mode */
590 0755, /* iDir_mask */
591 0000, /* iDir_force_mode */
592 0777, /* iDir_Security_mask */
593 0, /* iDir_Security_force_mode */
594 0, /* iMaxConnections */
595 CASE_LOWER, /* iDefaultCase */
596 DEFAULT_PRINTING, /* iPrinting */
597 2, /* iOplockContentionLimit */
599 1024, /* iBlock_size */
600 0, /* iDfreeCacheTime */
601 False, /* bPreexecClose */
602 False, /* bRootpreexecClose */
603 Auto, /* case sensitive */
604 True, /* case preserve */
605 True, /* short case preserve */
606 True, /* bHideDotFiles */
607 False, /* bHideSpecialFiles */
608 False, /* bHideUnReadable */
609 False, /* bHideUnWriteableFiles */
610 True, /* bBrowseable */
611 False, /* bAccessBasedShareEnum */
612 True, /* bAvailable */
613 True, /* bRead_only */
614 True, /* bNo_set_dir */
615 False, /* bGuest_only */
616 False, /* bAdministrative_share */
617 False, /* bGuest_ok */
618 False, /* bPrint_ok */
619 False, /* bMap_system */
620 False, /* bMap_hidden */
621 True, /* bMap_archive */
622 False, /* bStoreDosAttributes */
623 False, /* bDmapiSupport */
625 Auto, /* iStrictLocking */
626 True, /* bPosixLocking */
627 True, /* bShareModes */
629 True, /* bLevel2OpLocks */
630 False, /* bOnlyUser */
631 True, /* bMangledNames */
632 false, /* bWidelinks */
633 True, /* bSymlinks */
634 False, /* bSyncAlways */
635 False, /* bStrictAllocate */
636 False, /* bStrictSync */
637 '~', /* magic char */
639 False, /* bDeleteReadonly */
640 False, /* bFakeOplocks */
641 False, /* bDeleteVetoFiles */
642 False, /* bDosFilemode */
643 True, /* bDosFiletimes */
644 False, /* bDosFiletimeResolution */
645 False, /* bFakeDirCreateTimes */
646 True, /* bBlockingLocks */
647 False, /* bInheritPerms */
648 False, /* bInheritACLS */
649 False, /* bInheritOwner */
650 False, /* bMSDfsRoot */
651 False, /* bUseClientDriver */
652 True, /* bDefaultDevmode */
653 False, /* bForcePrintername */
654 True, /* bNTAclSupport */
655 False, /* bForceUnknownAclUser */
656 False, /* bUseSendfile */
657 False, /* bProfileAcls */
658 False, /* bMap_acl_inherit */
659 False, /* bAfs_Share */
660 False, /* bEASupport */
661 True, /* bAclCheckPermissions */
662 True, /* bAclMapFullControl */
663 False, /* bAclGroupControl */
664 True, /* bChangeNotify */
665 True, /* bKernelChangeNotify */
666 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
667 0, /* iAioReadSize */
668 0, /* iAioWriteSize */
669 MAP_READONLY_YES, /* iMap_readonly */
670 #ifdef BROKEN_DIRECTORY_HANDLING
671 0, /* iDirectoryNameCacheSize */
673 100, /* iDirectoryNameCacheSize */
675 Auto, /* ismb_encrypt */
676 NULL, /* Parametric options */
681 /* local variables */
682 static struct service **ServicePtrs = NULL;
683 static int iNumServices = 0;
684 static int iServiceIndex = 0;
685 static struct db_context *ServiceHash;
686 static int *invalid_services = NULL;
687 static int num_invalid_services = 0;
688 static bool bInGlobalSection = True;
689 static bool bGlobalOnly = False;
690 static int default_server_announce;
692 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
694 /* prototypes for the special type handlers */
695 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
696 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
697 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
698 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
699 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
700 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
701 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
702 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
703 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
704 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
705 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
706 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
708 static void set_default_server_announce_type(void);
709 static void set_allowed_client_auth(void);
711 static void *lp_local_ptr(struct service *service, void *ptr);
713 static void add_to_file_list(const char *fname, const char *subfname);
714 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
716 static const struct enum_list enum_protocol[] = {
717 {PROTOCOL_SMB2, "SMB2"},
718 {PROTOCOL_NT1, "NT1"},
719 {PROTOCOL_LANMAN2, "LANMAN2"},
720 {PROTOCOL_LANMAN1, "LANMAN1"},
721 {PROTOCOL_CORE, "CORE"},
722 {PROTOCOL_COREPLUS, "COREPLUS"},
723 {PROTOCOL_COREPLUS, "CORE+"},
727 static const struct enum_list enum_security[] = {
728 {SEC_SHARE, "SHARE"},
730 {SEC_SERVER, "SERVER"},
731 {SEC_DOMAIN, "DOMAIN"},
738 static const struct enum_list enum_printing[] = {
739 {PRINT_SYSV, "sysv"},
741 {PRINT_HPUX, "hpux"},
745 {PRINT_LPRNG, "lprng"},
746 {PRINT_CUPS, "cups"},
747 {PRINT_IPRINT, "iprint"},
749 {PRINT_LPROS2, "os2"},
751 {PRINT_TEST, "test"},
753 #endif /* DEVELOPER */
757 static const struct enum_list enum_ldap_sasl_wrapping[] = {
759 {ADS_AUTH_SASL_SIGN, "sign"},
760 {ADS_AUTH_SASL_SEAL, "seal"},
764 static const struct enum_list enum_ldap_ssl[] = {
765 {LDAP_SSL_OFF, "no"},
766 {LDAP_SSL_OFF, "off"},
767 {LDAP_SSL_START_TLS, "start tls"},
768 {LDAP_SSL_START_TLS, "start_tls"},
772 /* LDAP Dereferencing Alias types */
773 #define SAMBA_LDAP_DEREF_NEVER 0
774 #define SAMBA_LDAP_DEREF_SEARCHING 1
775 #define SAMBA_LDAP_DEREF_FINDING 2
776 #define SAMBA_LDAP_DEREF_ALWAYS 3
778 static const struct enum_list enum_ldap_deref[] = {
779 {SAMBA_LDAP_DEREF_NEVER, "never"},
780 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
781 {SAMBA_LDAP_DEREF_FINDING, "finding"},
782 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
786 static const struct enum_list enum_ldap_passwd_sync[] = {
787 {LDAP_PASSWD_SYNC_OFF, "no"},
788 {LDAP_PASSWD_SYNC_OFF, "off"},
789 {LDAP_PASSWD_SYNC_ON, "yes"},
790 {LDAP_PASSWD_SYNC_ON, "on"},
791 {LDAP_PASSWD_SYNC_ONLY, "only"},
795 /* Types of machine we can announce as. */
796 #define ANNOUNCE_AS_NT_SERVER 1
797 #define ANNOUNCE_AS_WIN95 2
798 #define ANNOUNCE_AS_WFW 3
799 #define ANNOUNCE_AS_NT_WORKSTATION 4
801 static const struct enum_list enum_announce_as[] = {
802 {ANNOUNCE_AS_NT_SERVER, "NT"},
803 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
804 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
805 {ANNOUNCE_AS_WIN95, "win95"},
806 {ANNOUNCE_AS_WFW, "WfW"},
810 static const struct enum_list enum_map_readonly[] = {
811 {MAP_READONLY_NO, "no"},
812 {MAP_READONLY_NO, "false"},
813 {MAP_READONLY_NO, "0"},
814 {MAP_READONLY_YES, "yes"},
815 {MAP_READONLY_YES, "true"},
816 {MAP_READONLY_YES, "1"},
817 {MAP_READONLY_PERMISSIONS, "permissions"},
818 {MAP_READONLY_PERMISSIONS, "perms"},
822 static const struct enum_list enum_case[] = {
823 {CASE_LOWER, "lower"},
824 {CASE_UPPER, "upper"},
830 static const struct enum_list enum_bool_auto[] = {
841 static const struct enum_list enum_csc_policy[] = {
842 {CSC_POLICY_MANUAL, "manual"},
843 {CSC_POLICY_DOCUMENTS, "documents"},
844 {CSC_POLICY_PROGRAMS, "programs"},
845 {CSC_POLICY_DISABLE, "disable"},
849 /* SMB signing types. */
850 static const struct enum_list enum_smb_signing_vals[] = {
862 {Required, "required"},
863 {Required, "mandatory"},
865 {Required, "forced"},
866 {Required, "enforced"},
870 /* ACL compatibility options. */
871 static const struct enum_list enum_acl_compat_vals[] = {
872 { ACL_COMPAT_AUTO, "auto" },
873 { ACL_COMPAT_WINNT, "winnt" },
874 { ACL_COMPAT_WIN2K, "win2k" },
879 Do you want session setups at user level security with a invalid
880 password to be rejected or allowed in as guest? WinNT rejects them
881 but it can be a pain as it means "net view" needs to use a password
883 You have 3 choices in the setting of map_to_guest:
885 "Never" means session setups with an invalid password
886 are rejected. This is the default.
888 "Bad User" means session setups with an invalid password
889 are rejected, unless the username does not exist, in which case it
890 is treated as a guest login
892 "Bad Password" means session setups with an invalid password
893 are treated as a guest login
895 Note that map_to_guest only has an effect in user or server
899 static const struct enum_list enum_map_to_guest[] = {
900 {NEVER_MAP_TO_GUEST, "Never"},
901 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
902 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
903 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
907 /* Config backend options */
909 static const struct enum_list enum_config_backend[] = {
910 {CONFIG_BACKEND_FILE, "file"},
911 {CONFIG_BACKEND_REGISTRY, "registry"},
915 /* ADS kerberos ticket verification options */
917 static const struct enum_list enum_kerberos_method[] = {
918 {KERBEROS_VERIFY_SECRETS, "default"},
919 {KERBEROS_VERIFY_SECRETS, "secrets only"},
920 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
921 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
922 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
926 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
928 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
929 * screen in SWAT. This is used to exclude parameters as well as to squash all
930 * parameters that have been duplicated by pseudonyms.
932 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
933 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
934 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
937 * NOTE2: Handling of duplicated (synonym) parameters:
938 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
939 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
940 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
941 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
944 static struct parm_struct parm_table[] = {
945 {N_("Base Options"), P_SEP, P_SEPARATOR},
948 .label = "dos charset",
951 .ptr = &Globals.dos_charset,
952 .special = handle_charset,
954 .flags = FLAG_ADVANCED
957 .label = "unix charset",
960 .ptr = &Globals.unix_charset,
961 .special = handle_charset,
963 .flags = FLAG_ADVANCED
966 .label = "display charset",
969 .ptr = &Globals.display_charset,
970 .special = handle_charset,
972 .flags = FLAG_ADVANCED
978 .ptr = &sDefault.comment,
981 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
987 .ptr = &sDefault.szPath,
990 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
993 .label = "directory",
996 .ptr = &sDefault.szPath,
1002 .label = "workgroup",
1004 .p_class = P_GLOBAL,
1005 .ptr = &Globals.szWorkgroup,
1006 .special = handle_workgroup,
1008 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1014 .p_class = P_GLOBAL,
1015 .ptr = &Globals.szRealm,
1018 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1022 .label = "netbios name",
1024 .p_class = P_GLOBAL,
1025 .ptr = &Globals.szNetbiosName,
1026 .special = handle_netbios_name,
1028 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1031 .label = "netbios aliases",
1033 .p_class = P_GLOBAL,
1034 .ptr = &Globals.szNetbiosAliases,
1035 .special = handle_netbios_aliases,
1037 .flags = FLAG_ADVANCED,
1040 .label = "netbios scope",
1042 .p_class = P_GLOBAL,
1043 .ptr = &Globals.szNetbiosScope,
1044 .special = handle_netbios_scope,
1046 .flags = FLAG_ADVANCED,
1049 .label = "server string",
1051 .p_class = P_GLOBAL,
1052 .ptr = &Globals.szServerString,
1055 .flags = FLAG_BASIC | FLAG_ADVANCED,
1058 .label = "interfaces",
1060 .p_class = P_GLOBAL,
1061 .ptr = &Globals.szInterfaces,
1064 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1067 .label = "bind interfaces only",
1069 .p_class = P_GLOBAL,
1070 .ptr = &Globals.bBindInterfacesOnly,
1073 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1076 .label = "config backend",
1078 .p_class = P_GLOBAL,
1079 .ptr = &Globals.ConfigBackend,
1081 .enum_list = enum_config_backend,
1082 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1085 {N_("Security Options"), P_SEP, P_SEPARATOR},
1088 .label = "security",
1090 .p_class = P_GLOBAL,
1091 .ptr = &Globals.security,
1093 .enum_list = enum_security,
1094 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1097 .label = "auth methods",
1099 .p_class = P_GLOBAL,
1100 .ptr = &Globals.AuthMethods,
1103 .flags = FLAG_ADVANCED,
1106 .label = "encrypt passwords",
1108 .p_class = P_GLOBAL,
1109 .ptr = &Globals.bEncryptPasswords,
1112 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1115 .label = "client schannel",
1117 .p_class = P_GLOBAL,
1118 .ptr = &Globals.clientSchannel,
1120 .enum_list = enum_bool_auto,
1121 .flags = FLAG_BASIC | FLAG_ADVANCED,
1124 .label = "server schannel",
1126 .p_class = P_GLOBAL,
1127 .ptr = &Globals.serverSchannel,
1129 .enum_list = enum_bool_auto,
1130 .flags = FLAG_BASIC | FLAG_ADVANCED,
1133 .label = "allow trusted domains",
1135 .p_class = P_GLOBAL,
1136 .ptr = &Globals.bAllowTrustedDomains,
1139 .flags = FLAG_ADVANCED,
1142 .label = "map to guest",
1144 .p_class = P_GLOBAL,
1145 .ptr = &Globals.map_to_guest,
1147 .enum_list = enum_map_to_guest,
1148 .flags = FLAG_ADVANCED,
1151 .label = "null passwords",
1153 .p_class = P_GLOBAL,
1154 .ptr = &Globals.bNullPasswords,
1157 .flags = FLAG_ADVANCED,
1160 .label = "obey pam restrictions",
1162 .p_class = P_GLOBAL,
1163 .ptr = &Globals.bObeyPamRestrictions,
1166 .flags = FLAG_ADVANCED,
1169 .label = "password server",
1171 .p_class = P_GLOBAL,
1172 .ptr = &Globals.szPasswordServer,
1175 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1178 .label = "smb passwd file",
1180 .p_class = P_GLOBAL,
1181 .ptr = &Globals.szSMBPasswdFile,
1184 .flags = FLAG_ADVANCED,
1187 .label = "private dir",
1189 .p_class = P_GLOBAL,
1190 .ptr = &Globals.szPrivateDir,
1193 .flags = FLAG_ADVANCED,
1196 .label = "passdb backend",
1198 .p_class = P_GLOBAL,
1199 .ptr = &Globals.szPassdbBackend,
1202 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1205 .label = "algorithmic rid base",
1207 .p_class = P_GLOBAL,
1208 .ptr = &Globals.AlgorithmicRidBase,
1211 .flags = FLAG_ADVANCED,
1214 .label = "root directory",
1216 .p_class = P_GLOBAL,
1217 .ptr = &Globals.szRootdir,
1220 .flags = FLAG_ADVANCED,
1223 .label = "root dir",
1225 .p_class = P_GLOBAL,
1226 .ptr = &Globals.szRootdir,
1234 .p_class = P_GLOBAL,
1235 .ptr = &Globals.szRootdir,
1241 .label = "guest account",
1243 .p_class = P_GLOBAL,
1244 .ptr = &Globals.szGuestaccount,
1247 .flags = FLAG_BASIC | FLAG_ADVANCED,
1250 .label = "enable privileges",
1252 .p_class = P_GLOBAL,
1253 .ptr = &Globals.bEnablePrivileges,
1256 .flags = FLAG_ADVANCED,
1260 .label = "pam password change",
1262 .p_class = P_GLOBAL,
1263 .ptr = &Globals.bPamPasswordChange,
1266 .flags = FLAG_ADVANCED,
1269 .label = "passwd program",
1271 .p_class = P_GLOBAL,
1272 .ptr = &Globals.szPasswdProgram,
1275 .flags = FLAG_ADVANCED,
1278 .label = "passwd chat",
1280 .p_class = P_GLOBAL,
1281 .ptr = &Globals.szPasswdChat,
1284 .flags = FLAG_ADVANCED,
1287 .label = "passwd chat debug",
1289 .p_class = P_GLOBAL,
1290 .ptr = &Globals.bPasswdChatDebug,
1293 .flags = FLAG_ADVANCED,
1296 .label = "passwd chat timeout",
1298 .p_class = P_GLOBAL,
1299 .ptr = &Globals.iPasswdChatTimeout,
1302 .flags = FLAG_ADVANCED,
1305 .label = "check password script",
1307 .p_class = P_GLOBAL,
1308 .ptr = &Globals.szCheckPasswordScript,
1311 .flags = FLAG_ADVANCED,
1314 .label = "username map",
1316 .p_class = P_GLOBAL,
1317 .ptr = &Globals.szUsernameMap,
1320 .flags = FLAG_ADVANCED,
1323 .label = "password level",
1325 .p_class = P_GLOBAL,
1326 .ptr = &Globals.pwordlevel,
1329 .flags = FLAG_ADVANCED,
1332 .label = "username level",
1334 .p_class = P_GLOBAL,
1335 .ptr = &Globals.unamelevel,
1338 .flags = FLAG_ADVANCED,
1341 .label = "unix password sync",
1343 .p_class = P_GLOBAL,
1344 .ptr = &Globals.bUnixPasswdSync,
1347 .flags = FLAG_ADVANCED,
1350 .label = "restrict anonymous",
1352 .p_class = P_GLOBAL,
1353 .ptr = &Globals.restrict_anonymous,
1356 .flags = FLAG_ADVANCED,
1359 .label = "lanman auth",
1361 .p_class = P_GLOBAL,
1362 .ptr = &Globals.bLanmanAuth,
1365 .flags = FLAG_ADVANCED,
1368 .label = "ntlm auth",
1370 .p_class = P_GLOBAL,
1371 .ptr = &Globals.bNTLMAuth,
1374 .flags = FLAG_ADVANCED,
1377 .label = "client NTLMv2 auth",
1379 .p_class = P_GLOBAL,
1380 .ptr = &Globals.bClientNTLMv2Auth,
1383 .flags = FLAG_ADVANCED,
1386 .label = "client lanman auth",
1388 .p_class = P_GLOBAL,
1389 .ptr = &Globals.bClientLanManAuth,
1392 .flags = FLAG_ADVANCED,
1395 .label = "client plaintext auth",
1397 .p_class = P_GLOBAL,
1398 .ptr = &Globals.bClientPlaintextAuth,
1401 .flags = FLAG_ADVANCED,
1404 .label = "client use spnego principal",
1406 .p_class = P_GLOBAL,
1407 .ptr = &Globals.client_use_spnego_principal,
1410 .flags = FLAG_ADVANCED,
1413 .label = "send spnego principal",
1415 .p_class = P_GLOBAL,
1416 .ptr = &Globals.send_spnego_principal,
1419 .flags = FLAG_ADVANCED,
1422 .label = "username",
1425 .ptr = &sDefault.szUsername,
1428 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1434 .ptr = &sDefault.szUsername,
1443 .ptr = &sDefault.szUsername,
1449 .label = "invalid users",
1452 .ptr = &sDefault.szInvalidUsers,
1455 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1458 .label = "valid users",
1461 .ptr = &sDefault.szValidUsers,
1464 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1467 .label = "admin users",
1470 .ptr = &sDefault.szAdminUsers,
1473 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1476 .label = "read list",
1479 .ptr = &sDefault.readlist,
1482 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1485 .label = "write list",
1488 .ptr = &sDefault.writelist,
1491 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1494 .label = "printer admin",
1497 .ptr = &sDefault.printer_admin,
1500 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1503 .label = "force user",
1506 .ptr = &sDefault.force_user,
1509 .flags = FLAG_ADVANCED | FLAG_SHARE,
1512 .label = "force group",
1515 .ptr = &sDefault.force_group,
1518 .flags = FLAG_ADVANCED | FLAG_SHARE,
1524 .ptr = &sDefault.force_group,
1527 .flags = FLAG_ADVANCED,
1530 .label = "read only",
1533 .ptr = &sDefault.bRead_only,
1536 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1539 .label = "write ok",
1542 .ptr = &sDefault.bRead_only,
1548 .label = "writeable",
1551 .ptr = &sDefault.bRead_only,
1557 .label = "writable",
1560 .ptr = &sDefault.bRead_only,
1566 .label = "acl check permissions",
1569 .ptr = &sDefault.bAclCheckPermissions,
1572 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1575 .label = "acl group control",
1578 .ptr = &sDefault.bAclGroupControl,
1581 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1584 .label = "acl map full control",
1587 .ptr = &sDefault.bAclMapFullControl,
1590 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1593 .label = "create mask",
1596 .ptr = &sDefault.iCreate_mask,
1599 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1602 .label = "create mode",
1605 .ptr = &sDefault.iCreate_mask,
1611 .label = "force create mode",
1614 .ptr = &sDefault.iCreate_force_mode,
1617 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1620 .label = "security mask",
1623 .ptr = &sDefault.iSecurity_mask,
1626 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1629 .label = "force security mode",
1632 .ptr = &sDefault.iSecurity_force_mode,
1635 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1638 .label = "directory mask",
1641 .ptr = &sDefault.iDir_mask,
1644 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1647 .label = "directory mode",
1650 .ptr = &sDefault.iDir_mask,
1653 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1656 .label = "force directory mode",
1659 .ptr = &sDefault.iDir_force_mode,
1662 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1665 .label = "directory security mask",
1668 .ptr = &sDefault.iDir_Security_mask,
1671 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1674 .label = "force directory security mode",
1677 .ptr = &sDefault.iDir_Security_force_mode,
1680 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1683 .label = "force unknown acl user",
1686 .ptr = &sDefault.bForceUnknownAclUser,
1689 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1692 .label = "inherit permissions",
1695 .ptr = &sDefault.bInheritPerms,
1698 .flags = FLAG_ADVANCED | FLAG_SHARE,
1701 .label = "inherit acls",
1704 .ptr = &sDefault.bInheritACLS,
1707 .flags = FLAG_ADVANCED | FLAG_SHARE,
1710 .label = "inherit owner",
1713 .ptr = &sDefault.bInheritOwner,
1716 .flags = FLAG_ADVANCED | FLAG_SHARE,
1719 .label = "guest only",
1722 .ptr = &sDefault.bGuest_only,
1725 .flags = FLAG_ADVANCED | FLAG_SHARE,
1728 .label = "only guest",
1731 .ptr = &sDefault.bGuest_only,
1737 .label = "administrative share",
1740 .ptr = &sDefault.bAdministrative_share,
1743 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1747 .label = "guest ok",
1750 .ptr = &sDefault.bGuest_ok,
1753 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1759 .ptr = &sDefault.bGuest_ok,
1765 .label = "only user",
1768 .ptr = &sDefault.bOnlyUser,
1771 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1774 .label = "hosts allow",
1777 .ptr = &sDefault.szHostsallow,
1780 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1783 .label = "allow hosts",
1786 .ptr = &sDefault.szHostsallow,
1792 .label = "hosts deny",
1795 .ptr = &sDefault.szHostsdeny,
1798 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1801 .label = "deny hosts",
1804 .ptr = &sDefault.szHostsdeny,
1810 .label = "preload modules",
1812 .p_class = P_GLOBAL,
1813 .ptr = &Globals.szPreloadModules,
1816 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1819 .label = "dedicated keytab file",
1821 .p_class = P_GLOBAL,
1822 .ptr = &Globals.szDedicatedKeytabFile,
1825 .flags = FLAG_ADVANCED,
1828 .label = "kerberos method",
1830 .p_class = P_GLOBAL,
1831 .ptr = &Globals.iKerberosMethod,
1833 .enum_list = enum_kerberos_method,
1834 .flags = FLAG_ADVANCED,
1837 .label = "map untrusted to domain",
1839 .p_class = P_GLOBAL,
1840 .ptr = &Globals.bMapUntrustedToDomain,
1843 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1847 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1850 .label = "log level",
1852 .p_class = P_GLOBAL,
1853 .ptr = &Globals.szLogLevel,
1854 .special = handle_debug_list,
1856 .flags = FLAG_ADVANCED,
1859 .label = "debuglevel",
1861 .p_class = P_GLOBAL,
1862 .ptr = &Globals.szLogLevel,
1863 .special = handle_debug_list,
1870 .p_class = P_GLOBAL,
1871 .ptr = &Globals.syslog,
1874 .flags = FLAG_ADVANCED,
1877 .label = "syslog only",
1879 .p_class = P_GLOBAL,
1880 .ptr = &Globals.bSyslogOnly,
1883 .flags = FLAG_ADVANCED,
1886 .label = "log file",
1888 .p_class = P_GLOBAL,
1889 .ptr = &Globals.szLogFile,
1892 .flags = FLAG_ADVANCED,
1895 .label = "max log size",
1897 .p_class = P_GLOBAL,
1898 .ptr = &Globals.max_log_size,
1901 .flags = FLAG_ADVANCED,
1904 .label = "debug timestamp",
1906 .p_class = P_GLOBAL,
1907 .ptr = &Globals.bTimestampLogs,
1910 .flags = FLAG_ADVANCED,
1913 .label = "timestamp logs",
1915 .p_class = P_GLOBAL,
1916 .ptr = &Globals.bTimestampLogs,
1919 .flags = FLAG_ADVANCED,
1922 .label = "debug prefix timestamp",
1924 .p_class = P_GLOBAL,
1925 .ptr = &Globals.bDebugPrefixTimestamp,
1928 .flags = FLAG_ADVANCED,
1931 .label = "debug hires timestamp",
1933 .p_class = P_GLOBAL,
1934 .ptr = &Globals.bDebugHiresTimestamp,
1937 .flags = FLAG_ADVANCED,
1940 .label = "debug pid",
1942 .p_class = P_GLOBAL,
1943 .ptr = &Globals.bDebugPid,
1946 .flags = FLAG_ADVANCED,
1949 .label = "debug uid",
1951 .p_class = P_GLOBAL,
1952 .ptr = &Globals.bDebugUid,
1955 .flags = FLAG_ADVANCED,
1958 .label = "debug class",
1960 .p_class = P_GLOBAL,
1961 .ptr = &Globals.bDebugClass,
1964 .flags = FLAG_ADVANCED,
1967 .label = "enable core files",
1969 .p_class = P_GLOBAL,
1970 .ptr = &Globals.bEnableCoreFiles,
1973 .flags = FLAG_ADVANCED,
1976 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1979 .label = "allocation roundup size",
1982 .ptr = &sDefault.iallocation_roundup_size,
1985 .flags = FLAG_ADVANCED,
1988 .label = "aio read size",
1991 .ptr = &sDefault.iAioReadSize,
1994 .flags = FLAG_ADVANCED,
1997 .label = "aio write size",
2000 .ptr = &sDefault.iAioWriteSize,
2003 .flags = FLAG_ADVANCED,
2006 .label = "aio write behind",
2009 .ptr = &sDefault.szAioWriteBehind,
2012 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2015 .label = "smb ports",
2017 .p_class = P_GLOBAL,
2018 .ptr = &Globals.smb_ports,
2021 .flags = FLAG_ADVANCED,
2024 .label = "large readwrite",
2026 .p_class = P_GLOBAL,
2027 .ptr = &Globals.bLargeReadwrite,
2030 .flags = FLAG_ADVANCED,
2033 .label = "max protocol",
2035 .p_class = P_GLOBAL,
2036 .ptr = &Globals.maxprotocol,
2038 .enum_list = enum_protocol,
2039 .flags = FLAG_ADVANCED,
2042 .label = "protocol",
2044 .p_class = P_GLOBAL,
2045 .ptr = &Globals.maxprotocol,
2047 .enum_list = enum_protocol,
2048 .flags = FLAG_ADVANCED,
2051 .label = "min protocol",
2053 .p_class = P_GLOBAL,
2054 .ptr = &Globals.minprotocol,
2056 .enum_list = enum_protocol,
2057 .flags = FLAG_ADVANCED,
2060 .label = "min receivefile size",
2062 .p_class = P_GLOBAL,
2063 .ptr = &Globals.iminreceivefile,
2066 .flags = FLAG_ADVANCED,
2069 .label = "read raw",
2071 .p_class = P_GLOBAL,
2072 .ptr = &Globals.bReadRaw,
2075 .flags = FLAG_ADVANCED,
2078 .label = "write raw",
2080 .p_class = P_GLOBAL,
2081 .ptr = &Globals.bWriteRaw,
2084 .flags = FLAG_ADVANCED,
2087 .label = "disable netbios",
2089 .p_class = P_GLOBAL,
2090 .ptr = &Globals.bDisableNetbios,
2093 .flags = FLAG_ADVANCED,
2096 .label = "reset on zero vc",
2098 .p_class = P_GLOBAL,
2099 .ptr = &Globals.bResetOnZeroVC,
2102 .flags = FLAG_ADVANCED,
2105 .label = "log writeable files on exit",
2107 .p_class = P_GLOBAL,
2108 .ptr = &Globals.bLogWriteableFilesOnExit,
2111 .flags = FLAG_ADVANCED,
2114 .label = "acl compatibility",
2116 .p_class = P_GLOBAL,
2117 .ptr = &Globals.iAclCompat,
2119 .enum_list = enum_acl_compat_vals,
2120 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2123 .label = "defer sharing violations",
2125 .p_class = P_GLOBAL,
2126 .ptr = &Globals.bDeferSharingViolations,
2129 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2132 .label = "ea support",
2135 .ptr = &sDefault.bEASupport,
2138 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2141 .label = "nt acl support",
2144 .ptr = &sDefault.bNTAclSupport,
2147 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2150 .label = "nt pipe support",
2152 .p_class = P_GLOBAL,
2153 .ptr = &Globals.bNTPipeSupport,
2156 .flags = FLAG_ADVANCED,
2159 .label = "nt status support",
2161 .p_class = P_GLOBAL,
2162 .ptr = &Globals.bNTStatusSupport,
2165 .flags = FLAG_ADVANCED,
2168 .label = "profile acls",
2171 .ptr = &sDefault.bProfileAcls,
2174 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2177 .label = "announce version",
2179 .p_class = P_GLOBAL,
2180 .ptr = &Globals.szAnnounceVersion,
2183 .flags = FLAG_ADVANCED,
2186 .label = "announce as",
2188 .p_class = P_GLOBAL,
2189 .ptr = &Globals.announce_as,
2191 .enum_list = enum_announce_as,
2192 .flags = FLAG_ADVANCED,
2195 .label = "map acl inherit",
2198 .ptr = &sDefault.bMap_acl_inherit,
2201 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2204 .label = "afs share",
2207 .ptr = &sDefault.bAfs_Share,
2210 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2215 .p_class = P_GLOBAL,
2216 .ptr = &Globals.max_mux,
2219 .flags = FLAG_ADVANCED,
2222 .label = "max xmit",
2224 .p_class = P_GLOBAL,
2225 .ptr = &Globals.max_xmit,
2228 .flags = FLAG_ADVANCED,
2231 .label = "name resolve order",
2233 .p_class = P_GLOBAL,
2234 .ptr = &Globals.szNameResolveOrder,
2237 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2242 .p_class = P_GLOBAL,
2243 .ptr = &Globals.max_ttl,
2246 .flags = FLAG_ADVANCED,
2249 .label = "max wins ttl",
2251 .p_class = P_GLOBAL,
2252 .ptr = &Globals.max_wins_ttl,
2255 .flags = FLAG_ADVANCED,
2258 .label = "min wins ttl",
2260 .p_class = P_GLOBAL,
2261 .ptr = &Globals.min_wins_ttl,
2264 .flags = FLAG_ADVANCED,
2267 .label = "time server",
2269 .p_class = P_GLOBAL,
2270 .ptr = &Globals.bTimeServer,
2273 .flags = FLAG_ADVANCED,
2276 .label = "unix extensions",
2278 .p_class = P_GLOBAL,
2279 .ptr = &Globals.bUnixExtensions,
2282 .flags = FLAG_ADVANCED,
2285 .label = "use spnego",
2287 .p_class = P_GLOBAL,
2288 .ptr = &Globals.bUseSpnego,
2291 .flags = FLAG_ADVANCED,
2294 .label = "client signing",
2296 .p_class = P_GLOBAL,
2297 .ptr = &Globals.client_signing,
2299 .enum_list = enum_smb_signing_vals,
2300 .flags = FLAG_ADVANCED,
2303 .label = "server signing",
2305 .p_class = P_GLOBAL,
2306 .ptr = &Globals.server_signing,
2308 .enum_list = enum_smb_signing_vals,
2309 .flags = FLAG_ADVANCED,
2312 .label = "smb encrypt",
2315 .ptr = &sDefault.ismb_encrypt,
2317 .enum_list = enum_smb_signing_vals,
2318 .flags = FLAG_ADVANCED,
2321 .label = "client use spnego",
2323 .p_class = P_GLOBAL,
2324 .ptr = &Globals.bClientUseSpnego,
2327 .flags = FLAG_ADVANCED,
2330 .label = "client ldap sasl wrapping",
2332 .p_class = P_GLOBAL,
2333 .ptr = &Globals.client_ldap_sasl_wrapping,
2335 .enum_list = enum_ldap_sasl_wrapping,
2336 .flags = FLAG_ADVANCED,
2339 .label = "enable asu support",
2341 .p_class = P_GLOBAL,
2342 .ptr = &Globals.bASUSupport,
2345 .flags = FLAG_ADVANCED,
2348 .label = "svcctl list",
2350 .p_class = P_GLOBAL,
2351 .ptr = &Globals.szServicesList,
2354 .flags = FLAG_ADVANCED,
2357 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2360 .label = "block size",
2363 .ptr = &sDefault.iBlock_size,
2366 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2369 .label = "deadtime",
2371 .p_class = P_GLOBAL,
2372 .ptr = &Globals.deadtime,
2375 .flags = FLAG_ADVANCED,
2378 .label = "getwd cache",
2380 .p_class = P_GLOBAL,
2381 .ptr = &Globals.getwd_cache,
2384 .flags = FLAG_ADVANCED,
2387 .label = "keepalive",
2389 .p_class = P_GLOBAL,
2390 .ptr = &Globals.iKeepalive,
2393 .flags = FLAG_ADVANCED,
2396 .label = "change notify",
2399 .ptr = &sDefault.bChangeNotify,
2402 .flags = FLAG_ADVANCED | FLAG_SHARE,
2405 .label = "directory name cache size",
2408 .ptr = &sDefault.iDirectoryNameCacheSize,
2411 .flags = FLAG_ADVANCED | FLAG_SHARE,
2414 .label = "kernel change notify",
2417 .ptr = &sDefault.bKernelChangeNotify,
2420 .flags = FLAG_ADVANCED | FLAG_SHARE,
2423 .label = "lpq cache time",
2425 .p_class = P_GLOBAL,
2426 .ptr = &Globals.lpqcachetime,
2429 .flags = FLAG_ADVANCED,
2432 .label = "max smbd processes",
2434 .p_class = P_GLOBAL,
2435 .ptr = &Globals.iMaxSmbdProcesses,
2438 .flags = FLAG_ADVANCED,
2441 .label = "max connections",
2444 .ptr = &sDefault.iMaxConnections,
2447 .flags = FLAG_ADVANCED | FLAG_SHARE,
2450 .label = "paranoid server security",
2452 .p_class = P_GLOBAL,
2453 .ptr = &Globals.paranoid_server_security,
2456 .flags = FLAG_ADVANCED,
2459 .label = "max disk size",
2461 .p_class = P_GLOBAL,
2462 .ptr = &Globals.maxdisksize,
2465 .flags = FLAG_ADVANCED,
2468 .label = "max open files",
2470 .p_class = P_GLOBAL,
2471 .ptr = &Globals.max_open_files,
2474 .flags = FLAG_ADVANCED,
2477 .label = "min print space",
2480 .ptr = &sDefault.iMinPrintSpace,
2483 .flags = FLAG_ADVANCED | FLAG_PRINT,
2486 .label = "socket options",
2488 .p_class = P_GLOBAL,
2489 .ptr = &Globals.szSocketOptions,
2492 .flags = FLAG_ADVANCED,
2495 .label = "strict allocate",
2498 .ptr = &sDefault.bStrictAllocate,
2501 .flags = FLAG_ADVANCED | FLAG_SHARE,
2504 .label = "strict sync",
2507 .ptr = &sDefault.bStrictSync,
2510 .flags = FLAG_ADVANCED | FLAG_SHARE,
2513 .label = "sync always",
2516 .ptr = &sDefault.bSyncAlways,
2519 .flags = FLAG_ADVANCED | FLAG_SHARE,
2522 .label = "use mmap",
2524 .p_class = P_GLOBAL,
2525 .ptr = &Globals.bUseMmap,
2528 .flags = FLAG_ADVANCED,
2531 .label = "use sendfile",
2534 .ptr = &sDefault.bUseSendfile,
2537 .flags = FLAG_ADVANCED | FLAG_SHARE,
2540 .label = "hostname lookups",
2542 .p_class = P_GLOBAL,
2543 .ptr = &Globals.bHostnameLookups,
2546 .flags = FLAG_ADVANCED,
2549 .label = "write cache size",
2552 .ptr = &sDefault.iWriteCacheSize,
2555 .flags = FLAG_ADVANCED | FLAG_SHARE,
2558 .label = "name cache timeout",
2560 .p_class = P_GLOBAL,
2561 .ptr = &Globals.name_cache_timeout,
2564 .flags = FLAG_ADVANCED,
2567 .label = "ctdbd socket",
2569 .p_class = P_GLOBAL,
2570 .ptr = &Globals.ctdbdSocket,
2573 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2576 .label = "cluster addresses",
2578 .p_class = P_GLOBAL,
2579 .ptr = &Globals.szClusterAddresses,
2582 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2585 .label = "clustering",
2587 .p_class = P_GLOBAL,
2588 .ptr = &Globals.clustering,
2591 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2594 .label = "ctdb timeout",
2596 .p_class = P_GLOBAL,
2597 .ptr = &Globals.ctdb_timeout,
2600 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2603 .label = "ctdb locktime warn threshold",
2605 .p_class = P_GLOBAL,
2606 .ptr = &Globals.ctdb_locktime_warn_threshold,
2609 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2612 .label = "smb2 max read",
2614 .p_class = P_GLOBAL,
2615 .ptr = &Globals.ismb2_max_read,
2618 .flags = FLAG_ADVANCED,
2621 .label = "smb2 max write",
2623 .p_class = P_GLOBAL,
2624 .ptr = &Globals.ismb2_max_write,
2627 .flags = FLAG_ADVANCED,
2630 .label = "smb2 max trans",
2632 .p_class = P_GLOBAL,
2633 .ptr = &Globals.ismb2_max_trans,
2636 .flags = FLAG_ADVANCED,
2639 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2642 .label = "max reported print jobs",
2645 .ptr = &sDefault.iMaxReportedPrintJobs,
2648 .flags = FLAG_ADVANCED | FLAG_PRINT,
2651 .label = "max print jobs",
2654 .ptr = &sDefault.iMaxPrintJobs,
2657 .flags = FLAG_ADVANCED | FLAG_PRINT,
2660 .label = "load printers",
2662 .p_class = P_GLOBAL,
2663 .ptr = &Globals.bLoadPrinters,
2666 .flags = FLAG_ADVANCED | FLAG_PRINT,
2669 .label = "printcap cache time",
2671 .p_class = P_GLOBAL,
2672 .ptr = &Globals.PrintcapCacheTime,
2675 .flags = FLAG_ADVANCED | FLAG_PRINT,
2678 .label = "printcap name",
2680 .p_class = P_GLOBAL,
2681 .ptr = &Globals.szPrintcapname,
2684 .flags = FLAG_ADVANCED | FLAG_PRINT,
2687 .label = "printcap",
2689 .p_class = P_GLOBAL,
2690 .ptr = &Globals.szPrintcapname,
2696 .label = "printable",
2699 .ptr = &sDefault.bPrint_ok,
2702 .flags = FLAG_ADVANCED | FLAG_PRINT,
2705 .label = "print ok",
2708 .ptr = &sDefault.bPrint_ok,
2714 .label = "printing",
2717 .ptr = &sDefault.iPrinting,
2718 .special = handle_printing,
2719 .enum_list = enum_printing,
2720 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2723 .label = "cups options",
2726 .ptr = &sDefault.szCupsOptions,
2729 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2732 .label = "cups server",
2734 .p_class = P_GLOBAL,
2735 .ptr = &Globals.szCupsServer,
2738 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2741 .label = "cups encrypt",
2743 .p_class = P_GLOBAL,
2744 .ptr = &Globals.CupsEncrypt,
2746 .enum_list = enum_bool_auto,
2747 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2751 .label = "cups connection timeout",
2753 .p_class = P_GLOBAL,
2754 .ptr = &Globals.cups_connection_timeout,
2757 .flags = FLAG_ADVANCED,
2760 .label = "iprint server",
2762 .p_class = P_GLOBAL,
2763 .ptr = &Globals.szIPrintServer,
2766 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2769 .label = "print command",
2772 .ptr = &sDefault.szPrintcommand,
2775 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2778 .label = "disable spoolss",
2780 .p_class = P_GLOBAL,
2781 .ptr = &Globals.bDisableSpoolss,
2784 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2787 .label = "enable spoolss",
2789 .p_class = P_GLOBAL,
2790 .ptr = &Globals.bDisableSpoolss,
2796 .label = "lpq command",
2799 .ptr = &sDefault.szLpqcommand,
2802 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2805 .label = "lprm command",
2808 .ptr = &sDefault.szLprmcommand,
2811 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2814 .label = "lppause command",
2817 .ptr = &sDefault.szLppausecommand,
2820 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2823 .label = "lpresume command",
2826 .ptr = &sDefault.szLpresumecommand,
2829 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2832 .label = "queuepause command",
2835 .ptr = &sDefault.szQueuepausecommand,
2838 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2841 .label = "queueresume command",
2844 .ptr = &sDefault.szQueueresumecommand,
2847 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2850 .label = "addport command",
2852 .p_class = P_GLOBAL,
2853 .ptr = &Globals.szAddPortCommand,
2856 .flags = FLAG_ADVANCED,
2859 .label = "enumports command",
2861 .p_class = P_GLOBAL,
2862 .ptr = &Globals.szEnumPortsCommand,
2865 .flags = FLAG_ADVANCED,
2868 .label = "addprinter command",
2870 .p_class = P_GLOBAL,
2871 .ptr = &Globals.szAddPrinterCommand,
2874 .flags = FLAG_ADVANCED,
2877 .label = "deleteprinter command",
2879 .p_class = P_GLOBAL,
2880 .ptr = &Globals.szDeletePrinterCommand,
2883 .flags = FLAG_ADVANCED,
2886 .label = "show add printer wizard",
2888 .p_class = P_GLOBAL,
2889 .ptr = &Globals.bMsAddPrinterWizard,
2892 .flags = FLAG_ADVANCED,
2895 .label = "os2 driver map",
2897 .p_class = P_GLOBAL,
2898 .ptr = &Globals.szOs2DriverMap,
2901 .flags = FLAG_ADVANCED,
2905 .label = "printer name",
2908 .ptr = &sDefault.szPrintername,
2911 .flags = FLAG_ADVANCED | FLAG_PRINT,
2917 .ptr = &sDefault.szPrintername,
2923 .label = "use client driver",
2926 .ptr = &sDefault.bUseClientDriver,
2929 .flags = FLAG_ADVANCED | FLAG_PRINT,
2932 .label = "default devmode",
2935 .ptr = &sDefault.bDefaultDevmode,
2938 .flags = FLAG_ADVANCED | FLAG_PRINT,
2941 .label = "force printername",
2944 .ptr = &sDefault.bForcePrintername,
2947 .flags = FLAG_ADVANCED | FLAG_PRINT,
2950 .label = "printjob username",
2953 .ptr = &sDefault.szPrintjobUsername,
2956 .flags = FLAG_ADVANCED | FLAG_PRINT,
2959 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2962 .label = "mangling method",
2964 .p_class = P_GLOBAL,
2965 .ptr = &Globals.szManglingMethod,
2968 .flags = FLAG_ADVANCED,
2971 .label = "mangle prefix",
2973 .p_class = P_GLOBAL,
2974 .ptr = &Globals.mangle_prefix,
2977 .flags = FLAG_ADVANCED,
2981 .label = "default case",
2984 .ptr = &sDefault.iDefaultCase,
2986 .enum_list = enum_case,
2987 .flags = FLAG_ADVANCED | FLAG_SHARE,
2990 .label = "case sensitive",
2993 .ptr = &sDefault.iCaseSensitive,
2995 .enum_list = enum_bool_auto,
2996 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2999 .label = "casesignames",
3002 .ptr = &sDefault.iCaseSensitive,
3004 .enum_list = enum_bool_auto,
3005 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
3008 .label = "preserve case",
3011 .ptr = &sDefault.bCasePreserve,
3014 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3017 .label = "short preserve case",
3020 .ptr = &sDefault.bShortCasePreserve,
3023 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3026 .label = "mangling char",
3029 .ptr = &sDefault.magic_char,
3032 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3035 .label = "hide dot files",
3038 .ptr = &sDefault.bHideDotFiles,
3041 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3044 .label = "hide special files",
3047 .ptr = &sDefault.bHideSpecialFiles,
3050 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3053 .label = "hide unreadable",
3056 .ptr = &sDefault.bHideUnReadable,
3059 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3062 .label = "hide unwriteable files",
3065 .ptr = &sDefault.bHideUnWriteableFiles,
3068 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3071 .label = "delete veto files",
3074 .ptr = &sDefault.bDeleteVetoFiles,
3077 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3080 .label = "veto files",
3083 .ptr = &sDefault.szVetoFiles,
3086 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3089 .label = "hide files",
3092 .ptr = &sDefault.szHideFiles,
3095 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3098 .label = "veto oplock files",
3101 .ptr = &sDefault.szVetoOplockFiles,
3104 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3107 .label = "map archive",
3110 .ptr = &sDefault.bMap_archive,
3113 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3116 .label = "map hidden",
3119 .ptr = &sDefault.bMap_hidden,
3122 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3125 .label = "map system",
3128 .ptr = &sDefault.bMap_system,
3131 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3134 .label = "map readonly",
3137 .ptr = &sDefault.iMap_readonly,
3139 .enum_list = enum_map_readonly,
3140 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3143 .label = "mangled names",
3146 .ptr = &sDefault.bMangledNames,
3149 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3152 .label = "max stat cache size",
3154 .p_class = P_GLOBAL,
3155 .ptr = &Globals.iMaxStatCacheSize,
3158 .flags = FLAG_ADVANCED,
3161 .label = "stat cache",
3163 .p_class = P_GLOBAL,
3164 .ptr = &Globals.bStatCache,
3167 .flags = FLAG_ADVANCED,
3170 .label = "store dos attributes",
3173 .ptr = &sDefault.bStoreDosAttributes,
3176 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3179 .label = "dmapi support",
3182 .ptr = &sDefault.bDmapiSupport,
3185 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3189 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3192 .label = "machine password timeout",
3194 .p_class = P_GLOBAL,
3195 .ptr = &Globals.machine_password_timeout,
3198 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3201 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3204 .label = "add user script",
3206 .p_class = P_GLOBAL,
3207 .ptr = &Globals.szAddUserScript,
3210 .flags = FLAG_ADVANCED,
3213 .label = "rename user script",
3215 .p_class = P_GLOBAL,
3216 .ptr = &Globals.szRenameUserScript,
3219 .flags = FLAG_ADVANCED,
3222 .label = "delete user script",
3224 .p_class = P_GLOBAL,
3225 .ptr = &Globals.szDelUserScript,
3228 .flags = FLAG_ADVANCED,
3231 .label = "add group script",
3233 .p_class = P_GLOBAL,
3234 .ptr = &Globals.szAddGroupScript,
3237 .flags = FLAG_ADVANCED,
3240 .label = "delete group script",
3242 .p_class = P_GLOBAL,
3243 .ptr = &Globals.szDelGroupScript,
3246 .flags = FLAG_ADVANCED,
3249 .label = "add user to group script",
3251 .p_class = P_GLOBAL,
3252 .ptr = &Globals.szAddUserToGroupScript,
3255 .flags = FLAG_ADVANCED,
3258 .label = "delete user from group script",
3260 .p_class = P_GLOBAL,
3261 .ptr = &Globals.szDelUserFromGroupScript,
3264 .flags = FLAG_ADVANCED,
3267 .label = "set primary group script",
3269 .p_class = P_GLOBAL,
3270 .ptr = &Globals.szSetPrimaryGroupScript,
3273 .flags = FLAG_ADVANCED,
3276 .label = "add machine script",
3278 .p_class = P_GLOBAL,
3279 .ptr = &Globals.szAddMachineScript,
3282 .flags = FLAG_ADVANCED,
3285 .label = "shutdown script",
3287 .p_class = P_GLOBAL,
3288 .ptr = &Globals.szShutdownScript,
3291 .flags = FLAG_ADVANCED,
3294 .label = "abort shutdown script",
3296 .p_class = P_GLOBAL,
3297 .ptr = &Globals.szAbortShutdownScript,
3300 .flags = FLAG_ADVANCED,
3303 .label = "username map script",
3305 .p_class = P_GLOBAL,
3306 .ptr = &Globals.szUsernameMapScript,
3309 .flags = FLAG_ADVANCED,
3312 .label = "username map cache time",
3314 .p_class = P_GLOBAL,
3315 .ptr = &Globals.iUsernameMapCacheTime,
3318 .flags = FLAG_ADVANCED,
3321 .label = "logon script",
3323 .p_class = P_GLOBAL,
3324 .ptr = &Globals.szLogonScript,
3327 .flags = FLAG_ADVANCED,
3330 .label = "logon path",
3332 .p_class = P_GLOBAL,
3333 .ptr = &Globals.szLogonPath,
3336 .flags = FLAG_ADVANCED,
3339 .label = "logon drive",
3341 .p_class = P_GLOBAL,
3342 .ptr = &Globals.szLogonDrive,
3345 .flags = FLAG_ADVANCED,
3348 .label = "logon home",
3350 .p_class = P_GLOBAL,
3351 .ptr = &Globals.szLogonHome,
3354 .flags = FLAG_ADVANCED,
3357 .label = "domain logons",
3359 .p_class = P_GLOBAL,
3360 .ptr = &Globals.bDomainLogons,
3363 .flags = FLAG_ADVANCED,
3367 .label = "init logon delayed hosts",
3369 .p_class = P_GLOBAL,
3370 .ptr = &Globals.szInitLogonDelayedHosts,
3373 .flags = FLAG_ADVANCED,
3377 .label = "init logon delay",
3379 .p_class = P_GLOBAL,
3380 .ptr = &Globals.InitLogonDelay,
3383 .flags = FLAG_ADVANCED,
3387 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3390 .label = "os level",
3392 .p_class = P_GLOBAL,
3393 .ptr = &Globals.os_level,
3396 .flags = FLAG_BASIC | FLAG_ADVANCED,
3399 .label = "lm announce",
3401 .p_class = P_GLOBAL,
3402 .ptr = &Globals.lm_announce,
3404 .enum_list = enum_bool_auto,
3405 .flags = FLAG_ADVANCED,
3408 .label = "lm interval",
3410 .p_class = P_GLOBAL,
3411 .ptr = &Globals.lm_interval,
3414 .flags = FLAG_ADVANCED,
3417 .label = "preferred master",
3419 .p_class = P_GLOBAL,
3420 .ptr = &Globals.iPreferredMaster,
3422 .enum_list = enum_bool_auto,
3423 .flags = FLAG_BASIC | FLAG_ADVANCED,
3426 .label = "prefered master",
3428 .p_class = P_GLOBAL,
3429 .ptr = &Globals.iPreferredMaster,
3431 .enum_list = enum_bool_auto,
3435 .label = "local master",
3437 .p_class = P_GLOBAL,
3438 .ptr = &Globals.bLocalMaster,
3441 .flags = FLAG_BASIC | FLAG_ADVANCED,
3444 .label = "domain master",
3446 .p_class = P_GLOBAL,
3447 .ptr = &Globals.iDomainMaster,
3449 .enum_list = enum_bool_auto,
3450 .flags = FLAG_BASIC | FLAG_ADVANCED,
3453 .label = "browse list",
3455 .p_class = P_GLOBAL,
3456 .ptr = &Globals.bBrowseList,
3459 .flags = FLAG_ADVANCED,
3462 .label = "browseable",
3465 .ptr = &sDefault.bBrowseable,
3468 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3471 .label = "browsable",
3474 .ptr = &sDefault.bBrowseable,
3480 .label = "access based share enum",
3483 .ptr = &sDefault.bAccessBasedShareEnum,
3486 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3489 .label = "enhanced browsing",
3491 .p_class = P_GLOBAL,
3492 .ptr = &Globals.enhanced_browsing,
3495 .flags = FLAG_ADVANCED,
3498 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3501 .label = "dns proxy",
3503 .p_class = P_GLOBAL,
3504 .ptr = &Globals.bDNSproxy,
3507 .flags = FLAG_ADVANCED,
3510 .label = "wins proxy",
3512 .p_class = P_GLOBAL,
3513 .ptr = &Globals.bWINSproxy,
3516 .flags = FLAG_ADVANCED,
3519 .label = "wins server",
3521 .p_class = P_GLOBAL,
3522 .ptr = &Globals.szWINSservers,
3525 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3528 .label = "wins support",
3530 .p_class = P_GLOBAL,
3531 .ptr = &Globals.bWINSsupport,
3534 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3537 .label = "wins hook",
3539 .p_class = P_GLOBAL,
3540 .ptr = &Globals.szWINSHook,
3543 .flags = FLAG_ADVANCED,
3546 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3549 .label = "blocking locks",
3552 .ptr = &sDefault.bBlockingLocks,
3555 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3558 .label = "csc policy",
3561 .ptr = &sDefault.iCSCPolicy,
3563 .enum_list = enum_csc_policy,
3564 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3567 .label = "fake oplocks",
3570 .ptr = &sDefault.bFakeOplocks,
3573 .flags = FLAG_ADVANCED | FLAG_SHARE,
3576 .label = "kernel oplocks",
3578 .p_class = P_GLOBAL,
3579 .ptr = &Globals.bKernelOplocks,
3582 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3588 .ptr = &sDefault.bLocking,
3591 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3594 .label = "lock spin time",
3596 .p_class = P_GLOBAL,
3597 .ptr = &Globals.iLockSpinTime,
3600 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3606 .ptr = &sDefault.bOpLocks,
3609 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3612 .label = "level2 oplocks",
3615 .ptr = &sDefault.bLevel2OpLocks,
3618 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3621 .label = "oplock break wait time",
3623 .p_class = P_GLOBAL,
3624 .ptr = &Globals.oplock_break_wait_time,
3627 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3630 .label = "oplock contention limit",
3633 .ptr = &sDefault.iOplockContentionLimit,
3636 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3639 .label = "posix locking",
3642 .ptr = &sDefault.bPosixLocking,
3645 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3648 .label = "strict locking",
3651 .ptr = &sDefault.iStrictLocking,
3653 .enum_list = enum_bool_auto,
3654 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3657 .label = "share modes",
3660 .ptr = &sDefault.bShareModes,
3663 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3666 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3669 .label = "ldap admin dn",
3671 .p_class = P_GLOBAL,
3672 .ptr = &Globals.szLdapAdminDn,
3675 .flags = FLAG_ADVANCED,
3678 .label = "ldap delete dn",
3680 .p_class = P_GLOBAL,
3681 .ptr = &Globals.ldap_delete_dn,
3684 .flags = FLAG_ADVANCED,
3687 .label = "ldap group suffix",
3689 .p_class = P_GLOBAL,
3690 .ptr = &Globals.szLdapGroupSuffix,
3693 .flags = FLAG_ADVANCED,
3696 .label = "ldap idmap suffix",
3698 .p_class = P_GLOBAL,
3699 .ptr = &Globals.szLdapIdmapSuffix,
3702 .flags = FLAG_ADVANCED,
3705 .label = "ldap machine suffix",
3707 .p_class = P_GLOBAL,
3708 .ptr = &Globals.szLdapMachineSuffix,
3711 .flags = FLAG_ADVANCED,
3714 .label = "ldap passwd sync",
3716 .p_class = P_GLOBAL,
3717 .ptr = &Globals.ldap_passwd_sync,
3719 .enum_list = enum_ldap_passwd_sync,
3720 .flags = FLAG_ADVANCED,
3723 .label = "ldap password sync",
3725 .p_class = P_GLOBAL,
3726 .ptr = &Globals.ldap_passwd_sync,
3728 .enum_list = enum_ldap_passwd_sync,
3732 .label = "ldap replication sleep",
3734 .p_class = P_GLOBAL,
3735 .ptr = &Globals.ldap_replication_sleep,
3738 .flags = FLAG_ADVANCED,
3741 .label = "ldap suffix",
3743 .p_class = P_GLOBAL,
3744 .ptr = &Globals.szLdapSuffix,
3747 .flags = FLAG_ADVANCED,
3750 .label = "ldap ssl",
3752 .p_class = P_GLOBAL,
3753 .ptr = &Globals.ldap_ssl,
3755 .enum_list = enum_ldap_ssl,
3756 .flags = FLAG_ADVANCED,
3759 .label = "ldap ssl ads",
3761 .p_class = P_GLOBAL,
3762 .ptr = &Globals.ldap_ssl_ads,
3765 .flags = FLAG_ADVANCED,
3768 .label = "ldap deref",
3770 .p_class = P_GLOBAL,
3771 .ptr = &Globals.ldap_deref,
3773 .enum_list = enum_ldap_deref,
3774 .flags = FLAG_ADVANCED,
3777 .label = "ldap follow referral",
3779 .p_class = P_GLOBAL,
3780 .ptr = &Globals.ldap_follow_referral,
3782 .enum_list = enum_bool_auto,
3783 .flags = FLAG_ADVANCED,
3786 .label = "ldap timeout",
3788 .p_class = P_GLOBAL,
3789 .ptr = &Globals.ldap_timeout,
3792 .flags = FLAG_ADVANCED,
3795 .label = "ldap connection timeout",
3797 .p_class = P_GLOBAL,
3798 .ptr = &Globals.ldap_connection_timeout,
3801 .flags = FLAG_ADVANCED,
3804 .label = "ldap page size",
3806 .p_class = P_GLOBAL,
3807 .ptr = &Globals.ldap_page_size,
3810 .flags = FLAG_ADVANCED,
3813 .label = "ldap user suffix",
3815 .p_class = P_GLOBAL,
3816 .ptr = &Globals.szLdapUserSuffix,
3819 .flags = FLAG_ADVANCED,
3822 .label = "ldap debug level",
3824 .p_class = P_GLOBAL,
3825 .ptr = &Globals.ldap_debug_level,
3826 .special = handle_ldap_debug_level,
3828 .flags = FLAG_ADVANCED,
3831 .label = "ldap debug threshold",
3833 .p_class = P_GLOBAL,
3834 .ptr = &Globals.ldap_debug_threshold,
3837 .flags = FLAG_ADVANCED,
3840 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3843 .label = "eventlog list",
3845 .p_class = P_GLOBAL,
3846 .ptr = &Globals.szEventLogs,
3849 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3852 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3855 .label = "add share command",
3857 .p_class = P_GLOBAL,
3858 .ptr = &Globals.szAddShareCommand,
3861 .flags = FLAG_ADVANCED,
3864 .label = "change share command",
3866 .p_class = P_GLOBAL,
3867 .ptr = &Globals.szChangeShareCommand,
3870 .flags = FLAG_ADVANCED,
3873 .label = "delete share command",
3875 .p_class = P_GLOBAL,
3876 .ptr = &Globals.szDeleteShareCommand,
3879 .flags = FLAG_ADVANCED,
3882 .label = "config file",
3884 .p_class = P_GLOBAL,
3885 .ptr = &Globals.szConfigFile,
3888 .flags = FLAG_HIDE|FLAG_META,
3893 .p_class = P_GLOBAL,
3894 .ptr = &Globals.szAutoServices,
3897 .flags = FLAG_ADVANCED,
3900 .label = "auto services",
3902 .p_class = P_GLOBAL,
3903 .ptr = &Globals.szAutoServices,
3906 .flags = FLAG_ADVANCED,
3909 .label = "lock directory",
3911 .p_class = P_GLOBAL,
3912 .ptr = &Globals.szLockDir,
3915 .flags = FLAG_ADVANCED,
3918 .label = "lock dir",
3920 .p_class = P_GLOBAL,
3921 .ptr = &Globals.szLockDir,
3927 .label = "state directory",
3929 .p_class = P_GLOBAL,
3930 .ptr = &Globals.szStateDir,
3933 .flags = FLAG_ADVANCED,
3936 .label = "cache directory",
3938 .p_class = P_GLOBAL,
3939 .ptr = &Globals.szCacheDir,
3942 .flags = FLAG_ADVANCED,
3945 .label = "pid directory",
3947 .p_class = P_GLOBAL,
3948 .ptr = &Globals.szPidDir,
3951 .flags = FLAG_ADVANCED,
3955 .label = "utmp directory",
3957 .p_class = P_GLOBAL,
3958 .ptr = &Globals.szUtmpDir,
3961 .flags = FLAG_ADVANCED,
3964 .label = "wtmp directory",
3966 .p_class = P_GLOBAL,
3967 .ptr = &Globals.szWtmpDir,
3970 .flags = FLAG_ADVANCED,
3975 .p_class = P_GLOBAL,
3976 .ptr = &Globals.bUtmp,
3979 .flags = FLAG_ADVANCED,
3983 .label = "default service",
3985 .p_class = P_GLOBAL,
3986 .ptr = &Globals.szDefaultService,
3989 .flags = FLAG_ADVANCED,
3994 .p_class = P_GLOBAL,
3995 .ptr = &Globals.szDefaultService,
3998 .flags = FLAG_ADVANCED,
4001 .label = "message command",
4003 .p_class = P_GLOBAL,
4004 .ptr = &Globals.szMsgCommand,
4007 .flags = FLAG_ADVANCED,
4010 .label = "dfree cache time",
4013 .ptr = &sDefault.iDfreeCacheTime,
4016 .flags = FLAG_ADVANCED,
4019 .label = "dfree command",
4022 .ptr = &sDefault.szDfree,
4025 .flags = FLAG_ADVANCED,
4028 .label = "get quota command",
4030 .p_class = P_GLOBAL,
4031 .ptr = &Globals.szGetQuota,
4034 .flags = FLAG_ADVANCED,
4037 .label = "set quota command",
4039 .p_class = P_GLOBAL,
4040 .ptr = &Globals.szSetQuota,
4043 .flags = FLAG_ADVANCED,
4046 .label = "remote announce",
4048 .p_class = P_GLOBAL,
4049 .ptr = &Globals.szRemoteAnnounce,
4052 .flags = FLAG_ADVANCED,
4055 .label = "remote browse sync",
4057 .p_class = P_GLOBAL,
4058 .ptr = &Globals.szRemoteBrowseSync,
4061 .flags = FLAG_ADVANCED,
4064 .label = "socket address",
4066 .p_class = P_GLOBAL,
4067 .ptr = &Globals.szSocketAddress,
4070 .flags = FLAG_ADVANCED,
4073 .label = "nmbd bind explicit broadcast",
4075 .p_class = P_GLOBAL,
4076 .ptr = &Globals.bNmbdBindExplicitBroadcast,
4079 .flags = FLAG_ADVANCED,
4082 .label = "homedir map",
4084 .p_class = P_GLOBAL,
4085 .ptr = &Globals.szNISHomeMapName,
4088 .flags = FLAG_ADVANCED,
4091 .label = "afs username map",
4093 .p_class = P_GLOBAL,
4094 .ptr = &Globals.szAfsUsernameMap,
4097 .flags = FLAG_ADVANCED,
4100 .label = "afs token lifetime",
4102 .p_class = P_GLOBAL,
4103 .ptr = &Globals.iAfsTokenLifetime,
4106 .flags = FLAG_ADVANCED,
4109 .label = "log nt token command",
4111 .p_class = P_GLOBAL,
4112 .ptr = &Globals.szLogNtTokenCommand,
4115 .flags = FLAG_ADVANCED,
4118 .label = "time offset",
4120 .p_class = P_GLOBAL,
4121 .ptr = &extra_time_offset,
4124 .flags = FLAG_ADVANCED,
4127 .label = "NIS homedir",
4129 .p_class = P_GLOBAL,
4130 .ptr = &Globals.bNISHomeMap,
4133 .flags = FLAG_ADVANCED,
4139 .ptr = &sDefault.valid,
4148 .ptr = &sDefault.szCopy,
4149 .special = handle_copy,
4157 .ptr = &sDefault.szInclude,
4158 .special = handle_include,
4160 .flags = FLAG_HIDE|FLAG_META,
4166 .ptr = &sDefault.szPreExec,
4169 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4175 .ptr = &sDefault.szPreExec,
4178 .flags = FLAG_ADVANCED,
4181 .label = "preexec close",
4184 .ptr = &sDefault.bPreexecClose,
4187 .flags = FLAG_ADVANCED | FLAG_SHARE,
4190 .label = "postexec",
4193 .ptr = &sDefault.szPostExec,
4196 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4199 .label = "root preexec",
4202 .ptr = &sDefault.szRootPreExec,
4205 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4208 .label = "root preexec close",
4211 .ptr = &sDefault.bRootpreexecClose,
4214 .flags = FLAG_ADVANCED | FLAG_SHARE,
4217 .label = "root postexec",
4220 .ptr = &sDefault.szRootPostExec,
4223 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4226 .label = "available",
4229 .ptr = &sDefault.bAvailable,
4232 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4235 .label = "registry shares",
4237 .p_class = P_GLOBAL,
4238 .ptr = &Globals.bRegistryShares,
4241 .flags = FLAG_ADVANCED,
4244 .label = "usershare allow guests",
4246 .p_class = P_GLOBAL,
4247 .ptr = &Globals.bUsershareAllowGuests,
4250 .flags = FLAG_ADVANCED,
4253 .label = "usershare max shares",
4255 .p_class = P_GLOBAL,
4256 .ptr = &Globals.iUsershareMaxShares,
4259 .flags = FLAG_ADVANCED,
4262 .label = "usershare owner only",
4264 .p_class = P_GLOBAL,
4265 .ptr = &Globals.bUsershareOwnerOnly,
4268 .flags = FLAG_ADVANCED,
4271 .label = "usershare path",
4273 .p_class = P_GLOBAL,
4274 .ptr = &Globals.szUsersharePath,
4277 .flags = FLAG_ADVANCED,
4280 .label = "usershare prefix allow list",
4282 .p_class = P_GLOBAL,
4283 .ptr = &Globals.szUsersharePrefixAllowList,
4286 .flags = FLAG_ADVANCED,
4289 .label = "usershare prefix deny list",
4291 .p_class = P_GLOBAL,
4292 .ptr = &Globals.szUsersharePrefixDenyList,
4295 .flags = FLAG_ADVANCED,
4298 .label = "usershare template share",
4300 .p_class = P_GLOBAL,
4301 .ptr = &Globals.szUsershareTemplateShare,
4304 .flags = FLAG_ADVANCED,
4310 .ptr = &sDefault.volume,
4313 .flags = FLAG_ADVANCED | FLAG_SHARE,
4319 .ptr = &sDefault.fstype,
4322 .flags = FLAG_ADVANCED | FLAG_SHARE,
4325 .label = "set directory",
4328 .ptr = &sDefault.bNo_set_dir,
4331 .flags = FLAG_ADVANCED | FLAG_SHARE,
4334 .label = "wide links",
4337 .ptr = &sDefault.bWidelinks,
4340 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4343 .label = "follow symlinks",
4346 .ptr = &sDefault.bSymlinks,
4349 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4352 .label = "dont descend",
4355 .ptr = &sDefault.szDontdescend,
4358 .flags = FLAG_ADVANCED | FLAG_SHARE,
4361 .label = "magic script",
4364 .ptr = &sDefault.szMagicScript,
4367 .flags = FLAG_ADVANCED | FLAG_SHARE,
4370 .label = "magic output",
4373 .ptr = &sDefault.szMagicOutput,
4376 .flags = FLAG_ADVANCED | FLAG_SHARE,
4379 .label = "delete readonly",
4382 .ptr = &sDefault.bDeleteReadonly,
4385 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4388 .label = "dos filemode",
4391 .ptr = &sDefault.bDosFilemode,
4394 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4397 .label = "dos filetimes",
4400 .ptr = &sDefault.bDosFiletimes,
4403 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4406 .label = "dos filetime resolution",
4409 .ptr = &sDefault.bDosFiletimeResolution,
4412 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4415 .label = "fake directory create times",
4418 .ptr = &sDefault.bFakeDirCreateTimes,
4421 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4424 .label = "async smb echo handler",
4426 .p_class = P_GLOBAL,
4427 .ptr = &Globals.bAsyncSMBEchoHandler,
4430 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4433 .label = "multicast dns register",
4435 .p_class = P_GLOBAL,
4436 .ptr = &Globals.bMulticastDnsRegister,
4439 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4442 .label = "panic action",
4444 .p_class = P_GLOBAL,
4445 .ptr = &Globals.szPanicAction,
4448 .flags = FLAG_ADVANCED,
4451 .label = "perfcount module",
4453 .p_class = P_GLOBAL,
4454 .ptr = &Globals.szSMBPerfcountModule,
4457 .flags = FLAG_ADVANCED,
4460 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4463 .label = "vfs objects",
4466 .ptr = &sDefault.szVfsObjects,
4469 .flags = FLAG_ADVANCED | FLAG_SHARE,
4472 .label = "vfs object",
4475 .ptr = &sDefault.szVfsObjects,
4482 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4485 .label = "msdfs root",
4488 .ptr = &sDefault.bMSDfsRoot,
4491 .flags = FLAG_ADVANCED | FLAG_SHARE,
4494 .label = "msdfs proxy",
4497 .ptr = &sDefault.szMSDfsProxy,
4500 .flags = FLAG_ADVANCED | FLAG_SHARE,
4503 .label = "host msdfs",
4505 .p_class = P_GLOBAL,
4506 .ptr = &Globals.bHostMSDfs,
4509 .flags = FLAG_ADVANCED,
4512 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4515 .label = "passdb expand explicit",
4517 .p_class = P_GLOBAL,
4518 .ptr = &Globals.bPassdbExpandExplicit,
4521 .flags = FLAG_ADVANCED,
4524 .label = "idmap backend",
4526 .p_class = P_GLOBAL,
4527 .ptr = &Globals.szIdmapBackend,
4530 .flags = FLAG_ADVANCED,
4533 .label = "idmap read only",
4535 .p_class = P_GLOBAL,
4536 .ptr = &Globals.bIdmapReadOnly,
4539 .flags = FLAG_ADVANCED,
4542 .label = "idmap cache time",
4544 .p_class = P_GLOBAL,
4545 .ptr = &Globals.iIdmapCacheTime,
4548 .flags = FLAG_ADVANCED,
4551 .label = "idmap negative cache time",
4553 .p_class = P_GLOBAL,
4554 .ptr = &Globals.iIdmapNegativeCacheTime,
4557 .flags = FLAG_ADVANCED,
4560 .label = "idmap uid",
4562 .p_class = P_GLOBAL,
4563 .ptr = &Globals.szIdmapUID,
4564 .special = handle_idmap_uid,
4566 .flags = FLAG_ADVANCED,
4569 .label = "winbind uid",
4571 .p_class = P_GLOBAL,
4572 .ptr = &Globals.szIdmapUID,
4573 .special = handle_idmap_uid,
4578 .label = "idmap gid",
4580 .p_class = P_GLOBAL,
4581 .ptr = &Globals.szIdmapGID,
4582 .special = handle_idmap_gid,
4584 .flags = FLAG_ADVANCED,
4587 .label = "winbind gid",
4589 .p_class = P_GLOBAL,
4590 .ptr = &Globals.szIdmapGID,
4591 .special = handle_idmap_gid,
4596 .label = "template homedir",
4598 .p_class = P_GLOBAL,
4599 .ptr = &Globals.szTemplateHomedir,
4602 .flags = FLAG_ADVANCED,
4605 .label = "template shell",
4607 .p_class = P_GLOBAL,
4608 .ptr = &Globals.szTemplateShell,
4611 .flags = FLAG_ADVANCED,
4614 .label = "winbind separator",
4616 .p_class = P_GLOBAL,
4617 .ptr = &Globals.szWinbindSeparator,
4620 .flags = FLAG_ADVANCED,
4623 .label = "winbind cache time",
4625 .p_class = P_GLOBAL,
4626 .ptr = &Globals.winbind_cache_time,
4629 .flags = FLAG_ADVANCED,
4632 .label = "winbind reconnect delay",
4634 .p_class = P_GLOBAL,
4635 .ptr = &Globals.winbind_reconnect_delay,
4638 .flags = FLAG_ADVANCED,
4641 .label = "winbind max clients",
4643 .p_class = P_GLOBAL,
4644 .ptr = &Globals.winbind_max_clients,
4647 .flags = FLAG_ADVANCED,
4650 .label = "winbind enum users",
4652 .p_class = P_GLOBAL,
4653 .ptr = &Globals.bWinbindEnumUsers,
4656 .flags = FLAG_ADVANCED,
4659 .label = "winbind enum groups",
4661 .p_class = P_GLOBAL,
4662 .ptr = &Globals.bWinbindEnumGroups,
4665 .flags = FLAG_ADVANCED,
4668 .label = "winbind use default domain",
4670 .p_class = P_GLOBAL,
4671 .ptr = &Globals.bWinbindUseDefaultDomain,
4674 .flags = FLAG_ADVANCED,
4677 .label = "winbind trusted domains only",
4679 .p_class = P_GLOBAL,
4680 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4683 .flags = FLAG_ADVANCED,
4686 .label = "winbind nested groups",
4688 .p_class = P_GLOBAL,
4689 .ptr = &Globals.bWinbindNestedGroups,
4692 .flags = FLAG_ADVANCED,
4695 .label = "winbind expand groups",
4697 .p_class = P_GLOBAL,
4698 .ptr = &Globals.winbind_expand_groups,
4701 .flags = FLAG_ADVANCED,
4704 .label = "winbind nss info",
4706 .p_class = P_GLOBAL,
4707 .ptr = &Globals.szWinbindNssInfo,
4710 .flags = FLAG_ADVANCED,
4713 .label = "winbind refresh tickets",
4715 .p_class = P_GLOBAL,
4716 .ptr = &Globals.bWinbindRefreshTickets,
4719 .flags = FLAG_ADVANCED,
4722 .label = "winbind offline logon",
4724 .p_class = P_GLOBAL,
4725 .ptr = &Globals.bWinbindOfflineLogon,
4728 .flags = FLAG_ADVANCED,
4731 .label = "winbind normalize names",
4733 .p_class = P_GLOBAL,
4734 .ptr = &Globals.bWinbindNormalizeNames,
4737 .flags = FLAG_ADVANCED,
4740 .label = "winbind rpc only",
4742 .p_class = P_GLOBAL,
4743 .ptr = &Globals.bWinbindRpcOnly,
4746 .flags = FLAG_ADVANCED,
4749 .label = "create krb5 conf",
4751 .p_class = P_GLOBAL,
4752 .ptr = &Globals.bCreateKrb5Conf,
4755 .flags = FLAG_ADVANCED,
4758 .label = "ncalrpc dir",
4760 .p_class = P_GLOBAL,
4761 .ptr = &Globals.ncalrpc_dir,
4764 .flags = FLAG_ADVANCED,
4767 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4770 /***************************************************************************
4771 Initialise the sDefault parameter structure for the printer values.
4772 ***************************************************************************/
4774 static void init_printer_values(struct service *pService)
4776 /* choose defaults depending on the type of printing */
4777 switch (pService->iPrinting) {
4782 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4783 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4784 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4789 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4790 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4791 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4792 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4793 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4794 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4795 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4801 /* set the lpq command to contain the destination printer
4802 name only. This is used by cups_queue_get() */
4803 string_set(&pService->szLpqcommand, "%p");
4804 string_set(&pService->szLprmcommand, "");
4805 string_set(&pService->szPrintcommand, "");
4806 string_set(&pService->szLppausecommand, "");
4807 string_set(&pService->szLpresumecommand, "");
4808 string_set(&pService->szQueuepausecommand, "");
4809 string_set(&pService->szQueueresumecommand, "");
4811 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4812 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4813 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4814 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4815 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4816 string_set(&pService->szQueuepausecommand, "disable '%p'");
4817 string_set(&pService->szQueueresumecommand, "enable '%p'");
4818 #endif /* HAVE_CUPS */
4823 string_set(&pService->szLpqcommand, "lpstat -o%p");
4824 string_set(&pService->szLprmcommand, "cancel %p-%j");
4825 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4826 string_set(&pService->szQueuepausecommand, "disable %p");
4827 string_set(&pService->szQueueresumecommand, "enable %p");
4829 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4830 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4835 string_set(&pService->szLpqcommand, "lpq -P%p");
4836 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4837 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4843 string_set(&pService->szPrintcommand, "vlp print %p %s");
4844 string_set(&pService->szLpqcommand, "vlp lpq %p");
4845 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4846 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4847 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4848 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4849 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4851 #endif /* DEVELOPER */
4856 * Function to return the default value for the maximum number of open
4857 * file descriptors permitted. This function tries to consult the
4858 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4859 * the smaller of those.
4861 static int max_open_files(void)
4863 int sysctl_max = MAX_OPEN_FILES;
4864 int rlimit_max = MAX_OPEN_FILES;
4866 #ifdef HAVE_SYSCTLBYNAME
4868 size_t size = sizeof(sysctl_max);
4869 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4874 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4880 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4881 rlimit_max = rl.rlim_cur;
4883 #if defined(RLIM_INFINITY)
4884 if(rl.rlim_cur == RLIM_INFINITY)
4885 rlimit_max = MAX_OPEN_FILES;
4890 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4891 DEBUG(2,("max_open_files: sysctl_max (%d) below "
4892 "minimum Windows limit (%d)\n",
4894 MIN_OPEN_FILES_WINDOWS));
4895 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4898 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4899 DEBUG(2,("rlimit_max: rlimit_max (%d) below "
4900 "minimum Windows limit (%d)\n",
4902 MIN_OPEN_FILES_WINDOWS));
4903 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4906 return MIN(sysctl_max, rlimit_max);
4910 * Common part of freeing allocated data for one parameter.
4912 static void free_one_parameter_common(void *parm_ptr,
4913 struct parm_struct parm)
4915 if ((parm.type == P_STRING) ||
4916 (parm.type == P_USTRING))
4918 string_free((char**)parm_ptr);
4919 } else if (parm.type == P_LIST) {
4920 TALLOC_FREE(*((char***)parm_ptr));
4925 * Free the allocated data for one parameter for a share
4926 * given as a service struct.
4928 static void free_one_parameter(struct service *service,
4929 struct parm_struct parm)
4933 if (parm.p_class != P_LOCAL) {
4937 parm_ptr = lp_local_ptr(service, parm.ptr);
4939 free_one_parameter_common(parm_ptr, parm);
4943 * Free the allocated parameter data of a share given
4944 * as a service struct.
4946 static void free_parameters(struct service *service)
4950 for (i=0; parm_table[i].label; i++) {
4951 free_one_parameter(service, parm_table[i]);
4956 * Free the allocated data for one parameter for a given share
4957 * specified by an snum.
4959 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4963 if (parm.ptr == NULL) {
4968 parm_ptr = parm.ptr;
4969 } else if (parm.p_class != P_LOCAL) {
4972 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4975 free_one_parameter_common(parm_ptr, parm);
4979 * Free the allocated parameter data for a share specified
4982 static void free_parameters_by_snum(int snum)
4986 for (i=0; parm_table[i].label; i++) {
4987 free_one_parameter_by_snum(snum, parm_table[i]);
4992 * Free the allocated global parameters.
4994 static void free_global_parameters(void)
4996 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4999 static int map_parameter(const char *pszParmName);
5001 struct lp_stored_option {
5002 struct lp_stored_option *prev, *next;
5007 static struct lp_stored_option *stored_options;
5010 save options set by lp_set_cmdline() into a list. This list is
5011 re-applied when we do a globals reset, so that cmdline set options
5012 are sticky across reloads of smb.conf
5014 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
5016 struct lp_stored_option *entry, *entry_next;
5017 for (entry = stored_options; entry != NULL; entry = entry_next) {
5018 entry_next = entry->next;
5019 if (strcmp(pszParmName, entry->label) == 0) {
5020 DLIST_REMOVE(stored_options, entry);
5026 entry = talloc(NULL, struct lp_stored_option);
5031 entry->label = talloc_strdup(entry, pszParmName);
5032 if (!entry->label) {
5037 entry->value = talloc_strdup(entry, pszParmValue);
5038 if (!entry->value) {
5043 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
5048 static bool apply_lp_set_cmdline(void)
5050 struct lp_stored_option *entry = NULL;
5051 for (entry = stored_options; entry != NULL; entry = entry->next) {
5052 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
5053 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
5054 entry->label, entry->value));
5061 /***************************************************************************
5062 Initialise the global parameter structure.
5063 ***************************************************************************/
5065 static void init_globals(bool reinit_globals)
5067 static bool done_init = False;
5071 /* If requested to initialize only once and we've already done it... */
5072 if (!reinit_globals && done_init) {
5073 /* ... then we have nothing more to do */
5078 /* The logfile can be set before this is invoked. Free it if so. */
5079 if (Globals.szLogFile != NULL) {
5080 string_free(&Globals.szLogFile);
5081 Globals.szLogFile = NULL;
5085 free_global_parameters();
5088 /* This memset and the free_global_parameters() above will
5089 * wipe out smb.conf options set with lp_set_cmdline(). The
5090 * apply_lp_set_cmdline() call puts these values back in the
5091 * table once the defaults are set */
5092 memset((void *)&Globals, '\0', sizeof(Globals));
5094 for (i = 0; parm_table[i].label; i++) {
5095 if ((parm_table[i].type == P_STRING ||
5096 parm_table[i].type == P_USTRING) &&
5099 string_set((char **)parm_table[i].ptr, "");
5103 string_set(&sDefault.fstype, FSTYPE_STRING);
5104 string_set(&sDefault.szPrintjobUsername, "%U");
5106 init_printer_values(&sDefault);
5109 DEBUG(3, ("Initialising global parameters\n"));
5111 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
5112 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
5114 /* use the new 'hash2' method by default, with a prefix of 1 */
5115 string_set(&Globals.szManglingMethod, "hash2");
5116 Globals.mangle_prefix = 1;
5118 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5120 /* using UTF8 by default allows us to support all chars */
5121 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5123 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
5124 /* If the system supports nl_langinfo(), try to grab the value
5125 from the user's locale */
5126 string_set(&Globals.display_charset, "LOCALE");
5128 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
5131 /* Use codepage 850 as a default for the dos character set */
5132 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5135 * Allow the default PASSWD_CHAT to be overridden in local.h.
5137 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5139 set_global_myname(myhostname());
5140 string_set(&Globals.szNetbiosName,global_myname());
5142 set_global_myworkgroup(WORKGROUP);
5143 string_set(&Globals.szWorkgroup, lp_workgroup());
5145 string_set(&Globals.szPasswdProgram, "");
5146 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5147 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5148 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5149 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5150 string_set(&Globals.szSocketAddress, "0.0.0.0");
5152 * By default support explicit binding to broadcast
5155 Globals.bNmbdBindExplicitBroadcast = true;
5157 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5158 smb_panic("init_globals: ENOMEM");
5160 string_set(&Globals.szServerString, s);
5162 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5163 DEFAULT_MINOR_VERSION) < 0) {
5164 smb_panic("init_globals: ENOMEM");
5166 string_set(&Globals.szAnnounceVersion, s);
5169 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5172 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5174 string_set(&Globals.szLogonDrive, "");
5175 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5176 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5177 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5179 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5180 string_set(&Globals.szPasswordServer, "*");
5182 Globals.AlgorithmicRidBase = BASE_RID;
5184 Globals.bLoadPrinters = True;
5185 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
5187 Globals.ConfigBackend = config_backend;
5189 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5190 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5191 Globals.max_xmit = 0x4104;
5192 Globals.max_mux = 50; /* This is *needed* for profile support. */
5193 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
5194 Globals.bDisableSpoolss = False;
5195 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5196 Globals.pwordlevel = 0;
5197 Globals.unamelevel = 0;
5198 Globals.deadtime = 0;
5199 Globals.getwd_cache = true;
5200 Globals.bLargeReadwrite = True;
5201 Globals.max_log_size = 5000;
5202 Globals.max_open_files = max_open_files();
5203 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5204 Globals.maxprotocol = PROTOCOL_NT1;
5205 Globals.minprotocol = PROTOCOL_CORE;
5206 Globals.security = SEC_USER;
5207 Globals.paranoid_server_security = True;
5208 Globals.bEncryptPasswords = True;
5209 Globals.bUpdateEncrypt = False;
5210 Globals.clientSchannel = Auto;
5211 Globals.serverSchannel = Auto;
5212 Globals.bReadRaw = True;
5213 Globals.bWriteRaw = True;
5214 Globals.bNullPasswords = False;
5215 Globals.bObeyPamRestrictions = False;
5217 Globals.bSyslogOnly = False;
5218 Globals.bTimestampLogs = True;
5219 string_set(&Globals.szLogLevel, "0");
5220 Globals.bDebugPrefixTimestamp = False;
5221 Globals.bDebugHiresTimestamp = true;
5222 Globals.bDebugPid = False;
5223 Globals.bDebugUid = False;
5224 Globals.bDebugClass = False;
5225 Globals.bEnableCoreFiles = True;
5226 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5227 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5228 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5229 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5230 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5231 Globals.lm_interval = 60;
5232 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5233 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5234 Globals.bNISHomeMap = False;
5235 #ifdef WITH_NISPLUS_HOME
5236 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5238 string_set(&Globals.szNISHomeMapName, "auto.home");
5241 Globals.bTimeServer = False;
5242 Globals.bBindInterfacesOnly = False;
5243 Globals.bUnixPasswdSync = False;
5244 Globals.bPamPasswordChange = False;
5245 Globals.bPasswdChatDebug = False;
5246 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5247 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5248 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5249 Globals.bStatCache = True; /* use stat cache by default */
5250 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5251 Globals.restrict_anonymous = 0;
5252 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5253 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5254 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5255 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5256 Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
5257 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
5259 Globals.map_to_guest = 0; /* By Default, "Never" */
5260 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5261 Globals.enhanced_browsing = true;
5262 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5263 #ifdef MMAP_BLACKLIST
5264 Globals.bUseMmap = False;
5266 Globals.bUseMmap = True;
5268 Globals.bUnixExtensions = True;
5269 Globals.bResetOnZeroVC = False;
5270 Globals.bLogWriteableFilesOnExit = False;
5271 Globals.bCreateKrb5Conf = true;
5273 /* hostname lookups can be very expensive and are broken on
5274 a large number of sites (tridge) */
5275 Globals.bHostnameLookups = False;
5277 string_set(&Globals.szPassdbBackend, "tdbsam");
5278 string_set(&Globals.szLdapSuffix, "");
5279 string_set(&Globals.szLdapMachineSuffix, "");
5280 string_set(&Globals.szLdapUserSuffix, "");
5281 string_set(&Globals.szLdapGroupSuffix, "");
5282 string_set(&Globals.szLdapIdmapSuffix, "");
5284 string_set(&Globals.szLdapAdminDn, "");
5285 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5286 Globals.ldap_ssl_ads = False;
5287 Globals.ldap_deref = -1;
5288 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5289 Globals.ldap_delete_dn = False;
5290 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5291 Globals.ldap_follow_referral = Auto;
5292 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5293 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5294 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5296 Globals.ldap_debug_level = 0;
5297 Globals.ldap_debug_threshold = 10;
5299 /* This is what we tell the afs client. in reality we set the token
5300 * to never expire, though, when this runs out the afs client will
5301 * forget the token. Set to 0 to get NEVERDATE.*/
5302 Globals.iAfsTokenLifetime = 604800;
5303 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5305 /* these parameters are set to defaults that are more appropriate
5306 for the increasing samba install base:
5308 as a member of the workgroup, that will possibly become a
5309 _local_ master browser (lm = True). this is opposed to a forced
5310 local master browser startup (pm = True).
5312 doesn't provide WINS server service by default (wsupp = False),
5313 and doesn't provide domain master browser services by default, either.
5317 Globals.bMsAddPrinterWizard = True;
5318 Globals.os_level = 20;
5319 Globals.bLocalMaster = True;
5320 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5321 Globals.bDomainLogons = False;
5322 Globals.bBrowseList = True;
5323 Globals.bWINSsupport = False;
5324 Globals.bWINSproxy = False;
5326 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5327 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5329 Globals.bDNSproxy = True;
5331 /* this just means to use them if they exist */
5332 Globals.bKernelOplocks = True;
5334 Globals.bAllowTrustedDomains = True;
5335 string_set(&Globals.szIdmapBackend, "tdb");
5336 Globals.bIdmapReadOnly = false;
5338 string_set(&Globals.szTemplateShell, "/bin/false");
5339 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5340 string_set(&Globals.szWinbindSeparator, "\\");
5342 string_set(&Globals.szCupsServer, "");
5343 string_set(&Globals.szIPrintServer, "");
5345 string_set(&Globals.ctdbdSocket, "");
5346 Globals.szClusterAddresses = NULL;
5347 Globals.clustering = False;
5348 Globals.ctdb_timeout = 0;
5349 Globals.ctdb_locktime_warn_threshold = 0;
5351 Globals.winbind_cache_time = 300; /* 5 minutes */
5352 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5353 Globals.winbind_max_clients = 200;
5354 Globals.bWinbindEnumUsers = False;
5355 Globals.bWinbindEnumGroups = False;
5356 Globals.bWinbindUseDefaultDomain = False;
5357 Globals.bWinbindTrustedDomainsOnly = False;
5358 Globals.bWinbindNestedGroups = True;
5359 Globals.winbind_expand_groups = 1;
5360 Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
5361 Globals.bWinbindRefreshTickets = False;
5362 Globals.bWinbindOfflineLogon = False;
5364 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5365 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5367 Globals.bPassdbExpandExplicit = False;
5369 Globals.name_cache_timeout = 660; /* In seconds */
5371 Globals.bUseSpnego = True;
5372 Globals.bClientUseSpnego = True;
5374 Globals.client_signing = Auto;
5375 Globals.server_signing = False;
5377 Globals.bDeferSharingViolations = True;
5378 string_set(&Globals.smb_ports, SMB_PORTS);
5380 Globals.bEnablePrivileges = True;
5381 Globals.bHostMSDfs = True;
5382 Globals.bASUSupport = False;
5384 /* User defined shares. */
5385 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5386 smb_panic("init_globals: ENOMEM");
5388 string_set(&Globals.szUsersharePath, s);
5390 string_set(&Globals.szUsershareTemplateShare, "");
5391 Globals.iUsershareMaxShares = 0;
5392 /* By default disallow sharing of directories not owned by the sharer. */
5393 Globals.bUsershareOwnerOnly = True;
5394 /* By default disallow guest access to usershares. */
5395 Globals.bUsershareAllowGuests = False;
5397 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5399 /* By default no shares out of the registry */
5400 Globals.bRegistryShares = False;
5402 Globals.iminreceivefile = 0;
5404 Globals.bMapUntrustedToDomain = false;
5405 Globals.bMulticastDnsRegister = true;
5407 Globals.ismb2_max_read = 1024*1024;
5408 Globals.ismb2_max_write = 1024*1024;
5409 Globals.ismb2_max_trans = 1024*1024;
5411 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5413 /* Now put back the settings that were set with lp_set_cmdline() */
5414 apply_lp_set_cmdline();
5417 /*******************************************************************
5418 Convenience routine to grab string parameters into temporary memory
5419 and run standard_sub_basic on them. The buffers can be written to by
5420 callers without affecting the source string.
5421 ********************************************************************/
5423 static char *lp_string(const char *s)
5426 TALLOC_CTX *ctx = talloc_tos();
5428 /* The follow debug is useful for tracking down memory problems
5429 especially if you have an inner loop that is calling a lp_*()
5430 function that returns a string. Perhaps this debug should be
5431 present all the time? */
5434 DEBUG(10, ("lp_string(%s)\n", s));
5440 ret = talloc_sub_basic(ctx,
5441 get_current_username(),
5442 current_user_info.domain,
5444 if (trim_char(ret, '\"', '\"')) {
5445 if (strchr(ret,'\"') != NULL) {
5447 ret = talloc_sub_basic(ctx,
5448 get_current_username(),
5449 current_user_info.domain,
5457 In this section all the functions that are used to access the
5458 parameters from the rest of the program are defined
5461 #define FN_GLOBAL_STRING(fn_name,ptr) \
5462 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5463 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5464 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5465 #define FN_GLOBAL_LIST(fn_name,ptr) \
5466 const char **fn_name(void) {return(*(const char ***)(ptr));}
5467 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5468 bool fn_name(void) {return(*(bool *)(ptr));}
5469 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5470 char fn_name(void) {return(*(char *)(ptr));}
5471 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5472 int fn_name(void) {return(*(int *)(ptr));}
5474 #define FN_LOCAL_STRING(fn_name,val) \
5475 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5476 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5477 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5478 #define FN_LOCAL_LIST(fn_name,val) \
5479 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5480 #define FN_LOCAL_BOOL(fn_name,val) \
5481 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5482 #define FN_LOCAL_INTEGER(fn_name,val) \
5483 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5485 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5486 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5487 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5488 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5489 #define FN_LOCAL_CHAR(fn_name,val) \
5490 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5492 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5493 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5494 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5495 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5496 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5497 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5498 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5499 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5500 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5501 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5502 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5503 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5504 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5505 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5506 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5507 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5508 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5509 * build process or in smb.conf, we use that value. Otherwise they
5510 * default to the value of lp_lockdir(). */
5511 char *lp_statedir(void) {
5512 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5513 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5514 return(lp_string(*(char **)(&Globals.szStateDir) ?
5515 *(char **)(&Globals.szStateDir) : ""));
5517 return(lp_string(*(char **)(&Globals.szLockDir) ?
5518 *(char **)(&Globals.szLockDir) : ""));
5520 char *lp_cachedir(void) {
5521 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5522 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5523 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5524 *(char **)(&Globals.szCacheDir) : ""));
5526 return(lp_string(*(char **)(&Globals.szLockDir) ?
5527 *(char **)(&Globals.szLockDir) : ""));
5529 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5530 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5531 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5532 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5533 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5534 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5535 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5536 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5537 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5538 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5539 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5540 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5541 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5542 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5543 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5544 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5545 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5546 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5547 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5548 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5549 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5550 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5551 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5552 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5553 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5554 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5555 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5556 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5557 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5558 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5559 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5560 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5561 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5562 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5563 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5564 * lp_passdb_backend() should be replace by the this macro again after
5567 const char *lp_passdb_backend(void)
5569 char *delim, *quote;
5571 delim = strchr( Globals.szPassdbBackend, ' ');
5572 /* no space at all */
5573 if (delim == NULL) {
5577 quote = strchr(Globals.szPassdbBackend, '"');
5578 /* no quote char or non in the first part */
5579 if (quote == NULL || quote > delim) {
5584 quote = strchr(quote+1, '"');
5585 if (quote == NULL) {
5586 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5588 } else if (*(quote+1) == '\0') {
5589 /* space, fitting quote char, and one backend only */
5592 /* terminate string after the fitting quote char */
5597 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5598 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5599 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5600 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5603 return Globals.szPassdbBackend;
5605 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5606 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5607 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5608 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5609 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5611 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5612 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5613 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5614 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5615 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5616 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5618 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5620 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5621 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5622 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5623 FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
5625 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5627 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5628 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5629 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5630 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5631 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5632 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5633 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5634 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5635 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5636 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5637 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5638 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5639 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5640 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5641 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5642 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5644 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5645 FN_GLOBAL_BOOL(lp_idmap_read_only, &Globals.bIdmapReadOnly)
5646 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5647 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5648 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5649 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5651 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5652 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5653 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5654 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5655 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5656 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5657 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5658 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5659 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5660 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5661 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5662 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5663 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5664 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5665 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5666 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5667 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5668 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5669 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5670 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5672 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5674 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5675 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5676 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5677 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5678 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5679 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5680 &Globals.bLogWriteableFilesOnExit)
5681 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5682 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5683 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5684 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5685 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5686 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5687 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5688 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5689 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5690 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5691 FN_GLOBAL_BOOL(_lp_readraw, &Globals.bReadRaw)
5692 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5693 FN_GLOBAL_BOOL(_lp_writeraw, &Globals.bWriteRaw)
5694 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5695 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5696 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5697 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5698 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5699 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5700 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5701 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5702 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5703 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5704 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5705 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5706 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5707 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5708 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5709 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5710 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5711 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5712 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5713 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5714 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5715 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5716 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5717 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5718 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5719 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5720 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5721 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5722 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5723 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5724 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5725 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5726 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5727 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5728 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5729 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5730 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5731 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5732 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5733 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5734 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
5735 FN_GLOBAL_BOOL(lp_send_spnego_principal, &Globals.send_spnego_principal)
5736 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5737 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5738 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5739 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5740 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5741 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5742 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5743 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5744 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5745 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5746 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5747 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5748 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5749 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5750 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5751 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5752 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5753 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5754 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5755 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5756 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5757 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5758 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5759 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5760 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5761 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5762 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5763 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5764 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5765 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5766 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5767 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5768 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5769 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5770 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5771 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5772 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5773 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5774 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5775 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5776 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5777 FN_GLOBAL_INTEGER(lp_smb2_max_read, &Globals.ismb2_max_read)
5778 FN_GLOBAL_INTEGER(lp_smb2_max_write, &Globals.ismb2_max_write)
5779 FN_GLOBAL_INTEGER(lp_smb2_max_trans, &Globals.ismb2_max_trans)
5781 FN_LOCAL_STRING(lp_preexec, szPreExec)
5782 FN_LOCAL_STRING(lp_postexec, szPostExec)
5783 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5784 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5785 FN_LOCAL_STRING(lp_servicename, szService)
5786 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5787 FN_LOCAL_STRING(lp_pathname, szPath)
5788 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5789 FN_LOCAL_STRING(lp_username, szUsername)
5790 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5791 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5792 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5793 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5794 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5795 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5796 int lp_cups_encrypt(void)
5799 #ifdef HAVE_HTTPCONNECTENCRYPT
5800 switch (Globals.CupsEncrypt) {
5802 result = HTTP_ENCRYPT_REQUIRED;
5805 result = HTTP_ENCRYPT_ALWAYS;
5808 result = HTTP_ENCRYPT_NEVER;
5814 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5815 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5816 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5817 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5818 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5819 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5820 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, &Globals.ctdb_locktime_warn_threshold)
5821 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5822 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5823 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5824 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5825 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5826 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5827 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5828 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5829 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5830 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5831 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5832 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5833 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5834 FN_LOCAL_STRING(lp_comment, comment)
5835 FN_LOCAL_STRING(lp_force_user, force_user)
5836 FN_LOCAL_STRING(lp_force_group, force_group)
5837 FN_LOCAL_LIST(lp_readlist, readlist)
5838 FN_LOCAL_LIST(lp_writelist, writelist)
5839 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5840 FN_LOCAL_STRING(lp_fstype, fstype)
5841 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5842 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5843 static FN_LOCAL_STRING(lp_volume, volume)
5844 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5845 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5846 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5847 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5848 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5849 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5850 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5851 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5852 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5853 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5854 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5855 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5856 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5857 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5858 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5859 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5860 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5861 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5862 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5863 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5864 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5865 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5866 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5867 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5868 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5869 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5870 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5871 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5872 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5873 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5874 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5875 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5876 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5877 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5878 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5879 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5880 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5881 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5882 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5883 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5884 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5885 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5886 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5887 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5888 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5889 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5890 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5891 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5892 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5893 FN_GLOBAL_BOOL(lp_multicast_dns_register, &Globals.bMulticastDnsRegister)
5894 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5895 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5896 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5897 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5898 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5899 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5900 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5901 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5902 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5903 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5904 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5905 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5906 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5907 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5908 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5909 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5910 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5911 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5912 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5913 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5914 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5915 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5916 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5917 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5918 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5919 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5920 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5921 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5922 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5923 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5924 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5925 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5926 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5927 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5928 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5929 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5930 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5931 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5932 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5933 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5934 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5935 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5936 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5937 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5938 FN_GLOBAL_INTEGER(lp_winbind_max_clients, &Globals.winbind_max_clients)
5939 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5940 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5941 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5942 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5943 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5944 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5946 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
5948 /* local prototypes */
5950 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5951 static const char *get_boolean(bool bool_value);
5952 static int getservicebyname(const char *pszServiceName,
5953 struct service *pserviceDest);
5954 static void copy_service(struct service *pserviceDest,
5955 struct service *pserviceSource,
5956 struct bitmap *pcopymapDest);
5957 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5959 static bool do_section(const char *pszSectionName, void *userdata);
5960 static void init_copymap(struct service *pservice);
5961 static bool hash_a_service(const char *name, int number);
5962 static void free_service_byindex(int iService);
5963 static void free_param_opts(struct param_opt_struct **popts);
5964 static void show_parameter(int parmIndex);
5965 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5968 * This is a helper function for parametrical options support. It returns a
5969 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5970 * parametrical functions are quite simple
5972 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5975 bool global_section = False;
5977 struct param_opt_struct *data;
5979 if (snum >= iNumServices) return NULL;
5982 data = Globals.param_opt;
5983 global_section = True;
5985 data = ServicePtrs[snum]->param_opt;
5988 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5989 DEBUG(0,("asprintf failed!\n"));
5994 if (strwicmp(data->key, param_key) == 0) {
5995 string_free(¶m_key);
6001 if (!global_section) {
6002 /* Try to fetch the same option but from globals */
6003 /* but only if we are not already working with Globals */
6004 data = Globals.param_opt;
6006 if (strwicmp(data->key, param_key) == 0) {
6007 string_free(¶m_key);
6014 string_free(¶m_key);
6020 #define MISSING_PARAMETER(name) \
6021 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
6023 /*******************************************************************
6024 convenience routine to return int parameters.
6025 ********************************************************************/
6026 static int lp_int(const char *s)
6030 MISSING_PARAMETER(lp_int);
6034 return (int)strtol(s, NULL, 0);
6037 /*******************************************************************
6038 convenience routine to return unsigned long parameters.
6039 ********************************************************************/
6040 static unsigned long lp_ulong(const char *s)
6044 MISSING_PARAMETER(lp_ulong);
6048 return strtoul(s, NULL, 0);
6051 /*******************************************************************
6052 convenience routine to return boolean parameters.
6053 ********************************************************************/
6054 static bool lp_bool(const char *s)
6059 MISSING_PARAMETER(lp_bool);
6063 if (!set_boolean(s, &ret)) {
6064 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
6071 /*******************************************************************
6072 convenience routine to return enum parameters.
6073 ********************************************************************/
6074 static int lp_enum(const char *s,const struct enum_list *_enum)
6078 if (!s || !*s || !_enum) {
6079 MISSING_PARAMETER(lp_enum);
6083 for (i=0; _enum[i].name; i++) {
6084 if (strequal(_enum[i].name,s))
6085 return _enum[i].value;
6088 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
6092 #undef MISSING_PARAMETER
6094 /* DO NOT USE lp_parm_string ANYMORE!!!!
6095 * use lp_parm_const_string or lp_parm_talloc_string
6097 * lp_parm_string is only used to let old modules find this symbol
6099 #undef lp_parm_string
6100 char *lp_parm_string(const char *servicename, const char *type, const char *option);
6101 char *lp_parm_string(const char *servicename, const char *type, const char *option)
6103 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
6106 /* Return parametric option from a given service. Type is a part of option before ':' */
6107 /* Parametric option has following syntax: 'Type: option = value' */
6108 /* the returned value is talloced on the talloc_tos() */
6109 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
6111 struct param_opt_struct *data = get_parametrics(snum, type, option);
6113 if (data == NULL||data->value==NULL) {
6115 return lp_string(def);
6121 return lp_string(data->value);
6124 /* Return parametric option from a given service. Type is a part of option before ':' */
6125 /* Parametric option has following syntax: 'Type: option = value' */
6126 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6128 struct param_opt_struct *data = get_parametrics(snum, type, option);
6130 if (data == NULL||data->value==NULL)
6136 /* Return parametric option from a given service. Type is a part of option before ':' */
6137 /* Parametric option has following syntax: 'Type: option = value' */
6139 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6141 struct param_opt_struct *data = get_parametrics(snum, type, option);
6143 if (data == NULL||data->value==NULL)
6144 return (const char **)def;
6146 if (data->list==NULL) {
6147 data->list = str_list_make_v3(NULL, data->value, NULL);
6150 return (const char **)data->list;
6153 /* Return parametric option from a given service. Type is a part of option before ':' */
6154 /* Parametric option has following syntax: 'Type: option = value' */
6156 int lp_parm_int(int snum, const char *type, const char *option, int def)
6158 struct param_opt_struct *data = get_parametrics(snum, type, option);
6160 if (data && data->value && *data->value)
6161 return lp_int(data->value);
6166 /* Return parametric option from a given service. Type is a part of option before ':' */
6167 /* Parametric option has following syntax: 'Type: option = value' */
6169 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6171 struct param_opt_struct *data = get_parametrics(snum, type, option);
6173 if (data && data->value && *data->value)
6174 return lp_ulong(data->value);
6179 /* Return parametric option from a given service. Type is a part of option before ':' */
6180 /* Parametric option has following syntax: 'Type: option = value' */
6182 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6184 struct param_opt_struct *data = get_parametrics(snum, type, option);
6186 if (data && data->value && *data->value)
6187 return lp_bool(data->value);
6192 /* Return parametric option from a given service. Type is a part of option before ':' */
6193 /* Parametric option has following syntax: 'Type: option = value' */
6195 int lp_parm_enum(int snum, const char *type, const char *option,
6196 const struct enum_list *_enum, int def)
6198 struct param_opt_struct *data = get_parametrics(snum, type, option);
6200 if (data && data->value && *data->value && _enum)
6201 return lp_enum(data->value, _enum);
6207 /***************************************************************************
6208 Initialise a service to the defaults.
6209 ***************************************************************************/
6211 static void init_service(struct service *pservice)
6213 memset((char *)pservice, '\0', sizeof(struct service));
6214 copy_service(pservice, &sDefault, NULL);
6219 * free a param_opts structure.
6220 * param_opts handling should be moved to talloc;
6221 * then this whole functions reduces to a TALLOC_FREE().
6224 static void free_param_opts(struct param_opt_struct **popts)
6226 struct param_opt_struct *opt, *next_opt;
6228 if (popts == NULL) {
6232 if (*popts != NULL) {
6233 DEBUG(5, ("Freeing parametrics:\n"));
6236 while (opt != NULL) {
6237 string_free(&opt->key);
6238 string_free(&opt->value);
6239 TALLOC_FREE(opt->list);
6240 next_opt = opt->next;
6247 /***************************************************************************
6248 Free the dynamically allocated parts of a service struct.
6249 ***************************************************************************/
6251 static void free_service(struct service *pservice)
6256 if (pservice->szService)
6257 DEBUG(5, ("free_service: Freeing service %s\n",
6258 pservice->szService));
6260 free_parameters(pservice);
6262 string_free(&pservice->szService);
6263 TALLOC_FREE(pservice->copymap);
6265 free_param_opts(&pservice->param_opt);
6267 ZERO_STRUCTP(pservice);
6271 /***************************************************************************
6272 remove a service indexed in the ServicePtrs array from the ServiceHash
6273 and free the dynamically allocated parts
6274 ***************************************************************************/
6276 static void free_service_byindex(int idx)
6278 if ( !LP_SNUM_OK(idx) )
6281 ServicePtrs[idx]->valid = False;
6282 invalid_services[num_invalid_services++] = idx;
6284 /* we have to cleanup the hash record */
6286 if (ServicePtrs[idx]->szService) {
6287 char *canon_name = canonicalize_servicename(
6289 ServicePtrs[idx]->szService );
6291 dbwrap_delete_bystring(ServiceHash, canon_name );
6292 TALLOC_FREE(canon_name);
6295 free_service(ServicePtrs[idx]);
6298 /***************************************************************************
6299 Add a new service to the services array initialising it with the given
6301 ***************************************************************************/
6303 static int add_a_service(const struct service *pservice, const char *name)
6306 struct service tservice;
6307 int num_to_alloc = iNumServices + 1;
6309 tservice = *pservice;
6311 /* it might already exist */
6313 i = getservicebyname(name, NULL);
6319 /* find an invalid one */
6321 if (num_invalid_services > 0) {
6322 i = invalid_services[--num_invalid_services];
6325 /* if not, then create one */
6326 if (i == iNumServices) {
6327 struct service **tsp;
6330 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6332 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6336 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6337 if (!ServicePtrs[iNumServices]) {
6338 DEBUG(0,("add_a_service: out of memory!\n"));
6343 /* enlarge invalid_services here for now... */
6344 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6346 if (tinvalid == NULL) {
6347 DEBUG(0,("add_a_service: failed to enlarge "
6348 "invalid_services!\n"));
6351 invalid_services = tinvalid;
6353 free_service_byindex(i);
6356 ServicePtrs[i]->valid = True;
6358 init_service(ServicePtrs[i]);
6359 copy_service(ServicePtrs[i], &tservice, NULL);
6361 string_set(&ServicePtrs[i]->szService, name);
6363 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6364 i, ServicePtrs[i]->szService));
6366 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6373 /***************************************************************************
6374 Convert a string to uppercase and remove whitespaces.
6375 ***************************************************************************/
6377 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6382 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6386 result = talloc_strdup(ctx, src);
6387 SMB_ASSERT(result != NULL);
6393 /***************************************************************************
6394 Add a name/index pair for the services array to the hash table.
6395 ***************************************************************************/
6397 static bool hash_a_service(const char *name, int idx)
6401 if ( !ServiceHash ) {
6402 DEBUG(10,("hash_a_service: creating servicehash\n"));
6403 ServiceHash = db_open_rbt(NULL);
6404 if ( !ServiceHash ) {
6405 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6410 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6413 canon_name = canonicalize_servicename(talloc_tos(), name );
6415 dbwrap_store_bystring(ServiceHash, canon_name,
6416 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6419 TALLOC_FREE(canon_name);
6424 /***************************************************************************
6425 Add a new home service, with the specified home directory, defaults coming
6427 ***************************************************************************/
6429 bool lp_add_home(const char *pszHomename, int iDefaultService,
6430 const char *user, const char *pszHomedir)
6434 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6435 pszHomedir[0] == '\0') {
6439 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6444 if (!(*(ServicePtrs[iDefaultService]->szPath))
6445 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6446 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6449 if (!(*(ServicePtrs[i]->comment))) {
6450 char *comment = NULL;
6451 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6454 string_set(&ServicePtrs[i]->comment, comment);
6458 /* set the browseable flag from the global default */
6460 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6461 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6463 ServicePtrs[i]->autoloaded = True;
6465 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6466 user, ServicePtrs[i]->szPath ));
6471 /***************************************************************************
6472 Add a new service, based on an old one.
6473 ***************************************************************************/
6475 int lp_add_service(const char *pszService, int iDefaultService)
6477 if (iDefaultService < 0) {
6478 return add_a_service(&sDefault, pszService);
6481 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6484 /***************************************************************************
6485 Add the IPC service.
6486 ***************************************************************************/
6488 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6490 char *comment = NULL;
6491 int i = add_a_service(&sDefault, ipc_name);
6496 if (asprintf(&comment, "IPC Service (%s)",
6497 Globals.szServerString) < 0) {
6501 string_set(&ServicePtrs[i]->szPath, tmpdir());
6502 string_set(&ServicePtrs[i]->szUsername, "");
6503 string_set(&ServicePtrs[i]->comment, comment);
6504 string_set(&ServicePtrs[i]->fstype, "IPC");
6505 ServicePtrs[i]->iMaxConnections = 0;
6506 ServicePtrs[i]->bAvailable = True;
6507 ServicePtrs[i]->bRead_only = True;
6508 ServicePtrs[i]->bGuest_only = False;
6509 ServicePtrs[i]->bAdministrative_share = True;
6510 ServicePtrs[i]->bGuest_ok = guest_ok;
6511 ServicePtrs[i]->bPrint_ok = False;
6512 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6514 DEBUG(3, ("adding IPC service\n"));
6520 /***************************************************************************
6521 Add a new printer service, with defaults coming from service iFrom.
6522 ***************************************************************************/
6524 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6526 const char *comment = "From Printcap";
6527 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6532 /* note that we do NOT default the availability flag to True - */
6533 /* we take it from the default service passed. This allows all */
6534 /* dynamic printers to be disabled by disabling the [printers] */
6535 /* entry (if/when the 'available' keyword is implemented!). */
6537 /* the printer name is set to the service name. */
6538 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6539 string_set(&ServicePtrs[i]->comment, comment);
6541 /* set the browseable flag from the gloabl default */
6542 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6544 /* Printers cannot be read_only. */
6545 ServicePtrs[i]->bRead_only = False;
6546 /* No share modes on printer services. */
6547 ServicePtrs[i]->bShareModes = False;
6548 /* No oplocks on printer services. */
6549 ServicePtrs[i]->bOpLocks = False;
6550 /* Printer services must be printable. */
6551 ServicePtrs[i]->bPrint_ok = True;
6553 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6559 /***************************************************************************
6560 Check whether the given parameter name is valid.
6561 Parametric options (names containing a colon) are considered valid.
6562 ***************************************************************************/
6564 bool lp_parameter_is_valid(const char *pszParmName)
6566 return ((map_parameter(pszParmName) != -1) ||
6567 (strchr(pszParmName, ':') != NULL));
6570 /***************************************************************************
6571 Check whether the given name is the name of a global parameter.
6572 Returns True for strings belonging to parameters of class
6573 P_GLOBAL, False for all other strings, also for parametric options
6574 and strings not belonging to any option.
6575 ***************************************************************************/
6577 bool lp_parameter_is_global(const char *pszParmName)
6579 int num = map_parameter(pszParmName);
6582 return (parm_table[num].p_class == P_GLOBAL);
6588 /**************************************************************************
6589 Check whether the given name is the canonical name of a parameter.
6590 Returns False if it is not a valid parameter Name.
6591 For parametric options, True is returned.
6592 **************************************************************************/
6594 bool lp_parameter_is_canonical(const char *parm_name)
6596 if (!lp_parameter_is_valid(parm_name)) {
6600 return (map_parameter(parm_name) ==
6601 map_parameter_canonical(parm_name, NULL));
6604 /**************************************************************************
6605 Determine the canonical name for a parameter.
6606 Indicate when it is an inverse (boolean) synonym instead of a
6608 **************************************************************************/
6610 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6615 if (!lp_parameter_is_valid(parm_name)) {
6620 num = map_parameter_canonical(parm_name, inverse);
6622 /* parametric option */
6623 *canon_parm = parm_name;
6625 *canon_parm = parm_table[num].label;
6632 /**************************************************************************
6633 Determine the canonical name for a parameter.
6634 Turn the value given into the inverse boolean expression when
6635 the synonym is an invers boolean synonym.
6637 Return True if parm_name is a valid parameter name and
6638 in case it is an invers boolean synonym, if the val string could
6639 successfully be converted to the reverse bool.
6640 Return false in all other cases.
6641 **************************************************************************/
6643 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6645 const char **canon_parm,
6646 const char **canon_val)
6651 if (!lp_parameter_is_valid(parm_name)) {
6657 num = map_parameter_canonical(parm_name, &inverse);
6659 /* parametric option */
6660 *canon_parm = parm_name;
6663 *canon_parm = parm_table[num].label;
6665 if (!lp_invert_boolean(val, canon_val)) {
6677 /***************************************************************************
6678 Map a parameter's string representation to something we can use.
6679 Returns False if the parameter string is not recognised, else TRUE.
6680 ***************************************************************************/
6682 static int map_parameter(const char *pszParmName)
6686 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6689 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6690 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6693 /* Warn only if it isn't parametric option */
6694 if (strchr(pszParmName, ':') == NULL)
6695 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6696 /* We do return 'fail' for parametric options as well because they are
6697 stored in different storage
6702 /***************************************************************************
6703 Map a parameter's string representation to the index of the canonical
6704 form of the parameter (it might be a synonym).
6705 Returns -1 if the parameter string is not recognised.
6706 ***************************************************************************/
6708 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6710 int parm_num, canon_num;
6711 bool loc_inverse = False;
6713 parm_num = map_parameter(pszParmName);
6714 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6715 /* invalid, parametric or no canidate for synonyms ... */
6719 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6720 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6721 parm_num = canon_num;
6727 if (inverse != NULL) {
6728 *inverse = loc_inverse;
6733 /***************************************************************************
6734 return true if parameter number parm1 is a synonym of parameter
6735 number parm2 (parm2 being the principal name).
6736 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6738 ***************************************************************************/
6740 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6742 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6743 (parm_table[parm1].flags & FLAG_HIDE) &&
6744 !(parm_table[parm2].flags & FLAG_HIDE))
6746 if (inverse != NULL) {
6747 if ((parm_table[parm1].type == P_BOOLREV) &&
6748 (parm_table[parm2].type == P_BOOL))
6760 /***************************************************************************
6761 Show one parameter's name, type, [values,] and flags.
6762 (helper functions for show_parameter_list)
6763 ***************************************************************************/
6765 static void show_parameter(int parmIndex)
6767 int enumIndex, flagIndex;
6772 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6773 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6775 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6776 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6777 FLAG_HIDE, FLAG_DOS_STRING};
6778 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6779 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6780 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6782 printf("%s=%s", parm_table[parmIndex].label,
6783 type[parm_table[parmIndex].type]);
6784 if (parm_table[parmIndex].type == P_ENUM) {
6787 parm_table[parmIndex].enum_list[enumIndex].name;
6791 enumIndex ? "|" : "",
6792 parm_table[parmIndex].enum_list[enumIndex].name);
6797 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6798 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6801 flag_names[flagIndex]);
6806 /* output synonyms */
6808 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6809 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6810 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6811 parm_table[parmIndex2].label);
6812 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6814 printf(" (synonyms: ");
6819 printf("%s%s", parm_table[parmIndex2].label,
6820 inverse ? "[i]" : "");
6830 /***************************************************************************
6831 Show all parameter's name, type, [values,] and flags.
6832 ***************************************************************************/
6834 void show_parameter_list(void)
6836 int classIndex, parmIndex;
6837 const char *section_names[] = { "local", "global", NULL};
6839 for (classIndex=0; section_names[classIndex]; classIndex++) {
6840 printf("[%s]\n", section_names[classIndex]);
6841 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6842 if (parm_table[parmIndex].p_class == classIndex) {
6843 show_parameter(parmIndex);
6849 /***************************************************************************
6850 Check if a given string correctly represents a boolean value.
6851 ***************************************************************************/
6853 bool lp_string_is_valid_boolean(const char *parm_value)
6855 return set_boolean(parm_value, NULL);
6858 /***************************************************************************
6859 Get the standard string representation of a boolean value ("yes" or "no")
6860 ***************************************************************************/
6862 static const char *get_boolean(bool bool_value)
6864 static const char *yes_str = "yes";
6865 static const char *no_str = "no";
6867 return (bool_value ? yes_str : no_str);
6870 /***************************************************************************
6871 Provide the string of the negated boolean value associated to the boolean
6872 given as a string. Returns False if the passed string does not correctly
6873 represent a boolean.
6874 ***************************************************************************/
6876 bool lp_invert_boolean(const char *str, const char **inverse_str)
6880 if (!set_boolean(str, &val)) {
6884 *inverse_str = get_boolean(!val);
6888 /***************************************************************************
6889 Provide the canonical string representation of a boolean value given
6890 as a string. Return True on success, False if the string given does
6891 not correctly represent a boolean.
6892 ***************************************************************************/
6894 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6898 if (!set_boolean(str, &val)) {
6902 *canon_str = get_boolean(val);
6906 /***************************************************************************
6907 Find a service by name. Otherwise works like get_service.
6908 ***************************************************************************/
6910 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6916 if (ServiceHash == NULL) {
6920 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6922 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6924 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6925 iService = *(int *)data.dptr;
6928 TALLOC_FREE(canon_name);
6930 if ((iService != -1) && (LP_SNUM_OK(iService))
6931 && (pserviceDest != NULL)) {
6932 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6938 /***************************************************************************
6939 Copy a service structure to another.
6940 If pcopymapDest is NULL then copy all fields
6941 ***************************************************************************/
6944 * Add a parametric option to a param_opt_struct,
6945 * replacing old value, if already present.
6947 static void set_param_opt(struct param_opt_struct **opt_list,
6948 const char *opt_name,
6949 const char *opt_value,
6952 struct param_opt_struct *new_opt, *opt;
6955 if (opt_list == NULL) {
6962 /* Traverse destination */
6964 /* If we already have same option, override it */
6965 if (strwicmp(opt->key, opt_name) == 0) {
6966 if ((opt->flags & FLAG_CMDLINE) &&
6967 !(flags & FLAG_CMDLINE)) {
6968 /* it's been marked as not to be
6972 string_free(&opt->value);
6973 TALLOC_FREE(opt->list);
6974 opt->value = SMB_STRDUP(opt_value);
6982 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6983 new_opt->key = SMB_STRDUP(opt_name);
6984 new_opt->value = SMB_STRDUP(opt_value);
6985 new_opt->list = NULL;
6986 new_opt->flags = flags;
6987 DLIST_ADD(*opt_list, new_opt);
6991 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6992 struct bitmap *pcopymapDest)
6995 bool bcopyall = (pcopymapDest == NULL);
6996 struct param_opt_struct *data;
6998 for (i = 0; parm_table[i].label; i++)
6999 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
7000 (bcopyall || bitmap_query(pcopymapDest,i))) {
7001 void *def_ptr = parm_table[i].ptr;
7003 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
7006 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
7009 switch (parm_table[i].type) {
7012 *(bool *)dest_ptr = *(bool *)src_ptr;
7018 *(int *)dest_ptr = *(int *)src_ptr;
7022 *(char *)dest_ptr = *(char *)src_ptr;
7026 string_set((char **)dest_ptr,
7031 string_set((char **)dest_ptr,
7033 strupper_m(*(char **)dest_ptr);
7036 TALLOC_FREE(*((char ***)dest_ptr));
7037 *((char ***)dest_ptr) = str_list_copy(NULL,
7038 *(const char ***)src_ptr);
7046 init_copymap(pserviceDest);
7047 if (pserviceSource->copymap)
7048 bitmap_copy(pserviceDest->copymap,
7049 pserviceSource->copymap);
7052 data = pserviceSource->param_opt;
7054 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->flags);
7059 /***************************************************************************
7060 Check a service for consistency. Return False if the service is in any way
7061 incomplete or faulty, else True.
7062 ***************************************************************************/
7064 bool service_ok(int iService)
7069 if (ServicePtrs[iService]->szService[0] == '\0') {
7070 DEBUG(0, ("The following message indicates an internal error:\n"));
7071 DEBUG(0, ("No service name in service entry.\n"));
7075 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
7076 /* I can't see why you'd want a non-printable printer service... */
7077 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
7078 if (!ServicePtrs[iService]->bPrint_ok) {
7079 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
7080 ServicePtrs[iService]->szService));
7081 ServicePtrs[iService]->bPrint_ok = True;
7083 /* [printers] service must also be non-browsable. */
7084 if (ServicePtrs[iService]->bBrowseable)
7085 ServicePtrs[iService]->bBrowseable = False;
7088 if (ServicePtrs[iService]->szPath[0] == '\0' &&
7089 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
7090 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
7092 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
7093 ServicePtrs[iService]->szService));
7094 ServicePtrs[iService]->bAvailable = False;
7097 /* If a service is flagged unavailable, log the fact at level 1. */
7098 if (!ServicePtrs[iService]->bAvailable)
7099 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
7100 ServicePtrs[iService]->szService));
7105 static struct smbconf_ctx *lp_smbconf_ctx(void)
7108 static struct smbconf_ctx *conf_ctx = NULL;
7110 if (conf_ctx == NULL) {
7111 werr = smbconf_init(NULL, &conf_ctx, "registry:");
7112 if (!W_ERROR_IS_OK(werr)) {
7113 DEBUG(1, ("error initializing registry configuration: "
7114 "%s\n", win_errstr(werr)));
7122 static bool process_smbconf_service(struct smbconf_service *service)
7127 if (service == NULL) {
7131 ret = do_section(service->name, NULL);
7135 for (count = 0; count < service->num_params; count++) {
7136 ret = do_parameter(service->param_names[count],
7137 service->param_values[count],
7143 if (iServiceIndex >= 0) {
7144 return service_ok(iServiceIndex);
7150 * load a service from registry and activate it
7152 bool process_registry_service(const char *service_name)
7155 struct smbconf_service *service = NULL;
7156 TALLOC_CTX *mem_ctx = talloc_stackframe();
7157 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7160 if (conf_ctx == NULL) {
7164 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7166 if (!smbconf_share_exists(conf_ctx, service_name)) {
7168 * Registry does not contain data for this service (yet),
7169 * but make sure lp_load doesn't return false.
7175 werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7176 if (!W_ERROR_IS_OK(werr)) {
7180 ret = process_smbconf_service(service);
7186 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7189 TALLOC_FREE(mem_ctx);
7194 * process_registry_globals
7196 static bool process_registry_globals(void)
7200 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7202 ret = do_parameter("registry shares", "yes", NULL);
7207 return process_registry_service(GLOBAL_NAME);
7210 bool process_registry_shares(void)
7214 struct smbconf_service **service = NULL;
7215 uint32_t num_shares = 0;
7216 TALLOC_CTX *mem_ctx = talloc_stackframe();
7217 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7220 if (conf_ctx == NULL) {
7224 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7225 if (!W_ERROR_IS_OK(werr)) {
7231 for (count = 0; count < num_shares; count++) {
7232 if (strequal(service[count]->name, GLOBAL_NAME)) {
7235 ret = process_smbconf_service(service[count]);
7242 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7245 TALLOC_FREE(mem_ctx);
7249 #define MAX_INCLUDE_DEPTH 100
7251 static uint8_t include_depth;
7253 static struct file_lists {
7254 struct file_lists *next;
7258 } *file_lists = NULL;
7260 /*******************************************************************
7261 Keep a linked list of all config files so we know when one has changed
7262 it's date and needs to be reloaded.
7263 ********************************************************************/
7265 static void add_to_file_list(const char *fname, const char *subfname)
7267 struct file_lists *f = file_lists;
7270 if (f->name && !strcmp(f->name, fname))
7276 f = SMB_MALLOC_P(struct file_lists);
7279 f->next = file_lists;
7280 f->name = SMB_STRDUP(fname);
7285 f->subfname = SMB_STRDUP(subfname);
7292 f->modtime = file_modtime(subfname);
7294 time_t t = file_modtime(subfname);
7302 * Free the file lists
7304 static void free_file_list(void)
7306 struct file_lists *f;
7307 struct file_lists *next;
7312 SAFE_FREE( f->name );
7313 SAFE_FREE( f->subfname );
7322 * Utility function for outsiders to check if we're running on registry.
7324 bool lp_config_backend_is_registry(void)
7326 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7330 * Utility function to check if the config backend is FILE.
7332 bool lp_config_backend_is_file(void)
7334 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7337 /*******************************************************************
7338 Check if a config file has changed date.
7339 ********************************************************************/
7341 bool lp_file_list_changed(void)
7343 struct file_lists *f = file_lists;
7345 DEBUG(6, ("lp_file_list_changed()\n"));
7350 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7351 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7353 if (conf_ctx == NULL) {
7356 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7359 DEBUGADD(6, ("registry config changed\n"));
7364 n2 = talloc_sub_basic(talloc_tos(),
7365 get_current_username(),
7366 current_user_info.domain,
7371 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7372 f->name, n2, ctime(&f->modtime)));
7374 mod_time = file_modtime(n2);
7377 ((f->modtime != mod_time) ||
7378 (f->subfname == NULL) ||
7379 (strcmp(n2, f->subfname) != 0)))
7382 ("file %s modified: %s\n", n2,
7384 f->modtime = mod_time;
7385 SAFE_FREE(f->subfname);
7386 f->subfname = SMB_STRDUP(n2);
7398 /***************************************************************************
7399 Run standard_sub_basic on netbios name... needed because global_myname
7400 is not accessed through any lp_ macro.
7401 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7402 ***************************************************************************/
7404 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7407 char *netbios_name = talloc_sub_basic(
7408 talloc_tos(), get_current_username(), current_user_info.domain,
7411 ret = set_global_myname(netbios_name);
7412 TALLOC_FREE(netbios_name);
7413 string_set(&Globals.szNetbiosName,global_myname());
7415 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7421 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7423 if (strcmp(*ptr, pszParmValue) != 0) {
7424 string_set(ptr, pszParmValue);
7432 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7436 ret = set_global_myworkgroup(pszParmValue);
7437 string_set(&Globals.szWorkgroup,lp_workgroup());
7442 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7446 ret = set_global_scope(pszParmValue);
7447 string_set(&Globals.szNetbiosScope,global_scope());
7452 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7454 TALLOC_FREE(Globals.szNetbiosAliases);
7455 Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
7456 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7459 /***************************************************************************
7460 Handle the include operation.
7461 ***************************************************************************/
7462 static bool bAllowIncludeRegistry = true;
7464 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7468 if (include_depth >= MAX_INCLUDE_DEPTH) {
7469 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7474 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7475 if (!bAllowIncludeRegistry) {
7478 if (bInGlobalSection) {
7481 ret = process_registry_globals();
7485 DEBUG(1, ("\"include = registry\" only effective "
7486 "in %s section\n", GLOBAL_NAME));
7491 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7492 current_user_info.domain,
7495 add_to_file_list(pszParmValue, fname);
7497 string_set(ptr, fname);
7499 if (file_exist(fname)) {
7502 ret = pm_process(fname, do_section, do_parameter, NULL);
7508 DEBUG(2, ("Can't find include file %s\n", fname));
7513 /***************************************************************************
7514 Handle the interpretation of the copy parameter.
7515 ***************************************************************************/
7517 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7521 struct service serviceTemp;
7523 string_set(ptr, pszParmValue);
7525 init_service(&serviceTemp);
7529 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7531 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7532 if (iTemp == iServiceIndex) {
7533 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7535 copy_service(ServicePtrs[iServiceIndex],
7537 ServicePtrs[iServiceIndex]->copymap);
7541 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7545 free_service(&serviceTemp);
7549 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7551 Globals.ldap_debug_level = lp_int(pszParmValue);
7552 init_ldap_debugging();
7556 /***************************************************************************
7557 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7562 idmap uid = 1000-1999
7565 We only do simple parsing checks here. The strings are parsed into useful
7566 structures in the idmap daemon code.
7568 ***************************************************************************/
7570 /* Some lp_ routines to return idmap [ug]id information */
7572 static uid_t idmap_uid_low, idmap_uid_high;
7573 static gid_t idmap_gid_low, idmap_gid_high;
7575 bool lp_idmap_uid(uid_t *low, uid_t *high)
7577 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7581 *low = idmap_uid_low;
7584 *high = idmap_uid_high;
7589 bool lp_idmap_gid(gid_t *low, gid_t *high)
7591 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7595 *low = idmap_gid_low;
7598 *high = idmap_gid_high;
7603 /* Do some simple checks on "idmap [ug]id" parameter values */
7605 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7609 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7614 string_set(ptr, pszParmValue);
7616 idmap_uid_low = low;
7617 idmap_uid_high = high;
7622 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7626 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7631 string_set(ptr, pszParmValue);
7633 idmap_gid_low = low;
7634 idmap_gid_high = high;
7639 /***************************************************************************
7640 Handle the DEBUG level list.
7641 ***************************************************************************/
7643 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7645 string_set(ptr, pszParmValueIn);
7646 return debug_parse_levels(pszParmValueIn);
7649 /***************************************************************************
7650 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7651 ***************************************************************************/
7653 static const char *append_ldap_suffix( const char *str )
7655 const char *suffix_string;
7658 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7659 Globals.szLdapSuffix );
7660 if ( !suffix_string ) {
7661 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7665 return suffix_string;
7668 const char *lp_ldap_machine_suffix(void)
7670 if (Globals.szLdapMachineSuffix[0])
7671 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7673 return lp_string(Globals.szLdapSuffix);
7676 const char *lp_ldap_user_suffix(void)
7678 if (Globals.szLdapUserSuffix[0])
7679 return append_ldap_suffix(Globals.szLdapUserSuffix);
7681 return lp_string(Globals.szLdapSuffix);
7684 const char *lp_ldap_group_suffix(void)
7686 if (Globals.szLdapGroupSuffix[0])
7687 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7689 return lp_string(Globals.szLdapSuffix);
7692 const char *lp_ldap_idmap_suffix(void)
7694 if (Globals.szLdapIdmapSuffix[0])
7695 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7697 return lp_string(Globals.szLdapSuffix);
7700 /****************************************************************************
7701 set the value for a P_ENUM
7702 ***************************************************************************/
7704 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7709 for (i = 0; parm->enum_list[i].name; i++) {
7710 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7711 *ptr = parm->enum_list[i].value;
7715 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7716 pszParmValue, parm->label));
7719 /***************************************************************************
7720 ***************************************************************************/
7722 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7724 static int parm_num = -1;
7727 if ( parm_num == -1 )
7728 parm_num = map_parameter( "printing" );
7730 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7735 s = ServicePtrs[snum];
7737 init_printer_values( s );
7743 /***************************************************************************
7744 Initialise a copymap.
7745 ***************************************************************************/
7747 static void init_copymap(struct service *pservice)
7751 TALLOC_FREE(pservice->copymap);
7753 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7754 if (!pservice->copymap)
7756 ("Couldn't allocate copymap!! (size %d)\n",
7757 (int)NUMPARAMETERS));
7759 for (i = 0; i < NUMPARAMETERS; i++)
7760 bitmap_set(pservice->copymap, i);
7763 /***************************************************************************
7764 Return the local pointer to a parameter given a service struct and the
7765 pointer into the default structure.
7766 ***************************************************************************/
7768 static void *lp_local_ptr(struct service *service, void *ptr)
7770 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7773 /***************************************************************************
7774 Return the local pointer to a parameter given the service number and the
7775 pointer into the default structure.
7776 ***************************************************************************/
7778 void *lp_local_ptr_by_snum(int snum, void *ptr)
7780 return lp_local_ptr(ServicePtrs[snum], ptr);
7783 /***************************************************************************
7784 Process a parameter for a particular service number. If snum < 0
7785 then assume we are in the globals.
7786 ***************************************************************************/
7788 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7791 void *parm_ptr = NULL; /* where we are going to store the result */
7792 void *def_ptr = NULL;
7793 struct param_opt_struct **opt_list;
7795 parmnum = map_parameter(pszParmName);
7798 if (strchr(pszParmName, ':') == NULL) {
7799 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7805 * We've got a parametric option
7808 opt_list = (snum < 0)
7809 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7810 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7815 /* if it's already been set by the command line, then we don't
7817 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7821 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7822 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7826 def_ptr = parm_table[parmnum].ptr;
7828 /* we might point at a service, the default service or a global */
7832 if (parm_table[parmnum].p_class == P_GLOBAL) {
7834 ("Global parameter %s found in service section!\n",
7838 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7842 if (!ServicePtrs[snum]->copymap)
7843 init_copymap(ServicePtrs[snum]);
7845 /* this handles the aliases - set the copymap for other entries with
7846 the same data pointer */
7847 for (i = 0; parm_table[i].label; i++)
7848 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7849 bitmap_clear(ServicePtrs[snum]->copymap, i);
7852 /* if it is a special case then go ahead */
7853 if (parm_table[parmnum].special) {
7854 return parm_table[parmnum].special(snum, pszParmValue,
7858 /* now switch on the type of variable it is */
7859 switch (parm_table[parmnum].type)
7862 *(bool *)parm_ptr = lp_bool(pszParmValue);
7866 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7870 *(int *)parm_ptr = lp_int(pszParmValue);
7874 *(char *)parm_ptr = *pszParmValue;
7878 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7880 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7885 TALLOC_FREE(*((char ***)parm_ptr));
7886 *(char ***)parm_ptr = str_list_make_v3(
7887 NULL, pszParmValue, NULL);
7891 string_set((char **)parm_ptr, pszParmValue);
7895 string_set((char **)parm_ptr, pszParmValue);
7896 strupper_m(*(char **)parm_ptr);
7900 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7909 /***************************************************************************
7910 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7911 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7912 ***************************************************************************/
7914 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7917 parmnum = map_parameter(pszParmName);
7919 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7920 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7923 parm_table[parmnum].flags |= FLAG_CMDLINE;
7925 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7926 * be grouped in the table, so we don't have to search the
7928 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
7929 parm_table[i].flags |= FLAG_CMDLINE;
7931 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
7932 parm_table[i].flags |= FLAG_CMDLINE;
7936 store_lp_set_cmdline(pszParmName, pszParmValue);
7941 /* it might be parametric */
7942 if (strchr(pszParmName, ':') != NULL) {
7943 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7945 store_lp_set_cmdline(pszParmName, pszParmValue);
7950 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7954 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7956 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7959 /***************************************************************************
7960 Process a parameter.
7961 ***************************************************************************/
7963 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7966 if (!bInGlobalSection && bGlobalOnly)
7969 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7971 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7972 pszParmName, pszParmValue));
7976 set a option from the commandline in 'a=b' format. Use to support --option
7978 bool lp_set_option(const char *option)
7983 s = talloc_strdup(NULL, option);
7996 ret = lp_set_cmdline(s, p+1);
8001 /**************************************************************************
8002 Print a parameter of the specified type.
8003 ***************************************************************************/
8005 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
8011 for (i = 0; p->enum_list[i].name; i++) {
8012 if (*(int *)ptr == p->enum_list[i].value) {
8014 p->enum_list[i].name);
8021 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
8025 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
8029 fprintf(f, "%d", *(int *)ptr);
8033 fprintf(f, "%c", *(char *)ptr);
8037 char *o = octal_string(*(int *)ptr);
8038 fprintf(f, "%s", o);
8044 if ((char ***)ptr && *(char ***)ptr) {
8045 char **list = *(char ***)ptr;
8046 for (; *list; list++) {
8047 /* surround strings with whitespace in double quotes */
8048 if ( strchr_m( *list, ' ' ) )
8049 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
8051 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
8058 if (*(char **)ptr) {
8059 fprintf(f, "%s", *(char **)ptr);
8067 /***************************************************************************
8068 Check if two parameters are equal.
8069 ***************************************************************************/
8071 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8076 return (*((bool *)ptr1) == *((bool *)ptr2));
8081 return (*((int *)ptr1) == *((int *)ptr2));
8084 return (*((char *)ptr1) == *((char *)ptr2));
8087 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8092 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8097 return (p1 == p2 || strequal(p1, p2));
8105 /***************************************************************************
8106 Initialize any local varients in the sDefault table.
8107 ***************************************************************************/
8109 void init_locals(void)
8114 /***************************************************************************
8115 Process a new section (service). At this stage all sections are services.
8116 Later we'll have special sections that permit server parameters to be set.
8117 Returns True on success, False on failure.
8118 ***************************************************************************/
8120 static bool do_section(const char *pszSectionName, void *userdata)
8123 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8124 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8127 /* if we were in a global section then do the local inits */
8128 if (bInGlobalSection && !isglobal)
8131 /* if we've just struck a global section, note the fact. */
8132 bInGlobalSection = isglobal;
8134 /* check for multiple global sections */
8135 if (bInGlobalSection) {
8136 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8140 if (!bInGlobalSection && bGlobalOnly)
8143 /* if we have a current service, tidy it up before moving on */
8146 if (iServiceIndex >= 0)
8147 bRetval = service_ok(iServiceIndex);
8149 /* if all is still well, move to the next record in the services array */
8151 /* We put this here to avoid an odd message order if messages are */
8152 /* issued by the post-processing of a previous section. */
8153 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8155 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8157 DEBUG(0, ("Failed to add a new service\n"));
8160 /* Clean all parametric options for service */
8161 /* They will be added during parsing again */
8162 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
8169 /***************************************************************************
8170 Determine if a partcular base parameter is currentl set to the default value.
8171 ***************************************************************************/
8173 static bool is_default(int i)
8175 if (!defaults_saved)
8177 switch (parm_table[i].type) {
8179 return str_list_equal((const char **)parm_table[i].def.lvalue,
8180 *(const char ***)parm_table[i].ptr);
8183 return strequal(parm_table[i].def.svalue,
8184 *(char **)parm_table[i].ptr);
8187 return parm_table[i].def.bvalue ==
8188 *(bool *)parm_table[i].ptr;
8190 return parm_table[i].def.cvalue ==
8191 *(char *)parm_table[i].ptr;
8195 return parm_table[i].def.ivalue ==
8196 *(int *)parm_table[i].ptr;
8203 /***************************************************************************
8204 Display the contents of the global structure.
8205 ***************************************************************************/
8207 static void dump_globals(FILE *f)
8210 struct param_opt_struct *data;
8212 fprintf(f, "[global]\n");
8214 for (i = 0; parm_table[i].label; i++)
8215 if (parm_table[i].p_class == P_GLOBAL &&
8216 !(parm_table[i].flags & FLAG_META) &&
8217 parm_table[i].ptr &&
8218 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8219 if (defaults_saved && is_default(i))
8221 fprintf(f, "\t%s = ", parm_table[i].label);
8222 print_parameter(&parm_table[i], parm_table[i].ptr, f);
8225 if (Globals.param_opt != NULL) {
8226 data = Globals.param_opt;
8228 fprintf(f, "\t%s = %s\n", data->key, data->value);
8235 /***************************************************************************
8236 Return True if a local parameter is currently set to the global default.
8237 ***************************************************************************/
8239 bool lp_is_default(int snum, struct parm_struct *parm)
8241 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8243 return equal_parameter(parm->type,
8244 ((char *)ServicePtrs[snum]) + pdiff,
8245 ((char *)&sDefault) + pdiff);
8248 /***************************************************************************
8249 Display the contents of a single services record.
8250 ***************************************************************************/
8252 static void dump_a_service(struct service *pService, FILE * f)
8255 struct param_opt_struct *data;
8257 if (pService != &sDefault)
8258 fprintf(f, "[%s]\n", pService->szService);
8260 for (i = 0; parm_table[i].label; i++) {
8262 if (parm_table[i].p_class == P_LOCAL &&
8263 !(parm_table[i].flags & FLAG_META) &&
8264 parm_table[i].ptr &&
8265 (*parm_table[i].label != '-') &&
8266 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8268 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8270 if (pService == &sDefault) {
8271 if (defaults_saved && is_default(i))
8274 if (equal_parameter(parm_table[i].type,
8275 ((char *)pService) +
8277 ((char *)&sDefault) +
8282 fprintf(f, "\t%s = ", parm_table[i].label);
8283 print_parameter(&parm_table[i],
8284 ((char *)pService) + pdiff, f);
8289 if (pService->param_opt != NULL) {
8290 data = pService->param_opt;
8292 fprintf(f, "\t%s = %s\n", data->key, data->value);
8298 /***************************************************************************
8299 Display the contents of a parameter of a single services record.
8300 ***************************************************************************/
8302 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8305 bool result = False;
8308 fstring local_parm_name;
8310 const char *parm_opt_value;
8312 /* check for parametrical option */
8313 fstrcpy( local_parm_name, parm_name);
8314 parm_opt = strchr( local_parm_name, ':');
8319 if (strlen(parm_opt)) {
8320 parm_opt_value = lp_parm_const_string( snum,
8321 local_parm_name, parm_opt, NULL);
8322 if (parm_opt_value) {
8323 printf( "%s\n", parm_opt_value);
8330 /* check for a key and print the value */
8337 for (i = 0; parm_table[i].label; i++) {
8338 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8339 !(parm_table[i].flags & FLAG_META) &&
8340 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8341 parm_table[i].ptr &&
8342 (*parm_table[i].label != '-') &&
8343 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8348 ptr = parm_table[i].ptr;
8350 struct service *pService = ServicePtrs[snum];
8351 ptr = ((char *)pService) +
8352 PTR_DIFF(parm_table[i].ptr, &sDefault);
8355 print_parameter(&parm_table[i],
8366 /***************************************************************************
8367 Return info about the requested parameter (given as a string).
8368 Return NULL when the string is not a valid parameter name.
8369 ***************************************************************************/
8371 struct parm_struct *lp_get_parameter(const char *param_name)
8373 int num = map_parameter(param_name);
8379 return &parm_table[num];
8382 /***************************************************************************
8383 Return info about the next parameter in a service.
8384 snum==GLOBAL_SECTION_SNUM gives the globals.
8385 Return NULL when out of parameters.
8386 ***************************************************************************/
8388 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8391 /* do the globals */
8392 for (; parm_table[*i].label; (*i)++) {
8393 if (parm_table[*i].p_class == P_SEPARATOR)
8394 return &parm_table[(*i)++];
8396 if (!parm_table[*i].ptr
8397 || (*parm_table[*i].label == '-'))
8401 && (parm_table[*i].ptr ==
8402 parm_table[(*i) - 1].ptr))
8405 if (is_default(*i) && !allparameters)
8408 return &parm_table[(*i)++];
8411 struct service *pService = ServicePtrs[snum];
8413 for (; parm_table[*i].label; (*i)++) {
8414 if (parm_table[*i].p_class == P_SEPARATOR)
8415 return &parm_table[(*i)++];
8417 if (parm_table[*i].p_class == P_LOCAL &&
8418 parm_table[*i].ptr &&
8419 (*parm_table[*i].label != '-') &&
8421 (parm_table[*i].ptr !=
8422 parm_table[(*i) - 1].ptr)))
8425 PTR_DIFF(parm_table[*i].ptr,
8428 if (allparameters ||
8429 !equal_parameter(parm_table[*i].type,
8430 ((char *)pService) +
8432 ((char *)&sDefault) +
8435 return &parm_table[(*i)++];
8446 /***************************************************************************
8447 Display the contents of a single copy structure.
8448 ***************************************************************************/
8449 static void dump_copy_map(bool *pcopymap)
8455 printf("\n\tNon-Copied parameters:\n");
8457 for (i = 0; parm_table[i].label; i++)
8458 if (parm_table[i].p_class == P_LOCAL &&
8459 parm_table[i].ptr && !pcopymap[i] &&
8460 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8462 printf("\t\t%s\n", parm_table[i].label);
8467 /***************************************************************************
8468 Return TRUE if the passed service number is within range.
8469 ***************************************************************************/
8471 bool lp_snum_ok(int iService)
8473 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8476 /***************************************************************************
8477 Auto-load some home services.
8478 ***************************************************************************/
8480 static void lp_add_auto_services(char *str)
8490 s = SMB_STRDUP(str);
8494 homes = lp_servicenumber(HOMES_NAME);
8496 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8497 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8500 if (lp_servicenumber(p) >= 0)
8503 home = get_user_home_dir(talloc_tos(), p);
8505 if (home && home[0] && homes >= 0)
8506 lp_add_home(p, homes, p, home);
8513 /***************************************************************************
8514 Auto-load one printer.
8515 ***************************************************************************/
8517 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8519 int printers = lp_servicenumber(PRINTERS_NAME);
8522 if (lp_servicenumber(name) < 0) {
8523 lp_add_printer(name, printers);
8524 if ((i = lp_servicenumber(name)) >= 0) {
8525 string_set(&ServicePtrs[i]->comment, comment);
8526 ServicePtrs[i]->autoloaded = True;
8531 /***************************************************************************
8532 Have we loaded a services file yet?
8533 ***************************************************************************/
8535 bool lp_loaded(void)
8540 /***************************************************************************
8541 Unload unused services.
8542 ***************************************************************************/
8544 void lp_killunused(bool (*snumused) (int))
8547 for (i = 0; i < iNumServices; i++) {
8551 /* don't kill autoloaded or usershare services */
8552 if ( ServicePtrs[i]->autoloaded ||
8553 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8557 if (!snumused || !snumused(i)) {
8558 free_service_byindex(i);
8564 * Kill all except autoloaded and usershare services - convenience wrapper
8566 void lp_kill_all_services(void)
8568 lp_killunused(NULL);
8571 /***************************************************************************
8573 ***************************************************************************/
8575 void lp_killservice(int iServiceIn)
8577 if (VALID(iServiceIn)) {
8578 free_service_byindex(iServiceIn);
8582 /***************************************************************************
8583 Save the curent values of all global and sDefault parameters into the
8584 defaults union. This allows swat and testparm to show only the
8585 changed (ie. non-default) parameters.
8586 ***************************************************************************/
8588 static void lp_save_defaults(void)
8591 for (i = 0; parm_table[i].label; i++) {
8592 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8594 switch (parm_table[i].type) {
8596 parm_table[i].def.lvalue = str_list_copy(
8597 NULL, *(const char ***)parm_table[i].ptr);
8601 if (parm_table[i].ptr) {
8602 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8604 parm_table[i].def.svalue = NULL;
8609 parm_table[i].def.bvalue =
8610 *(bool *)parm_table[i].ptr;
8613 parm_table[i].def.cvalue =
8614 *(char *)parm_table[i].ptr;
8619 parm_table[i].def.ivalue =
8620 *(int *)parm_table[i].ptr;
8626 defaults_saved = True;
8629 /***********************************************************
8630 If we should send plaintext/LANMAN passwords in the clinet
8631 ************************************************************/
8633 static void set_allowed_client_auth(void)
8635 if (Globals.bClientNTLMv2Auth) {
8636 Globals.bClientLanManAuth = False;
8638 if (!Globals.bClientLanManAuth) {
8639 Globals.bClientPlaintextAuth = False;
8643 /***************************************************************************
8645 The following code allows smbd to read a user defined share file.
8646 Yes, this is my intent. Yes, I'm comfortable with that...
8648 THE FOLLOWING IS SECURITY CRITICAL CODE.
8650 It washes your clothes, it cleans your house, it guards you while you sleep...
8651 Do not f%^k with it....
8652 ***************************************************************************/
8654 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8656 /***************************************************************************
8657 Check allowed stat state of a usershare file.
8658 Ensure we print out who is dicking with us so the admin can
8659 get their sorry ass fired.
8660 ***************************************************************************/
8662 static bool check_usershare_stat(const char *fname,
8663 const SMB_STRUCT_STAT *psbuf)
8665 if (!S_ISREG(psbuf->st_ex_mode)) {
8666 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8667 "not a regular file\n",
8668 fname, (unsigned int)psbuf->st_ex_uid ));
8672 /* Ensure this doesn't have the other write bit set. */
8673 if (psbuf->st_ex_mode & S_IWOTH) {
8674 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8675 "public write. Refusing to allow as a usershare file.\n",
8676 fname, (unsigned int)psbuf->st_ex_uid ));
8680 /* Should be 10k or less. */
8681 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8682 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8683 "too large (%u) to be a user share file.\n",
8684 fname, (unsigned int)psbuf->st_ex_uid,
8685 (unsigned int)psbuf->st_ex_size ));
8692 /***************************************************************************
8693 Parse the contents of a usershare file.
8694 ***************************************************************************/
8696 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8697 SMB_STRUCT_STAT *psbuf,
8698 const char *servicename,
8702 char **pp_sharepath,
8704 char **pp_cp_servicename,
8705 struct security_descriptor **ppsd,
8708 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8709 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8712 SMB_STRUCT_STAT sbuf;
8713 char *sharepath = NULL;
8714 char *comment = NULL;
8716 *pp_sharepath = NULL;
8719 *pallow_guest = False;
8722 return USERSHARE_MALFORMED_FILE;
8725 if (strcmp(lines[0], "#VERSION 1") == 0) {
8727 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8730 return USERSHARE_MALFORMED_FILE;
8733 return USERSHARE_BAD_VERSION;
8736 if (strncmp(lines[1], "path=", 5) != 0) {
8737 return USERSHARE_MALFORMED_PATH;
8740 sharepath = talloc_strdup(ctx, &lines[1][5]);
8742 return USERSHARE_POSIX_ERR;
8744 trim_string(sharepath, " ", " ");
8746 if (strncmp(lines[2], "comment=", 8) != 0) {
8747 return USERSHARE_MALFORMED_COMMENT_DEF;
8750 comment = talloc_strdup(ctx, &lines[2][8]);
8752 return USERSHARE_POSIX_ERR;
8754 trim_string(comment, " ", " ");
8755 trim_char(comment, '"', '"');
8757 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8758 return USERSHARE_MALFORMED_ACL_DEF;
8761 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8762 return USERSHARE_ACL_ERR;
8766 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8767 return USERSHARE_MALFORMED_ACL_DEF;
8769 if (lines[4][9] == 'y') {
8770 *pallow_guest = True;
8773 /* Backwards compatible extension to file version #2. */
8775 if (strncmp(lines[5], "sharename=", 10) != 0) {
8776 return USERSHARE_MALFORMED_SHARENAME_DEF;
8778 if (!strequal(&lines[5][10], servicename)) {
8779 return USERSHARE_BAD_SHARENAME;
8781 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8782 if (!*pp_cp_servicename) {
8783 return USERSHARE_POSIX_ERR;
8788 if (*pp_cp_servicename == NULL) {
8789 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8790 if (!*pp_cp_servicename) {
8791 return USERSHARE_POSIX_ERR;
8795 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8796 /* Path didn't change, no checks needed. */
8797 *pp_sharepath = sharepath;
8798 *pp_comment = comment;
8799 return USERSHARE_OK;
8802 /* The path *must* be absolute. */
8803 if (sharepath[0] != '/') {
8804 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8805 servicename, sharepath));
8806 return USERSHARE_PATH_NOT_ABSOLUTE;
8809 /* If there is a usershare prefix deny list ensure one of these paths
8810 doesn't match the start of the user given path. */
8811 if (prefixdenylist) {
8813 for ( i=0; prefixdenylist[i]; i++ ) {
8814 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8815 servicename, i, prefixdenylist[i], sharepath ));
8816 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8817 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8818 "usershare prefix deny list entries.\n",
8819 servicename, sharepath));
8820 return USERSHARE_PATH_IS_DENIED;
8825 /* If there is a usershare prefix allow list ensure one of these paths
8826 does match the start of the user given path. */
8828 if (prefixallowlist) {
8830 for ( i=0; prefixallowlist[i]; i++ ) {
8831 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8832 servicename, i, prefixallowlist[i], sharepath ));
8833 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8837 if (prefixallowlist[i] == NULL) {
8838 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8839 "usershare prefix allow list entries.\n",
8840 servicename, sharepath));
8841 return USERSHARE_PATH_NOT_ALLOWED;
8845 /* Ensure this is pointing to a directory. */
8846 dp = sys_opendir(sharepath);
8849 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8850 servicename, sharepath));
8851 return USERSHARE_PATH_NOT_DIRECTORY;
8854 /* Ensure the owner of the usershare file has permission to share
8857 if (sys_stat(sharepath, &sbuf, false) == -1) {
8858 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8859 servicename, sharepath, strerror(errno) ));
8861 return USERSHARE_POSIX_ERR;
8866 if (!S_ISDIR(sbuf.st_ex_mode)) {
8867 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8868 servicename, sharepath ));
8869 return USERSHARE_PATH_NOT_DIRECTORY;
8872 /* Check if sharing is restricted to owner-only. */
8873 /* psbuf is the stat of the usershare definition file,
8874 sbuf is the stat of the target directory to be shared. */
8876 if (lp_usershare_owner_only()) {
8877 /* root can share anything. */
8878 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8879 return USERSHARE_PATH_NOT_ALLOWED;
8883 *pp_sharepath = sharepath;
8884 *pp_comment = comment;
8885 return USERSHARE_OK;
8888 /***************************************************************************
8889 Deal with a usershare file.
8892 -1 - Bad name, invalid contents.
8893 - service name already existed and not a usershare, problem
8894 with permissions to share directory etc.
8895 ***************************************************************************/
8897 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8899 SMB_STRUCT_STAT sbuf;
8900 SMB_STRUCT_STAT lsbuf;
8902 char *sharepath = NULL;
8903 char *comment = NULL;
8904 char *cp_service_name = NULL;
8905 char **lines = NULL;
8909 TALLOC_CTX *ctx = talloc_stackframe();
8910 struct security_descriptor *psd = NULL;
8911 bool guest_ok = False;
8912 char *canon_name = NULL;
8913 bool added_service = false;
8916 /* Ensure share name doesn't contain invalid characters. */
8917 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8918 DEBUG(0,("process_usershare_file: share name %s contains "
8919 "invalid characters (any of %s)\n",
8920 file_name, INVALID_SHARENAME_CHARS ));
8924 canon_name = canonicalize_servicename(ctx, file_name);
8929 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8934 /* Minimize the race condition by doing an lstat before we
8935 open and fstat. Ensure this isn't a symlink link. */
8937 if (sys_lstat(fname, &lsbuf, false) != 0) {
8938 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8939 fname, strerror(errno) ));
8943 /* This must be a regular file, not a symlink, directory or
8944 other strange filetype. */
8945 if (!check_usershare_stat(fname, &lsbuf)) {
8950 TDB_DATA data = dbwrap_fetch_bystring(
8951 ServiceHash, canon_name, canon_name);
8955 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8956 iService = *(int *)data.dptr;
8960 if (iService != -1 &&
8961 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8962 &lsbuf.st_ex_mtime) == 0) {
8963 /* Nothing changed - Mark valid and return. */
8964 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8966 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8971 /* Try and open the file read only - no symlinks allowed. */
8973 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8975 fd = sys_open(fname, O_RDONLY, 0);
8979 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8980 fname, strerror(errno) ));
8984 /* Now fstat to be *SURE* it's a regular file. */
8985 if (sys_fstat(fd, &sbuf, false) != 0) {
8987 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8988 fname, strerror(errno) ));
8992 /* Is it the same dev/inode as was lstated ? */
8993 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8995 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8996 "Symlink spoofing going on ?\n", fname ));
9000 /* This must be a regular file, not a symlink, directory or
9001 other strange filetype. */
9002 if (!check_usershare_stat(fname, &sbuf)) {
9006 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
9009 if (lines == NULL) {
9010 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
9011 fname, (unsigned int)sbuf.st_ex_uid ));
9015 if (parse_usershare_file(ctx, &sbuf, file_name,
9016 iService, lines, numlines, &sharepath,
9017 &comment, &cp_service_name,
9018 &psd, &guest_ok) != USERSHARE_OK) {
9022 /* Everything ok - add the service possibly using a template. */
9024 const struct service *sp = &sDefault;
9025 if (snum_template != -1) {
9026 sp = ServicePtrs[snum_template];
9029 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
9030 DEBUG(0, ("process_usershare_file: Failed to add "
9031 "new service %s\n", cp_service_name));
9035 added_service = true;
9037 /* Read only is controlled by usershare ACL below. */
9038 ServicePtrs[iService]->bRead_only = False;
9041 /* Write the ACL of the new/modified share. */
9042 if (!set_share_security(canon_name, psd)) {
9043 DEBUG(0, ("process_usershare_file: Failed to set share "
9044 "security for user share %s\n",
9049 /* If from a template it may be marked invalid. */
9050 ServicePtrs[iService]->valid = True;
9052 /* Set the service as a valid usershare. */
9053 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9055 /* Set guest access. */
9056 if (lp_usershare_allow_guests()) {
9057 ServicePtrs[iService]->bGuest_ok = guest_ok;
9060 /* And note when it was loaded. */
9061 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
9062 string_set(&ServicePtrs[iService]->szPath, sharepath);
9063 string_set(&ServicePtrs[iService]->comment, comment);
9069 if (ret == -1 && iService != -1 && added_service) {
9070 lp_remove_service(iService);
9078 /***************************************************************************
9079 Checks if a usershare entry has been modified since last load.
9080 ***************************************************************************/
9082 static bool usershare_exists(int iService, struct timespec *last_mod)
9084 SMB_STRUCT_STAT lsbuf;
9085 const char *usersharepath = Globals.szUsersharePath;
9088 if (asprintf(&fname, "%s/%s",
9090 ServicePtrs[iService]->szService) < 0) {
9094 if (sys_lstat(fname, &lsbuf, false) != 0) {
9099 if (!S_ISREG(lsbuf.st_ex_mode)) {
9105 *last_mod = lsbuf.st_ex_mtime;
9109 /***************************************************************************
9110 Load a usershare service by name. Returns a valid servicenumber or -1.
9111 ***************************************************************************/
9113 int load_usershare_service(const char *servicename)
9115 SMB_STRUCT_STAT sbuf;
9116 const char *usersharepath = Globals.szUsersharePath;
9117 int max_user_shares = Globals.iUsershareMaxShares;
9118 int snum_template = -1;
9120 if (*usersharepath == 0 || max_user_shares == 0) {
9124 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9125 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9126 usersharepath, strerror(errno) ));
9130 if (!S_ISDIR(sbuf.st_ex_mode)) {
9131 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9137 * This directory must be owned by root, and have the 't' bit set.
9138 * It also must not be writable by "other".
9142 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9144 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9146 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9147 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9152 /* Ensure the template share exists if it's set. */
9153 if (Globals.szUsershareTemplateShare[0]) {
9154 /* We can't use lp_servicenumber here as we are recommending that
9155 template shares have -valid=False set. */
9156 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9157 if (ServicePtrs[snum_template]->szService &&
9158 strequal(ServicePtrs[snum_template]->szService,
9159 Globals.szUsershareTemplateShare)) {
9164 if (snum_template == -1) {
9165 DEBUG(0,("load_usershare_service: usershare template share %s "
9166 "does not exist.\n",
9167 Globals.szUsershareTemplateShare ));
9172 return process_usershare_file(usersharepath, servicename, snum_template);
9175 /***************************************************************************
9176 Load all user defined shares from the user share directory.
9177 We only do this if we're enumerating the share list.
9178 This is the function that can delete usershares that have
9180 ***************************************************************************/
9182 int load_usershare_shares(void)
9185 SMB_STRUCT_STAT sbuf;
9186 SMB_STRUCT_DIRENT *de;
9187 int num_usershares = 0;
9188 int max_user_shares = Globals.iUsershareMaxShares;
9189 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9190 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9191 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9193 int snum_template = -1;
9194 const char *usersharepath = Globals.szUsersharePath;
9195 int ret = lp_numservices();
9197 if (max_user_shares == 0 || *usersharepath == '\0') {
9198 return lp_numservices();
9201 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9202 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9203 usersharepath, strerror(errno) ));
9208 * This directory must be owned by root, and have the 't' bit set.
9209 * It also must not be writable by "other".
9213 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9215 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9217 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9218 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9223 /* Ensure the template share exists if it's set. */
9224 if (Globals.szUsershareTemplateShare[0]) {
9225 /* We can't use lp_servicenumber here as we are recommending that
9226 template shares have -valid=False set. */
9227 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9228 if (ServicePtrs[snum_template]->szService &&
9229 strequal(ServicePtrs[snum_template]->szService,
9230 Globals.szUsershareTemplateShare)) {
9235 if (snum_template == -1) {
9236 DEBUG(0,("load_usershare_shares: usershare template share %s "
9237 "does not exist.\n",
9238 Globals.szUsershareTemplateShare ));
9243 /* Mark all existing usershares as pending delete. */
9244 for (iService = iNumServices - 1; iService >= 0; iService--) {
9245 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9246 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9250 dp = sys_opendir(usersharepath);
9252 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9253 usersharepath, strerror(errno) ));
9257 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9258 (de = sys_readdir(dp));
9259 num_dir_entries++ ) {
9261 const char *n = de->d_name;
9263 /* Ignore . and .. */
9265 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9271 /* Temporary file used when creating a share. */
9272 num_tmp_dir_entries++;
9275 /* Allow 20% tmp entries. */
9276 if (num_tmp_dir_entries > allowed_tmp_entries) {
9277 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9278 "in directory %s\n",
9279 num_tmp_dir_entries, usersharepath));
9283 r = process_usershare_file(usersharepath, n, snum_template);
9285 /* Update the services count. */
9287 if (num_usershares >= max_user_shares) {
9288 DEBUG(0,("load_usershare_shares: max user shares reached "
9289 "on file %s in directory %s\n",
9290 n, usersharepath ));
9293 } else if (r == -1) {
9294 num_bad_dir_entries++;
9297 /* Allow 20% bad entries. */
9298 if (num_bad_dir_entries > allowed_bad_entries) {
9299 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9300 "in directory %s\n",
9301 num_bad_dir_entries, usersharepath));
9305 /* Allow 20% bad entries. */
9306 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9307 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9308 "in directory %s\n",
9309 num_dir_entries, usersharepath));
9316 /* Sweep through and delete any non-refreshed usershares that are
9317 not currently in use. */
9318 for (iService = iNumServices - 1; iService >= 0; iService--) {
9319 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9320 if (conn_snum_used(iService)) {
9323 /* Remove from the share ACL db. */
9324 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9325 lp_servicename(iService) ));
9326 delete_share_security(lp_servicename(iService));
9327 free_service_byindex(iService);
9331 return lp_numservices();
9334 /********************************************************
9335 Destroy global resources allocated in this file
9336 ********************************************************/
9338 void gfree_loadparm(void)
9344 /* Free resources allocated to services */
9346 for ( i = 0; i < iNumServices; i++ ) {
9348 free_service_byindex(i);
9352 SAFE_FREE( ServicePtrs );
9355 /* Now release all resources allocated to global
9356 parameters and the default service */
9358 free_global_parameters();
9362 /***************************************************************************
9363 Allow client apps to specify that they are a client
9364 ***************************************************************************/
9365 void lp_set_in_client(bool b)
9371 /***************************************************************************
9372 Determine if we're running in a client app
9373 ***************************************************************************/
9374 bool lp_is_in_client(void)
9379 /***************************************************************************
9380 Load the services array from the services file. Return True on success,
9382 ***************************************************************************/
9384 static bool lp_load_ex(const char *pszFname,
9388 bool initialize_globals,
9389 bool allow_include_registry,
9390 bool allow_registry_shares)
9397 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9399 bInGlobalSection = True;
9400 bGlobalOnly = global_only;
9401 bAllowIncludeRegistry = allow_include_registry;
9403 init_globals(initialize_globals);
9408 if (save_defaults) {
9413 free_param_opts(&Globals.param_opt);
9415 /* We get sections first, so have to start 'behind' to make up */
9418 if (lp_config_backend_is_file()) {
9419 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9420 current_user_info.domain,
9423 smb_panic("lp_load_ex: out of memory");
9426 add_to_file_list(pszFname, n2);
9428 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9431 /* finish up the last section */
9432 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9434 if (iServiceIndex >= 0) {
9435 bRetval = service_ok(iServiceIndex);
9439 if (lp_config_backend_is_registry()) {
9440 /* config backend changed to registry in config file */
9442 * We need to use this extra global variable here to
9443 * survive restart: init_globals uses this as a default
9444 * for ConfigBackend. Otherwise, init_globals would
9445 * send us into an endless loop here.
9447 config_backend = CONFIG_BACKEND_REGISTRY;
9449 DEBUG(1, ("lp_load_ex: changing to config backend "
9452 lp_kill_all_services();
9453 return lp_load_ex(pszFname, global_only, save_defaults,
9454 add_ipc, initialize_globals,
9455 allow_include_registry,
9456 allow_registry_shares);
9458 } else if (lp_config_backend_is_registry()) {
9459 bRetval = process_registry_globals();
9461 DEBUG(0, ("Illegal config backend given: %d\n",
9462 lp_config_backend()));
9466 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9467 bRetval = process_registry_shares();
9470 lp_add_auto_services(lp_auto_services());
9473 /* When 'restrict anonymous = 2' guest connections to ipc$
9475 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9476 if ( lp_enable_asu_support() ) {
9477 lp_add_ipc("ADMIN$", false);
9482 set_default_server_announce_type();
9483 set_allowed_client_auth();
9487 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9488 /* if bWINSsupport is true and we are in the client */
9489 if (lp_is_in_client() && Globals.bWINSsupport) {
9490 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9495 bAllowIncludeRegistry = true;
9500 bool lp_load(const char *pszFname,
9504 bool initialize_globals)
9506 return lp_load_ex(pszFname,
9511 true, /* allow_include_registry */
9512 false); /* allow_registry_shares*/
9515 bool lp_load_initial_only(const char *pszFname)
9517 return lp_load_ex(pszFname,
9518 true, /* global only */
9519 false, /* save_defaults */
9520 false, /* add_ipc */
9521 true, /* initialize_globals */
9522 false, /* allow_include_registry */
9523 false); /* allow_registry_shares*/
9526 bool lp_load_with_registry_shares(const char *pszFname,
9530 bool initialize_globals)
9532 return lp_load_ex(pszFname,
9537 true, /* allow_include_registry */
9538 true); /* allow_registry_shares*/
9541 /***************************************************************************
9542 Return the max number of services.
9543 ***************************************************************************/
9545 int lp_numservices(void)
9547 return (iNumServices);
9550 /***************************************************************************
9551 Display the contents of the services array in human-readable form.
9552 ***************************************************************************/
9554 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9559 defaults_saved = False;
9563 dump_a_service(&sDefault, f);
9565 for (iService = 0; iService < maxtoprint; iService++) {
9567 lp_dump_one(f, show_defaults, iService);
9571 /***************************************************************************
9572 Display the contents of one service in human-readable form.
9573 ***************************************************************************/
9575 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9578 if (ServicePtrs[snum]->szService[0] == '\0')
9580 dump_a_service(ServicePtrs[snum], f);
9584 /***************************************************************************
9585 Return the number of the service with the given name, or -1 if it doesn't
9586 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9587 getservicebyname()! This works ONLY if all services have been loaded, and
9588 does not copy the found service.
9589 ***************************************************************************/
9591 int lp_servicenumber(const char *pszServiceName)
9594 fstring serviceName;
9596 if (!pszServiceName) {
9597 return GLOBAL_SECTION_SNUM;
9600 for (iService = iNumServices - 1; iService >= 0; iService--) {
9601 if (VALID(iService) && ServicePtrs[iService]->szService) {
9603 * The substitution here is used to support %U is
9606 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9607 standard_sub_basic(get_current_username(),
9608 current_user_info.domain,
9609 serviceName,sizeof(serviceName));
9610 if (strequal(serviceName, pszServiceName)) {
9616 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9617 struct timespec last_mod;
9619 if (!usershare_exists(iService, &last_mod)) {
9620 /* Remove the share security tdb entry for it. */
9621 delete_share_security(lp_servicename(iService));
9622 /* Remove it from the array. */
9623 free_service_byindex(iService);
9624 /* Doesn't exist anymore. */
9625 return GLOBAL_SECTION_SNUM;
9628 /* Has it been modified ? If so delete and reload. */
9629 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9631 /* Remove it from the array. */
9632 free_service_byindex(iService);
9633 /* and now reload it. */
9634 iService = load_usershare_service(pszServiceName);
9639 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9640 return GLOBAL_SECTION_SNUM;
9646 bool share_defined(const char *service_name)
9648 return (lp_servicenumber(service_name) != -1);
9651 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9652 const char *sharename)
9654 struct share_params *result;
9658 snum = find_service(mem_ctx, sharename, &sname);
9659 if (snum < 0 || sname == NULL) {
9663 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9664 DEBUG(0, ("talloc failed\n"));
9668 result->service = snum;
9672 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9674 struct share_iterator *result;
9676 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9677 DEBUG(0, ("talloc failed\n"));
9681 result->next_id = 0;
9685 struct share_params *next_share(struct share_iterator *list)
9687 struct share_params *result;
9689 while (!lp_snum_ok(list->next_id) &&
9690 (list->next_id < lp_numservices())) {
9694 if (list->next_id >= lp_numservices()) {
9698 if (!(result = TALLOC_P(list, struct share_params))) {
9699 DEBUG(0, ("talloc failed\n"));
9703 result->service = list->next_id;
9708 struct share_params *next_printer(struct share_iterator *list)
9710 struct share_params *result;
9712 while ((result = next_share(list)) != NULL) {
9713 if (lp_print_ok(result->service)) {
9721 * This is a hack for a transition period until we transformed all code from
9722 * service numbers to struct share_params.
9725 struct share_params *snum2params_static(int snum)
9727 static struct share_params result;
9728 result.service = snum;
9732 /*******************************************************************
9733 A useful volume label function.
9734 ********************************************************************/
9736 const char *volume_label(int snum)
9739 const char *label = lp_volume(snum);
9741 label = lp_servicename(snum);
9744 /* This returns a 33 byte guarenteed null terminated string. */
9745 ret = talloc_strndup(talloc_tos(), label, 32);
9752 /*******************************************************************
9753 Set the server type we will announce as via nmbd.
9754 ********************************************************************/
9756 static void set_default_server_announce_type(void)
9758 default_server_announce = 0;
9759 default_server_announce |= SV_TYPE_WORKSTATION;
9760 default_server_announce |= SV_TYPE_SERVER;
9761 default_server_announce |= SV_TYPE_SERVER_UNIX;
9763 /* note that the flag should be set only if we have a
9764 printer service but nmbd doesn't actually load the
9765 services so we can't tell --jerry */
9767 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9769 switch (lp_announce_as()) {
9770 case ANNOUNCE_AS_NT_SERVER:
9771 default_server_announce |= SV_TYPE_SERVER_NT;
9772 /* fall through... */
9773 case ANNOUNCE_AS_NT_WORKSTATION:
9774 default_server_announce |= SV_TYPE_NT;
9776 case ANNOUNCE_AS_WIN95:
9777 default_server_announce |= SV_TYPE_WIN95_PLUS;
9779 case ANNOUNCE_AS_WFW:
9780 default_server_announce |= SV_TYPE_WFW;
9786 switch (lp_server_role()) {
9787 case ROLE_DOMAIN_MEMBER:
9788 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9790 case ROLE_DOMAIN_PDC:
9791 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9793 case ROLE_DOMAIN_BDC:
9794 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9796 case ROLE_STANDALONE:
9800 if (lp_time_server())
9801 default_server_announce |= SV_TYPE_TIME_SOURCE;
9803 if (lp_host_msdfs())
9804 default_server_announce |= SV_TYPE_DFS_SERVER;
9807 /***********************************************************
9808 If we are PDC then prefer us as DMB
9809 ************************************************************/
9811 bool lp_domain_master(void)
9813 if (Globals.iDomainMaster == Auto)
9814 return (lp_server_role() == ROLE_DOMAIN_PDC);
9816 return (bool)Globals.iDomainMaster;
9819 /***********************************************************
9820 If we are PDC then prefer us as DMB
9821 ************************************************************/
9823 bool lp_domain_master_true_or_auto(void)
9825 if (Globals.iDomainMaster) /* auto or yes */
9831 /***********************************************************
9832 If we are DMB then prefer us as LMB
9833 ************************************************************/
9835 bool lp_preferred_master(void)
9837 if (Globals.iPreferredMaster == Auto)
9838 return (lp_local_master() && lp_domain_master());
9840 return (bool)Globals.iPreferredMaster;
9843 /*******************************************************************
9845 ********************************************************************/
9847 void lp_remove_service(int snum)
9849 ServicePtrs[snum]->valid = False;
9850 invalid_services[num_invalid_services++] = snum;
9853 /*******************************************************************
9855 ********************************************************************/
9857 void lp_copy_service(int snum, const char *new_name)
9859 do_section(new_name, NULL);
9861 snum = lp_servicenumber(new_name);
9863 lp_do_parameter(snum, "copy", lp_servicename(snum));
9868 /*******************************************************************
9869 Get the default server type we will announce as via nmbd.
9870 ********************************************************************/
9872 int lp_default_server_announce(void)
9874 return default_server_announce;
9877 /*******************************************************************
9878 Split the announce version into major and minor numbers.
9879 ********************************************************************/
9881 int lp_major_announce_version(void)
9883 static bool got_major = False;
9884 static int major_version = DEFAULT_MAJOR_VERSION;
9889 return major_version;
9892 if ((vers = lp_announce_version()) == NULL)
9893 return major_version;
9895 if ((p = strchr_m(vers, '.')) == 0)
9896 return major_version;
9899 major_version = atoi(vers);
9900 return major_version;
9903 int lp_minor_announce_version(void)
9905 static bool got_minor = False;
9906 static int minor_version = DEFAULT_MINOR_VERSION;
9911 return minor_version;
9914 if ((vers = lp_announce_version()) == NULL)
9915 return minor_version;
9917 if ((p = strchr_m(vers, '.')) == 0)
9918 return minor_version;
9921 minor_version = atoi(p);
9922 return minor_version;
9925 /***********************************************************
9926 Set the global name resolution order (used in smbclient).
9927 ************************************************************/
9929 void lp_set_name_resolve_order(const char *new_order)
9931 string_set(&Globals.szNameResolveOrder, new_order);
9934 const char *lp_printername(int snum)
9936 const char *ret = _lp_printername(snum);
9937 if (ret == NULL || (ret != NULL && *ret == '\0'))
9938 ret = lp_const_servicename(snum);
9944 /***********************************************************
9945 Allow daemons such as winbindd to fix their logfile name.
9946 ************************************************************/
9948 void lp_set_logfile(const char *name)
9950 string_set(&Globals.szLogFile, name);
9951 debug_set_logfile(name);
9954 /*******************************************************************
9955 Return the max print jobs per queue.
9956 ********************************************************************/
9958 int lp_maxprintjobs(int snum)
9960 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9961 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9962 maxjobs = PRINT_MAX_JOBID - 1;
9967 const char *lp_printcapname(void)
9969 if ((Globals.szPrintcapname != NULL) &&
9970 (Globals.szPrintcapname[0] != '\0'))
9971 return Globals.szPrintcapname;
9973 if (sDefault.iPrinting == PRINT_CUPS) {
9981 if (sDefault.iPrinting == PRINT_BSD)
9982 return "/etc/printcap";
9984 return PRINTCAP_NAME;
9987 static uint32 spoolss_state;
9989 bool lp_disable_spoolss( void )
9991 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9992 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9994 return spoolss_state == SVCCTL_STOPPED ? True : False;
9997 void lp_set_spoolss_state( uint32 state )
9999 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
10001 spoolss_state = state;
10004 uint32 lp_get_spoolss_state( void )
10006 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
10009 /*******************************************************************
10010 Ensure we don't use sendfile if server smb signing is active.
10011 ********************************************************************/
10013 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
10015 bool sign_active = false;
10017 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
10018 if (get_Protocol() < PROTOCOL_NT1) {
10021 if (signing_state) {
10022 sign_active = smb_signing_is_active(signing_state);
10024 return (_lp_use_sendfile(snum) &&
10025 (get_remote_arch() != RA_WIN95) &&
10029 /*******************************************************************
10030 Turn off sendfile if we find the underlying OS doesn't support it.
10031 ********************************************************************/
10033 void set_use_sendfile(int snum, bool val)
10035 if (LP_SNUM_OK(snum))
10036 ServicePtrs[snum]->bUseSendfile = val;
10038 sDefault.bUseSendfile = val;
10041 /*******************************************************************
10042 Turn off storing DOS attributes if this share doesn't support it.
10043 ********************************************************************/
10045 void set_store_dos_attributes(int snum, bool val)
10047 if (!LP_SNUM_OK(snum))
10049 ServicePtrs[(snum)]->bStoreDosAttributes = val;
10052 void lp_set_mangling_method(const char *new_method)
10054 string_set(&Globals.szManglingMethod, new_method);
10057 /*******************************************************************
10058 Global state for POSIX pathname processing.
10059 ********************************************************************/
10061 static bool posix_pathnames;
10063 bool lp_posix_pathnames(void)
10065 return posix_pathnames;
10068 /*******************************************************************
10069 Change everything needed to ensure POSIX pathname processing (currently
10071 ********************************************************************/
10073 void lp_set_posix_pathnames(void)
10075 posix_pathnames = True;
10078 /*******************************************************************
10079 Global state for POSIX lock processing - CIFS unix extensions.
10080 ********************************************************************/
10082 bool posix_default_lock_was_set;
10083 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
10085 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
10087 if (posix_default_lock_was_set) {
10088 return posix_cifsx_locktype;
10090 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
10094 /*******************************************************************
10095 ********************************************************************/
10097 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
10099 posix_default_lock_was_set = True;
10100 posix_cifsx_locktype = val;
10103 int lp_min_receive_file_size(void)
10105 if (Globals.iminreceivefile < 0) {
10108 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
10111 /*******************************************************************
10112 If socket address is an empty character string, it is necessary to
10113 define it as "0.0.0.0".
10114 ********************************************************************/
10116 const char *lp_socket_address(void)
10118 char *sock_addr = Globals.szSocketAddress;
10120 if (sock_addr[0] == '\0'){
10121 string_set(&Globals.szSocketAddress, "0.0.0.0");
10123 return Globals.szSocketAddress;
10126 void lp_set_passdb_backend(const char *backend)
10128 string_set(&Globals.szPassdbBackend, backend);
10131 /*******************************************************************
10132 Safe wide links checks.
10133 This helper function always verify the validity of wide links,
10134 even after a configuration file reload.
10135 ********************************************************************/
10137 static bool lp_widelinks_internal(int snum)
10139 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
10140 sDefault.bWidelinks);
10143 void widelinks_warning(int snum)
10145 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10146 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10147 "These parameters are incompatible. "
10148 "Wide links will be disabled for this share.\n",
10149 lp_servicename(snum) ));
10153 bool lp_widelinks(int snum)
10155 /* wide links is always incompatible with unix extensions */
10156 if (lp_unix_extensions()) {
10160 return lp_widelinks_internal(snum);
10163 bool lp_writeraw(void)
10165 if (lp_async_smb_echo_handler()) {
10168 return _lp_writeraw();
10171 bool lp_readraw(void)
10173 if (lp_async_smb_echo_handler()) {
10176 return _lp_readraw();