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"
66 #ifdef HAVE_SYS_SYSCTL_H
67 #include <sys/sysctl.h>
70 #ifdef HAVE_HTTPCONNECTENCRYPT
71 #include <cups/http.h>
76 extern userdom_struct current_user_info;
79 #define GLOBAL_NAME "global"
83 #define PRINTERS_NAME "printers"
87 #define HOMES_NAME "homes"
90 /* the special value for the include parameter
91 * to be interpreted not as a file name but to
92 * trigger loading of the global smb.conf options
94 #ifndef INCLUDE_REGISTRY_NAME
95 #define INCLUDE_REGISTRY_NAME "registry"
98 static bool in_client = False; /* Not in the client by default */
99 static struct smbconf_csn conf_last_csn;
101 #define CONFIG_BACKEND_FILE 0
102 #define CONFIG_BACKEND_REGISTRY 1
104 static int config_backend = CONFIG_BACKEND_FILE;
106 /* some helpful bits */
107 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
108 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
110 #define USERSHARE_VALID 1
111 #define USERSHARE_PENDING_DELETE 2
113 static bool defaults_saved = False;
115 struct param_opt_struct {
116 struct param_opt_struct *prev, *next;
124 * This structure describes global (ie., server-wide) parameters.
131 char *display_charset;
132 char *szPrintcapname;
133 char *szAddPortCommand;
134 char *szEnumPortsCommand;
135 char *szAddPrinterCommand;
136 char *szDeletePrinterCommand;
137 char *szOs2DriverMap;
143 char *szDefaultService;
147 char *szServerString;
148 char *szAutoServices;
149 char *szPasswdProgram;
153 char *szSMBPasswdFile;
155 char *szPassdbBackend;
156 char **szPreloadModules;
157 char *szPasswordServer;
158 char *szSocketOptions;
160 char *szAfsUsernameMap;
161 int iAfsTokenLifetime;
162 char *szLogNtTokenCommand;
168 char **szWINSservers;
170 char *szRemoteAnnounce;
171 char *szRemoteBrowseSync;
172 char *szSocketAddress;
173 bool bNmbdBindExplicitBroadcast;
174 char *szNISHomeMapName;
175 char *szAnnounceVersion; /* This is initialised in init_globals */
178 char **szNetbiosAliases;
179 char *szNetbiosScope;
180 char *szNameResolveOrder;
182 char *szAddUserScript;
183 char *szRenameUserScript;
184 char *szDelUserScript;
185 char *szAddGroupScript;
186 char *szDelGroupScript;
187 char *szAddUserToGroupScript;
188 char *szDelUserFromGroupScript;
189 char *szSetPrimaryGroupScript;
190 char *szAddMachineScript;
191 char *szShutdownScript;
192 char *szAbortShutdownScript;
193 char *szUsernameMapScript;
194 int iUsernameMapCacheTime;
195 char *szCheckPasswordScript;
202 bool bPassdbExpandExplicit;
203 int AlgorithmicRidBase;
204 char *szTemplateHomedir;
205 char *szTemplateShell;
206 char *szWinbindSeparator;
207 bool bWinbindEnumUsers;
208 bool bWinbindEnumGroups;
209 bool bWinbindUseDefaultDomain;
210 bool bWinbindTrustedDomainsOnly;
211 bool bWinbindNestedGroups;
212 int winbind_expand_groups;
213 bool bWinbindRefreshTickets;
214 bool bWinbindOfflineLogon;
215 bool bWinbindNormalizeNames;
216 bool bWinbindRpcOnly;
217 bool bCreateKrb5Conf;
218 char *szIdmapBackend;
220 char *szAddShareCommand;
221 char *szChangeShareCommand;
222 char *szDeleteShareCommand;
224 char *szGuestaccount;
225 char *szManglingMethod;
226 char **szServicesList;
227 char *szUsersharePath;
228 char *szUsershareTemplateShare;
229 char **szUsersharePrefixAllowList;
230 char **szUsersharePrefixDenyList;
237 int open_files_db_hash_size;
246 bool paranoid_server_security;
249 int iMaxSmbdProcesses;
250 bool bDisableSpoolss;
253 bool enhanced_browsing;
259 int announce_as; /* This is initialised in init_globals */
260 int machine_password_timeout;
262 int oplock_break_wait_time;
263 int winbind_cache_time;
264 int winbind_reconnect_delay;
265 int winbind_max_idle_children;
266 char **szWinbindNssInfo;
268 char *szLdapMachineSuffix;
269 char *szLdapUserSuffix;
270 char *szLdapIdmapSuffix;
271 char *szLdapGroupSuffix;
275 int ldap_follow_referral;
278 int ldap_debug_level;
279 int ldap_debug_threshold;
283 char *szIPrintServer;
285 char **szClusterAddresses;
288 int ctdb_locktime_warn_threshold;
289 int ldap_passwd_sync;
290 int ldap_replication_sleep;
291 int ldap_timeout; /* This is initialised in init_globals */
292 int ldap_connection_timeout;
295 bool bMsAddPrinterWizard;
300 int iPreferredMaster;
303 char **szInitLogonDelayedHosts;
305 bool bEncryptPasswords;
310 bool bObeyPamRestrictions;
312 int PrintcapCacheTime;
313 bool bLargeReadwrite;
320 bool bBindInterfacesOnly;
321 bool bPamPasswordChange;
322 bool bUnixPasswdSync;
323 bool bPasswdChatDebug;
324 int iPasswdChatTimeout;
328 bool bNTStatusSupport;
330 int iMaxStatCacheSize;
332 bool bAllowTrustedDomains;
336 bool bClientLanManAuth;
337 bool bClientNTLMv2Auth;
338 bool bClientPlaintextAuth;
339 bool bClientUseSpnego;
340 bool bDebugPrefixTimestamp;
341 bool bDebugHiresTimestamp;
345 bool bEnableCoreFiles;
348 bool bHostnameLookups;
349 bool bUnixExtensions;
350 bool bDisableNetbios;
351 char * szDedicatedKeytabFile;
353 bool bDeferSharingViolations;
354 bool bEnablePrivileges;
356 bool bUsershareOwnerOnly;
357 bool bUsershareAllowGuests;
358 bool bRegistryShares;
359 int restrict_anonymous;
360 int name_cache_timeout;
363 int client_ldap_sasl_wrapping;
364 int iUsershareMaxShares;
366 int iIdmapNegativeCacheTime;
368 bool bLogWriteableFilesOnExit;
371 struct param_opt_struct *param_opt;
372 int cups_connection_timeout;
373 char *szSMBPerfcountModule;
374 bool bMapUntrustedToDomain;
375 bool bAsyncSMBEchoHandler;
381 static struct global Globals;
384 * This structure describes a single service.
390 struct timespec usershare_last_mod;
394 char **szInvalidUsers;
402 char *szRootPostExec;
404 char *szPrintcommand;
407 char *szLppausecommand;
408 char *szLpresumecommand;
409 char *szQueuepausecommand;
410 char *szQueueresumecommand;
412 char *szPrintjobUsername;
420 char *szVetoOplockFiles;
426 char **printer_admin;
431 char *szAioWriteBehind;
435 int iMaxReportedPrintJobs;
438 int iCreate_force_mode;
440 int iSecurity_force_mode;
443 int iDir_Security_mask;
444 int iDir_Security_force_mode;
448 int iOplockContentionLimit;
453 bool bRootpreexecClose;
456 bool bShortCasePreserve;
458 bool bHideSpecialFiles;
459 bool bHideUnReadable;
460 bool bHideUnWriteableFiles;
462 bool bAccessBasedShareEnum;
467 bool bAdministrative_share;
473 bool bStoreDosAttributes;
486 bool bStrictAllocate;
489 struct bitmap *copymap;
490 bool bDeleteReadonly;
492 bool bDeleteVetoFiles;
495 bool bDosFiletimeResolution;
496 bool bFakeDirCreateTimes;
502 bool bUseClientDriver;
503 bool bDefaultDevmode;
504 bool bForcePrintername;
506 bool bForceUnknownAclUser;
509 bool bMap_acl_inherit;
512 bool bAclCheckPermissions;
513 bool bAclMapFullControl;
514 bool bAclGroupControl;
516 bool bKernelChangeNotify;
517 int iallocation_roundup_size;
521 int iDirectoryNameCacheSize;
523 struct param_opt_struct *param_opt;
525 char dummy[3]; /* for alignment */
529 /* This is a default service used to prime a services structure */
530 static struct service sDefault = {
532 False, /* not autoloaded */
533 0, /* not a usershare */
534 {0, }, /* No last mod time */
535 NULL, /* szService */
537 NULL, /* szUsername */
538 NULL, /* szInvalidUsers */
539 NULL, /* szValidUsers */
540 NULL, /* szAdminUsers */
542 NULL, /* szInclude */
543 NULL, /* szPreExec */
544 NULL, /* szPostExec */
545 NULL, /* szRootPreExec */
546 NULL, /* szRootPostExec */
547 NULL, /* szCupsOptions */
548 NULL, /* szPrintcommand */
549 NULL, /* szLpqcommand */
550 NULL, /* szLprmcommand */
551 NULL, /* szLppausecommand */
552 NULL, /* szLpresumecommand */
553 NULL, /* szQueuepausecommand */
554 NULL, /* szQueueresumecommand */
555 NULL, /* szPrintername */
556 NULL, /* szPrintjobUsername */
557 NULL, /* szDontdescend */
558 NULL, /* szHostsallow */
559 NULL, /* szHostsdeny */
560 NULL, /* szMagicScript */
561 NULL, /* szMagicOutput */
562 NULL, /* szVetoFiles */
563 NULL, /* szHideFiles */
564 NULL, /* szVetoOplockFiles */
566 NULL, /* force user */
567 NULL, /* force group */
569 NULL, /* writelist */
570 NULL, /* printer admin */
573 NULL, /* vfs objects */
574 NULL, /* szMSDfsProxy */
575 NULL, /* szAioWriteBehind */
577 0, /* iMinPrintSpace */
578 1000, /* iMaxPrintJobs */
579 0, /* iMaxReportedPrintJobs */
580 0, /* iWriteCacheSize */
581 0744, /* iCreate_mask */
582 0000, /* iCreate_force_mode */
583 0777, /* iSecurity_mask */
584 0, /* iSecurity_force_mode */
585 0755, /* iDir_mask */
586 0000, /* iDir_force_mode */
587 0777, /* iDir_Security_mask */
588 0, /* iDir_Security_force_mode */
589 0, /* iMaxConnections */
590 CASE_LOWER, /* iDefaultCase */
591 DEFAULT_PRINTING, /* iPrinting */
592 2, /* iOplockContentionLimit */
594 1024, /* iBlock_size */
595 0, /* iDfreeCacheTime */
596 False, /* bPreexecClose */
597 False, /* bRootpreexecClose */
598 Auto, /* case sensitive */
599 True, /* case preserve */
600 True, /* short case preserve */
601 True, /* bHideDotFiles */
602 False, /* bHideSpecialFiles */
603 False, /* bHideUnReadable */
604 False, /* bHideUnWriteableFiles */
605 True, /* bBrowseable */
606 False, /* bAccessBasedShareEnum */
607 True, /* bAvailable */
608 True, /* bRead_only */
609 True, /* bNo_set_dir */
610 False, /* bGuest_only */
611 False, /* bAdministrative_share */
612 False, /* bGuest_ok */
613 False, /* bPrint_ok */
614 False, /* bMap_system */
615 False, /* bMap_hidden */
616 True, /* bMap_archive */
617 False, /* bStoreDosAttributes */
618 False, /* bDmapiSupport */
620 Auto, /* iStrictLocking */
621 True, /* bPosixLocking */
622 True, /* bShareModes */
624 True, /* bLevel2OpLocks */
625 False, /* bOnlyUser */
626 True, /* bMangledNames */
627 false, /* bWidelinks */
628 True, /* bSymlinks */
629 False, /* bSyncAlways */
630 False, /* bStrictAllocate */
631 False, /* bStrictSync */
632 '~', /* magic char */
634 False, /* bDeleteReadonly */
635 False, /* bFakeOplocks */
636 False, /* bDeleteVetoFiles */
637 False, /* bDosFilemode */
638 True, /* bDosFiletimes */
639 False, /* bDosFiletimeResolution */
640 False, /* bFakeDirCreateTimes */
641 True, /* bBlockingLocks */
642 False, /* bInheritPerms */
643 False, /* bInheritACLS */
644 False, /* bInheritOwner */
645 False, /* bMSDfsRoot */
646 False, /* bUseClientDriver */
647 True, /* bDefaultDevmode */
648 False, /* bForcePrintername */
649 True, /* bNTAclSupport */
650 False, /* bForceUnknownAclUser */
651 False, /* bUseSendfile */
652 False, /* bProfileAcls */
653 False, /* bMap_acl_inherit */
654 False, /* bAfs_Share */
655 False, /* bEASupport */
656 True, /* bAclCheckPermissions */
657 True, /* bAclMapFullControl */
658 False, /* bAclGroupControl */
659 True, /* bChangeNotify */
660 True, /* bKernelChangeNotify */
661 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
662 0, /* iAioReadSize */
663 0, /* iAioWriteSize */
664 MAP_READONLY_YES, /* iMap_readonly */
665 #ifdef BROKEN_DIRECTORY_HANDLING
666 0, /* iDirectoryNameCacheSize */
668 100, /* iDirectoryNameCacheSize */
670 Auto, /* ismb_encrypt */
671 NULL, /* Parametric options */
676 /* local variables */
677 static struct service **ServicePtrs = NULL;
678 static int iNumServices = 0;
679 static int iServiceIndex = 0;
680 static struct db_context *ServiceHash;
681 static int *invalid_services = NULL;
682 static int num_invalid_services = 0;
683 static bool bInGlobalSection = True;
684 static bool bGlobalOnly = False;
685 static int default_server_announce;
687 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
689 /* prototypes for the special type handlers */
690 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
691 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
692 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
693 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
694 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
695 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
696 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
697 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
698 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
699 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
700 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
701 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
703 static void set_default_server_announce_type(void);
704 static void set_allowed_client_auth(void);
706 static void *lp_local_ptr(struct service *service, void *ptr);
708 static void add_to_file_list(const char *fname, const char *subfname);
709 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
711 static const struct enum_list enum_protocol[] = {
712 {PROTOCOL_SMB2, "SMB2"},
713 {PROTOCOL_NT1, "NT1"},
714 {PROTOCOL_LANMAN2, "LANMAN2"},
715 {PROTOCOL_LANMAN1, "LANMAN1"},
716 {PROTOCOL_CORE, "CORE"},
717 {PROTOCOL_COREPLUS, "COREPLUS"},
718 {PROTOCOL_COREPLUS, "CORE+"},
722 static const struct enum_list enum_security[] = {
723 {SEC_SHARE, "SHARE"},
725 {SEC_SERVER, "SERVER"},
726 {SEC_DOMAIN, "DOMAIN"},
733 static const struct enum_list enum_printing[] = {
734 {PRINT_SYSV, "sysv"},
736 {PRINT_HPUX, "hpux"},
740 {PRINT_LPRNG, "lprng"},
741 {PRINT_CUPS, "cups"},
742 {PRINT_IPRINT, "iprint"},
744 {PRINT_LPROS2, "os2"},
746 {PRINT_TEST, "test"},
748 #endif /* DEVELOPER */
752 static const struct enum_list enum_ldap_sasl_wrapping[] = {
754 {ADS_AUTH_SASL_SIGN, "sign"},
755 {ADS_AUTH_SASL_SEAL, "seal"},
759 static const struct enum_list enum_ldap_ssl[] = {
760 {LDAP_SSL_OFF, "no"},
761 {LDAP_SSL_OFF, "off"},
762 {LDAP_SSL_START_TLS, "start tls"},
763 {LDAP_SSL_START_TLS, "start_tls"},
767 /* LDAP Dereferencing Alias types */
768 #define SAMBA_LDAP_DEREF_NEVER 0
769 #define SAMBA_LDAP_DEREF_SEARCHING 1
770 #define SAMBA_LDAP_DEREF_FINDING 2
771 #define SAMBA_LDAP_DEREF_ALWAYS 3
773 static const struct enum_list enum_ldap_deref[] = {
774 {SAMBA_LDAP_DEREF_NEVER, "never"},
775 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
776 {SAMBA_LDAP_DEREF_FINDING, "finding"},
777 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
781 static const struct enum_list enum_ldap_passwd_sync[] = {
782 {LDAP_PASSWD_SYNC_OFF, "no"},
783 {LDAP_PASSWD_SYNC_OFF, "off"},
784 {LDAP_PASSWD_SYNC_ON, "yes"},
785 {LDAP_PASSWD_SYNC_ON, "on"},
786 {LDAP_PASSWD_SYNC_ONLY, "only"},
790 /* Types of machine we can announce as. */
791 #define ANNOUNCE_AS_NT_SERVER 1
792 #define ANNOUNCE_AS_WIN95 2
793 #define ANNOUNCE_AS_WFW 3
794 #define ANNOUNCE_AS_NT_WORKSTATION 4
796 static const struct enum_list enum_announce_as[] = {
797 {ANNOUNCE_AS_NT_SERVER, "NT"},
798 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
799 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
800 {ANNOUNCE_AS_WIN95, "win95"},
801 {ANNOUNCE_AS_WFW, "WfW"},
805 static const struct enum_list enum_map_readonly[] = {
806 {MAP_READONLY_NO, "no"},
807 {MAP_READONLY_NO, "false"},
808 {MAP_READONLY_NO, "0"},
809 {MAP_READONLY_YES, "yes"},
810 {MAP_READONLY_YES, "true"},
811 {MAP_READONLY_YES, "1"},
812 {MAP_READONLY_PERMISSIONS, "permissions"},
813 {MAP_READONLY_PERMISSIONS, "perms"},
817 static const struct enum_list enum_case[] = {
818 {CASE_LOWER, "lower"},
819 {CASE_UPPER, "upper"},
825 static const struct enum_list enum_bool_auto[] = {
836 static const struct enum_list enum_csc_policy[] = {
837 {CSC_POLICY_MANUAL, "manual"},
838 {CSC_POLICY_DOCUMENTS, "documents"},
839 {CSC_POLICY_PROGRAMS, "programs"},
840 {CSC_POLICY_DISABLE, "disable"},
844 /* SMB signing types. */
845 static const struct enum_list enum_smb_signing_vals[] = {
857 {Required, "required"},
858 {Required, "mandatory"},
860 {Required, "forced"},
861 {Required, "enforced"},
865 /* ACL compatibility options. */
866 static const struct enum_list enum_acl_compat_vals[] = {
867 { ACL_COMPAT_AUTO, "auto" },
868 { ACL_COMPAT_WINNT, "winnt" },
869 { ACL_COMPAT_WIN2K, "win2k" },
874 Do you want session setups at user level security with a invalid
875 password to be rejected or allowed in as guest? WinNT rejects them
876 but it can be a pain as it means "net view" needs to use a password
878 You have 3 choices in the setting of map_to_guest:
880 "Never" means session setups with an invalid password
881 are rejected. This is the default.
883 "Bad User" means session setups with an invalid password
884 are rejected, unless the username does not exist, in which case it
885 is treated as a guest login
887 "Bad Password" means session setups with an invalid password
888 are treated as a guest login
890 Note that map_to_guest only has an effect in user or server
894 static const struct enum_list enum_map_to_guest[] = {
895 {NEVER_MAP_TO_GUEST, "Never"},
896 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
897 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
898 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
902 /* Config backend options */
904 static const struct enum_list enum_config_backend[] = {
905 {CONFIG_BACKEND_FILE, "file"},
906 {CONFIG_BACKEND_REGISTRY, "registry"},
910 /* ADS kerberos ticket verification options */
912 static const struct enum_list enum_kerberos_method[] = {
913 {KERBEROS_VERIFY_SECRETS, "default"},
914 {KERBEROS_VERIFY_SECRETS, "secrets only"},
915 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
916 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
917 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
921 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
923 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
924 * screen in SWAT. This is used to exclude parameters as well as to squash all
925 * parameters that have been duplicated by pseudonyms.
927 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
928 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
929 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
932 * NOTE2: Handling of duplicated (synonym) parameters:
933 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
934 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
935 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
936 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
939 static struct parm_struct parm_table[] = {
940 {N_("Base Options"), P_SEP, P_SEPARATOR},
943 .label = "dos charset",
946 .ptr = &Globals.dos_charset,
947 .special = handle_charset,
949 .flags = FLAG_ADVANCED
952 .label = "unix charset",
955 .ptr = &Globals.unix_charset,
956 .special = handle_charset,
958 .flags = FLAG_ADVANCED
961 .label = "display charset",
964 .ptr = &Globals.display_charset,
965 .special = handle_charset,
967 .flags = FLAG_ADVANCED
973 .ptr = &sDefault.comment,
976 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
982 .ptr = &sDefault.szPath,
985 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
988 .label = "directory",
991 .ptr = &sDefault.szPath,
997 .label = "workgroup",
1000 .ptr = &Globals.szWorkgroup,
1001 .special = handle_workgroup,
1003 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1009 .p_class = P_GLOBAL,
1010 .ptr = &Globals.szRealm,
1013 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1017 .label = "netbios name",
1019 .p_class = P_GLOBAL,
1020 .ptr = &Globals.szNetbiosName,
1021 .special = handle_netbios_name,
1023 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1026 .label = "netbios aliases",
1028 .p_class = P_GLOBAL,
1029 .ptr = &Globals.szNetbiosAliases,
1030 .special = handle_netbios_aliases,
1032 .flags = FLAG_ADVANCED,
1035 .label = "netbios scope",
1037 .p_class = P_GLOBAL,
1038 .ptr = &Globals.szNetbiosScope,
1039 .special = handle_netbios_scope,
1041 .flags = FLAG_ADVANCED,
1044 .label = "server string",
1046 .p_class = P_GLOBAL,
1047 .ptr = &Globals.szServerString,
1050 .flags = FLAG_BASIC | FLAG_ADVANCED,
1053 .label = "interfaces",
1055 .p_class = P_GLOBAL,
1056 .ptr = &Globals.szInterfaces,
1059 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1062 .label = "bind interfaces only",
1064 .p_class = P_GLOBAL,
1065 .ptr = &Globals.bBindInterfacesOnly,
1068 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1071 .label = "config backend",
1073 .p_class = P_GLOBAL,
1074 .ptr = &Globals.ConfigBackend,
1076 .enum_list = enum_config_backend,
1077 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1080 {N_("Security Options"), P_SEP, P_SEPARATOR},
1083 .label = "security",
1085 .p_class = P_GLOBAL,
1086 .ptr = &Globals.security,
1088 .enum_list = enum_security,
1089 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1092 .label = "auth methods",
1094 .p_class = P_GLOBAL,
1095 .ptr = &Globals.AuthMethods,
1098 .flags = FLAG_ADVANCED,
1101 .label = "encrypt passwords",
1103 .p_class = P_GLOBAL,
1104 .ptr = &Globals.bEncryptPasswords,
1107 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1110 .label = "client schannel",
1112 .p_class = P_GLOBAL,
1113 .ptr = &Globals.clientSchannel,
1115 .enum_list = enum_bool_auto,
1116 .flags = FLAG_BASIC | FLAG_ADVANCED,
1119 .label = "server schannel",
1121 .p_class = P_GLOBAL,
1122 .ptr = &Globals.serverSchannel,
1124 .enum_list = enum_bool_auto,
1125 .flags = FLAG_BASIC | FLAG_ADVANCED,
1128 .label = "allow trusted domains",
1130 .p_class = P_GLOBAL,
1131 .ptr = &Globals.bAllowTrustedDomains,
1134 .flags = FLAG_ADVANCED,
1137 .label = "map to guest",
1139 .p_class = P_GLOBAL,
1140 .ptr = &Globals.map_to_guest,
1142 .enum_list = enum_map_to_guest,
1143 .flags = FLAG_ADVANCED,
1146 .label = "null passwords",
1148 .p_class = P_GLOBAL,
1149 .ptr = &Globals.bNullPasswords,
1152 .flags = FLAG_ADVANCED,
1155 .label = "obey pam restrictions",
1157 .p_class = P_GLOBAL,
1158 .ptr = &Globals.bObeyPamRestrictions,
1161 .flags = FLAG_ADVANCED,
1164 .label = "password server",
1166 .p_class = P_GLOBAL,
1167 .ptr = &Globals.szPasswordServer,
1170 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1173 .label = "smb passwd file",
1175 .p_class = P_GLOBAL,
1176 .ptr = &Globals.szSMBPasswdFile,
1179 .flags = FLAG_ADVANCED,
1182 .label = "private dir",
1184 .p_class = P_GLOBAL,
1185 .ptr = &Globals.szPrivateDir,
1188 .flags = FLAG_ADVANCED,
1191 .label = "passdb backend",
1193 .p_class = P_GLOBAL,
1194 .ptr = &Globals.szPassdbBackend,
1197 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1200 .label = "algorithmic rid base",
1202 .p_class = P_GLOBAL,
1203 .ptr = &Globals.AlgorithmicRidBase,
1206 .flags = FLAG_ADVANCED,
1209 .label = "root directory",
1211 .p_class = P_GLOBAL,
1212 .ptr = &Globals.szRootdir,
1215 .flags = FLAG_ADVANCED,
1218 .label = "root dir",
1220 .p_class = P_GLOBAL,
1221 .ptr = &Globals.szRootdir,
1229 .p_class = P_GLOBAL,
1230 .ptr = &Globals.szRootdir,
1236 .label = "guest account",
1238 .p_class = P_GLOBAL,
1239 .ptr = &Globals.szGuestaccount,
1242 .flags = FLAG_BASIC | FLAG_ADVANCED,
1245 .label = "enable privileges",
1247 .p_class = P_GLOBAL,
1248 .ptr = &Globals.bEnablePrivileges,
1251 .flags = FLAG_ADVANCED,
1255 .label = "pam password change",
1257 .p_class = P_GLOBAL,
1258 .ptr = &Globals.bPamPasswordChange,
1261 .flags = FLAG_ADVANCED,
1264 .label = "passwd program",
1266 .p_class = P_GLOBAL,
1267 .ptr = &Globals.szPasswdProgram,
1270 .flags = FLAG_ADVANCED,
1273 .label = "passwd chat",
1275 .p_class = P_GLOBAL,
1276 .ptr = &Globals.szPasswdChat,
1279 .flags = FLAG_ADVANCED,
1282 .label = "passwd chat debug",
1284 .p_class = P_GLOBAL,
1285 .ptr = &Globals.bPasswdChatDebug,
1288 .flags = FLAG_ADVANCED,
1291 .label = "passwd chat timeout",
1293 .p_class = P_GLOBAL,
1294 .ptr = &Globals.iPasswdChatTimeout,
1297 .flags = FLAG_ADVANCED,
1300 .label = "check password script",
1302 .p_class = P_GLOBAL,
1303 .ptr = &Globals.szCheckPasswordScript,
1306 .flags = FLAG_ADVANCED,
1309 .label = "username map",
1311 .p_class = P_GLOBAL,
1312 .ptr = &Globals.szUsernameMap,
1315 .flags = FLAG_ADVANCED,
1318 .label = "password level",
1320 .p_class = P_GLOBAL,
1321 .ptr = &Globals.pwordlevel,
1324 .flags = FLAG_ADVANCED,
1327 .label = "username level",
1329 .p_class = P_GLOBAL,
1330 .ptr = &Globals.unamelevel,
1333 .flags = FLAG_ADVANCED,
1336 .label = "unix password sync",
1338 .p_class = P_GLOBAL,
1339 .ptr = &Globals.bUnixPasswdSync,
1342 .flags = FLAG_ADVANCED,
1345 .label = "restrict anonymous",
1347 .p_class = P_GLOBAL,
1348 .ptr = &Globals.restrict_anonymous,
1351 .flags = FLAG_ADVANCED,
1354 .label = "lanman auth",
1356 .p_class = P_GLOBAL,
1357 .ptr = &Globals.bLanmanAuth,
1360 .flags = FLAG_ADVANCED,
1363 .label = "ntlm auth",
1365 .p_class = P_GLOBAL,
1366 .ptr = &Globals.bNTLMAuth,
1369 .flags = FLAG_ADVANCED,
1372 .label = "client NTLMv2 auth",
1374 .p_class = P_GLOBAL,
1375 .ptr = &Globals.bClientNTLMv2Auth,
1378 .flags = FLAG_ADVANCED,
1381 .label = "client lanman auth",
1383 .p_class = P_GLOBAL,
1384 .ptr = &Globals.bClientLanManAuth,
1387 .flags = FLAG_ADVANCED,
1390 .label = "client plaintext auth",
1392 .p_class = P_GLOBAL,
1393 .ptr = &Globals.bClientPlaintextAuth,
1396 .flags = FLAG_ADVANCED,
1399 .label = "username",
1402 .ptr = &sDefault.szUsername,
1405 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1411 .ptr = &sDefault.szUsername,
1420 .ptr = &sDefault.szUsername,
1426 .label = "invalid users",
1429 .ptr = &sDefault.szInvalidUsers,
1432 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1435 .label = "valid users",
1438 .ptr = &sDefault.szValidUsers,
1441 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1444 .label = "admin users",
1447 .ptr = &sDefault.szAdminUsers,
1450 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1453 .label = "read list",
1456 .ptr = &sDefault.readlist,
1459 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1462 .label = "write list",
1465 .ptr = &sDefault.writelist,
1468 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1471 .label = "printer admin",
1474 .ptr = &sDefault.printer_admin,
1477 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1480 .label = "force user",
1483 .ptr = &sDefault.force_user,
1486 .flags = FLAG_ADVANCED | FLAG_SHARE,
1489 .label = "force group",
1492 .ptr = &sDefault.force_group,
1495 .flags = FLAG_ADVANCED | FLAG_SHARE,
1501 .ptr = &sDefault.force_group,
1504 .flags = FLAG_ADVANCED,
1507 .label = "read only",
1510 .ptr = &sDefault.bRead_only,
1513 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1516 .label = "write ok",
1519 .ptr = &sDefault.bRead_only,
1525 .label = "writeable",
1528 .ptr = &sDefault.bRead_only,
1534 .label = "writable",
1537 .ptr = &sDefault.bRead_only,
1543 .label = "acl check permissions",
1546 .ptr = &sDefault.bAclCheckPermissions,
1549 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1552 .label = "acl group control",
1555 .ptr = &sDefault.bAclGroupControl,
1558 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1561 .label = "acl map full control",
1564 .ptr = &sDefault.bAclMapFullControl,
1567 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1570 .label = "create mask",
1573 .ptr = &sDefault.iCreate_mask,
1576 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1579 .label = "create mode",
1582 .ptr = &sDefault.iCreate_mask,
1588 .label = "force create mode",
1591 .ptr = &sDefault.iCreate_force_mode,
1594 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1597 .label = "security mask",
1600 .ptr = &sDefault.iSecurity_mask,
1603 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1606 .label = "force security mode",
1609 .ptr = &sDefault.iSecurity_force_mode,
1612 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1615 .label = "directory mask",
1618 .ptr = &sDefault.iDir_mask,
1621 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1624 .label = "directory mode",
1627 .ptr = &sDefault.iDir_mask,
1630 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1633 .label = "force directory mode",
1636 .ptr = &sDefault.iDir_force_mode,
1639 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1642 .label = "directory security mask",
1645 .ptr = &sDefault.iDir_Security_mask,
1648 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1651 .label = "force directory security mode",
1654 .ptr = &sDefault.iDir_Security_force_mode,
1657 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1660 .label = "force unknown acl user",
1663 .ptr = &sDefault.bForceUnknownAclUser,
1666 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1669 .label = "inherit permissions",
1672 .ptr = &sDefault.bInheritPerms,
1675 .flags = FLAG_ADVANCED | FLAG_SHARE,
1678 .label = "inherit acls",
1681 .ptr = &sDefault.bInheritACLS,
1684 .flags = FLAG_ADVANCED | FLAG_SHARE,
1687 .label = "inherit owner",
1690 .ptr = &sDefault.bInheritOwner,
1693 .flags = FLAG_ADVANCED | FLAG_SHARE,
1696 .label = "guest only",
1699 .ptr = &sDefault.bGuest_only,
1702 .flags = FLAG_ADVANCED | FLAG_SHARE,
1705 .label = "only guest",
1708 .ptr = &sDefault.bGuest_only,
1714 .label = "administrative share",
1717 .ptr = &sDefault.bAdministrative_share,
1720 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1724 .label = "guest ok",
1727 .ptr = &sDefault.bGuest_ok,
1730 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1736 .ptr = &sDefault.bGuest_ok,
1742 .label = "only user",
1745 .ptr = &sDefault.bOnlyUser,
1748 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1751 .label = "hosts allow",
1754 .ptr = &sDefault.szHostsallow,
1757 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1760 .label = "allow hosts",
1763 .ptr = &sDefault.szHostsallow,
1769 .label = "hosts deny",
1772 .ptr = &sDefault.szHostsdeny,
1775 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1778 .label = "deny hosts",
1781 .ptr = &sDefault.szHostsdeny,
1787 .label = "preload modules",
1789 .p_class = P_GLOBAL,
1790 .ptr = &Globals.szPreloadModules,
1793 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1796 .label = "dedicated keytab file",
1798 .p_class = P_GLOBAL,
1799 .ptr = &Globals.szDedicatedKeytabFile,
1802 .flags = FLAG_ADVANCED,
1805 .label = "kerberos method",
1807 .p_class = P_GLOBAL,
1808 .ptr = &Globals.iKerberosMethod,
1810 .enum_list = enum_kerberos_method,
1811 .flags = FLAG_ADVANCED,
1814 .label = "map untrusted to domain",
1816 .p_class = P_GLOBAL,
1817 .ptr = &Globals.bMapUntrustedToDomain,
1820 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1824 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1827 .label = "log level",
1829 .p_class = P_GLOBAL,
1830 .ptr = &Globals.szLogLevel,
1831 .special = handle_debug_list,
1833 .flags = FLAG_ADVANCED,
1836 .label = "debuglevel",
1838 .p_class = P_GLOBAL,
1839 .ptr = &Globals.szLogLevel,
1840 .special = handle_debug_list,
1847 .p_class = P_GLOBAL,
1848 .ptr = &Globals.syslog,
1851 .flags = FLAG_ADVANCED,
1854 .label = "syslog only",
1856 .p_class = P_GLOBAL,
1857 .ptr = &Globals.bSyslogOnly,
1860 .flags = FLAG_ADVANCED,
1863 .label = "log file",
1865 .p_class = P_GLOBAL,
1866 .ptr = &Globals.szLogFile,
1869 .flags = FLAG_ADVANCED,
1872 .label = "max log size",
1874 .p_class = P_GLOBAL,
1875 .ptr = &Globals.max_log_size,
1878 .flags = FLAG_ADVANCED,
1881 .label = "debug timestamp",
1883 .p_class = P_GLOBAL,
1884 .ptr = &Globals.bTimestampLogs,
1887 .flags = FLAG_ADVANCED,
1890 .label = "timestamp logs",
1892 .p_class = P_GLOBAL,
1893 .ptr = &Globals.bTimestampLogs,
1896 .flags = FLAG_ADVANCED,
1899 .label = "debug prefix timestamp",
1901 .p_class = P_GLOBAL,
1902 .ptr = &Globals.bDebugPrefixTimestamp,
1905 .flags = FLAG_ADVANCED,
1908 .label = "debug hires timestamp",
1910 .p_class = P_GLOBAL,
1911 .ptr = &Globals.bDebugHiresTimestamp,
1914 .flags = FLAG_ADVANCED,
1917 .label = "debug pid",
1919 .p_class = P_GLOBAL,
1920 .ptr = &Globals.bDebugPid,
1923 .flags = FLAG_ADVANCED,
1926 .label = "debug uid",
1928 .p_class = P_GLOBAL,
1929 .ptr = &Globals.bDebugUid,
1932 .flags = FLAG_ADVANCED,
1935 .label = "debug class",
1937 .p_class = P_GLOBAL,
1938 .ptr = &Globals.bDebugClass,
1941 .flags = FLAG_ADVANCED,
1944 .label = "enable core files",
1946 .p_class = P_GLOBAL,
1947 .ptr = &Globals.bEnableCoreFiles,
1950 .flags = FLAG_ADVANCED,
1953 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1956 .label = "allocation roundup size",
1959 .ptr = &sDefault.iallocation_roundup_size,
1962 .flags = FLAG_ADVANCED,
1965 .label = "aio read size",
1968 .ptr = &sDefault.iAioReadSize,
1971 .flags = FLAG_ADVANCED,
1974 .label = "aio write size",
1977 .ptr = &sDefault.iAioWriteSize,
1980 .flags = FLAG_ADVANCED,
1983 .label = "aio write behind",
1986 .ptr = &sDefault.szAioWriteBehind,
1989 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1992 .label = "smb ports",
1994 .p_class = P_GLOBAL,
1995 .ptr = &Globals.smb_ports,
1998 .flags = FLAG_ADVANCED,
2001 .label = "large readwrite",
2003 .p_class = P_GLOBAL,
2004 .ptr = &Globals.bLargeReadwrite,
2007 .flags = FLAG_ADVANCED,
2010 .label = "max protocol",
2012 .p_class = P_GLOBAL,
2013 .ptr = &Globals.maxprotocol,
2015 .enum_list = enum_protocol,
2016 .flags = FLAG_ADVANCED,
2019 .label = "protocol",
2021 .p_class = P_GLOBAL,
2022 .ptr = &Globals.maxprotocol,
2024 .enum_list = enum_protocol,
2025 .flags = FLAG_ADVANCED,
2028 .label = "min protocol",
2030 .p_class = P_GLOBAL,
2031 .ptr = &Globals.minprotocol,
2033 .enum_list = enum_protocol,
2034 .flags = FLAG_ADVANCED,
2037 .label = "min receivefile size",
2039 .p_class = P_GLOBAL,
2040 .ptr = &Globals.iminreceivefile,
2043 .flags = FLAG_ADVANCED,
2046 .label = "read raw",
2048 .p_class = P_GLOBAL,
2049 .ptr = &Globals.bReadRaw,
2052 .flags = FLAG_ADVANCED,
2055 .label = "write raw",
2057 .p_class = P_GLOBAL,
2058 .ptr = &Globals.bWriteRaw,
2061 .flags = FLAG_ADVANCED,
2064 .label = "disable netbios",
2066 .p_class = P_GLOBAL,
2067 .ptr = &Globals.bDisableNetbios,
2070 .flags = FLAG_ADVANCED,
2073 .label = "reset on zero vc",
2075 .p_class = P_GLOBAL,
2076 .ptr = &Globals.bResetOnZeroVC,
2079 .flags = FLAG_ADVANCED,
2082 .label = "log writeable files on exit",
2084 .p_class = P_GLOBAL,
2085 .ptr = &Globals.bLogWriteableFilesOnExit,
2088 .flags = FLAG_ADVANCED,
2091 .label = "acl compatibility",
2093 .p_class = P_GLOBAL,
2094 .ptr = &Globals.iAclCompat,
2096 .enum_list = enum_acl_compat_vals,
2097 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2100 .label = "defer sharing violations",
2102 .p_class = P_GLOBAL,
2103 .ptr = &Globals.bDeferSharingViolations,
2106 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2109 .label = "ea support",
2112 .ptr = &sDefault.bEASupport,
2115 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2118 .label = "nt acl support",
2121 .ptr = &sDefault.bNTAclSupport,
2124 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2127 .label = "nt pipe support",
2129 .p_class = P_GLOBAL,
2130 .ptr = &Globals.bNTPipeSupport,
2133 .flags = FLAG_ADVANCED,
2136 .label = "nt status support",
2138 .p_class = P_GLOBAL,
2139 .ptr = &Globals.bNTStatusSupport,
2142 .flags = FLAG_ADVANCED,
2145 .label = "profile acls",
2148 .ptr = &sDefault.bProfileAcls,
2151 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2154 .label = "announce version",
2156 .p_class = P_GLOBAL,
2157 .ptr = &Globals.szAnnounceVersion,
2160 .flags = FLAG_ADVANCED,
2163 .label = "announce as",
2165 .p_class = P_GLOBAL,
2166 .ptr = &Globals.announce_as,
2168 .enum_list = enum_announce_as,
2169 .flags = FLAG_ADVANCED,
2172 .label = "map acl inherit",
2175 .ptr = &sDefault.bMap_acl_inherit,
2178 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2181 .label = "afs share",
2184 .ptr = &sDefault.bAfs_Share,
2187 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2192 .p_class = P_GLOBAL,
2193 .ptr = &Globals.max_mux,
2196 .flags = FLAG_ADVANCED,
2199 .label = "max xmit",
2201 .p_class = P_GLOBAL,
2202 .ptr = &Globals.max_xmit,
2205 .flags = FLAG_ADVANCED,
2208 .label = "name resolve order",
2210 .p_class = P_GLOBAL,
2211 .ptr = &Globals.szNameResolveOrder,
2214 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2219 .p_class = P_GLOBAL,
2220 .ptr = &Globals.max_ttl,
2223 .flags = FLAG_ADVANCED,
2226 .label = "max wins ttl",
2228 .p_class = P_GLOBAL,
2229 .ptr = &Globals.max_wins_ttl,
2232 .flags = FLAG_ADVANCED,
2235 .label = "min wins ttl",
2237 .p_class = P_GLOBAL,
2238 .ptr = &Globals.min_wins_ttl,
2241 .flags = FLAG_ADVANCED,
2244 .label = "time server",
2246 .p_class = P_GLOBAL,
2247 .ptr = &Globals.bTimeServer,
2250 .flags = FLAG_ADVANCED,
2253 .label = "unix extensions",
2255 .p_class = P_GLOBAL,
2256 .ptr = &Globals.bUnixExtensions,
2259 .flags = FLAG_ADVANCED,
2262 .label = "use spnego",
2264 .p_class = P_GLOBAL,
2265 .ptr = &Globals.bUseSpnego,
2268 .flags = FLAG_ADVANCED,
2271 .label = "client signing",
2273 .p_class = P_GLOBAL,
2274 .ptr = &Globals.client_signing,
2276 .enum_list = enum_smb_signing_vals,
2277 .flags = FLAG_ADVANCED,
2280 .label = "server signing",
2282 .p_class = P_GLOBAL,
2283 .ptr = &Globals.server_signing,
2285 .enum_list = enum_smb_signing_vals,
2286 .flags = FLAG_ADVANCED,
2289 .label = "smb encrypt",
2292 .ptr = &sDefault.ismb_encrypt,
2294 .enum_list = enum_smb_signing_vals,
2295 .flags = FLAG_ADVANCED,
2298 .label = "client use spnego",
2300 .p_class = P_GLOBAL,
2301 .ptr = &Globals.bClientUseSpnego,
2304 .flags = FLAG_ADVANCED,
2307 .label = "client ldap sasl wrapping",
2309 .p_class = P_GLOBAL,
2310 .ptr = &Globals.client_ldap_sasl_wrapping,
2312 .enum_list = enum_ldap_sasl_wrapping,
2313 .flags = FLAG_ADVANCED,
2316 .label = "enable asu support",
2318 .p_class = P_GLOBAL,
2319 .ptr = &Globals.bASUSupport,
2322 .flags = FLAG_ADVANCED,
2325 .label = "svcctl list",
2327 .p_class = P_GLOBAL,
2328 .ptr = &Globals.szServicesList,
2331 .flags = FLAG_ADVANCED,
2334 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2337 .label = "block size",
2340 .ptr = &sDefault.iBlock_size,
2343 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2346 .label = "deadtime",
2348 .p_class = P_GLOBAL,
2349 .ptr = &Globals.deadtime,
2352 .flags = FLAG_ADVANCED,
2355 .label = "getwd cache",
2357 .p_class = P_GLOBAL,
2358 .ptr = &Globals.getwd_cache,
2361 .flags = FLAG_ADVANCED,
2364 .label = "keepalive",
2366 .p_class = P_GLOBAL,
2367 .ptr = &Globals.iKeepalive,
2370 .flags = FLAG_ADVANCED,
2373 .label = "change notify",
2376 .ptr = &sDefault.bChangeNotify,
2379 .flags = FLAG_ADVANCED | FLAG_SHARE,
2382 .label = "directory name cache size",
2385 .ptr = &sDefault.iDirectoryNameCacheSize,
2388 .flags = FLAG_ADVANCED | FLAG_SHARE,
2391 .label = "kernel change notify",
2394 .ptr = &sDefault.bKernelChangeNotify,
2397 .flags = FLAG_ADVANCED | FLAG_SHARE,
2400 .label = "lpq cache time",
2402 .p_class = P_GLOBAL,
2403 .ptr = &Globals.lpqcachetime,
2406 .flags = FLAG_ADVANCED,
2409 .label = "max smbd processes",
2411 .p_class = P_GLOBAL,
2412 .ptr = &Globals.iMaxSmbdProcesses,
2415 .flags = FLAG_ADVANCED,
2418 .label = "max connections",
2421 .ptr = &sDefault.iMaxConnections,
2424 .flags = FLAG_ADVANCED | FLAG_SHARE,
2427 .label = "paranoid server security",
2429 .p_class = P_GLOBAL,
2430 .ptr = &Globals.paranoid_server_security,
2433 .flags = FLAG_ADVANCED,
2436 .label = "max disk size",
2438 .p_class = P_GLOBAL,
2439 .ptr = &Globals.maxdisksize,
2442 .flags = FLAG_ADVANCED,
2445 .label = "max open files",
2447 .p_class = P_GLOBAL,
2448 .ptr = &Globals.max_open_files,
2451 .flags = FLAG_ADVANCED,
2454 .label = "min print space",
2457 .ptr = &sDefault.iMinPrintSpace,
2460 .flags = FLAG_ADVANCED | FLAG_PRINT,
2463 .label = "socket options",
2465 .p_class = P_GLOBAL,
2466 .ptr = &Globals.szSocketOptions,
2469 .flags = FLAG_ADVANCED,
2472 .label = "strict allocate",
2475 .ptr = &sDefault.bStrictAllocate,
2478 .flags = FLAG_ADVANCED | FLAG_SHARE,
2481 .label = "strict sync",
2484 .ptr = &sDefault.bStrictSync,
2487 .flags = FLAG_ADVANCED | FLAG_SHARE,
2490 .label = "sync always",
2493 .ptr = &sDefault.bSyncAlways,
2496 .flags = FLAG_ADVANCED | FLAG_SHARE,
2499 .label = "use mmap",
2501 .p_class = P_GLOBAL,
2502 .ptr = &Globals.bUseMmap,
2505 .flags = FLAG_ADVANCED,
2508 .label = "use sendfile",
2511 .ptr = &sDefault.bUseSendfile,
2514 .flags = FLAG_ADVANCED | FLAG_SHARE,
2517 .label = "hostname lookups",
2519 .p_class = P_GLOBAL,
2520 .ptr = &Globals.bHostnameLookups,
2523 .flags = FLAG_ADVANCED,
2526 .label = "write cache size",
2529 .ptr = &sDefault.iWriteCacheSize,
2532 .flags = FLAG_ADVANCED | FLAG_SHARE,
2535 .label = "name cache timeout",
2537 .p_class = P_GLOBAL,
2538 .ptr = &Globals.name_cache_timeout,
2541 .flags = FLAG_ADVANCED,
2544 .label = "ctdbd socket",
2546 .p_class = P_GLOBAL,
2547 .ptr = &Globals.ctdbdSocket,
2550 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2553 .label = "cluster addresses",
2555 .p_class = P_GLOBAL,
2556 .ptr = &Globals.szClusterAddresses,
2559 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2562 .label = "clustering",
2564 .p_class = P_GLOBAL,
2565 .ptr = &Globals.clustering,
2568 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2571 .label = "ctdb timeout",
2573 .p_class = P_GLOBAL,
2574 .ptr = &Globals.ctdb_timeout,
2577 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2580 .label = "ctdb locktime warn threshold",
2582 .p_class = P_GLOBAL,
2583 .ptr = &Globals.ctdb_locktime_warn_threshold,
2586 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2589 .label = "smb2 max read",
2591 .p_class = P_GLOBAL,
2592 .ptr = &Globals.ismb2_max_read,
2595 .flags = FLAG_ADVANCED,
2598 .label = "smb2 max write",
2600 .p_class = P_GLOBAL,
2601 .ptr = &Globals.ismb2_max_write,
2604 .flags = FLAG_ADVANCED,
2607 .label = "smb2 max trans",
2609 .p_class = P_GLOBAL,
2610 .ptr = &Globals.ismb2_max_trans,
2613 .flags = FLAG_ADVANCED,
2616 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2619 .label = "max reported print jobs",
2622 .ptr = &sDefault.iMaxReportedPrintJobs,
2625 .flags = FLAG_ADVANCED | FLAG_PRINT,
2628 .label = "max print jobs",
2631 .ptr = &sDefault.iMaxPrintJobs,
2634 .flags = FLAG_ADVANCED | FLAG_PRINT,
2637 .label = "load printers",
2639 .p_class = P_GLOBAL,
2640 .ptr = &Globals.bLoadPrinters,
2643 .flags = FLAG_ADVANCED | FLAG_PRINT,
2646 .label = "printcap cache time",
2648 .p_class = P_GLOBAL,
2649 .ptr = &Globals.PrintcapCacheTime,
2652 .flags = FLAG_ADVANCED | FLAG_PRINT,
2655 .label = "printcap name",
2657 .p_class = P_GLOBAL,
2658 .ptr = &Globals.szPrintcapname,
2661 .flags = FLAG_ADVANCED | FLAG_PRINT,
2664 .label = "printcap",
2666 .p_class = P_GLOBAL,
2667 .ptr = &Globals.szPrintcapname,
2673 .label = "printable",
2676 .ptr = &sDefault.bPrint_ok,
2679 .flags = FLAG_ADVANCED | FLAG_PRINT,
2682 .label = "print ok",
2685 .ptr = &sDefault.bPrint_ok,
2691 .label = "printing",
2694 .ptr = &sDefault.iPrinting,
2695 .special = handle_printing,
2696 .enum_list = enum_printing,
2697 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2700 .label = "cups options",
2703 .ptr = &sDefault.szCupsOptions,
2706 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2709 .label = "cups server",
2711 .p_class = P_GLOBAL,
2712 .ptr = &Globals.szCupsServer,
2715 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2718 .label = "cups encrypt",
2720 .p_class = P_GLOBAL,
2721 .ptr = &Globals.CupsEncrypt,
2723 .enum_list = enum_bool_auto,
2724 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2728 .label = "cups connection timeout",
2730 .p_class = P_GLOBAL,
2731 .ptr = &Globals.cups_connection_timeout,
2734 .flags = FLAG_ADVANCED,
2737 .label = "iprint server",
2739 .p_class = P_GLOBAL,
2740 .ptr = &Globals.szIPrintServer,
2743 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2746 .label = "print command",
2749 .ptr = &sDefault.szPrintcommand,
2752 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2755 .label = "disable spoolss",
2757 .p_class = P_GLOBAL,
2758 .ptr = &Globals.bDisableSpoolss,
2761 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2764 .label = "enable spoolss",
2766 .p_class = P_GLOBAL,
2767 .ptr = &Globals.bDisableSpoolss,
2773 .label = "lpq command",
2776 .ptr = &sDefault.szLpqcommand,
2779 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2782 .label = "lprm command",
2785 .ptr = &sDefault.szLprmcommand,
2788 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2791 .label = "lppause command",
2794 .ptr = &sDefault.szLppausecommand,
2797 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2800 .label = "lpresume command",
2803 .ptr = &sDefault.szLpresumecommand,
2806 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2809 .label = "queuepause command",
2812 .ptr = &sDefault.szQueuepausecommand,
2815 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2818 .label = "queueresume command",
2821 .ptr = &sDefault.szQueueresumecommand,
2824 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2827 .label = "addport command",
2829 .p_class = P_GLOBAL,
2830 .ptr = &Globals.szAddPortCommand,
2833 .flags = FLAG_ADVANCED,
2836 .label = "enumports command",
2838 .p_class = P_GLOBAL,
2839 .ptr = &Globals.szEnumPortsCommand,
2842 .flags = FLAG_ADVANCED,
2845 .label = "addprinter command",
2847 .p_class = P_GLOBAL,
2848 .ptr = &Globals.szAddPrinterCommand,
2851 .flags = FLAG_ADVANCED,
2854 .label = "deleteprinter command",
2856 .p_class = P_GLOBAL,
2857 .ptr = &Globals.szDeletePrinterCommand,
2860 .flags = FLAG_ADVANCED,
2863 .label = "show add printer wizard",
2865 .p_class = P_GLOBAL,
2866 .ptr = &Globals.bMsAddPrinterWizard,
2869 .flags = FLAG_ADVANCED,
2872 .label = "os2 driver map",
2874 .p_class = P_GLOBAL,
2875 .ptr = &Globals.szOs2DriverMap,
2878 .flags = FLAG_ADVANCED,
2882 .label = "printer name",
2885 .ptr = &sDefault.szPrintername,
2888 .flags = FLAG_ADVANCED | FLAG_PRINT,
2894 .ptr = &sDefault.szPrintername,
2900 .label = "use client driver",
2903 .ptr = &sDefault.bUseClientDriver,
2906 .flags = FLAG_ADVANCED | FLAG_PRINT,
2909 .label = "default devmode",
2912 .ptr = &sDefault.bDefaultDevmode,
2915 .flags = FLAG_ADVANCED | FLAG_PRINT,
2918 .label = "force printername",
2921 .ptr = &sDefault.bForcePrintername,
2924 .flags = FLAG_ADVANCED | FLAG_PRINT,
2927 .label = "printjob username",
2930 .ptr = &sDefault.szPrintjobUsername,
2933 .flags = FLAG_ADVANCED | FLAG_PRINT,
2936 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2939 .label = "mangling method",
2941 .p_class = P_GLOBAL,
2942 .ptr = &Globals.szManglingMethod,
2945 .flags = FLAG_ADVANCED,
2948 .label = "mangle prefix",
2950 .p_class = P_GLOBAL,
2951 .ptr = &Globals.mangle_prefix,
2954 .flags = FLAG_ADVANCED,
2958 .label = "default case",
2961 .ptr = &sDefault.iDefaultCase,
2963 .enum_list = enum_case,
2964 .flags = FLAG_ADVANCED | FLAG_SHARE,
2967 .label = "case sensitive",
2970 .ptr = &sDefault.iCaseSensitive,
2972 .enum_list = enum_bool_auto,
2973 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2976 .label = "casesignames",
2979 .ptr = &sDefault.iCaseSensitive,
2981 .enum_list = enum_bool_auto,
2982 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2985 .label = "preserve case",
2988 .ptr = &sDefault.bCasePreserve,
2991 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2994 .label = "short preserve case",
2997 .ptr = &sDefault.bShortCasePreserve,
3000 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3003 .label = "mangling char",
3006 .ptr = &sDefault.magic_char,
3009 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3012 .label = "hide dot files",
3015 .ptr = &sDefault.bHideDotFiles,
3018 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3021 .label = "hide special files",
3024 .ptr = &sDefault.bHideSpecialFiles,
3027 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3030 .label = "hide unreadable",
3033 .ptr = &sDefault.bHideUnReadable,
3036 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3039 .label = "hide unwriteable files",
3042 .ptr = &sDefault.bHideUnWriteableFiles,
3045 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3048 .label = "delete veto files",
3051 .ptr = &sDefault.bDeleteVetoFiles,
3054 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3057 .label = "veto files",
3060 .ptr = &sDefault.szVetoFiles,
3063 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3066 .label = "hide files",
3069 .ptr = &sDefault.szHideFiles,
3072 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3075 .label = "veto oplock files",
3078 .ptr = &sDefault.szVetoOplockFiles,
3081 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3084 .label = "map archive",
3087 .ptr = &sDefault.bMap_archive,
3090 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3093 .label = "map hidden",
3096 .ptr = &sDefault.bMap_hidden,
3099 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3102 .label = "map system",
3105 .ptr = &sDefault.bMap_system,
3108 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3111 .label = "map readonly",
3114 .ptr = &sDefault.iMap_readonly,
3116 .enum_list = enum_map_readonly,
3117 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3120 .label = "mangled names",
3123 .ptr = &sDefault.bMangledNames,
3126 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3129 .label = "max stat cache size",
3131 .p_class = P_GLOBAL,
3132 .ptr = &Globals.iMaxStatCacheSize,
3135 .flags = FLAG_ADVANCED,
3138 .label = "stat cache",
3140 .p_class = P_GLOBAL,
3141 .ptr = &Globals.bStatCache,
3144 .flags = FLAG_ADVANCED,
3147 .label = "store dos attributes",
3150 .ptr = &sDefault.bStoreDosAttributes,
3153 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3156 .label = "dmapi support",
3159 .ptr = &sDefault.bDmapiSupport,
3162 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3166 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3169 .label = "machine password timeout",
3171 .p_class = P_GLOBAL,
3172 .ptr = &Globals.machine_password_timeout,
3175 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3178 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3181 .label = "add user script",
3183 .p_class = P_GLOBAL,
3184 .ptr = &Globals.szAddUserScript,
3187 .flags = FLAG_ADVANCED,
3190 .label = "rename user script",
3192 .p_class = P_GLOBAL,
3193 .ptr = &Globals.szRenameUserScript,
3196 .flags = FLAG_ADVANCED,
3199 .label = "delete user script",
3201 .p_class = P_GLOBAL,
3202 .ptr = &Globals.szDelUserScript,
3205 .flags = FLAG_ADVANCED,
3208 .label = "add group script",
3210 .p_class = P_GLOBAL,
3211 .ptr = &Globals.szAddGroupScript,
3214 .flags = FLAG_ADVANCED,
3217 .label = "delete group script",
3219 .p_class = P_GLOBAL,
3220 .ptr = &Globals.szDelGroupScript,
3223 .flags = FLAG_ADVANCED,
3226 .label = "add user to group script",
3228 .p_class = P_GLOBAL,
3229 .ptr = &Globals.szAddUserToGroupScript,
3232 .flags = FLAG_ADVANCED,
3235 .label = "delete user from group script",
3237 .p_class = P_GLOBAL,
3238 .ptr = &Globals.szDelUserFromGroupScript,
3241 .flags = FLAG_ADVANCED,
3244 .label = "set primary group script",
3246 .p_class = P_GLOBAL,
3247 .ptr = &Globals.szSetPrimaryGroupScript,
3250 .flags = FLAG_ADVANCED,
3253 .label = "add machine script",
3255 .p_class = P_GLOBAL,
3256 .ptr = &Globals.szAddMachineScript,
3259 .flags = FLAG_ADVANCED,
3262 .label = "shutdown script",
3264 .p_class = P_GLOBAL,
3265 .ptr = &Globals.szShutdownScript,
3268 .flags = FLAG_ADVANCED,
3271 .label = "abort shutdown script",
3273 .p_class = P_GLOBAL,
3274 .ptr = &Globals.szAbortShutdownScript,
3277 .flags = FLAG_ADVANCED,
3280 .label = "username map script",
3282 .p_class = P_GLOBAL,
3283 .ptr = &Globals.szUsernameMapScript,
3286 .flags = FLAG_ADVANCED,
3289 .label = "username map cache time",
3291 .p_class = P_GLOBAL,
3292 .ptr = &Globals.iUsernameMapCacheTime,
3295 .flags = FLAG_ADVANCED,
3298 .label = "logon script",
3300 .p_class = P_GLOBAL,
3301 .ptr = &Globals.szLogonScript,
3304 .flags = FLAG_ADVANCED,
3307 .label = "logon path",
3309 .p_class = P_GLOBAL,
3310 .ptr = &Globals.szLogonPath,
3313 .flags = FLAG_ADVANCED,
3316 .label = "logon drive",
3318 .p_class = P_GLOBAL,
3319 .ptr = &Globals.szLogonDrive,
3322 .flags = FLAG_ADVANCED,
3325 .label = "logon home",
3327 .p_class = P_GLOBAL,
3328 .ptr = &Globals.szLogonHome,
3331 .flags = FLAG_ADVANCED,
3334 .label = "domain logons",
3336 .p_class = P_GLOBAL,
3337 .ptr = &Globals.bDomainLogons,
3340 .flags = FLAG_ADVANCED,
3344 .label = "init logon delayed hosts",
3346 .p_class = P_GLOBAL,
3347 .ptr = &Globals.szInitLogonDelayedHosts,
3350 .flags = FLAG_ADVANCED,
3354 .label = "init logon delay",
3356 .p_class = P_GLOBAL,
3357 .ptr = &Globals.InitLogonDelay,
3360 .flags = FLAG_ADVANCED,
3364 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3367 .label = "os level",
3369 .p_class = P_GLOBAL,
3370 .ptr = &Globals.os_level,
3373 .flags = FLAG_BASIC | FLAG_ADVANCED,
3376 .label = "lm announce",
3378 .p_class = P_GLOBAL,
3379 .ptr = &Globals.lm_announce,
3381 .enum_list = enum_bool_auto,
3382 .flags = FLAG_ADVANCED,
3385 .label = "lm interval",
3387 .p_class = P_GLOBAL,
3388 .ptr = &Globals.lm_interval,
3391 .flags = FLAG_ADVANCED,
3394 .label = "preferred master",
3396 .p_class = P_GLOBAL,
3397 .ptr = &Globals.iPreferredMaster,
3399 .enum_list = enum_bool_auto,
3400 .flags = FLAG_BASIC | FLAG_ADVANCED,
3403 .label = "prefered master",
3405 .p_class = P_GLOBAL,
3406 .ptr = &Globals.iPreferredMaster,
3408 .enum_list = enum_bool_auto,
3412 .label = "local master",
3414 .p_class = P_GLOBAL,
3415 .ptr = &Globals.bLocalMaster,
3418 .flags = FLAG_BASIC | FLAG_ADVANCED,
3421 .label = "domain master",
3423 .p_class = P_GLOBAL,
3424 .ptr = &Globals.iDomainMaster,
3426 .enum_list = enum_bool_auto,
3427 .flags = FLAG_BASIC | FLAG_ADVANCED,
3430 .label = "browse list",
3432 .p_class = P_GLOBAL,
3433 .ptr = &Globals.bBrowseList,
3436 .flags = FLAG_ADVANCED,
3439 .label = "browseable",
3442 .ptr = &sDefault.bBrowseable,
3445 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3448 .label = "browsable",
3451 .ptr = &sDefault.bBrowseable,
3457 .label = "access based share enum",
3460 .ptr = &sDefault.bAccessBasedShareEnum,
3463 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3466 .label = "enhanced browsing",
3468 .p_class = P_GLOBAL,
3469 .ptr = &Globals.enhanced_browsing,
3472 .flags = FLAG_ADVANCED,
3475 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3478 .label = "dns proxy",
3480 .p_class = P_GLOBAL,
3481 .ptr = &Globals.bDNSproxy,
3484 .flags = FLAG_ADVANCED,
3487 .label = "wins proxy",
3489 .p_class = P_GLOBAL,
3490 .ptr = &Globals.bWINSproxy,
3493 .flags = FLAG_ADVANCED,
3496 .label = "wins server",
3498 .p_class = P_GLOBAL,
3499 .ptr = &Globals.szWINSservers,
3502 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3505 .label = "wins support",
3507 .p_class = P_GLOBAL,
3508 .ptr = &Globals.bWINSsupport,
3511 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3514 .label = "wins hook",
3516 .p_class = P_GLOBAL,
3517 .ptr = &Globals.szWINSHook,
3520 .flags = FLAG_ADVANCED,
3523 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3526 .label = "blocking locks",
3529 .ptr = &sDefault.bBlockingLocks,
3532 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3535 .label = "csc policy",
3538 .ptr = &sDefault.iCSCPolicy,
3540 .enum_list = enum_csc_policy,
3541 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3544 .label = "fake oplocks",
3547 .ptr = &sDefault.bFakeOplocks,
3550 .flags = FLAG_ADVANCED | FLAG_SHARE,
3553 .label = "kernel oplocks",
3555 .p_class = P_GLOBAL,
3556 .ptr = &Globals.bKernelOplocks,
3559 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3565 .ptr = &sDefault.bLocking,
3568 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3571 .label = "lock spin time",
3573 .p_class = P_GLOBAL,
3574 .ptr = &Globals.iLockSpinTime,
3577 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3583 .ptr = &sDefault.bOpLocks,
3586 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3589 .label = "level2 oplocks",
3592 .ptr = &sDefault.bLevel2OpLocks,
3595 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3598 .label = "oplock break wait time",
3600 .p_class = P_GLOBAL,
3601 .ptr = &Globals.oplock_break_wait_time,
3604 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3607 .label = "oplock contention limit",
3610 .ptr = &sDefault.iOplockContentionLimit,
3613 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3616 .label = "posix locking",
3619 .ptr = &sDefault.bPosixLocking,
3622 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3625 .label = "strict locking",
3628 .ptr = &sDefault.iStrictLocking,
3630 .enum_list = enum_bool_auto,
3631 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3634 .label = "share modes",
3637 .ptr = &sDefault.bShareModes,
3640 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3643 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3646 .label = "ldap admin dn",
3648 .p_class = P_GLOBAL,
3649 .ptr = &Globals.szLdapAdminDn,
3652 .flags = FLAG_ADVANCED,
3655 .label = "ldap delete dn",
3657 .p_class = P_GLOBAL,
3658 .ptr = &Globals.ldap_delete_dn,
3661 .flags = FLAG_ADVANCED,
3664 .label = "ldap group suffix",
3666 .p_class = P_GLOBAL,
3667 .ptr = &Globals.szLdapGroupSuffix,
3670 .flags = FLAG_ADVANCED,
3673 .label = "ldap idmap suffix",
3675 .p_class = P_GLOBAL,
3676 .ptr = &Globals.szLdapIdmapSuffix,
3679 .flags = FLAG_ADVANCED,
3682 .label = "ldap machine suffix",
3684 .p_class = P_GLOBAL,
3685 .ptr = &Globals.szLdapMachineSuffix,
3688 .flags = FLAG_ADVANCED,
3691 .label = "ldap passwd sync",
3693 .p_class = P_GLOBAL,
3694 .ptr = &Globals.ldap_passwd_sync,
3696 .enum_list = enum_ldap_passwd_sync,
3697 .flags = FLAG_ADVANCED,
3700 .label = "ldap password sync",
3702 .p_class = P_GLOBAL,
3703 .ptr = &Globals.ldap_passwd_sync,
3705 .enum_list = enum_ldap_passwd_sync,
3709 .label = "ldap replication sleep",
3711 .p_class = P_GLOBAL,
3712 .ptr = &Globals.ldap_replication_sleep,
3715 .flags = FLAG_ADVANCED,
3718 .label = "ldap suffix",
3720 .p_class = P_GLOBAL,
3721 .ptr = &Globals.szLdapSuffix,
3724 .flags = FLAG_ADVANCED,
3727 .label = "ldap ssl",
3729 .p_class = P_GLOBAL,
3730 .ptr = &Globals.ldap_ssl,
3732 .enum_list = enum_ldap_ssl,
3733 .flags = FLAG_ADVANCED,
3736 .label = "ldap ssl ads",
3738 .p_class = P_GLOBAL,
3739 .ptr = &Globals.ldap_ssl_ads,
3742 .flags = FLAG_ADVANCED,
3745 .label = "ldap deref",
3747 .p_class = P_GLOBAL,
3748 .ptr = &Globals.ldap_deref,
3750 .enum_list = enum_ldap_deref,
3751 .flags = FLAG_ADVANCED,
3754 .label = "ldap follow referral",
3756 .p_class = P_GLOBAL,
3757 .ptr = &Globals.ldap_follow_referral,
3759 .enum_list = enum_bool_auto,
3760 .flags = FLAG_ADVANCED,
3763 .label = "ldap timeout",
3765 .p_class = P_GLOBAL,
3766 .ptr = &Globals.ldap_timeout,
3769 .flags = FLAG_ADVANCED,
3772 .label = "ldap connection timeout",
3774 .p_class = P_GLOBAL,
3775 .ptr = &Globals.ldap_connection_timeout,
3778 .flags = FLAG_ADVANCED,
3781 .label = "ldap page size",
3783 .p_class = P_GLOBAL,
3784 .ptr = &Globals.ldap_page_size,
3787 .flags = FLAG_ADVANCED,
3790 .label = "ldap user suffix",
3792 .p_class = P_GLOBAL,
3793 .ptr = &Globals.szLdapUserSuffix,
3796 .flags = FLAG_ADVANCED,
3799 .label = "ldap debug level",
3801 .p_class = P_GLOBAL,
3802 .ptr = &Globals.ldap_debug_level,
3803 .special = handle_ldap_debug_level,
3805 .flags = FLAG_ADVANCED,
3808 .label = "ldap debug threshold",
3810 .p_class = P_GLOBAL,
3811 .ptr = &Globals.ldap_debug_threshold,
3814 .flags = FLAG_ADVANCED,
3817 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3820 .label = "eventlog list",
3822 .p_class = P_GLOBAL,
3823 .ptr = &Globals.szEventLogs,
3826 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3829 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3832 .label = "add share command",
3834 .p_class = P_GLOBAL,
3835 .ptr = &Globals.szAddShareCommand,
3838 .flags = FLAG_ADVANCED,
3841 .label = "change share command",
3843 .p_class = P_GLOBAL,
3844 .ptr = &Globals.szChangeShareCommand,
3847 .flags = FLAG_ADVANCED,
3850 .label = "delete share command",
3852 .p_class = P_GLOBAL,
3853 .ptr = &Globals.szDeleteShareCommand,
3856 .flags = FLAG_ADVANCED,
3859 .label = "config file",
3861 .p_class = P_GLOBAL,
3862 .ptr = &Globals.szConfigFile,
3865 .flags = FLAG_HIDE|FLAG_META,
3870 .p_class = P_GLOBAL,
3871 .ptr = &Globals.szAutoServices,
3874 .flags = FLAG_ADVANCED,
3877 .label = "auto services",
3879 .p_class = P_GLOBAL,
3880 .ptr = &Globals.szAutoServices,
3883 .flags = FLAG_ADVANCED,
3886 .label = "lock directory",
3888 .p_class = P_GLOBAL,
3889 .ptr = &Globals.szLockDir,
3892 .flags = FLAG_ADVANCED,
3895 .label = "lock dir",
3897 .p_class = P_GLOBAL,
3898 .ptr = &Globals.szLockDir,
3904 .label = "state directory",
3906 .p_class = P_GLOBAL,
3907 .ptr = &Globals.szStateDir,
3910 .flags = FLAG_ADVANCED,
3913 .label = "cache directory",
3915 .p_class = P_GLOBAL,
3916 .ptr = &Globals.szCacheDir,
3919 .flags = FLAG_ADVANCED,
3922 .label = "pid directory",
3924 .p_class = P_GLOBAL,
3925 .ptr = &Globals.szPidDir,
3928 .flags = FLAG_ADVANCED,
3932 .label = "utmp directory",
3934 .p_class = P_GLOBAL,
3935 .ptr = &Globals.szUtmpDir,
3938 .flags = FLAG_ADVANCED,
3941 .label = "wtmp directory",
3943 .p_class = P_GLOBAL,
3944 .ptr = &Globals.szWtmpDir,
3947 .flags = FLAG_ADVANCED,
3952 .p_class = P_GLOBAL,
3953 .ptr = &Globals.bUtmp,
3956 .flags = FLAG_ADVANCED,
3960 .label = "default service",
3962 .p_class = P_GLOBAL,
3963 .ptr = &Globals.szDefaultService,
3966 .flags = FLAG_ADVANCED,
3971 .p_class = P_GLOBAL,
3972 .ptr = &Globals.szDefaultService,
3975 .flags = FLAG_ADVANCED,
3978 .label = "message command",
3980 .p_class = P_GLOBAL,
3981 .ptr = &Globals.szMsgCommand,
3984 .flags = FLAG_ADVANCED,
3987 .label = "dfree cache time",
3990 .ptr = &sDefault.iDfreeCacheTime,
3993 .flags = FLAG_ADVANCED,
3996 .label = "dfree command",
3999 .ptr = &sDefault.szDfree,
4002 .flags = FLAG_ADVANCED,
4005 .label = "get quota command",
4007 .p_class = P_GLOBAL,
4008 .ptr = &Globals.szGetQuota,
4011 .flags = FLAG_ADVANCED,
4014 .label = "set quota command",
4016 .p_class = P_GLOBAL,
4017 .ptr = &Globals.szSetQuota,
4020 .flags = FLAG_ADVANCED,
4023 .label = "remote announce",
4025 .p_class = P_GLOBAL,
4026 .ptr = &Globals.szRemoteAnnounce,
4029 .flags = FLAG_ADVANCED,
4032 .label = "remote browse sync",
4034 .p_class = P_GLOBAL,
4035 .ptr = &Globals.szRemoteBrowseSync,
4038 .flags = FLAG_ADVANCED,
4041 .label = "socket address",
4043 .p_class = P_GLOBAL,
4044 .ptr = &Globals.szSocketAddress,
4047 .flags = FLAG_ADVANCED,
4050 .label = "nmbd bind explicit broadcast",
4052 .p_class = P_GLOBAL,
4053 .ptr = &Globals.bNmbdBindExplicitBroadcast,
4056 .flags = FLAG_ADVANCED,
4059 .label = "homedir map",
4061 .p_class = P_GLOBAL,
4062 .ptr = &Globals.szNISHomeMapName,
4065 .flags = FLAG_ADVANCED,
4068 .label = "afs username map",
4070 .p_class = P_GLOBAL,
4071 .ptr = &Globals.szAfsUsernameMap,
4074 .flags = FLAG_ADVANCED,
4077 .label = "afs token lifetime",
4079 .p_class = P_GLOBAL,
4080 .ptr = &Globals.iAfsTokenLifetime,
4083 .flags = FLAG_ADVANCED,
4086 .label = "log nt token command",
4088 .p_class = P_GLOBAL,
4089 .ptr = &Globals.szLogNtTokenCommand,
4092 .flags = FLAG_ADVANCED,
4095 .label = "time offset",
4097 .p_class = P_GLOBAL,
4098 .ptr = &extra_time_offset,
4101 .flags = FLAG_ADVANCED,
4104 .label = "NIS homedir",
4106 .p_class = P_GLOBAL,
4107 .ptr = &Globals.bNISHomeMap,
4110 .flags = FLAG_ADVANCED,
4116 .ptr = &sDefault.valid,
4125 .ptr = &sDefault.szCopy,
4126 .special = handle_copy,
4134 .ptr = &sDefault.szInclude,
4135 .special = handle_include,
4137 .flags = FLAG_HIDE|FLAG_META,
4143 .ptr = &sDefault.szPreExec,
4146 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4152 .ptr = &sDefault.szPreExec,
4155 .flags = FLAG_ADVANCED,
4158 .label = "preexec close",
4161 .ptr = &sDefault.bPreexecClose,
4164 .flags = FLAG_ADVANCED | FLAG_SHARE,
4167 .label = "postexec",
4170 .ptr = &sDefault.szPostExec,
4173 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4176 .label = "root preexec",
4179 .ptr = &sDefault.szRootPreExec,
4182 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4185 .label = "root preexec close",
4188 .ptr = &sDefault.bRootpreexecClose,
4191 .flags = FLAG_ADVANCED | FLAG_SHARE,
4194 .label = "root postexec",
4197 .ptr = &sDefault.szRootPostExec,
4200 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4203 .label = "available",
4206 .ptr = &sDefault.bAvailable,
4209 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4212 .label = "registry shares",
4214 .p_class = P_GLOBAL,
4215 .ptr = &Globals.bRegistryShares,
4218 .flags = FLAG_ADVANCED,
4221 .label = "usershare allow guests",
4223 .p_class = P_GLOBAL,
4224 .ptr = &Globals.bUsershareAllowGuests,
4227 .flags = FLAG_ADVANCED,
4230 .label = "usershare max shares",
4232 .p_class = P_GLOBAL,
4233 .ptr = &Globals.iUsershareMaxShares,
4236 .flags = FLAG_ADVANCED,
4239 .label = "usershare owner only",
4241 .p_class = P_GLOBAL,
4242 .ptr = &Globals.bUsershareOwnerOnly,
4245 .flags = FLAG_ADVANCED,
4248 .label = "usershare path",
4250 .p_class = P_GLOBAL,
4251 .ptr = &Globals.szUsersharePath,
4254 .flags = FLAG_ADVANCED,
4257 .label = "usershare prefix allow list",
4259 .p_class = P_GLOBAL,
4260 .ptr = &Globals.szUsersharePrefixAllowList,
4263 .flags = FLAG_ADVANCED,
4266 .label = "usershare prefix deny list",
4268 .p_class = P_GLOBAL,
4269 .ptr = &Globals.szUsersharePrefixDenyList,
4272 .flags = FLAG_ADVANCED,
4275 .label = "usershare template share",
4277 .p_class = P_GLOBAL,
4278 .ptr = &Globals.szUsershareTemplateShare,
4281 .flags = FLAG_ADVANCED,
4287 .ptr = &sDefault.volume,
4290 .flags = FLAG_ADVANCED | FLAG_SHARE,
4296 .ptr = &sDefault.fstype,
4299 .flags = FLAG_ADVANCED | FLAG_SHARE,
4302 .label = "set directory",
4305 .ptr = &sDefault.bNo_set_dir,
4308 .flags = FLAG_ADVANCED | FLAG_SHARE,
4311 .label = "wide links",
4314 .ptr = &sDefault.bWidelinks,
4317 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4320 .label = "follow symlinks",
4323 .ptr = &sDefault.bSymlinks,
4326 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4329 .label = "dont descend",
4332 .ptr = &sDefault.szDontdescend,
4335 .flags = FLAG_ADVANCED | FLAG_SHARE,
4338 .label = "magic script",
4341 .ptr = &sDefault.szMagicScript,
4344 .flags = FLAG_ADVANCED | FLAG_SHARE,
4347 .label = "magic output",
4350 .ptr = &sDefault.szMagicOutput,
4353 .flags = FLAG_ADVANCED | FLAG_SHARE,
4356 .label = "delete readonly",
4359 .ptr = &sDefault.bDeleteReadonly,
4362 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4365 .label = "dos filemode",
4368 .ptr = &sDefault.bDosFilemode,
4371 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4374 .label = "dos filetimes",
4377 .ptr = &sDefault.bDosFiletimes,
4380 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4383 .label = "dos filetime resolution",
4386 .ptr = &sDefault.bDosFiletimeResolution,
4389 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4392 .label = "fake directory create times",
4395 .ptr = &sDefault.bFakeDirCreateTimes,
4398 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4401 .label = "async smb echo handler",
4403 .p_class = P_GLOBAL,
4404 .ptr = &Globals.bAsyncSMBEchoHandler,
4407 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4410 .label = "panic action",
4412 .p_class = P_GLOBAL,
4413 .ptr = &Globals.szPanicAction,
4416 .flags = FLAG_ADVANCED,
4419 .label = "perfcount module",
4421 .p_class = P_GLOBAL,
4422 .ptr = &Globals.szSMBPerfcountModule,
4425 .flags = FLAG_ADVANCED,
4428 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4431 .label = "vfs objects",
4434 .ptr = &sDefault.szVfsObjects,
4437 .flags = FLAG_ADVANCED | FLAG_SHARE,
4440 .label = "vfs object",
4443 .ptr = &sDefault.szVfsObjects,
4450 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4453 .label = "msdfs root",
4456 .ptr = &sDefault.bMSDfsRoot,
4459 .flags = FLAG_ADVANCED | FLAG_SHARE,
4462 .label = "msdfs proxy",
4465 .ptr = &sDefault.szMSDfsProxy,
4468 .flags = FLAG_ADVANCED | FLAG_SHARE,
4471 .label = "host msdfs",
4473 .p_class = P_GLOBAL,
4474 .ptr = &Globals.bHostMSDfs,
4477 .flags = FLAG_ADVANCED,
4480 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4483 .label = "passdb expand explicit",
4485 .p_class = P_GLOBAL,
4486 .ptr = &Globals.bPassdbExpandExplicit,
4489 .flags = FLAG_ADVANCED,
4492 .label = "idmap backend",
4494 .p_class = P_GLOBAL,
4495 .ptr = &Globals.szIdmapBackend,
4498 .flags = FLAG_ADVANCED,
4501 .label = "idmap read only",
4503 .p_class = P_GLOBAL,
4504 .ptr = &Globals.bIdmapReadOnly,
4507 .flags = FLAG_ADVANCED,
4510 .label = "idmap cache time",
4512 .p_class = P_GLOBAL,
4513 .ptr = &Globals.iIdmapCacheTime,
4516 .flags = FLAG_ADVANCED,
4519 .label = "idmap negative cache time",
4521 .p_class = P_GLOBAL,
4522 .ptr = &Globals.iIdmapNegativeCacheTime,
4525 .flags = FLAG_ADVANCED,
4528 .label = "idmap uid",
4530 .p_class = P_GLOBAL,
4531 .ptr = &Globals.szIdmapUID,
4532 .special = handle_idmap_uid,
4534 .flags = FLAG_ADVANCED,
4537 .label = "winbind uid",
4539 .p_class = P_GLOBAL,
4540 .ptr = &Globals.szIdmapUID,
4541 .special = handle_idmap_uid,
4546 .label = "idmap gid",
4548 .p_class = P_GLOBAL,
4549 .ptr = &Globals.szIdmapGID,
4550 .special = handle_idmap_gid,
4552 .flags = FLAG_ADVANCED,
4555 .label = "winbind gid",
4557 .p_class = P_GLOBAL,
4558 .ptr = &Globals.szIdmapGID,
4559 .special = handle_idmap_gid,
4564 .label = "template homedir",
4566 .p_class = P_GLOBAL,
4567 .ptr = &Globals.szTemplateHomedir,
4570 .flags = FLAG_ADVANCED,
4573 .label = "template shell",
4575 .p_class = P_GLOBAL,
4576 .ptr = &Globals.szTemplateShell,
4579 .flags = FLAG_ADVANCED,
4582 .label = "winbind separator",
4584 .p_class = P_GLOBAL,
4585 .ptr = &Globals.szWinbindSeparator,
4588 .flags = FLAG_ADVANCED,
4591 .label = "winbind cache time",
4593 .p_class = P_GLOBAL,
4594 .ptr = &Globals.winbind_cache_time,
4597 .flags = FLAG_ADVANCED,
4600 .label = "winbind reconnect delay",
4602 .p_class = P_GLOBAL,
4603 .ptr = &Globals.winbind_reconnect_delay,
4606 .flags = FLAG_ADVANCED,
4609 .label = "winbind enum users",
4611 .p_class = P_GLOBAL,
4612 .ptr = &Globals.bWinbindEnumUsers,
4615 .flags = FLAG_ADVANCED,
4618 .label = "winbind enum groups",
4620 .p_class = P_GLOBAL,
4621 .ptr = &Globals.bWinbindEnumGroups,
4624 .flags = FLAG_ADVANCED,
4627 .label = "winbind use default domain",
4629 .p_class = P_GLOBAL,
4630 .ptr = &Globals.bWinbindUseDefaultDomain,
4633 .flags = FLAG_ADVANCED,
4636 .label = "winbind trusted domains only",
4638 .p_class = P_GLOBAL,
4639 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4642 .flags = FLAG_ADVANCED,
4645 .label = "winbind nested groups",
4647 .p_class = P_GLOBAL,
4648 .ptr = &Globals.bWinbindNestedGroups,
4651 .flags = FLAG_ADVANCED,
4654 .label = "winbind expand groups",
4656 .p_class = P_GLOBAL,
4657 .ptr = &Globals.winbind_expand_groups,
4660 .flags = FLAG_ADVANCED,
4663 .label = "winbind nss info",
4665 .p_class = P_GLOBAL,
4666 .ptr = &Globals.szWinbindNssInfo,
4669 .flags = FLAG_ADVANCED,
4672 .label = "winbind refresh tickets",
4674 .p_class = P_GLOBAL,
4675 .ptr = &Globals.bWinbindRefreshTickets,
4678 .flags = FLAG_ADVANCED,
4681 .label = "winbind offline logon",
4683 .p_class = P_GLOBAL,
4684 .ptr = &Globals.bWinbindOfflineLogon,
4687 .flags = FLAG_ADVANCED,
4690 .label = "winbind normalize names",
4692 .p_class = P_GLOBAL,
4693 .ptr = &Globals.bWinbindNormalizeNames,
4696 .flags = FLAG_ADVANCED,
4699 .label = "winbind rpc only",
4701 .p_class = P_GLOBAL,
4702 .ptr = &Globals.bWinbindRpcOnly,
4705 .flags = FLAG_ADVANCED,
4708 .label = "create krb5 conf",
4710 .p_class = P_GLOBAL,
4711 .ptr = &Globals.bCreateKrb5Conf,
4714 .flags = FLAG_ADVANCED,
4717 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4720 /***************************************************************************
4721 Initialise the sDefault parameter structure for the printer values.
4722 ***************************************************************************/
4724 static void init_printer_values(struct service *pService)
4726 /* choose defaults depending on the type of printing */
4727 switch (pService->iPrinting) {
4732 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4733 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4734 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4739 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4740 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4741 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4742 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4743 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4744 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4745 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4751 /* set the lpq command to contain the destination printer
4752 name only. This is used by cups_queue_get() */
4753 string_set(&pService->szLpqcommand, "%p");
4754 string_set(&pService->szLprmcommand, "");
4755 string_set(&pService->szPrintcommand, "");
4756 string_set(&pService->szLppausecommand, "");
4757 string_set(&pService->szLpresumecommand, "");
4758 string_set(&pService->szQueuepausecommand, "");
4759 string_set(&pService->szQueueresumecommand, "");
4761 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4762 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4763 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4764 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4765 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4766 string_set(&pService->szQueuepausecommand, "disable '%p'");
4767 string_set(&pService->szQueueresumecommand, "enable '%p'");
4768 #endif /* HAVE_CUPS */
4773 string_set(&pService->szLpqcommand, "lpstat -o%p");
4774 string_set(&pService->szLprmcommand, "cancel %p-%j");
4775 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4776 string_set(&pService->szQueuepausecommand, "disable %p");
4777 string_set(&pService->szQueueresumecommand, "enable %p");
4779 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4780 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4785 string_set(&pService->szLpqcommand, "lpq -P%p");
4786 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4787 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4793 string_set(&pService->szPrintcommand, "vlp print %p %s");
4794 string_set(&pService->szLpqcommand, "vlp lpq %p");
4795 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4796 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4797 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4798 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4799 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4801 #endif /* DEVELOPER */
4806 * Function to return the default value for the maximum number of open
4807 * file descriptors permitted. This function tries to consult the
4808 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4809 * the smaller of those.
4811 static int max_open_files(void)
4813 int sysctl_max = MAX_OPEN_FILES;
4814 int rlimit_max = MAX_OPEN_FILES;
4816 #ifdef HAVE_SYSCTLBYNAME
4818 size_t size = sizeof(sysctl_max);
4819 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4824 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4830 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4831 rlimit_max = rl.rlim_cur;
4833 #if defined(RLIM_INFINITY)
4834 if(rl.rlim_cur == RLIM_INFINITY)
4835 rlimit_max = MAX_OPEN_FILES;
4840 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4841 DEBUG(2,("max_open_files: sysctl_max (%d) below "
4842 "minimum Windows limit (%d)\n",
4844 MIN_OPEN_FILES_WINDOWS));
4845 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4848 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4849 DEBUG(2,("rlimit_max: rlimit_max (%d) below "
4850 "minimum Windows limit (%d)\n",
4852 MIN_OPEN_FILES_WINDOWS));
4853 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4856 return MIN(sysctl_max, rlimit_max);
4860 * Common part of freeing allocated data for one parameter.
4862 static void free_one_parameter_common(void *parm_ptr,
4863 struct parm_struct parm)
4865 if ((parm.type == P_STRING) ||
4866 (parm.type == P_USTRING))
4868 string_free((char**)parm_ptr);
4869 } else if (parm.type == P_LIST) {
4870 TALLOC_FREE(*((char***)parm_ptr));
4875 * Free the allocated data for one parameter for a share
4876 * given as a service struct.
4878 static void free_one_parameter(struct service *service,
4879 struct parm_struct parm)
4883 if (parm.p_class != P_LOCAL) {
4887 parm_ptr = lp_local_ptr(service, parm.ptr);
4889 free_one_parameter_common(parm_ptr, parm);
4893 * Free the allocated parameter data of a share given
4894 * as a service struct.
4896 static void free_parameters(struct service *service)
4900 for (i=0; parm_table[i].label; i++) {
4901 free_one_parameter(service, parm_table[i]);
4906 * Free the allocated data for one parameter for a given share
4907 * specified by an snum.
4909 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4913 if (parm.ptr == NULL) {
4918 parm_ptr = parm.ptr;
4919 } else if (parm.p_class != P_LOCAL) {
4922 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4925 free_one_parameter_common(parm_ptr, parm);
4929 * Free the allocated parameter data for a share specified
4932 static void free_parameters_by_snum(int snum)
4936 for (i=0; parm_table[i].label; i++) {
4937 free_one_parameter_by_snum(snum, parm_table[i]);
4942 * Free the allocated global parameters.
4944 static void free_global_parameters(void)
4946 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4949 static int map_parameter(const char *pszParmName);
4951 struct lp_stored_option {
4952 struct lp_stored_option *prev, *next;
4957 static struct lp_stored_option *stored_options;
4960 save options set by lp_set_cmdline() into a list. This list is
4961 re-applied when we do a globals reset, so that cmdline set options
4962 are sticky across reloads of smb.conf
4964 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
4966 struct lp_stored_option *entry = NULL;
4967 for (entry = stored_options; entry != NULL; entry = entry->next) {
4968 if (strcmp(pszParmName, entry->label) == 0) {
4969 DLIST_REMOVE(stored_options, entry);
4975 entry = talloc(NULL, struct lp_stored_option);
4980 entry->label = talloc_strdup(entry, pszParmName);
4981 if (!entry->label) {
4986 entry->value = talloc_strdup(entry, pszParmValue);
4987 if (!entry->value) {
4992 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
4997 static bool apply_lp_set_cmdline(void)
4999 struct lp_stored_option *entry = NULL;
5000 for (entry = stored_options; entry != NULL; entry = entry->next) {
5001 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
5002 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
5003 entry->label, entry->value));
5010 /***************************************************************************
5011 Initialise the global parameter structure.
5012 ***************************************************************************/
5014 static void init_globals(bool reinit_globals)
5016 static bool done_init = False;
5020 /* If requested to initialize only once and we've already done it... */
5021 if (!reinit_globals && done_init) {
5022 /* ... then we have nothing more to do */
5027 /* The logfile can be set before this is invoked. Free it if so. */
5028 if (Globals.szLogFile != NULL) {
5029 string_free(&Globals.szLogFile);
5030 Globals.szLogFile = NULL;
5034 free_global_parameters();
5037 /* This memset and the free_global_parameters() above will
5038 * wipe out smb.conf options set with lp_set_cmdline(). The
5039 * apply_lp_set_cmdline() call puts these values back in the
5040 * table once the defaults are set */
5041 memset((void *)&Globals, '\0', sizeof(Globals));
5043 for (i = 0; parm_table[i].label; i++) {
5044 if ((parm_table[i].type == P_STRING ||
5045 parm_table[i].type == P_USTRING) &&
5048 string_set((char **)parm_table[i].ptr, "");
5052 string_set(&sDefault.fstype, FSTYPE_STRING);
5053 string_set(&sDefault.szPrintjobUsername, "%U");
5055 init_printer_values(&sDefault);
5058 DEBUG(3, ("Initialising global parameters\n"));
5060 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
5061 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
5063 /* use the new 'hash2' method by default, with a prefix of 1 */
5064 string_set(&Globals.szManglingMethod, "hash2");
5065 Globals.mangle_prefix = 1;
5067 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5069 /* using UTF8 by default allows us to support all chars */
5070 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5072 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
5073 /* If the system supports nl_langinfo(), try to grab the value
5074 from the user's locale */
5075 string_set(&Globals.display_charset, "LOCALE");
5077 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
5080 /* Use codepage 850 as a default for the dos character set */
5081 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5084 * Allow the default PASSWD_CHAT to be overridden in local.h.
5086 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5088 set_global_myname(myhostname());
5089 string_set(&Globals.szNetbiosName,global_myname());
5091 set_global_myworkgroup(WORKGROUP);
5092 string_set(&Globals.szWorkgroup, lp_workgroup());
5094 string_set(&Globals.szPasswdProgram, "");
5095 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5096 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5097 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5098 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5099 string_set(&Globals.szSocketAddress, "0.0.0.0");
5101 * By default support explicit binding to broadcast
5104 Globals.bNmbdBindExplicitBroadcast = true;
5106 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5107 smb_panic("init_globals: ENOMEM");
5109 string_set(&Globals.szServerString, s);
5111 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5112 DEFAULT_MINOR_VERSION) < 0) {
5113 smb_panic("init_globals: ENOMEM");
5115 string_set(&Globals.szAnnounceVersion, s);
5118 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5121 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5123 string_set(&Globals.szLogonDrive, "");
5124 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5125 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5126 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5128 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5129 string_set(&Globals.szPasswordServer, "*");
5131 Globals.AlgorithmicRidBase = BASE_RID;
5133 Globals.bLoadPrinters = True;
5134 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
5136 Globals.ConfigBackend = config_backend;
5138 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5139 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5140 Globals.max_xmit = 0x4104;
5141 Globals.max_mux = 50; /* This is *needed* for profile support. */
5142 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
5143 Globals.bDisableSpoolss = False;
5144 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5145 Globals.pwordlevel = 0;
5146 Globals.unamelevel = 0;
5147 Globals.deadtime = 0;
5148 Globals.getwd_cache = true;
5149 Globals.bLargeReadwrite = True;
5150 Globals.max_log_size = 5000;
5151 Globals.max_open_files = max_open_files();
5152 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5153 Globals.maxprotocol = PROTOCOL_NT1;
5154 Globals.minprotocol = PROTOCOL_CORE;
5155 Globals.security = SEC_USER;
5156 Globals.paranoid_server_security = True;
5157 Globals.bEncryptPasswords = True;
5158 Globals.bUpdateEncrypt = False;
5159 Globals.clientSchannel = Auto;
5160 Globals.serverSchannel = Auto;
5161 Globals.bReadRaw = True;
5162 Globals.bWriteRaw = True;
5163 Globals.bNullPasswords = False;
5164 Globals.bObeyPamRestrictions = False;
5166 Globals.bSyslogOnly = False;
5167 Globals.bTimestampLogs = True;
5168 string_set(&Globals.szLogLevel, "0");
5169 Globals.bDebugPrefixTimestamp = False;
5170 Globals.bDebugHiresTimestamp = true;
5171 Globals.bDebugPid = False;
5172 Globals.bDebugUid = False;
5173 Globals.bDebugClass = False;
5174 Globals.bEnableCoreFiles = True;
5175 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5176 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5177 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5178 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5179 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5180 Globals.lm_interval = 60;
5181 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5182 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5183 Globals.bNISHomeMap = False;
5184 #ifdef WITH_NISPLUS_HOME
5185 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5187 string_set(&Globals.szNISHomeMapName, "auto.home");
5190 Globals.bTimeServer = False;
5191 Globals.bBindInterfacesOnly = False;
5192 Globals.bUnixPasswdSync = False;
5193 Globals.bPamPasswordChange = False;
5194 Globals.bPasswdChatDebug = False;
5195 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5196 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5197 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5198 Globals.bStatCache = True; /* use stat cache by default */
5199 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5200 Globals.restrict_anonymous = 0;
5201 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5202 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5203 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5204 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5205 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
5206 /* Note, that we will use NTLM2 session security (which is different), if it is available */
5208 Globals.map_to_guest = 0; /* By Default, "Never" */
5209 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5210 Globals.enhanced_browsing = true;
5211 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5212 #ifdef MMAP_BLACKLIST
5213 Globals.bUseMmap = False;
5215 Globals.bUseMmap = True;
5217 Globals.bUnixExtensions = True;
5218 Globals.bResetOnZeroVC = False;
5219 Globals.bLogWriteableFilesOnExit = False;
5220 Globals.bCreateKrb5Conf = true;
5222 /* hostname lookups can be very expensive and are broken on
5223 a large number of sites (tridge) */
5224 Globals.bHostnameLookups = False;
5226 string_set(&Globals.szPassdbBackend, "tdbsam");
5227 string_set(&Globals.szLdapSuffix, "");
5228 string_set(&Globals.szLdapMachineSuffix, "");
5229 string_set(&Globals.szLdapUserSuffix, "");
5230 string_set(&Globals.szLdapGroupSuffix, "");
5231 string_set(&Globals.szLdapIdmapSuffix, "");
5233 string_set(&Globals.szLdapAdminDn, "");
5234 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5235 Globals.ldap_ssl_ads = False;
5236 Globals.ldap_deref = -1;
5237 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5238 Globals.ldap_delete_dn = False;
5239 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5240 Globals.ldap_follow_referral = Auto;
5241 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5242 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5243 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5245 Globals.ldap_debug_level = 0;
5246 Globals.ldap_debug_threshold = 10;
5248 /* This is what we tell the afs client. in reality we set the token
5249 * to never expire, though, when this runs out the afs client will
5250 * forget the token. Set to 0 to get NEVERDATE.*/
5251 Globals.iAfsTokenLifetime = 604800;
5252 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5254 /* these parameters are set to defaults that are more appropriate
5255 for the increasing samba install base:
5257 as a member of the workgroup, that will possibly become a
5258 _local_ master browser (lm = True). this is opposed to a forced
5259 local master browser startup (pm = True).
5261 doesn't provide WINS server service by default (wsupp = False),
5262 and doesn't provide domain master browser services by default, either.
5266 Globals.bMsAddPrinterWizard = True;
5267 Globals.os_level = 20;
5268 Globals.bLocalMaster = True;
5269 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5270 Globals.bDomainLogons = False;
5271 Globals.bBrowseList = True;
5272 Globals.bWINSsupport = False;
5273 Globals.bWINSproxy = False;
5275 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5276 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5278 Globals.bDNSproxy = True;
5280 /* this just means to use them if they exist */
5281 Globals.bKernelOplocks = True;
5283 Globals.bAllowTrustedDomains = True;
5284 string_set(&Globals.szIdmapBackend, "tdb");
5285 Globals.bIdmapReadOnly = false;
5287 string_set(&Globals.szTemplateShell, "/bin/false");
5288 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5289 string_set(&Globals.szWinbindSeparator, "\\");
5291 string_set(&Globals.szCupsServer, "");
5292 string_set(&Globals.szIPrintServer, "");
5294 string_set(&Globals.ctdbdSocket, "");
5295 Globals.szClusterAddresses = NULL;
5296 Globals.clustering = False;
5297 Globals.ctdb_timeout = 0;
5298 Globals.ctdb_locktime_warn_threshold = 0;
5300 Globals.winbind_cache_time = 300; /* 5 minutes */
5301 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5302 Globals.bWinbindEnumUsers = False;
5303 Globals.bWinbindEnumGroups = False;
5304 Globals.bWinbindUseDefaultDomain = False;
5305 Globals.bWinbindTrustedDomainsOnly = False;
5306 Globals.bWinbindNestedGroups = True;
5307 Globals.winbind_expand_groups = 1;
5308 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5309 Globals.bWinbindRefreshTickets = False;
5310 Globals.bWinbindOfflineLogon = False;
5312 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5313 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5315 Globals.bPassdbExpandExplicit = False;
5317 Globals.name_cache_timeout = 660; /* In seconds */
5319 Globals.bUseSpnego = True;
5320 Globals.bClientUseSpnego = True;
5322 Globals.client_signing = Auto;
5323 Globals.server_signing = False;
5325 Globals.bDeferSharingViolations = True;
5326 string_set(&Globals.smb_ports, SMB_PORTS);
5328 Globals.bEnablePrivileges = True;
5329 Globals.bHostMSDfs = True;
5330 Globals.bASUSupport = False;
5332 /* User defined shares. */
5333 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5334 smb_panic("init_globals: ENOMEM");
5336 string_set(&Globals.szUsersharePath, s);
5338 string_set(&Globals.szUsershareTemplateShare, "");
5339 Globals.iUsershareMaxShares = 0;
5340 /* By default disallow sharing of directories not owned by the sharer. */
5341 Globals.bUsershareOwnerOnly = True;
5342 /* By default disallow guest access to usershares. */
5343 Globals.bUsershareAllowGuests = False;
5345 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5347 /* By default no shares out of the registry */
5348 Globals.bRegistryShares = False;
5350 Globals.iminreceivefile = 0;
5352 Globals.bMapUntrustedToDomain = false;
5354 Globals.ismb2_max_read = 1024*1024;
5355 Globals.ismb2_max_write = 1024*1024;
5356 Globals.ismb2_max_trans = 1024*1024;
5358 /* Now put back the settings that were set with lp_set_cmdline() */
5359 apply_lp_set_cmdline();
5362 /*******************************************************************
5363 Convenience routine to grab string parameters into temporary memory
5364 and run standard_sub_basic on them. The buffers can be written to by
5365 callers without affecting the source string.
5366 ********************************************************************/
5368 static char *lp_string(const char *s)
5371 TALLOC_CTX *ctx = talloc_tos();
5373 /* The follow debug is useful for tracking down memory problems
5374 especially if you have an inner loop that is calling a lp_*()
5375 function that returns a string. Perhaps this debug should be
5376 present all the time? */
5379 DEBUG(10, ("lp_string(%s)\n", s));
5385 ret = talloc_sub_basic(ctx,
5386 get_current_username(),
5387 current_user_info.domain,
5389 if (trim_char(ret, '\"', '\"')) {
5390 if (strchr(ret,'\"') != NULL) {
5392 ret = talloc_sub_basic(ctx,
5393 get_current_username(),
5394 current_user_info.domain,
5402 In this section all the functions that are used to access the
5403 parameters from the rest of the program are defined
5406 #define FN_GLOBAL_STRING(fn_name,ptr) \
5407 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5408 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5409 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5410 #define FN_GLOBAL_LIST(fn_name,ptr) \
5411 const char **fn_name(void) {return(*(const char ***)(ptr));}
5412 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5413 bool fn_name(void) {return(*(bool *)(ptr));}
5414 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5415 char fn_name(void) {return(*(char *)(ptr));}
5416 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5417 int fn_name(void) {return(*(int *)(ptr));}
5419 #define FN_LOCAL_STRING(fn_name,val) \
5420 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5421 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5422 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5423 #define FN_LOCAL_LIST(fn_name,val) \
5424 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5425 #define FN_LOCAL_BOOL(fn_name,val) \
5426 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5427 #define FN_LOCAL_INTEGER(fn_name,val) \
5428 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5430 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5431 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5432 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5433 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5434 #define FN_LOCAL_CHAR(fn_name,val) \
5435 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5437 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5438 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5439 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5440 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5441 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5442 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5443 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5444 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5445 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5446 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5447 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5448 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5449 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5450 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5451 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5452 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5453 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5454 * build process or in smb.conf, we use that value. Otherwise they
5455 * default to the value of lp_lockdir(). */
5456 char *lp_statedir(void) {
5457 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5458 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5459 return(lp_string(*(char **)(&Globals.szStateDir) ?
5460 *(char **)(&Globals.szStateDir) : ""));
5462 return(lp_string(*(char **)(&Globals.szLockDir) ?
5463 *(char **)(&Globals.szLockDir) : ""));
5465 char *lp_cachedir(void) {
5466 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5467 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5468 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5469 *(char **)(&Globals.szCacheDir) : ""));
5471 return(lp_string(*(char **)(&Globals.szLockDir) ?
5472 *(char **)(&Globals.szLockDir) : ""));
5474 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5475 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5476 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5477 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5478 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5479 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5480 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5481 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5482 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5483 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5484 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5485 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5486 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5487 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5488 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5489 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5490 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5491 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5492 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5493 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5494 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5495 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5496 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5497 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5498 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5499 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5500 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5501 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5502 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5503 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5504 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5505 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5506 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5507 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5508 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5509 * lp_passdb_backend() should be replace by the this macro again after
5512 const char *lp_passdb_backend(void)
5514 char *delim, *quote;
5516 delim = strchr( Globals.szPassdbBackend, ' ');
5517 /* no space at all */
5518 if (delim == NULL) {
5522 quote = strchr(Globals.szPassdbBackend, '"');
5523 /* no quote char or non in the first part */
5524 if (quote == NULL || quote > delim) {
5529 quote = strchr(quote+1, '"');
5530 if (quote == NULL) {
5531 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5533 } else if (*(quote+1) == '\0') {
5534 /* space, fitting quote char, and one backend only */
5537 /* terminate string after the fitting quote char */
5542 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5543 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5544 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5545 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5548 return Globals.szPassdbBackend;
5550 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5551 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5552 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5553 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5554 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5556 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5557 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5558 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5559 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5560 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5561 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5563 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5565 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5566 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5567 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5568 FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
5570 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5572 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5573 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5574 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5575 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5576 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5577 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5578 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5579 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5580 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5581 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5582 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5583 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5584 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5585 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5586 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5587 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5589 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5590 FN_GLOBAL_BOOL(lp_idmap_read_only, &Globals.bIdmapReadOnly)
5591 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5592 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5593 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5594 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5596 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5597 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5598 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5599 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5600 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5601 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5602 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5603 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5604 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5605 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5606 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5607 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5608 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5609 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5610 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5611 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5612 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5613 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5614 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5615 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5617 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5619 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5620 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5621 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5622 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5623 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5624 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5625 &Globals.bLogWriteableFilesOnExit)
5626 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5627 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5628 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5629 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5630 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5631 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5632 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5633 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5634 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5635 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5636 FN_GLOBAL_BOOL(_lp_readraw, &Globals.bReadRaw)
5637 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5638 FN_GLOBAL_BOOL(_lp_writeraw, &Globals.bWriteRaw)
5639 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5640 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5641 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5642 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5643 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5644 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5645 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5646 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5647 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5648 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5649 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5650 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5651 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5652 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5653 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5654 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5655 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5656 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5657 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5658 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5659 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5660 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5661 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5662 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5663 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5664 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5665 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5666 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5667 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5668 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5669 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5670 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5671 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5672 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5673 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5674 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5675 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5676 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5677 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5678 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5679 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5680 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5681 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5682 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5683 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5684 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5685 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5686 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5687 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5688 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5689 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5690 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5691 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5692 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5693 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5694 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5695 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5696 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5697 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5698 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5699 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5700 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5701 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5702 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5703 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5704 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5705 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5706 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5707 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5708 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5709 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5710 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5711 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5712 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5713 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5714 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5715 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5716 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5717 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5718 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5719 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5720 FN_GLOBAL_INTEGER(lp_smb2_max_read, &Globals.ismb2_max_read)
5721 FN_GLOBAL_INTEGER(lp_smb2_max_write, &Globals.ismb2_max_write)
5722 FN_GLOBAL_INTEGER(lp_smb2_max_trans, &Globals.ismb2_max_trans)
5724 FN_LOCAL_STRING(lp_preexec, szPreExec)
5725 FN_LOCAL_STRING(lp_postexec, szPostExec)
5726 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5727 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5728 FN_LOCAL_STRING(lp_servicename, szService)
5729 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5730 FN_LOCAL_STRING(lp_pathname, szPath)
5731 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5732 FN_LOCAL_STRING(lp_username, szUsername)
5733 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5734 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5735 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5736 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5737 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5738 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5739 int lp_cups_encrypt(void)
5742 #ifdef HAVE_HTTPCONNECTENCRYPT
5743 switch (Globals.CupsEncrypt) {
5745 result = HTTP_ENCRYPT_REQUIRED;
5748 result = HTTP_ENCRYPT_ALWAYS;
5751 result = HTTP_ENCRYPT_NEVER;
5757 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5758 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5759 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5760 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5761 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5762 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5763 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, &Globals.ctdb_locktime_warn_threshold)
5764 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5765 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5766 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5767 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5768 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5769 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5770 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5771 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5772 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5773 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5774 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5775 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5776 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5777 FN_LOCAL_STRING(lp_comment, comment)
5778 FN_LOCAL_STRING(lp_force_user, force_user)
5779 FN_LOCAL_STRING(lp_force_group, force_group)
5780 FN_LOCAL_LIST(lp_readlist, readlist)
5781 FN_LOCAL_LIST(lp_writelist, writelist)
5782 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5783 FN_LOCAL_STRING(lp_fstype, fstype)
5784 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5785 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5786 static FN_LOCAL_STRING(lp_volume, volume)
5787 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5788 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5789 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5790 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5791 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5792 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5793 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5794 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5795 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5796 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5797 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5798 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5799 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5800 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5801 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5802 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5803 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5804 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5805 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5806 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5807 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5808 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5809 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5810 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5811 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5812 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5813 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5814 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5815 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5816 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5817 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5818 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5819 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5820 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5821 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5822 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5823 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5824 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5825 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5826 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5827 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5828 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5829 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5830 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5831 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5832 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5833 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5834 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5835 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5836 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5837 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5838 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5839 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5840 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5841 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5842 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5843 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5844 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5845 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5846 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5847 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5848 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5849 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5850 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5851 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5852 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5853 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5854 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5855 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5856 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5857 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5858 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5859 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5860 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5861 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5862 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5863 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5864 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5865 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5866 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5867 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5868 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5869 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5870 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5871 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5872 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5873 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5874 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5875 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5876 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5877 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5878 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5879 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5880 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5881 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5882 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5883 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5884 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5885 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5887 /* local prototypes */
5889 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5890 static const char *get_boolean(bool bool_value);
5891 static int getservicebyname(const char *pszServiceName,
5892 struct service *pserviceDest);
5893 static void copy_service(struct service *pserviceDest,
5894 struct service *pserviceSource,
5895 struct bitmap *pcopymapDest);
5896 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5898 static bool do_section(const char *pszSectionName, void *userdata);
5899 static void init_copymap(struct service *pservice);
5900 static bool hash_a_service(const char *name, int number);
5901 static void free_service_byindex(int iService);
5902 static void free_param_opts(struct param_opt_struct **popts);
5903 static void show_parameter(int parmIndex);
5904 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5907 * This is a helper function for parametrical options support. It returns a
5908 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5909 * parametrical functions are quite simple
5911 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5914 bool global_section = False;
5916 struct param_opt_struct *data;
5918 if (snum >= iNumServices) return NULL;
5921 data = Globals.param_opt;
5922 global_section = True;
5924 data = ServicePtrs[snum]->param_opt;
5927 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5928 DEBUG(0,("asprintf failed!\n"));
5933 if (strwicmp(data->key, param_key) == 0) {
5934 string_free(¶m_key);
5940 if (!global_section) {
5941 /* Try to fetch the same option but from globals */
5942 /* but only if we are not already working with Globals */
5943 data = Globals.param_opt;
5945 if (strwicmp(data->key, param_key) == 0) {
5946 string_free(¶m_key);
5953 string_free(¶m_key);
5959 #define MISSING_PARAMETER(name) \
5960 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5962 /*******************************************************************
5963 convenience routine to return int parameters.
5964 ********************************************************************/
5965 static int lp_int(const char *s)
5969 MISSING_PARAMETER(lp_int);
5973 return (int)strtol(s, NULL, 0);
5976 /*******************************************************************
5977 convenience routine to return unsigned long parameters.
5978 ********************************************************************/
5979 static unsigned long lp_ulong(const char *s)
5983 MISSING_PARAMETER(lp_ulong);
5987 return strtoul(s, NULL, 0);
5990 /*******************************************************************
5991 convenience routine to return boolean parameters.
5992 ********************************************************************/
5993 static bool lp_bool(const char *s)
5998 MISSING_PARAMETER(lp_bool);
6002 if (!set_boolean(s, &ret)) {
6003 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
6010 /*******************************************************************
6011 convenience routine to return enum parameters.
6012 ********************************************************************/
6013 static int lp_enum(const char *s,const struct enum_list *_enum)
6017 if (!s || !*s || !_enum) {
6018 MISSING_PARAMETER(lp_enum);
6022 for (i=0; _enum[i].name; i++) {
6023 if (strequal(_enum[i].name,s))
6024 return _enum[i].value;
6027 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
6031 #undef MISSING_PARAMETER
6033 /* DO NOT USE lp_parm_string ANYMORE!!!!
6034 * use lp_parm_const_string or lp_parm_talloc_string
6036 * lp_parm_string is only used to let old modules find this symbol
6038 #undef lp_parm_string
6039 char *lp_parm_string(const char *servicename, const char *type, const char *option);
6040 char *lp_parm_string(const char *servicename, const char *type, const char *option)
6042 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
6045 /* Return parametric option from a given service. Type is a part of option before ':' */
6046 /* Parametric option has following syntax: 'Type: option = value' */
6047 /* the returned value is talloced on the talloc_tos() */
6048 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
6050 struct param_opt_struct *data = get_parametrics(snum, type, option);
6052 if (data == NULL||data->value==NULL) {
6054 return lp_string(def);
6060 return lp_string(data->value);
6063 /* Return parametric option from a given service. Type is a part of option before ':' */
6064 /* Parametric option has following syntax: 'Type: option = value' */
6065 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6067 struct param_opt_struct *data = get_parametrics(snum, type, option);
6069 if (data == NULL||data->value==NULL)
6075 /* Return parametric option from a given service. Type is a part of option before ':' */
6076 /* Parametric option has following syntax: 'Type: option = value' */
6078 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6080 struct param_opt_struct *data = get_parametrics(snum, type, option);
6082 if (data == NULL||data->value==NULL)
6083 return (const char **)def;
6085 if (data->list==NULL) {
6086 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
6089 return (const char **)data->list;
6092 /* Return parametric option from a given service. Type is a part of option before ':' */
6093 /* Parametric option has following syntax: 'Type: option = value' */
6095 int lp_parm_int(int snum, const char *type, const char *option, int def)
6097 struct param_opt_struct *data = get_parametrics(snum, type, option);
6099 if (data && data->value && *data->value)
6100 return lp_int(data->value);
6105 /* Return parametric option from a given service. Type is a part of option before ':' */
6106 /* Parametric option has following syntax: 'Type: option = value' */
6108 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6110 struct param_opt_struct *data = get_parametrics(snum, type, option);
6112 if (data && data->value && *data->value)
6113 return lp_ulong(data->value);
6118 /* Return parametric option from a given service. Type is a part of option before ':' */
6119 /* Parametric option has following syntax: 'Type: option = value' */
6121 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6123 struct param_opt_struct *data = get_parametrics(snum, type, option);
6125 if (data && data->value && *data->value)
6126 return lp_bool(data->value);
6131 /* Return parametric option from a given service. Type is a part of option before ':' */
6132 /* Parametric option has following syntax: 'Type: option = value' */
6134 int lp_parm_enum(int snum, const char *type, const char *option,
6135 const struct enum_list *_enum, int def)
6137 struct param_opt_struct *data = get_parametrics(snum, type, option);
6139 if (data && data->value && *data->value && _enum)
6140 return lp_enum(data->value, _enum);
6146 /***************************************************************************
6147 Initialise a service to the defaults.
6148 ***************************************************************************/
6150 static void init_service(struct service *pservice)
6152 memset((char *)pservice, '\0', sizeof(struct service));
6153 copy_service(pservice, &sDefault, NULL);
6158 * free a param_opts structure.
6159 * param_opts handling should be moved to talloc;
6160 * then this whole functions reduces to a TALLOC_FREE().
6163 static void free_param_opts(struct param_opt_struct **popts)
6165 struct param_opt_struct *opt, *next_opt;
6167 if (popts == NULL) {
6171 if (*popts != NULL) {
6172 DEBUG(5, ("Freeing parametrics:\n"));
6175 while (opt != NULL) {
6176 string_free(&opt->key);
6177 string_free(&opt->value);
6178 TALLOC_FREE(opt->list);
6179 next_opt = opt->next;
6186 /***************************************************************************
6187 Free the dynamically allocated parts of a service struct.
6188 ***************************************************************************/
6190 static void free_service(struct service *pservice)
6195 if (pservice->szService)
6196 DEBUG(5, ("free_service: Freeing service %s\n",
6197 pservice->szService));
6199 free_parameters(pservice);
6201 string_free(&pservice->szService);
6202 TALLOC_FREE(pservice->copymap);
6204 free_param_opts(&pservice->param_opt);
6206 ZERO_STRUCTP(pservice);
6210 /***************************************************************************
6211 remove a service indexed in the ServicePtrs array from the ServiceHash
6212 and free the dynamically allocated parts
6213 ***************************************************************************/
6215 static void free_service_byindex(int idx)
6217 if ( !LP_SNUM_OK(idx) )
6220 ServicePtrs[idx]->valid = False;
6221 invalid_services[num_invalid_services++] = idx;
6223 /* we have to cleanup the hash record */
6225 if (ServicePtrs[idx]->szService) {
6226 char *canon_name = canonicalize_servicename(
6228 ServicePtrs[idx]->szService );
6230 dbwrap_delete_bystring(ServiceHash, canon_name );
6231 TALLOC_FREE(canon_name);
6234 free_service(ServicePtrs[idx]);
6237 /***************************************************************************
6238 Add a new service to the services array initialising it with the given
6240 ***************************************************************************/
6242 static int add_a_service(const struct service *pservice, const char *name)
6245 struct service tservice;
6246 int num_to_alloc = iNumServices + 1;
6248 tservice = *pservice;
6250 /* it might already exist */
6252 i = getservicebyname(name, NULL);
6254 /* Clean all parametric options for service */
6255 /* They will be added during parsing again */
6256 free_param_opts(&ServicePtrs[i]->param_opt);
6261 /* find an invalid one */
6263 if (num_invalid_services > 0) {
6264 i = invalid_services[--num_invalid_services];
6267 /* if not, then create one */
6268 if (i == iNumServices) {
6269 struct service **tsp;
6272 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6274 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6278 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6279 if (!ServicePtrs[iNumServices]) {
6280 DEBUG(0,("add_a_service: out of memory!\n"));
6285 /* enlarge invalid_services here for now... */
6286 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6288 if (tinvalid == NULL) {
6289 DEBUG(0,("add_a_service: failed to enlarge "
6290 "invalid_services!\n"));
6293 invalid_services = tinvalid;
6295 free_service_byindex(i);
6298 ServicePtrs[i]->valid = True;
6300 init_service(ServicePtrs[i]);
6301 copy_service(ServicePtrs[i], &tservice, NULL);
6303 string_set(&ServicePtrs[i]->szService, name);
6305 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6306 i, ServicePtrs[i]->szService));
6308 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6315 /***************************************************************************
6316 Convert a string to uppercase and remove whitespaces.
6317 ***************************************************************************/
6319 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6324 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6328 result = talloc_strdup(ctx, src);
6329 SMB_ASSERT(result != NULL);
6335 /***************************************************************************
6336 Add a name/index pair for the services array to the hash table.
6337 ***************************************************************************/
6339 static bool hash_a_service(const char *name, int idx)
6343 if ( !ServiceHash ) {
6344 DEBUG(10,("hash_a_service: creating servicehash\n"));
6345 ServiceHash = db_open_rbt(NULL);
6346 if ( !ServiceHash ) {
6347 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6352 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6355 canon_name = canonicalize_servicename(talloc_tos(), name );
6357 dbwrap_store_bystring(ServiceHash, canon_name,
6358 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6361 TALLOC_FREE(canon_name);
6366 /***************************************************************************
6367 Add a new home service, with the specified home directory, defaults coming
6369 ***************************************************************************/
6371 bool lp_add_home(const char *pszHomename, int iDefaultService,
6372 const char *user, const char *pszHomedir)
6376 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6377 pszHomedir[0] == '\0') {
6381 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6386 if (!(*(ServicePtrs[iDefaultService]->szPath))
6387 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6388 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6391 if (!(*(ServicePtrs[i]->comment))) {
6392 char *comment = NULL;
6393 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6396 string_set(&ServicePtrs[i]->comment, comment);
6400 /* set the browseable flag from the global default */
6402 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6403 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6405 ServicePtrs[i]->autoloaded = True;
6407 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6408 user, ServicePtrs[i]->szPath ));
6413 /***************************************************************************
6414 Add a new service, based on an old one.
6415 ***************************************************************************/
6417 int lp_add_service(const char *pszService, int iDefaultService)
6419 if (iDefaultService < 0) {
6420 return add_a_service(&sDefault, pszService);
6423 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6426 /***************************************************************************
6427 Add the IPC service.
6428 ***************************************************************************/
6430 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6432 char *comment = NULL;
6433 int i = add_a_service(&sDefault, ipc_name);
6438 if (asprintf(&comment, "IPC Service (%s)",
6439 Globals.szServerString) < 0) {
6443 string_set(&ServicePtrs[i]->szPath, tmpdir());
6444 string_set(&ServicePtrs[i]->szUsername, "");
6445 string_set(&ServicePtrs[i]->comment, comment);
6446 string_set(&ServicePtrs[i]->fstype, "IPC");
6447 ServicePtrs[i]->iMaxConnections = 0;
6448 ServicePtrs[i]->bAvailable = True;
6449 ServicePtrs[i]->bRead_only = True;
6450 ServicePtrs[i]->bGuest_only = False;
6451 ServicePtrs[i]->bAdministrative_share = True;
6452 ServicePtrs[i]->bGuest_ok = guest_ok;
6453 ServicePtrs[i]->bPrint_ok = False;
6454 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6456 DEBUG(3, ("adding IPC service\n"));
6462 /***************************************************************************
6463 Add a new printer service, with defaults coming from service iFrom.
6464 ***************************************************************************/
6466 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6468 const char *comment = "From Printcap";
6469 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6474 /* note that we do NOT default the availability flag to True - */
6475 /* we take it from the default service passed. This allows all */
6476 /* dynamic printers to be disabled by disabling the [printers] */
6477 /* entry (if/when the 'available' keyword is implemented!). */
6479 /* the printer name is set to the service name. */
6480 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6481 string_set(&ServicePtrs[i]->comment, comment);
6483 /* set the browseable flag from the gloabl default */
6484 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6486 /* Printers cannot be read_only. */
6487 ServicePtrs[i]->bRead_only = False;
6488 /* No share modes on printer services. */
6489 ServicePtrs[i]->bShareModes = False;
6490 /* No oplocks on printer services. */
6491 ServicePtrs[i]->bOpLocks = False;
6492 /* Printer services must be printable. */
6493 ServicePtrs[i]->bPrint_ok = True;
6495 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6501 /***************************************************************************
6502 Check whether the given parameter name is valid.
6503 Parametric options (names containing a colon) are considered valid.
6504 ***************************************************************************/
6506 bool lp_parameter_is_valid(const char *pszParmName)
6508 return ((map_parameter(pszParmName) != -1) ||
6509 (strchr(pszParmName, ':') != NULL));
6512 /***************************************************************************
6513 Check whether the given name is the name of a global parameter.
6514 Returns True for strings belonging to parameters of class
6515 P_GLOBAL, False for all other strings, also for parametric options
6516 and strings not belonging to any option.
6517 ***************************************************************************/
6519 bool lp_parameter_is_global(const char *pszParmName)
6521 int num = map_parameter(pszParmName);
6524 return (parm_table[num].p_class == P_GLOBAL);
6530 /**************************************************************************
6531 Check whether the given name is the canonical name of a parameter.
6532 Returns False if it is not a valid parameter Name.
6533 For parametric options, True is returned.
6534 **************************************************************************/
6536 bool lp_parameter_is_canonical(const char *parm_name)
6538 if (!lp_parameter_is_valid(parm_name)) {
6542 return (map_parameter(parm_name) ==
6543 map_parameter_canonical(parm_name, NULL));
6546 /**************************************************************************
6547 Determine the canonical name for a parameter.
6548 Indicate when it is an inverse (boolean) synonym instead of a
6550 **************************************************************************/
6552 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6557 if (!lp_parameter_is_valid(parm_name)) {
6562 num = map_parameter_canonical(parm_name, inverse);
6564 /* parametric option */
6565 *canon_parm = parm_name;
6567 *canon_parm = parm_table[num].label;
6574 /**************************************************************************
6575 Determine the canonical name for a parameter.
6576 Turn the value given into the inverse boolean expression when
6577 the synonym is an invers boolean synonym.
6579 Return True if parm_name is a valid parameter name and
6580 in case it is an invers boolean synonym, if the val string could
6581 successfully be converted to the reverse bool.
6582 Return false in all other cases.
6583 **************************************************************************/
6585 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6587 const char **canon_parm,
6588 const char **canon_val)
6593 if (!lp_parameter_is_valid(parm_name)) {
6599 num = map_parameter_canonical(parm_name, &inverse);
6601 /* parametric option */
6602 *canon_parm = parm_name;
6605 *canon_parm = parm_table[num].label;
6607 if (!lp_invert_boolean(val, canon_val)) {
6619 /***************************************************************************
6620 Map a parameter's string representation to something we can use.
6621 Returns False if the parameter string is not recognised, else TRUE.
6622 ***************************************************************************/
6624 static int map_parameter(const char *pszParmName)
6628 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6631 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6632 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6635 /* Warn only if it isn't parametric option */
6636 if (strchr(pszParmName, ':') == NULL)
6637 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6638 /* We do return 'fail' for parametric options as well because they are
6639 stored in different storage
6644 /***************************************************************************
6645 Map a parameter's string representation to the index of the canonical
6646 form of the parameter (it might be a synonym).
6647 Returns -1 if the parameter string is not recognised.
6648 ***************************************************************************/
6650 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6652 int parm_num, canon_num;
6653 bool loc_inverse = False;
6655 parm_num = map_parameter(pszParmName);
6656 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6657 /* invalid, parametric or no canidate for synonyms ... */
6661 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6662 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6663 parm_num = canon_num;
6669 if (inverse != NULL) {
6670 *inverse = loc_inverse;
6675 /***************************************************************************
6676 return true if parameter number parm1 is a synonym of parameter
6677 number parm2 (parm2 being the principal name).
6678 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6680 ***************************************************************************/
6682 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6684 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6685 (parm_table[parm1].flags & FLAG_HIDE) &&
6686 !(parm_table[parm2].flags & FLAG_HIDE))
6688 if (inverse != NULL) {
6689 if ((parm_table[parm1].type == P_BOOLREV) &&
6690 (parm_table[parm2].type == P_BOOL))
6702 /***************************************************************************
6703 Show one parameter's name, type, [values,] and flags.
6704 (helper functions for show_parameter_list)
6705 ***************************************************************************/
6707 static void show_parameter(int parmIndex)
6709 int enumIndex, flagIndex;
6714 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6715 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6717 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6718 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6719 FLAG_HIDE, FLAG_DOS_STRING};
6720 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6721 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6722 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6724 printf("%s=%s", parm_table[parmIndex].label,
6725 type[parm_table[parmIndex].type]);
6726 if (parm_table[parmIndex].type == P_ENUM) {
6729 parm_table[parmIndex].enum_list[enumIndex].name;
6733 enumIndex ? "|" : "",
6734 parm_table[parmIndex].enum_list[enumIndex].name);
6739 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6740 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6743 flag_names[flagIndex]);
6748 /* output synonyms */
6750 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6751 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6752 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6753 parm_table[parmIndex2].label);
6754 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6756 printf(" (synonyms: ");
6761 printf("%s%s", parm_table[parmIndex2].label,
6762 inverse ? "[i]" : "");
6772 /***************************************************************************
6773 Show all parameter's name, type, [values,] and flags.
6774 ***************************************************************************/
6776 void show_parameter_list(void)
6778 int classIndex, parmIndex;
6779 const char *section_names[] = { "local", "global", NULL};
6781 for (classIndex=0; section_names[classIndex]; classIndex++) {
6782 printf("[%s]\n", section_names[classIndex]);
6783 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6784 if (parm_table[parmIndex].p_class == classIndex) {
6785 show_parameter(parmIndex);
6791 /***************************************************************************
6792 Check if a given string correctly represents a boolean value.
6793 ***************************************************************************/
6795 bool lp_string_is_valid_boolean(const char *parm_value)
6797 return set_boolean(parm_value, NULL);
6800 /***************************************************************************
6801 Get the standard string representation of a boolean value ("yes" or "no")
6802 ***************************************************************************/
6804 static const char *get_boolean(bool bool_value)
6806 static const char *yes_str = "yes";
6807 static const char *no_str = "no";
6809 return (bool_value ? yes_str : no_str);
6812 /***************************************************************************
6813 Provide the string of the negated boolean value associated to the boolean
6814 given as a string. Returns False if the passed string does not correctly
6815 represent a boolean.
6816 ***************************************************************************/
6818 bool lp_invert_boolean(const char *str, const char **inverse_str)
6822 if (!set_boolean(str, &val)) {
6826 *inverse_str = get_boolean(!val);
6830 /***************************************************************************
6831 Provide the canonical string representation of a boolean value given
6832 as a string. Return True on success, False if the string given does
6833 not correctly represent a boolean.
6834 ***************************************************************************/
6836 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6840 if (!set_boolean(str, &val)) {
6844 *canon_str = get_boolean(val);
6848 /***************************************************************************
6849 Find a service by name. Otherwise works like get_service.
6850 ***************************************************************************/
6852 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6858 if (ServiceHash == NULL) {
6862 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6864 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6866 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6867 iService = *(int *)data.dptr;
6870 TALLOC_FREE(canon_name);
6872 if ((iService != -1) && (LP_SNUM_OK(iService))
6873 && (pserviceDest != NULL)) {
6874 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6880 /***************************************************************************
6881 Copy a service structure to another.
6882 If pcopymapDest is NULL then copy all fields
6883 ***************************************************************************/
6886 * Add a parametric option to a param_opt_struct,
6887 * replacing old value, if already present.
6889 static void set_param_opt(struct param_opt_struct **opt_list,
6890 const char *opt_name,
6891 const char *opt_value,
6894 struct param_opt_struct *new_opt, *opt;
6897 if (opt_list == NULL) {
6904 /* Traverse destination */
6906 /* If we already have same option, override it */
6907 if (strwicmp(opt->key, opt_name) == 0) {
6908 if ((opt->flags & FLAG_CMDLINE) &&
6909 !(flags & FLAG_CMDLINE)) {
6910 /* it's been marked as not to be
6914 string_free(&opt->value);
6915 TALLOC_FREE(opt->list);
6916 opt->value = SMB_STRDUP(opt_value);
6924 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6925 new_opt->key = SMB_STRDUP(opt_name);
6926 new_opt->value = SMB_STRDUP(opt_value);
6927 new_opt->list = NULL;
6928 new_opt->flags = flags;
6929 DLIST_ADD(*opt_list, new_opt);
6933 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6934 struct bitmap *pcopymapDest)
6937 bool bcopyall = (pcopymapDest == NULL);
6938 struct param_opt_struct *data;
6940 for (i = 0; parm_table[i].label; i++)
6941 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6942 (bcopyall || bitmap_query(pcopymapDest,i))) {
6943 void *def_ptr = parm_table[i].ptr;
6945 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6948 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6951 switch (parm_table[i].type) {
6954 *(bool *)dest_ptr = *(bool *)src_ptr;
6960 *(int *)dest_ptr = *(int *)src_ptr;
6964 *(char *)dest_ptr = *(char *)src_ptr;
6968 string_set((char **)dest_ptr,
6973 string_set((char **)dest_ptr,
6975 strupper_m(*(char **)dest_ptr);
6978 TALLOC_FREE(*((char ***)dest_ptr));
6979 *((char ***)dest_ptr) = str_list_copy(NULL,
6980 *(const char ***)src_ptr);
6988 init_copymap(pserviceDest);
6989 if (pserviceSource->copymap)
6990 bitmap_copy(pserviceDest->copymap,
6991 pserviceSource->copymap);
6994 data = pserviceSource->param_opt;
6996 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->flags);
7001 /***************************************************************************
7002 Check a service for consistency. Return False if the service is in any way
7003 incomplete or faulty, else True.
7004 ***************************************************************************/
7006 bool service_ok(int iService)
7011 if (ServicePtrs[iService]->szService[0] == '\0') {
7012 DEBUG(0, ("The following message indicates an internal error:\n"));
7013 DEBUG(0, ("No service name in service entry.\n"));
7017 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
7018 /* I can't see why you'd want a non-printable printer service... */
7019 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
7020 if (!ServicePtrs[iService]->bPrint_ok) {
7021 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
7022 ServicePtrs[iService]->szService));
7023 ServicePtrs[iService]->bPrint_ok = True;
7025 /* [printers] service must also be non-browsable. */
7026 if (ServicePtrs[iService]->bBrowseable)
7027 ServicePtrs[iService]->bBrowseable = False;
7030 if (ServicePtrs[iService]->szPath[0] == '\0' &&
7031 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
7032 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
7034 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
7035 ServicePtrs[iService]->szService));
7036 ServicePtrs[iService]->bAvailable = False;
7039 /* If a service is flagged unavailable, log the fact at level 1. */
7040 if (!ServicePtrs[iService]->bAvailable)
7041 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
7042 ServicePtrs[iService]->szService));
7047 static struct smbconf_ctx *lp_smbconf_ctx(void)
7050 static struct smbconf_ctx *conf_ctx = NULL;
7052 if (conf_ctx == NULL) {
7053 werr = smbconf_init(NULL, &conf_ctx, "registry:");
7054 if (!W_ERROR_IS_OK(werr)) {
7055 DEBUG(1, ("error initializing registry configuration: "
7056 "%s\n", win_errstr(werr)));
7064 static bool process_smbconf_service(struct smbconf_service *service)
7069 if (service == NULL) {
7073 ret = do_section(service->name, NULL);
7077 for (count = 0; count < service->num_params; count++) {
7078 ret = do_parameter(service->param_names[count],
7079 service->param_values[count],
7085 if (iServiceIndex >= 0) {
7086 return service_ok(iServiceIndex);
7092 * load a service from registry and activate it
7094 bool process_registry_service(const char *service_name)
7097 struct smbconf_service *service = NULL;
7098 TALLOC_CTX *mem_ctx = talloc_stackframe();
7099 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7102 if (conf_ctx == NULL) {
7106 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7108 if (!smbconf_share_exists(conf_ctx, service_name)) {
7110 * Registry does not contain data for this service (yet),
7111 * but make sure lp_load doesn't return false.
7117 werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7118 if (!W_ERROR_IS_OK(werr)) {
7122 ret = process_smbconf_service(service);
7128 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7131 TALLOC_FREE(mem_ctx);
7136 * process_registry_globals
7138 static bool process_registry_globals(void)
7142 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7144 ret = do_parameter("registry shares", "yes", NULL);
7149 return process_registry_service(GLOBAL_NAME);
7152 bool process_registry_shares(void)
7156 struct smbconf_service **service = NULL;
7157 uint32_t num_shares = 0;
7158 TALLOC_CTX *mem_ctx = talloc_stackframe();
7159 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7162 if (conf_ctx == NULL) {
7166 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7167 if (!W_ERROR_IS_OK(werr)) {
7173 for (count = 0; count < num_shares; count++) {
7174 if (strequal(service[count]->name, GLOBAL_NAME)) {
7177 ret = process_smbconf_service(service[count]);
7184 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7187 TALLOC_FREE(mem_ctx);
7191 #define MAX_INCLUDE_DEPTH 100
7193 static uint8_t include_depth;
7195 static struct file_lists {
7196 struct file_lists *next;
7200 } *file_lists = NULL;
7202 /*******************************************************************
7203 Keep a linked list of all config files so we know when one has changed
7204 it's date and needs to be reloaded.
7205 ********************************************************************/
7207 static void add_to_file_list(const char *fname, const char *subfname)
7209 struct file_lists *f = file_lists;
7212 if (f->name && !strcmp(f->name, fname))
7218 f = SMB_MALLOC_P(struct file_lists);
7221 f->next = file_lists;
7222 f->name = SMB_STRDUP(fname);
7227 f->subfname = SMB_STRDUP(subfname);
7234 f->modtime = file_modtime(subfname);
7236 time_t t = file_modtime(subfname);
7244 * Free the file lists
7246 static void free_file_list(void)
7248 struct file_lists *f;
7249 struct file_lists *next;
7254 SAFE_FREE( f->name );
7255 SAFE_FREE( f->subfname );
7264 * Utility function for outsiders to check if we're running on registry.
7266 bool lp_config_backend_is_registry(void)
7268 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7272 * Utility function to check if the config backend is FILE.
7274 bool lp_config_backend_is_file(void)
7276 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7279 /*******************************************************************
7280 Check if a config file has changed date.
7281 ********************************************************************/
7283 bool lp_file_list_changed(void)
7285 struct file_lists *f = file_lists;
7287 DEBUG(6, ("lp_file_list_changed()\n"));
7292 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7293 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7295 if (conf_ctx == NULL) {
7298 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7301 DEBUGADD(6, ("registry config changed\n"));
7306 n2 = talloc_sub_basic(talloc_tos(),
7307 get_current_username(),
7308 current_user_info.domain,
7313 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7314 f->name, n2, ctime(&f->modtime)));
7316 mod_time = file_modtime(n2);
7319 ((f->modtime != mod_time) ||
7320 (f->subfname == NULL) ||
7321 (strcmp(n2, f->subfname) != 0)))
7324 ("file %s modified: %s\n", n2,
7326 f->modtime = mod_time;
7327 SAFE_FREE(f->subfname);
7328 f->subfname = SMB_STRDUP(n2);
7340 /***************************************************************************
7341 Run standard_sub_basic on netbios name... needed because global_myname
7342 is not accessed through any lp_ macro.
7343 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7344 ***************************************************************************/
7346 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7349 char *netbios_name = talloc_sub_basic(
7350 talloc_tos(), get_current_username(), current_user_info.domain,
7353 ret = set_global_myname(netbios_name);
7354 TALLOC_FREE(netbios_name);
7355 string_set(&Globals.szNetbiosName,global_myname());
7357 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7363 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7365 if (strcmp(*ptr, pszParmValue) != 0) {
7366 string_set(ptr, pszParmValue);
7374 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7378 ret = set_global_myworkgroup(pszParmValue);
7379 string_set(&Globals.szWorkgroup,lp_workgroup());
7384 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7388 ret = set_global_scope(pszParmValue);
7389 string_set(&Globals.szNetbiosScope,global_scope());
7394 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7396 TALLOC_FREE(Globals.szNetbiosAliases);
7397 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7398 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7401 /***************************************************************************
7402 Handle the include operation.
7403 ***************************************************************************/
7404 static bool bAllowIncludeRegistry = true;
7406 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7410 if (include_depth >= MAX_INCLUDE_DEPTH) {
7411 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7416 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7417 if (!bAllowIncludeRegistry) {
7420 if (bInGlobalSection) {
7423 ret = process_registry_globals();
7427 DEBUG(1, ("\"include = registry\" only effective "
7428 "in %s section\n", GLOBAL_NAME));
7433 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7434 current_user_info.domain,
7437 add_to_file_list(pszParmValue, fname);
7439 string_set(ptr, fname);
7441 if (file_exist(fname)) {
7444 ret = pm_process(fname, do_section, do_parameter, NULL);
7450 DEBUG(2, ("Can't find include file %s\n", fname));
7455 /***************************************************************************
7456 Handle the interpretation of the copy parameter.
7457 ***************************************************************************/
7459 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7463 struct service serviceTemp;
7465 string_set(ptr, pszParmValue);
7467 init_service(&serviceTemp);
7471 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7473 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7474 if (iTemp == iServiceIndex) {
7475 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7477 copy_service(ServicePtrs[iServiceIndex],
7479 ServicePtrs[iServiceIndex]->copymap);
7483 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7487 free_service(&serviceTemp);
7491 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7493 Globals.ldap_debug_level = lp_int(pszParmValue);
7494 init_ldap_debugging();
7498 /***************************************************************************
7499 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7504 idmap uid = 1000-1999
7507 We only do simple parsing checks here. The strings are parsed into useful
7508 structures in the idmap daemon code.
7510 ***************************************************************************/
7512 /* Some lp_ routines to return idmap [ug]id information */
7514 static uid_t idmap_uid_low, idmap_uid_high;
7515 static gid_t idmap_gid_low, idmap_gid_high;
7517 bool lp_idmap_uid(uid_t *low, uid_t *high)
7519 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7523 *low = idmap_uid_low;
7526 *high = idmap_uid_high;
7531 bool lp_idmap_gid(gid_t *low, gid_t *high)
7533 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7537 *low = idmap_gid_low;
7540 *high = idmap_gid_high;
7545 /* Do some simple checks on "idmap [ug]id" parameter values */
7547 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7551 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7556 string_set(ptr, pszParmValue);
7558 idmap_uid_low = low;
7559 idmap_uid_high = high;
7564 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7568 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7573 string_set(ptr, pszParmValue);
7575 idmap_gid_low = low;
7576 idmap_gid_high = high;
7581 /***************************************************************************
7582 Handle the DEBUG level list.
7583 ***************************************************************************/
7585 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7587 string_set(ptr, pszParmValueIn);
7588 return debug_parse_levels(pszParmValueIn);
7591 /***************************************************************************
7592 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7593 ***************************************************************************/
7595 static const char *append_ldap_suffix( const char *str )
7597 const char *suffix_string;
7600 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7601 Globals.szLdapSuffix );
7602 if ( !suffix_string ) {
7603 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7607 return suffix_string;
7610 const char *lp_ldap_machine_suffix(void)
7612 if (Globals.szLdapMachineSuffix[0])
7613 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7615 return lp_string(Globals.szLdapSuffix);
7618 const char *lp_ldap_user_suffix(void)
7620 if (Globals.szLdapUserSuffix[0])
7621 return append_ldap_suffix(Globals.szLdapUserSuffix);
7623 return lp_string(Globals.szLdapSuffix);
7626 const char *lp_ldap_group_suffix(void)
7628 if (Globals.szLdapGroupSuffix[0])
7629 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7631 return lp_string(Globals.szLdapSuffix);
7634 const char *lp_ldap_idmap_suffix(void)
7636 if (Globals.szLdapIdmapSuffix[0])
7637 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7639 return lp_string(Globals.szLdapSuffix);
7642 /****************************************************************************
7643 set the value for a P_ENUM
7644 ***************************************************************************/
7646 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7651 for (i = 0; parm->enum_list[i].name; i++) {
7652 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7653 *ptr = parm->enum_list[i].value;
7657 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7658 pszParmValue, parm->label));
7661 /***************************************************************************
7662 ***************************************************************************/
7664 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7666 static int parm_num = -1;
7669 if ( parm_num == -1 )
7670 parm_num = map_parameter( "printing" );
7672 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7677 s = ServicePtrs[snum];
7679 init_printer_values( s );
7685 /***************************************************************************
7686 Initialise a copymap.
7687 ***************************************************************************/
7689 static void init_copymap(struct service *pservice)
7693 TALLOC_FREE(pservice->copymap);
7695 pservice->copymap = bitmap_talloc(talloc_autofree_context(),
7697 if (!pservice->copymap)
7699 ("Couldn't allocate copymap!! (size %d)\n",
7700 (int)NUMPARAMETERS));
7702 for (i = 0; i < NUMPARAMETERS; i++)
7703 bitmap_set(pservice->copymap, i);
7706 /***************************************************************************
7707 Return the local pointer to a parameter given a service struct and the
7708 pointer into the default structure.
7709 ***************************************************************************/
7711 static void *lp_local_ptr(struct service *service, void *ptr)
7713 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7716 /***************************************************************************
7717 Return the local pointer to a parameter given the service number and the
7718 pointer into the default structure.
7719 ***************************************************************************/
7721 void *lp_local_ptr_by_snum(int snum, void *ptr)
7723 return lp_local_ptr(ServicePtrs[snum], ptr);
7726 /***************************************************************************
7727 Process a parameter for a particular service number. If snum < 0
7728 then assume we are in the globals.
7729 ***************************************************************************/
7731 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7734 void *parm_ptr = NULL; /* where we are going to store the result */
7735 void *def_ptr = NULL;
7736 struct param_opt_struct **opt_list;
7738 parmnum = map_parameter(pszParmName);
7741 if (strchr(pszParmName, ':') == NULL) {
7742 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7748 * We've got a parametric option
7751 opt_list = (snum < 0)
7752 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7753 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7758 /* if it's already been set by the command line, then we don't
7760 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7764 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7765 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7769 def_ptr = parm_table[parmnum].ptr;
7771 /* we might point at a service, the default service or a global */
7775 if (parm_table[parmnum].p_class == P_GLOBAL) {
7777 ("Global parameter %s found in service section!\n",
7781 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7785 if (!ServicePtrs[snum]->copymap)
7786 init_copymap(ServicePtrs[snum]);
7788 /* this handles the aliases - set the copymap for other entries with
7789 the same data pointer */
7790 for (i = 0; parm_table[i].label; i++)
7791 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7792 bitmap_clear(ServicePtrs[snum]->copymap, i);
7795 /* if it is a special case then go ahead */
7796 if (parm_table[parmnum].special) {
7797 return parm_table[parmnum].special(snum, pszParmValue,
7801 /* now switch on the type of variable it is */
7802 switch (parm_table[parmnum].type)
7805 *(bool *)parm_ptr = lp_bool(pszParmValue);
7809 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7813 *(int *)parm_ptr = lp_int(pszParmValue);
7817 *(char *)parm_ptr = *pszParmValue;
7821 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7823 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7828 TALLOC_FREE(*((char ***)parm_ptr));
7829 *(char ***)parm_ptr = str_list_make_v3(
7830 talloc_autofree_context(), pszParmValue, NULL);
7834 string_set((char **)parm_ptr, pszParmValue);
7838 string_set((char **)parm_ptr, pszParmValue);
7839 strupper_m(*(char **)parm_ptr);
7843 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7852 /***************************************************************************
7853 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7854 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7855 ***************************************************************************/
7857 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7860 parmnum = map_parameter(pszParmName);
7862 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7863 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7866 parm_table[parmnum].flags |= FLAG_CMDLINE;
7868 store_lp_set_cmdline(pszParmName, pszParmValue);
7872 /* it might be parametric */
7873 if (strchr(pszParmName, ':') != NULL) {
7874 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7875 store_lp_set_cmdline(pszParmName, pszParmValue);
7879 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7883 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7885 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7888 /***************************************************************************
7889 Process a parameter.
7890 ***************************************************************************/
7892 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7895 if (!bInGlobalSection && bGlobalOnly)
7898 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7900 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7901 pszParmName, pszParmValue));
7905 set a option from the commandline in 'a=b' format. Use to support --option
7907 bool lp_set_option(const char *option)
7912 s = talloc_strdup(NULL, option);
7925 ret = lp_set_cmdline(s, p+1);
7930 /**************************************************************************
7931 Print a parameter of the specified type.
7932 ***************************************************************************/
7934 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7940 for (i = 0; p->enum_list[i].name; i++) {
7941 if (*(int *)ptr == p->enum_list[i].value) {
7943 p->enum_list[i].name);
7950 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7954 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7958 fprintf(f, "%d", *(int *)ptr);
7962 fprintf(f, "%c", *(char *)ptr);
7966 char *o = octal_string(*(int *)ptr);
7967 fprintf(f, "%s", o);
7973 if ((char ***)ptr && *(char ***)ptr) {
7974 char **list = *(char ***)ptr;
7975 for (; *list; list++) {
7976 /* surround strings with whitespace in double quotes */
7977 if ( strchr_m( *list, ' ' ) )
7978 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7980 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7987 if (*(char **)ptr) {
7988 fprintf(f, "%s", *(char **)ptr);
7996 /***************************************************************************
7997 Check if two parameters are equal.
7998 ***************************************************************************/
8000 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8005 return (*((bool *)ptr1) == *((bool *)ptr2));
8010 return (*((int *)ptr1) == *((int *)ptr2));
8013 return (*((char *)ptr1) == *((char *)ptr2));
8016 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8021 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8026 return (p1 == p2 || strequal(p1, p2));
8034 /***************************************************************************
8035 Initialize any local varients in the sDefault table.
8036 ***************************************************************************/
8038 void init_locals(void)
8043 /***************************************************************************
8044 Process a new section (service). At this stage all sections are services.
8045 Later we'll have special sections that permit server parameters to be set.
8046 Returns True on success, False on failure.
8047 ***************************************************************************/
8049 static bool do_section(const char *pszSectionName, void *userdata)
8052 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8053 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8056 /* if we were in a global section then do the local inits */
8057 if (bInGlobalSection && !isglobal)
8060 /* if we've just struck a global section, note the fact. */
8061 bInGlobalSection = isglobal;
8063 /* check for multiple global sections */
8064 if (bInGlobalSection) {
8065 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8069 if (!bInGlobalSection && bGlobalOnly)
8072 /* if we have a current service, tidy it up before moving on */
8075 if (iServiceIndex >= 0)
8076 bRetval = service_ok(iServiceIndex);
8078 /* if all is still well, move to the next record in the services array */
8080 /* We put this here to avoid an odd message order if messages are */
8081 /* issued by the post-processing of a previous section. */
8082 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8084 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8086 DEBUG(0, ("Failed to add a new service\n"));
8095 /***************************************************************************
8096 Determine if a partcular base parameter is currentl set to the default value.
8097 ***************************************************************************/
8099 static bool is_default(int i)
8101 if (!defaults_saved)
8103 switch (parm_table[i].type) {
8105 return str_list_equal((const char **)parm_table[i].def.lvalue,
8106 *(const char ***)parm_table[i].ptr);
8109 return strequal(parm_table[i].def.svalue,
8110 *(char **)parm_table[i].ptr);
8113 return parm_table[i].def.bvalue ==
8114 *(bool *)parm_table[i].ptr;
8116 return parm_table[i].def.cvalue ==
8117 *(char *)parm_table[i].ptr;
8121 return parm_table[i].def.ivalue ==
8122 *(int *)parm_table[i].ptr;
8129 /***************************************************************************
8130 Display the contents of the global structure.
8131 ***************************************************************************/
8133 static void dump_globals(FILE *f)
8136 struct param_opt_struct *data;
8138 fprintf(f, "[global]\n");
8140 for (i = 0; parm_table[i].label; i++)
8141 if (parm_table[i].p_class == P_GLOBAL &&
8142 !(parm_table[i].flags & FLAG_META) &&
8143 parm_table[i].ptr &&
8144 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8145 if (defaults_saved && is_default(i))
8147 fprintf(f, "\t%s = ", parm_table[i].label);
8148 print_parameter(&parm_table[i], parm_table[i].ptr, f);
8151 if (Globals.param_opt != NULL) {
8152 data = Globals.param_opt;
8154 fprintf(f, "\t%s = %s\n", data->key, data->value);
8161 /***************************************************************************
8162 Return True if a local parameter is currently set to the global default.
8163 ***************************************************************************/
8165 bool lp_is_default(int snum, struct parm_struct *parm)
8167 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8169 return equal_parameter(parm->type,
8170 ((char *)ServicePtrs[snum]) + pdiff,
8171 ((char *)&sDefault) + pdiff);
8174 /***************************************************************************
8175 Display the contents of a single services record.
8176 ***************************************************************************/
8178 static void dump_a_service(struct service *pService, FILE * f)
8181 struct param_opt_struct *data;
8183 if (pService != &sDefault)
8184 fprintf(f, "[%s]\n", pService->szService);
8186 for (i = 0; parm_table[i].label; i++) {
8188 if (parm_table[i].p_class == P_LOCAL &&
8189 !(parm_table[i].flags & FLAG_META) &&
8190 parm_table[i].ptr &&
8191 (*parm_table[i].label != '-') &&
8192 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8194 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8196 if (pService == &sDefault) {
8197 if (defaults_saved && is_default(i))
8200 if (equal_parameter(parm_table[i].type,
8201 ((char *)pService) +
8203 ((char *)&sDefault) +
8208 fprintf(f, "\t%s = ", parm_table[i].label);
8209 print_parameter(&parm_table[i],
8210 ((char *)pService) + pdiff, f);
8215 if (pService->param_opt != NULL) {
8216 data = pService->param_opt;
8218 fprintf(f, "\t%s = %s\n", data->key, data->value);
8224 /***************************************************************************
8225 Display the contents of a parameter of a single services record.
8226 ***************************************************************************/
8228 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8231 bool result = False;
8234 fstring local_parm_name;
8236 const char *parm_opt_value;
8238 /* check for parametrical option */
8239 fstrcpy( local_parm_name, parm_name);
8240 parm_opt = strchr( local_parm_name, ':');
8245 if (strlen(parm_opt)) {
8246 parm_opt_value = lp_parm_const_string( snum,
8247 local_parm_name, parm_opt, NULL);
8248 if (parm_opt_value) {
8249 printf( "%s\n", parm_opt_value);
8256 /* check for a key and print the value */
8263 for (i = 0; parm_table[i].label; i++) {
8264 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8265 !(parm_table[i].flags & FLAG_META) &&
8266 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8267 parm_table[i].ptr &&
8268 (*parm_table[i].label != '-') &&
8269 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8274 ptr = parm_table[i].ptr;
8276 struct service *pService = ServicePtrs[snum];
8277 ptr = ((char *)pService) +
8278 PTR_DIFF(parm_table[i].ptr, &sDefault);
8281 print_parameter(&parm_table[i],
8292 /***************************************************************************
8293 Return info about the requested parameter (given as a string).
8294 Return NULL when the string is not a valid parameter name.
8295 ***************************************************************************/
8297 struct parm_struct *lp_get_parameter(const char *param_name)
8299 int num = map_parameter(param_name);
8305 return &parm_table[num];
8308 /***************************************************************************
8309 Return info about the next parameter in a service.
8310 snum==GLOBAL_SECTION_SNUM gives the globals.
8311 Return NULL when out of parameters.
8312 ***************************************************************************/
8314 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8317 /* do the globals */
8318 for (; parm_table[*i].label; (*i)++) {
8319 if (parm_table[*i].p_class == P_SEPARATOR)
8320 return &parm_table[(*i)++];
8322 if (!parm_table[*i].ptr
8323 || (*parm_table[*i].label == '-'))
8327 && (parm_table[*i].ptr ==
8328 parm_table[(*i) - 1].ptr))
8331 if (is_default(*i) && !allparameters)
8334 return &parm_table[(*i)++];
8337 struct service *pService = ServicePtrs[snum];
8339 for (; parm_table[*i].label; (*i)++) {
8340 if (parm_table[*i].p_class == P_SEPARATOR)
8341 return &parm_table[(*i)++];
8343 if (parm_table[*i].p_class == P_LOCAL &&
8344 parm_table[*i].ptr &&
8345 (*parm_table[*i].label != '-') &&
8347 (parm_table[*i].ptr !=
8348 parm_table[(*i) - 1].ptr)))
8351 PTR_DIFF(parm_table[*i].ptr,
8354 if (allparameters ||
8355 !equal_parameter(parm_table[*i].type,
8356 ((char *)pService) +
8358 ((char *)&sDefault) +
8361 return &parm_table[(*i)++];
8372 /***************************************************************************
8373 Display the contents of a single copy structure.
8374 ***************************************************************************/
8375 static void dump_copy_map(bool *pcopymap)
8381 printf("\n\tNon-Copied parameters:\n");
8383 for (i = 0; parm_table[i].label; i++)
8384 if (parm_table[i].p_class == P_LOCAL &&
8385 parm_table[i].ptr && !pcopymap[i] &&
8386 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8388 printf("\t\t%s\n", parm_table[i].label);
8393 /***************************************************************************
8394 Return TRUE if the passed service number is within range.
8395 ***************************************************************************/
8397 bool lp_snum_ok(int iService)
8399 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8402 /***************************************************************************
8403 Auto-load some home services.
8404 ***************************************************************************/
8406 static void lp_add_auto_services(char *str)
8416 s = SMB_STRDUP(str);
8420 homes = lp_servicenumber(HOMES_NAME);
8422 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8423 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8426 if (lp_servicenumber(p) >= 0)
8429 home = get_user_home_dir(talloc_tos(), p);
8431 if (home && home[0] && homes >= 0)
8432 lp_add_home(p, homes, p, home);
8439 /***************************************************************************
8440 Auto-load one printer.
8441 ***************************************************************************/
8443 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8445 int printers = lp_servicenumber(PRINTERS_NAME);
8448 if (lp_servicenumber(name) < 0) {
8449 lp_add_printer(name, printers);
8450 if ((i = lp_servicenumber(name)) >= 0) {
8451 string_set(&ServicePtrs[i]->comment, comment);
8452 ServicePtrs[i]->autoloaded = True;
8457 /***************************************************************************
8458 Have we loaded a services file yet?
8459 ***************************************************************************/
8461 bool lp_loaded(void)
8466 /***************************************************************************
8467 Unload unused services.
8468 ***************************************************************************/
8470 void lp_killunused(bool (*snumused) (int))
8473 for (i = 0; i < iNumServices; i++) {
8477 /* don't kill autoloaded or usershare services */
8478 if ( ServicePtrs[i]->autoloaded ||
8479 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8483 if (!snumused || !snumused(i)) {
8484 free_service_byindex(i);
8490 * Kill all except autoloaded and usershare services - convenience wrapper
8492 void lp_kill_all_services(void)
8494 lp_killunused(NULL);
8497 /***************************************************************************
8499 ***************************************************************************/
8501 void lp_killservice(int iServiceIn)
8503 if (VALID(iServiceIn)) {
8504 free_service_byindex(iServiceIn);
8508 /***************************************************************************
8509 Save the curent values of all global and sDefault parameters into the
8510 defaults union. This allows swat and testparm to show only the
8511 changed (ie. non-default) parameters.
8512 ***************************************************************************/
8514 static void lp_save_defaults(void)
8517 for (i = 0; parm_table[i].label; i++) {
8518 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8520 switch (parm_table[i].type) {
8522 parm_table[i].def.lvalue = str_list_copy(
8523 NULL, *(const char ***)parm_table[i].ptr);
8527 if (parm_table[i].ptr) {
8528 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8530 parm_table[i].def.svalue = NULL;
8535 parm_table[i].def.bvalue =
8536 *(bool *)parm_table[i].ptr;
8539 parm_table[i].def.cvalue =
8540 *(char *)parm_table[i].ptr;
8545 parm_table[i].def.ivalue =
8546 *(int *)parm_table[i].ptr;
8552 defaults_saved = True;
8555 /***********************************************************
8556 If we should send plaintext/LANMAN passwords in the clinet
8557 ************************************************************/
8559 static void set_allowed_client_auth(void)
8561 if (Globals.bClientNTLMv2Auth) {
8562 Globals.bClientLanManAuth = False;
8564 if (!Globals.bClientLanManAuth) {
8565 Globals.bClientPlaintextAuth = False;
8569 /***************************************************************************
8571 The following code allows smbd to read a user defined share file.
8572 Yes, this is my intent. Yes, I'm comfortable with that...
8574 THE FOLLOWING IS SECURITY CRITICAL CODE.
8576 It washes your clothes, it cleans your house, it guards you while you sleep...
8577 Do not f%^k with it....
8578 ***************************************************************************/
8580 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8582 /***************************************************************************
8583 Check allowed stat state of a usershare file.
8584 Ensure we print out who is dicking with us so the admin can
8585 get their sorry ass fired.
8586 ***************************************************************************/
8588 static bool check_usershare_stat(const char *fname,
8589 const SMB_STRUCT_STAT *psbuf)
8591 if (!S_ISREG(psbuf->st_ex_mode)) {
8592 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8593 "not a regular file\n",
8594 fname, (unsigned int)psbuf->st_ex_uid ));
8598 /* Ensure this doesn't have the other write bit set. */
8599 if (psbuf->st_ex_mode & S_IWOTH) {
8600 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8601 "public write. Refusing to allow as a usershare file.\n",
8602 fname, (unsigned int)psbuf->st_ex_uid ));
8606 /* Should be 10k or less. */
8607 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8608 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8609 "too large (%u) to be a user share file.\n",
8610 fname, (unsigned int)psbuf->st_ex_uid,
8611 (unsigned int)psbuf->st_ex_size ));
8618 /***************************************************************************
8619 Parse the contents of a usershare file.
8620 ***************************************************************************/
8622 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8623 SMB_STRUCT_STAT *psbuf,
8624 const char *servicename,
8628 char **pp_sharepath,
8630 char **pp_cp_servicename,
8631 struct security_descriptor **ppsd,
8634 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8635 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8638 SMB_STRUCT_STAT sbuf;
8639 char *sharepath = NULL;
8640 char *comment = NULL;
8642 *pp_sharepath = NULL;
8645 *pallow_guest = False;
8648 return USERSHARE_MALFORMED_FILE;
8651 if (strcmp(lines[0], "#VERSION 1") == 0) {
8653 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8656 return USERSHARE_MALFORMED_FILE;
8659 return USERSHARE_BAD_VERSION;
8662 if (strncmp(lines[1], "path=", 5) != 0) {
8663 return USERSHARE_MALFORMED_PATH;
8666 sharepath = talloc_strdup(ctx, &lines[1][5]);
8668 return USERSHARE_POSIX_ERR;
8670 trim_string(sharepath, " ", " ");
8672 if (strncmp(lines[2], "comment=", 8) != 0) {
8673 return USERSHARE_MALFORMED_COMMENT_DEF;
8676 comment = talloc_strdup(ctx, &lines[2][8]);
8678 return USERSHARE_POSIX_ERR;
8680 trim_string(comment, " ", " ");
8681 trim_char(comment, '"', '"');
8683 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8684 return USERSHARE_MALFORMED_ACL_DEF;
8687 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8688 return USERSHARE_ACL_ERR;
8692 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8693 return USERSHARE_MALFORMED_ACL_DEF;
8695 if (lines[4][9] == 'y') {
8696 *pallow_guest = True;
8699 /* Backwards compatible extension to file version #2. */
8701 if (strncmp(lines[5], "sharename=", 10) != 0) {
8702 return USERSHARE_MALFORMED_SHARENAME_DEF;
8704 if (!strequal(&lines[5][10], servicename)) {
8705 return USERSHARE_BAD_SHARENAME;
8707 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8708 if (!*pp_cp_servicename) {
8709 return USERSHARE_POSIX_ERR;
8714 if (*pp_cp_servicename == NULL) {
8715 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8716 if (!*pp_cp_servicename) {
8717 return USERSHARE_POSIX_ERR;
8721 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8722 /* Path didn't change, no checks needed. */
8723 *pp_sharepath = sharepath;
8724 *pp_comment = comment;
8725 return USERSHARE_OK;
8728 /* The path *must* be absolute. */
8729 if (sharepath[0] != '/') {
8730 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8731 servicename, sharepath));
8732 return USERSHARE_PATH_NOT_ABSOLUTE;
8735 /* If there is a usershare prefix deny list ensure one of these paths
8736 doesn't match the start of the user given path. */
8737 if (prefixdenylist) {
8739 for ( i=0; prefixdenylist[i]; i++ ) {
8740 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8741 servicename, i, prefixdenylist[i], sharepath ));
8742 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8743 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8744 "usershare prefix deny list entries.\n",
8745 servicename, sharepath));
8746 return USERSHARE_PATH_IS_DENIED;
8751 /* If there is a usershare prefix allow list ensure one of these paths
8752 does match the start of the user given path. */
8754 if (prefixallowlist) {
8756 for ( i=0; prefixallowlist[i]; i++ ) {
8757 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8758 servicename, i, prefixallowlist[i], sharepath ));
8759 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8763 if (prefixallowlist[i] == NULL) {
8764 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8765 "usershare prefix allow list entries.\n",
8766 servicename, sharepath));
8767 return USERSHARE_PATH_NOT_ALLOWED;
8771 /* Ensure this is pointing to a directory. */
8772 dp = sys_opendir(sharepath);
8775 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8776 servicename, sharepath));
8777 return USERSHARE_PATH_NOT_DIRECTORY;
8780 /* Ensure the owner of the usershare file has permission to share
8783 if (sys_stat(sharepath, &sbuf, false) == -1) {
8784 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8785 servicename, sharepath, strerror(errno) ));
8787 return USERSHARE_POSIX_ERR;
8792 if (!S_ISDIR(sbuf.st_ex_mode)) {
8793 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8794 servicename, sharepath ));
8795 return USERSHARE_PATH_NOT_DIRECTORY;
8798 /* Check if sharing is restricted to owner-only. */
8799 /* psbuf is the stat of the usershare definition file,
8800 sbuf is the stat of the target directory to be shared. */
8802 if (lp_usershare_owner_only()) {
8803 /* root can share anything. */
8804 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8805 return USERSHARE_PATH_NOT_ALLOWED;
8809 *pp_sharepath = sharepath;
8810 *pp_comment = comment;
8811 return USERSHARE_OK;
8814 /***************************************************************************
8815 Deal with a usershare file.
8818 -1 - Bad name, invalid contents.
8819 - service name already existed and not a usershare, problem
8820 with permissions to share directory etc.
8821 ***************************************************************************/
8823 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8825 SMB_STRUCT_STAT sbuf;
8826 SMB_STRUCT_STAT lsbuf;
8828 char *sharepath = NULL;
8829 char *comment = NULL;
8830 char *cp_service_name = NULL;
8831 char **lines = NULL;
8835 TALLOC_CTX *ctx = talloc_stackframe();
8836 struct security_descriptor *psd = NULL;
8837 bool guest_ok = False;
8838 char *canon_name = NULL;
8839 bool added_service = false;
8842 /* Ensure share name doesn't contain invalid characters. */
8843 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8844 DEBUG(0,("process_usershare_file: share name %s contains "
8845 "invalid characters (any of %s)\n",
8846 file_name, INVALID_SHARENAME_CHARS ));
8850 canon_name = canonicalize_servicename(ctx, file_name);
8855 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8860 /* Minimize the race condition by doing an lstat before we
8861 open and fstat. Ensure this isn't a symlink link. */
8863 if (sys_lstat(fname, &lsbuf, false) != 0) {
8864 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8865 fname, strerror(errno) ));
8869 /* This must be a regular file, not a symlink, directory or
8870 other strange filetype. */
8871 if (!check_usershare_stat(fname, &lsbuf)) {
8876 TDB_DATA data = dbwrap_fetch_bystring(
8877 ServiceHash, canon_name, canon_name);
8881 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8882 iService = *(int *)data.dptr;
8886 if (iService != -1 &&
8887 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8888 &lsbuf.st_ex_mtime) == 0) {
8889 /* Nothing changed - Mark valid and return. */
8890 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8892 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8897 /* Try and open the file read only - no symlinks allowed. */
8899 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8901 fd = sys_open(fname, O_RDONLY, 0);
8905 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8906 fname, strerror(errno) ));
8910 /* Now fstat to be *SURE* it's a regular file. */
8911 if (sys_fstat(fd, &sbuf, false) != 0) {
8913 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8914 fname, strerror(errno) ));
8918 /* Is it the same dev/inode as was lstated ? */
8919 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8921 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8922 "Symlink spoofing going on ?\n", fname ));
8926 /* This must be a regular file, not a symlink, directory or
8927 other strange filetype. */
8928 if (!check_usershare_stat(fname, &sbuf)) {
8932 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8935 if (lines == NULL) {
8936 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8937 fname, (unsigned int)sbuf.st_ex_uid ));
8941 if (parse_usershare_file(ctx, &sbuf, file_name,
8942 iService, lines, numlines, &sharepath,
8943 &comment, &cp_service_name,
8944 &psd, &guest_ok) != USERSHARE_OK) {
8948 /* Everything ok - add the service possibly using a template. */
8950 const struct service *sp = &sDefault;
8951 if (snum_template != -1) {
8952 sp = ServicePtrs[snum_template];
8955 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8956 DEBUG(0, ("process_usershare_file: Failed to add "
8957 "new service %s\n", cp_service_name));
8961 added_service = true;
8963 /* Read only is controlled by usershare ACL below. */
8964 ServicePtrs[iService]->bRead_only = False;
8967 /* Write the ACL of the new/modified share. */
8968 if (!set_share_security(canon_name, psd)) {
8969 DEBUG(0, ("process_usershare_file: Failed to set share "
8970 "security for user share %s\n",
8975 /* If from a template it may be marked invalid. */
8976 ServicePtrs[iService]->valid = True;
8978 /* Set the service as a valid usershare. */
8979 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8981 /* Set guest access. */
8982 if (lp_usershare_allow_guests()) {
8983 ServicePtrs[iService]->bGuest_ok = guest_ok;
8986 /* And note when it was loaded. */
8987 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8988 string_set(&ServicePtrs[iService]->szPath, sharepath);
8989 string_set(&ServicePtrs[iService]->comment, comment);
8995 if (ret == -1 && iService != -1 && added_service) {
8996 lp_remove_service(iService);
9004 /***************************************************************************
9005 Checks if a usershare entry has been modified since last load.
9006 ***************************************************************************/
9008 static bool usershare_exists(int iService, struct timespec *last_mod)
9010 SMB_STRUCT_STAT lsbuf;
9011 const char *usersharepath = Globals.szUsersharePath;
9014 if (asprintf(&fname, "%s/%s",
9016 ServicePtrs[iService]->szService) < 0) {
9020 if (sys_lstat(fname, &lsbuf, false) != 0) {
9025 if (!S_ISREG(lsbuf.st_ex_mode)) {
9031 *last_mod = lsbuf.st_ex_mtime;
9035 /***************************************************************************
9036 Load a usershare service by name. Returns a valid servicenumber or -1.
9037 ***************************************************************************/
9039 int load_usershare_service(const char *servicename)
9041 SMB_STRUCT_STAT sbuf;
9042 const char *usersharepath = Globals.szUsersharePath;
9043 int max_user_shares = Globals.iUsershareMaxShares;
9044 int snum_template = -1;
9046 if (*usersharepath == 0 || max_user_shares == 0) {
9050 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9051 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9052 usersharepath, strerror(errno) ));
9056 if (!S_ISDIR(sbuf.st_ex_mode)) {
9057 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9063 * This directory must be owned by root, and have the 't' bit set.
9064 * It also must not be writable by "other".
9068 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9070 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9072 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9073 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9078 /* Ensure the template share exists if it's set. */
9079 if (Globals.szUsershareTemplateShare[0]) {
9080 /* We can't use lp_servicenumber here as we are recommending that
9081 template shares have -valid=False set. */
9082 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9083 if (ServicePtrs[snum_template]->szService &&
9084 strequal(ServicePtrs[snum_template]->szService,
9085 Globals.szUsershareTemplateShare)) {
9090 if (snum_template == -1) {
9091 DEBUG(0,("load_usershare_service: usershare template share %s "
9092 "does not exist.\n",
9093 Globals.szUsershareTemplateShare ));
9098 return process_usershare_file(usersharepath, servicename, snum_template);
9101 /***************************************************************************
9102 Load all user defined shares from the user share directory.
9103 We only do this if we're enumerating the share list.
9104 This is the function that can delete usershares that have
9106 ***************************************************************************/
9108 int load_usershare_shares(void)
9111 SMB_STRUCT_STAT sbuf;
9112 SMB_STRUCT_DIRENT *de;
9113 int num_usershares = 0;
9114 int max_user_shares = Globals.iUsershareMaxShares;
9115 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9116 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9117 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9119 int snum_template = -1;
9120 const char *usersharepath = Globals.szUsersharePath;
9121 int ret = lp_numservices();
9123 if (max_user_shares == 0 || *usersharepath == '\0') {
9124 return lp_numservices();
9127 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9128 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9129 usersharepath, strerror(errno) ));
9134 * This directory must be owned by root, and have the 't' bit set.
9135 * It also must not be writable by "other".
9139 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9141 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9143 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9144 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9149 /* Ensure the template share exists if it's set. */
9150 if (Globals.szUsershareTemplateShare[0]) {
9151 /* We can't use lp_servicenumber here as we are recommending that
9152 template shares have -valid=False set. */
9153 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9154 if (ServicePtrs[snum_template]->szService &&
9155 strequal(ServicePtrs[snum_template]->szService,
9156 Globals.szUsershareTemplateShare)) {
9161 if (snum_template == -1) {
9162 DEBUG(0,("load_usershare_shares: usershare template share %s "
9163 "does not exist.\n",
9164 Globals.szUsershareTemplateShare ));
9169 /* Mark all existing usershares as pending delete. */
9170 for (iService = iNumServices - 1; iService >= 0; iService--) {
9171 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9172 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9176 dp = sys_opendir(usersharepath);
9178 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9179 usersharepath, strerror(errno) ));
9183 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9184 (de = sys_readdir(dp));
9185 num_dir_entries++ ) {
9187 const char *n = de->d_name;
9189 /* Ignore . and .. */
9191 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9197 /* Temporary file used when creating a share. */
9198 num_tmp_dir_entries++;
9201 /* Allow 20% tmp entries. */
9202 if (num_tmp_dir_entries > allowed_tmp_entries) {
9203 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9204 "in directory %s\n",
9205 num_tmp_dir_entries, usersharepath));
9209 r = process_usershare_file(usersharepath, n, snum_template);
9211 /* Update the services count. */
9213 if (num_usershares >= max_user_shares) {
9214 DEBUG(0,("load_usershare_shares: max user shares reached "
9215 "on file %s in directory %s\n",
9216 n, usersharepath ));
9219 } else if (r == -1) {
9220 num_bad_dir_entries++;
9223 /* Allow 20% bad entries. */
9224 if (num_bad_dir_entries > allowed_bad_entries) {
9225 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9226 "in directory %s\n",
9227 num_bad_dir_entries, usersharepath));
9231 /* Allow 20% bad entries. */
9232 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9233 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9234 "in directory %s\n",
9235 num_dir_entries, usersharepath));
9242 /* Sweep through and delete any non-refreshed usershares that are
9243 not currently in use. */
9244 for (iService = iNumServices - 1; iService >= 0; iService--) {
9245 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9246 if (conn_snum_used(iService)) {
9249 /* Remove from the share ACL db. */
9250 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9251 lp_servicename(iService) ));
9252 delete_share_security(lp_servicename(iService));
9253 free_service_byindex(iService);
9257 return lp_numservices();
9260 /********************************************************
9261 Destroy global resources allocated in this file
9262 ********************************************************/
9264 void gfree_loadparm(void)
9270 /* Free resources allocated to services */
9272 for ( i = 0; i < iNumServices; i++ ) {
9274 free_service_byindex(i);
9278 SAFE_FREE( ServicePtrs );
9281 /* Now release all resources allocated to global
9282 parameters and the default service */
9284 free_global_parameters();
9288 /***************************************************************************
9289 Allow client apps to specify that they are a client
9290 ***************************************************************************/
9291 void lp_set_in_client(bool b)
9297 /***************************************************************************
9298 Determine if we're running in a client app
9299 ***************************************************************************/
9300 bool lp_is_in_client(void)
9305 /***************************************************************************
9306 Load the services array from the services file. Return True on success,
9308 ***************************************************************************/
9310 static bool lp_load_ex(const char *pszFname,
9314 bool initialize_globals,
9315 bool allow_include_registry,
9316 bool allow_registry_shares)
9323 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9325 bInGlobalSection = True;
9326 bGlobalOnly = global_only;
9327 bAllowIncludeRegistry = allow_include_registry;
9329 init_globals(initialize_globals);
9334 if (save_defaults) {
9339 free_param_opts(&Globals.param_opt);
9341 /* We get sections first, so have to start 'behind' to make up */
9344 if (lp_config_backend_is_file()) {
9345 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9346 current_user_info.domain,
9349 smb_panic("lp_load_ex: out of memory");
9352 add_to_file_list(pszFname, n2);
9354 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9357 /* finish up the last section */
9358 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9360 if (iServiceIndex >= 0) {
9361 bRetval = service_ok(iServiceIndex);
9365 if (lp_config_backend_is_registry()) {
9366 /* config backend changed to registry in config file */
9368 * We need to use this extra global variable here to
9369 * survive restart: init_globals uses this as a default
9370 * for ConfigBackend. Otherwise, init_globals would
9371 * send us into an endless loop here.
9373 config_backend = CONFIG_BACKEND_REGISTRY;
9375 DEBUG(1, ("lp_load_ex: changing to config backend "
9378 lp_kill_all_services();
9379 return lp_load_ex(pszFname, global_only, save_defaults,
9380 add_ipc, initialize_globals,
9381 allow_include_registry,
9382 allow_registry_shares);
9384 } else if (lp_config_backend_is_registry()) {
9385 bRetval = process_registry_globals();
9387 DEBUG(0, ("Illegal config backend given: %d\n",
9388 lp_config_backend()));
9392 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9393 bRetval = process_registry_shares();
9396 lp_add_auto_services(lp_auto_services());
9399 /* When 'restrict anonymous = 2' guest connections to ipc$
9401 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9402 if ( lp_enable_asu_support() ) {
9403 lp_add_ipc("ADMIN$", false);
9408 set_default_server_announce_type();
9409 set_allowed_client_auth();
9413 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9414 /* if bWINSsupport is true and we are in the client */
9415 if (lp_is_in_client() && Globals.bWINSsupport) {
9416 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9421 bAllowIncludeRegistry = true;
9426 bool lp_load(const char *pszFname,
9430 bool initialize_globals)
9432 return lp_load_ex(pszFname,
9437 true, /* allow_include_registry */
9438 false); /* allow_registry_shares*/
9441 bool lp_load_initial_only(const char *pszFname)
9443 return lp_load_ex(pszFname,
9444 true, /* global only */
9445 false, /* save_defaults */
9446 false, /* add_ipc */
9447 true, /* initialize_globals */
9448 false, /* allow_include_registry */
9449 false); /* allow_registry_shares*/
9452 bool lp_load_with_registry_shares(const char *pszFname,
9456 bool initialize_globals)
9458 return lp_load_ex(pszFname,
9463 true, /* allow_include_registry */
9464 true); /* allow_registry_shares*/
9467 /***************************************************************************
9468 Return the max number of services.
9469 ***************************************************************************/
9471 int lp_numservices(void)
9473 return (iNumServices);
9476 /***************************************************************************
9477 Display the contents of the services array in human-readable form.
9478 ***************************************************************************/
9480 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9485 defaults_saved = False;
9489 dump_a_service(&sDefault, f);
9491 for (iService = 0; iService < maxtoprint; iService++) {
9493 lp_dump_one(f, show_defaults, iService);
9497 /***************************************************************************
9498 Display the contents of one service in human-readable form.
9499 ***************************************************************************/
9501 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9504 if (ServicePtrs[snum]->szService[0] == '\0')
9506 dump_a_service(ServicePtrs[snum], f);
9510 /***************************************************************************
9511 Return the number of the service with the given name, or -1 if it doesn't
9512 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9513 getservicebyname()! This works ONLY if all services have been loaded, and
9514 does not copy the found service.
9515 ***************************************************************************/
9517 int lp_servicenumber(const char *pszServiceName)
9520 fstring serviceName;
9522 if (!pszServiceName) {
9523 return GLOBAL_SECTION_SNUM;
9526 for (iService = iNumServices - 1; iService >= 0; iService--) {
9527 if (VALID(iService) && ServicePtrs[iService]->szService) {
9529 * The substitution here is used to support %U is
9532 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9533 standard_sub_basic(get_current_username(),
9534 current_user_info.domain,
9535 serviceName,sizeof(serviceName));
9536 if (strequal(serviceName, pszServiceName)) {
9542 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9543 struct timespec last_mod;
9545 if (!usershare_exists(iService, &last_mod)) {
9546 /* Remove the share security tdb entry for it. */
9547 delete_share_security(lp_servicename(iService));
9548 /* Remove it from the array. */
9549 free_service_byindex(iService);
9550 /* Doesn't exist anymore. */
9551 return GLOBAL_SECTION_SNUM;
9554 /* Has it been modified ? If so delete and reload. */
9555 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9557 /* Remove it from the array. */
9558 free_service_byindex(iService);
9559 /* and now reload it. */
9560 iService = load_usershare_service(pszServiceName);
9565 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9566 return GLOBAL_SECTION_SNUM;
9572 bool share_defined(const char *service_name)
9574 return (lp_servicenumber(service_name) != -1);
9577 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9578 const char *sharename)
9580 struct share_params *result;
9584 if (!(sname = SMB_STRDUP(sharename))) {
9588 snum = find_service(sname);
9595 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9596 DEBUG(0, ("talloc failed\n"));
9600 result->service = snum;
9604 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9606 struct share_iterator *result;
9608 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9609 DEBUG(0, ("talloc failed\n"));
9613 result->next_id = 0;
9617 struct share_params *next_share(struct share_iterator *list)
9619 struct share_params *result;
9621 while (!lp_snum_ok(list->next_id) &&
9622 (list->next_id < lp_numservices())) {
9626 if (list->next_id >= lp_numservices()) {
9630 if (!(result = TALLOC_P(list, struct share_params))) {
9631 DEBUG(0, ("talloc failed\n"));
9635 result->service = list->next_id;
9640 struct share_params *next_printer(struct share_iterator *list)
9642 struct share_params *result;
9644 while ((result = next_share(list)) != NULL) {
9645 if (lp_print_ok(result->service)) {
9653 * This is a hack for a transition period until we transformed all code from
9654 * service numbers to struct share_params.
9657 struct share_params *snum2params_static(int snum)
9659 static struct share_params result;
9660 result.service = snum;
9664 /*******************************************************************
9665 A useful volume label function.
9666 ********************************************************************/
9668 const char *volume_label(int snum)
9671 const char *label = lp_volume(snum);
9673 label = lp_servicename(snum);
9676 /* This returns a 33 byte guarenteed null terminated string. */
9677 ret = talloc_strndup(talloc_tos(), label, 32);
9684 /*******************************************************************
9685 Set the server type we will announce as via nmbd.
9686 ********************************************************************/
9688 static void set_default_server_announce_type(void)
9690 default_server_announce = 0;
9691 default_server_announce |= SV_TYPE_WORKSTATION;
9692 default_server_announce |= SV_TYPE_SERVER;
9693 default_server_announce |= SV_TYPE_SERVER_UNIX;
9695 /* note that the flag should be set only if we have a
9696 printer service but nmbd doesn't actually load the
9697 services so we can't tell --jerry */
9699 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9701 switch (lp_announce_as()) {
9702 case ANNOUNCE_AS_NT_SERVER:
9703 default_server_announce |= SV_TYPE_SERVER_NT;
9704 /* fall through... */
9705 case ANNOUNCE_AS_NT_WORKSTATION:
9706 default_server_announce |= SV_TYPE_NT;
9708 case ANNOUNCE_AS_WIN95:
9709 default_server_announce |= SV_TYPE_WIN95_PLUS;
9711 case ANNOUNCE_AS_WFW:
9712 default_server_announce |= SV_TYPE_WFW;
9718 switch (lp_server_role()) {
9719 case ROLE_DOMAIN_MEMBER:
9720 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9722 case ROLE_DOMAIN_PDC:
9723 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9725 case ROLE_DOMAIN_BDC:
9726 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9728 case ROLE_STANDALONE:
9732 if (lp_time_server())
9733 default_server_announce |= SV_TYPE_TIME_SOURCE;
9735 if (lp_host_msdfs())
9736 default_server_announce |= SV_TYPE_DFS_SERVER;
9739 /***********************************************************
9740 If we are PDC then prefer us as DMB
9741 ************************************************************/
9743 bool lp_domain_master(void)
9745 if (Globals.iDomainMaster == Auto)
9746 return (lp_server_role() == ROLE_DOMAIN_PDC);
9748 return (bool)Globals.iDomainMaster;
9751 /***********************************************************
9752 If we are PDC then prefer us as DMB
9753 ************************************************************/
9755 bool lp_domain_master_true_or_auto(void)
9757 if (Globals.iDomainMaster) /* auto or yes */
9763 /***********************************************************
9764 If we are DMB then prefer us as LMB
9765 ************************************************************/
9767 bool lp_preferred_master(void)
9769 if (Globals.iPreferredMaster == Auto)
9770 return (lp_local_master() && lp_domain_master());
9772 return (bool)Globals.iPreferredMaster;
9775 /*******************************************************************
9777 ********************************************************************/
9779 void lp_remove_service(int snum)
9781 ServicePtrs[snum]->valid = False;
9782 invalid_services[num_invalid_services++] = snum;
9785 /*******************************************************************
9787 ********************************************************************/
9789 void lp_copy_service(int snum, const char *new_name)
9791 do_section(new_name, NULL);
9793 snum = lp_servicenumber(new_name);
9795 lp_do_parameter(snum, "copy", lp_servicename(snum));
9800 /*******************************************************************
9801 Get the default server type we will announce as via nmbd.
9802 ********************************************************************/
9804 int lp_default_server_announce(void)
9806 return default_server_announce;
9809 /*******************************************************************
9810 Split the announce version into major and minor numbers.
9811 ********************************************************************/
9813 int lp_major_announce_version(void)
9815 static bool got_major = False;
9816 static int major_version = DEFAULT_MAJOR_VERSION;
9821 return major_version;
9824 if ((vers = lp_announce_version()) == NULL)
9825 return major_version;
9827 if ((p = strchr_m(vers, '.')) == 0)
9828 return major_version;
9831 major_version = atoi(vers);
9832 return major_version;
9835 int lp_minor_announce_version(void)
9837 static bool got_minor = False;
9838 static int minor_version = DEFAULT_MINOR_VERSION;
9843 return minor_version;
9846 if ((vers = lp_announce_version()) == NULL)
9847 return minor_version;
9849 if ((p = strchr_m(vers, '.')) == 0)
9850 return minor_version;
9853 minor_version = atoi(p);
9854 return minor_version;
9857 /***********************************************************
9858 Set the global name resolution order (used in smbclient).
9859 ************************************************************/
9861 void lp_set_name_resolve_order(const char *new_order)
9863 string_set(&Globals.szNameResolveOrder, new_order);
9866 const char *lp_printername(int snum)
9868 const char *ret = _lp_printername(snum);
9869 if (ret == NULL || (ret != NULL && *ret == '\0'))
9870 ret = lp_const_servicename(snum);
9876 /***********************************************************
9877 Allow daemons such as winbindd to fix their logfile name.
9878 ************************************************************/
9880 void lp_set_logfile(const char *name)
9882 string_set(&Globals.szLogFile, name);
9883 debug_set_logfile(name);
9886 /*******************************************************************
9887 Return the max print jobs per queue.
9888 ********************************************************************/
9890 int lp_maxprintjobs(int snum)
9892 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9893 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9894 maxjobs = PRINT_MAX_JOBID - 1;
9899 const char *lp_printcapname(void)
9901 if ((Globals.szPrintcapname != NULL) &&
9902 (Globals.szPrintcapname[0] != '\0'))
9903 return Globals.szPrintcapname;
9905 if (sDefault.iPrinting == PRINT_CUPS) {
9913 if (sDefault.iPrinting == PRINT_BSD)
9914 return "/etc/printcap";
9916 return PRINTCAP_NAME;
9919 static uint32 spoolss_state;
9921 bool lp_disable_spoolss( void )
9923 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9924 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9926 return spoolss_state == SVCCTL_STOPPED ? True : False;
9929 void lp_set_spoolss_state( uint32 state )
9931 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9933 spoolss_state = state;
9936 uint32 lp_get_spoolss_state( void )
9938 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9941 /*******************************************************************
9942 Ensure we don't use sendfile if server smb signing is active.
9943 ********************************************************************/
9945 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9947 bool sign_active = false;
9949 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9950 if (get_Protocol() < PROTOCOL_NT1) {
9953 if (signing_state) {
9954 sign_active = smb_signing_is_active(signing_state);
9956 return (_lp_use_sendfile(snum) &&
9957 (get_remote_arch() != RA_WIN95) &&
9961 /*******************************************************************
9962 Turn off sendfile if we find the underlying OS doesn't support it.
9963 ********************************************************************/
9965 void set_use_sendfile(int snum, bool val)
9967 if (LP_SNUM_OK(snum))
9968 ServicePtrs[snum]->bUseSendfile = val;
9970 sDefault.bUseSendfile = val;
9973 /*******************************************************************
9974 Turn off storing DOS attributes if this share doesn't support it.
9975 ********************************************************************/
9977 void set_store_dos_attributes(int snum, bool val)
9979 if (!LP_SNUM_OK(snum))
9981 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9984 void lp_set_mangling_method(const char *new_method)
9986 string_set(&Globals.szManglingMethod, new_method);
9989 /*******************************************************************
9990 Global state for POSIX pathname processing.
9991 ********************************************************************/
9993 static bool posix_pathnames;
9995 bool lp_posix_pathnames(void)
9997 return posix_pathnames;
10000 /*******************************************************************
10001 Change everything needed to ensure POSIX pathname processing (currently
10003 ********************************************************************/
10005 void lp_set_posix_pathnames(void)
10007 posix_pathnames = True;
10010 /*******************************************************************
10011 Global state for POSIX lock processing - CIFS unix extensions.
10012 ********************************************************************/
10014 bool posix_default_lock_was_set;
10015 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
10017 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
10019 if (posix_default_lock_was_set) {
10020 return posix_cifsx_locktype;
10022 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
10026 /*******************************************************************
10027 ********************************************************************/
10029 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
10031 posix_default_lock_was_set = True;
10032 posix_cifsx_locktype = val;
10035 int lp_min_receive_file_size(void)
10037 if (Globals.iminreceivefile < 0) {
10040 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
10043 /*******************************************************************
10044 If socket address is an empty character string, it is necessary to
10045 define it as "0.0.0.0".
10046 ********************************************************************/
10048 const char *lp_socket_address(void)
10050 char *sock_addr = Globals.szSocketAddress;
10052 if (sock_addr[0] == '\0'){
10053 string_set(&Globals.szSocketAddress, "0.0.0.0");
10055 return Globals.szSocketAddress;
10058 void lp_set_passdb_backend(const char *backend)
10060 string_set(&Globals.szPassdbBackend, backend);
10063 /*******************************************************************
10064 Safe wide links checks.
10065 This helper function always verify the validity of wide links,
10066 even after a configuration file reload.
10067 ********************************************************************/
10069 static bool lp_widelinks_internal(int snum)
10071 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
10072 sDefault.bWidelinks);
10075 void widelinks_warning(int snum)
10077 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10078 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10079 "These parameters are incompatible. "
10080 "Wide links will be disabled for this share.\n",
10081 lp_servicename(snum) ));
10085 bool lp_widelinks(int snum)
10087 /* wide links is always incompatible with unix extensions */
10088 if (lp_unix_extensions()) {
10092 return lp_widelinks_internal(snum);
10095 bool lp_writeraw(void)
10097 if (lp_async_smb_echo_handler()) {
10100 return _lp_writeraw();
10103 bool lp_readraw(void)
10105 if (lp_async_smb_echo_handler()) {
10108 return _lp_readraw();