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
59 extern enum protocol_types Protocol;
60 extern userdom_struct current_user_info;
63 #define GLOBAL_NAME "global"
67 #define PRINTERS_NAME "printers"
71 #define HOMES_NAME "homes"
74 /* the special value for the include parameter
75 * to be interpreted not as a file name but to
76 * trigger loading of the global smb.conf options
78 #ifndef INCLUDE_REGISTRY_NAME
79 #define INCLUDE_REGISTRY_NAME "registry"
82 static bool in_client = False; /* Not in the client by default */
83 static struct smbconf_csn conf_last_csn;
85 #define CONFIG_BACKEND_FILE 0
86 #define CONFIG_BACKEND_REGISTRY 1
88 static int config_backend = CONFIG_BACKEND_FILE;
90 /* some helpful bits */
91 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
92 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
94 #define USERSHARE_VALID 1
95 #define USERSHARE_PENDING_DELETE 2
97 static bool defaults_saved = False;
99 struct param_opt_struct {
100 struct param_opt_struct *prev, *next;
107 * This structure describes global (ie., server-wide) parameters.
114 char *display_charset;
115 char *szPrintcapname;
116 char *szAddPortCommand;
117 char *szEnumPortsCommand;
118 char *szAddPrinterCommand;
119 char *szDeletePrinterCommand;
120 char *szOs2DriverMap;
126 char *szDefaultService;
130 char *szServerString;
131 char *szAutoServices;
132 char *szPasswdProgram;
136 char *szSMBPasswdFile;
138 char *szPassdbBackend;
139 char **szPreloadModules;
140 char *szPasswordServer;
141 char *szSocketOptions;
143 char *szAfsUsernameMap;
144 int iAfsTokenLifetime;
145 char *szLogNtTokenCommand;
151 char **szWINSservers;
153 char *szRemoteAnnounce;
154 char *szRemoteBrowseSync;
155 char *szSocketAddress;
156 char *szNISHomeMapName;
157 char *szAnnounceVersion; /* This is initialised in init_globals */
160 char **szNetbiosAliases;
161 char *szNetbiosScope;
162 char *szNameResolveOrder;
164 char *szAddUserScript;
165 char *szRenameUserScript;
166 char *szDelUserScript;
167 char *szAddGroupScript;
168 char *szDelGroupScript;
169 char *szAddUserToGroupScript;
170 char *szDelUserFromGroupScript;
171 char *szSetPrimaryGroupScript;
172 char *szAddMachineScript;
173 char *szShutdownScript;
174 char *szAbortShutdownScript;
175 char *szUsernameMapScript;
176 char *szCheckPasswordScript;
183 bool bPassdbExpandExplicit;
184 int AlgorithmicRidBase;
185 char *szTemplateHomedir;
186 char *szTemplateShell;
187 char *szWinbindSeparator;
188 bool bWinbindEnumUsers;
189 bool bWinbindEnumGroups;
190 bool bWinbindUseDefaultDomain;
191 bool bWinbindTrustedDomainsOnly;
192 bool bWinbindNestedGroups;
193 int winbind_expand_groups;
194 bool bWinbindRefreshTickets;
195 bool bWinbindOfflineLogon;
196 bool bWinbindNormalizeNames;
197 bool bWinbindRpcOnly;
198 char *szIdmapBackend;
199 char *szIdmapAllocBackend;
200 char *szAddShareCommand;
201 char *szChangeShareCommand;
202 char *szDeleteShareCommand;
204 char *szGuestaccount;
205 char *szManglingMethod;
206 char **szServicesList;
207 char *szUsersharePath;
208 char *szUsershareTemplateShare;
209 char **szUsersharePrefixAllowList;
210 char **szUsersharePrefixDenyList;
217 int open_files_db_hash_size;
226 bool paranoid_server_security;
229 int iMaxSmbdProcesses;
230 bool bDisableSpoolss;
233 bool enhanced_browsing;
239 int announce_as; /* This is initialised in init_globals */
240 int machine_password_timeout;
242 int oplock_break_wait_time;
243 int winbind_cache_time;
244 int winbind_reconnect_delay;
245 int winbind_max_idle_children;
246 char **szWinbindNssInfo;
248 char *szLdapMachineSuffix;
249 char *szLdapUserSuffix;
250 char *szLdapIdmapSuffix;
251 char *szLdapGroupSuffix;
256 int ldap_debug_level;
257 int ldap_debug_threshold;
260 char *szIPrintServer;
262 char **szClusterAddresses;
264 int ldap_passwd_sync;
265 int ldap_replication_sleep;
266 int ldap_timeout; /* This is initialised in init_globals */
267 int ldap_connection_timeout;
270 bool bMsAddPrinterWizard;
275 int iPreferredMaster;
278 char **szInitLogonDelayedHosts;
280 bool bEncryptPasswords;
285 bool bObeyPamRestrictions;
287 int PrintcapCacheTime;
288 bool bLargeReadwrite;
295 bool bBindInterfacesOnly;
296 bool bPamPasswordChange;
297 bool bUnixPasswdSync;
298 bool bPasswdChatDebug;
299 int iPasswdChatTimeout;
303 bool bNTStatusSupport;
305 int iMaxStatCacheSize;
307 bool bAllowTrustedDomains;
311 bool bClientLanManAuth;
312 bool bClientNTLMv2Auth;
313 bool bClientPlaintextAuth;
314 bool bClientUseSpnego;
315 bool bDebugPrefixTimestamp;
316 bool bDebugHiresTimestamp;
320 bool bEnableCoreFiles;
323 bool bHostnameLookups;
324 bool bUnixExtensions;
325 bool bDisableNetbios;
326 char * szDedicatedKeytabFile;
328 bool bDeferSharingViolations;
329 bool bEnablePrivileges;
331 bool bUsershareOwnerOnly;
332 bool bUsershareAllowGuests;
333 bool bRegistryShares;
334 int restrict_anonymous;
335 int name_cache_timeout;
338 int client_ldap_sasl_wrapping;
339 int iUsershareMaxShares;
341 int iIdmapNegativeCacheTime;
345 struct param_opt_struct *param_opt;
346 int cups_connection_timeout;
347 char *szSMBPerfcountModule;
350 static struct global Globals;
353 * This structure describes a single service.
359 time_t usershare_last_mod;
363 char **szInvalidUsers;
371 char *szRootPostExec;
373 char *szPrintcommand;
376 char *szLppausecommand;
377 char *szLpresumecommand;
378 char *szQueuepausecommand;
379 char *szQueueresumecommand;
381 char *szPrintjobUsername;
389 char *szVetoOplockFiles;
395 char **printer_admin;
400 char *szAioWriteBehind;
404 int iMaxReportedPrintJobs;
407 int iCreate_force_mode;
409 int iSecurity_force_mode;
412 int iDir_Security_mask;
413 int iDir_Security_force_mode;
417 int iOplockContentionLimit;
422 bool bRootpreexecClose;
425 bool bShortCasePreserve;
427 bool bHideSpecialFiles;
428 bool bHideUnReadable;
429 bool bHideUnWriteableFiles;
431 bool bAccessBasedShareEnum;
436 bool bAdministrative_share;
442 bool bStoreDosAttributes;
455 bool bStrictAllocate;
458 struct bitmap *copymap;
459 bool bDeleteReadonly;
461 bool bDeleteVetoFiles;
464 bool bDosFiletimeResolution;
465 bool bFakeDirCreateTimes;
471 bool bUseClientDriver;
472 bool bDefaultDevmode;
473 bool bForcePrintername;
475 bool bForceUnknownAclUser;
478 bool bMap_acl_inherit;
481 bool bAclCheckPermissions;
482 bool bAclMapFullControl;
483 bool bAclGroupControl;
485 bool bKernelChangeNotify;
486 int iallocation_roundup_size;
490 int iDirectoryNameCacheSize;
492 struct param_opt_struct *param_opt;
494 char dummy[3]; /* for alignment */
498 /* This is a default service used to prime a services structure */
499 static struct service sDefault = {
501 False, /* not autoloaded */
502 0, /* not a usershare */
503 (time_t)0, /* No last mod time */
504 NULL, /* szService */
506 NULL, /* szUsername */
507 NULL, /* szInvalidUsers */
508 NULL, /* szValidUsers */
509 NULL, /* szAdminUsers */
511 NULL, /* szInclude */
512 NULL, /* szPreExec */
513 NULL, /* szPostExec */
514 NULL, /* szRootPreExec */
515 NULL, /* szRootPostExec */
516 NULL, /* szCupsOptions */
517 NULL, /* szPrintcommand */
518 NULL, /* szLpqcommand */
519 NULL, /* szLprmcommand */
520 NULL, /* szLppausecommand */
521 NULL, /* szLpresumecommand */
522 NULL, /* szQueuepausecommand */
523 NULL, /* szQueueresumecommand */
524 NULL, /* szPrintername */
525 NULL, /* szPrintjobUsername */
526 NULL, /* szDontdescend */
527 NULL, /* szHostsallow */
528 NULL, /* szHostsdeny */
529 NULL, /* szMagicScript */
530 NULL, /* szMagicOutput */
531 NULL, /* szVetoFiles */
532 NULL, /* szHideFiles */
533 NULL, /* szVetoOplockFiles */
535 NULL, /* force user */
536 NULL, /* force group */
538 NULL, /* writelist */
539 NULL, /* printer admin */
542 NULL, /* vfs objects */
543 NULL, /* szMSDfsProxy */
544 NULL, /* szAioWriteBehind */
546 0, /* iMinPrintSpace */
547 1000, /* iMaxPrintJobs */
548 0, /* iMaxReportedPrintJobs */
549 0, /* iWriteCacheSize */
550 0744, /* iCreate_mask */
551 0000, /* iCreate_force_mode */
552 0777, /* iSecurity_mask */
553 0, /* iSecurity_force_mode */
554 0755, /* iDir_mask */
555 0000, /* iDir_force_mode */
556 0777, /* iDir_Security_mask */
557 0, /* iDir_Security_force_mode */
558 0, /* iMaxConnections */
559 CASE_LOWER, /* iDefaultCase */
560 DEFAULT_PRINTING, /* iPrinting */
561 2, /* iOplockContentionLimit */
563 1024, /* iBlock_size */
564 0, /* iDfreeCacheTime */
565 False, /* bPreexecClose */
566 False, /* bRootpreexecClose */
567 Auto, /* case sensitive */
568 True, /* case preserve */
569 True, /* short case preserve */
570 True, /* bHideDotFiles */
571 False, /* bHideSpecialFiles */
572 False, /* bHideUnReadable */
573 False, /* bHideUnWriteableFiles */
574 True, /* bBrowseable */
575 False, /* bAccessBasedShareEnum */
576 True, /* bAvailable */
577 True, /* bRead_only */
578 True, /* bNo_set_dir */
579 False, /* bGuest_only */
580 False, /* bAdministrative_share */
581 False, /* bGuest_ok */
582 False, /* bPrint_ok */
583 False, /* bMap_system */
584 False, /* bMap_hidden */
585 True, /* bMap_archive */
586 False, /* bStoreDosAttributes */
587 False, /* bDmapiSupport */
589 Auto, /* iStrictLocking */
590 True, /* bPosixLocking */
591 True, /* bShareModes */
593 True, /* bLevel2OpLocks */
594 False, /* bOnlyUser */
595 True, /* bMangledNames */
596 True, /* bWidelinks */
597 True, /* bSymlinks */
598 False, /* bSyncAlways */
599 False, /* bStrictAllocate */
600 False, /* bStrictSync */
601 '~', /* magic char */
603 False, /* bDeleteReadonly */
604 False, /* bFakeOplocks */
605 False, /* bDeleteVetoFiles */
606 False, /* bDosFilemode */
607 True, /* bDosFiletimes */
608 False, /* bDosFiletimeResolution */
609 False, /* bFakeDirCreateTimes */
610 True, /* bBlockingLocks */
611 False, /* bInheritPerms */
612 False, /* bInheritACLS */
613 False, /* bInheritOwner */
614 False, /* bMSDfsRoot */
615 False, /* bUseClientDriver */
616 True, /* bDefaultDevmode */
617 False, /* bForcePrintername */
618 True, /* bNTAclSupport */
619 False, /* bForceUnknownAclUser */
620 False, /* bUseSendfile */
621 False, /* bProfileAcls */
622 False, /* bMap_acl_inherit */
623 False, /* bAfs_Share */
624 False, /* bEASupport */
625 True, /* bAclCheckPermissions */
626 True, /* bAclMapFullControl */
627 False, /* bAclGroupControl */
628 True, /* bChangeNotify */
629 True, /* bKernelChangeNotify */
630 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
631 0, /* iAioReadSize */
632 0, /* iAioWriteSize */
633 MAP_READONLY_YES, /* iMap_readonly */
634 #ifdef BROKEN_DIRECTORY_HANDLING
635 0, /* iDirectoryNameCacheSize */
637 100, /* iDirectoryNameCacheSize */
639 Auto, /* ismb_encrypt */
640 NULL, /* Parametric options */
645 /* local variables */
646 static struct service **ServicePtrs = NULL;
647 static int iNumServices = 0;
648 static int iServiceIndex = 0;
649 static struct db_context *ServiceHash;
650 static int *invalid_services = NULL;
651 static int num_invalid_services = 0;
652 static bool bInGlobalSection = True;
653 static bool bGlobalOnly = False;
654 static int server_role;
655 static int default_server_announce;
657 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
659 /* prototypes for the special type handlers */
660 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
661 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
662 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
663 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
664 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
665 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
666 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
667 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
668 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
669 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
670 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
671 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
673 static void set_server_role(void);
674 static void set_default_server_announce_type(void);
675 static void set_allowed_client_auth(void);
677 static void *lp_local_ptr(struct service *service, void *ptr);
679 static const struct enum_list enum_protocol[] = {
680 {PROTOCOL_NT1, "NT1"},
681 {PROTOCOL_LANMAN2, "LANMAN2"},
682 {PROTOCOL_LANMAN1, "LANMAN1"},
683 {PROTOCOL_CORE, "CORE"},
684 {PROTOCOL_COREPLUS, "COREPLUS"},
685 {PROTOCOL_COREPLUS, "CORE+"},
689 static const struct enum_list enum_security[] = {
690 {SEC_SHARE, "SHARE"},
692 {SEC_SERVER, "SERVER"},
693 {SEC_DOMAIN, "DOMAIN"},
700 static const struct enum_list enum_printing[] = {
701 {PRINT_SYSV, "sysv"},
703 {PRINT_HPUX, "hpux"},
707 {PRINT_LPRNG, "lprng"},
708 {PRINT_CUPS, "cups"},
709 {PRINT_IPRINT, "iprint"},
711 {PRINT_LPROS2, "os2"},
713 {PRINT_TEST, "test"},
715 #endif /* DEVELOPER */
719 static const struct enum_list enum_ldap_sasl_wrapping[] = {
721 {ADS_AUTH_SASL_SIGN, "sign"},
722 {ADS_AUTH_SASL_SEAL, "seal"},
726 static const struct enum_list enum_ldap_ssl[] = {
727 {LDAP_SSL_OFF, "no"},
728 {LDAP_SSL_OFF, "off"},
729 {LDAP_SSL_START_TLS, "start tls"},
730 {LDAP_SSL_START_TLS, "start_tls"},
734 static const struct enum_list enum_ldap_passwd_sync[] = {
735 {LDAP_PASSWD_SYNC_OFF, "no"},
736 {LDAP_PASSWD_SYNC_OFF, "off"},
737 {LDAP_PASSWD_SYNC_ON, "yes"},
738 {LDAP_PASSWD_SYNC_ON, "on"},
739 {LDAP_PASSWD_SYNC_ONLY, "only"},
743 /* Types of machine we can announce as. */
744 #define ANNOUNCE_AS_NT_SERVER 1
745 #define ANNOUNCE_AS_WIN95 2
746 #define ANNOUNCE_AS_WFW 3
747 #define ANNOUNCE_AS_NT_WORKSTATION 4
749 static const struct enum_list enum_announce_as[] = {
750 {ANNOUNCE_AS_NT_SERVER, "NT"},
751 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
752 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
753 {ANNOUNCE_AS_WIN95, "win95"},
754 {ANNOUNCE_AS_WFW, "WfW"},
758 static const struct enum_list enum_map_readonly[] = {
759 {MAP_READONLY_NO, "no"},
760 {MAP_READONLY_NO, "false"},
761 {MAP_READONLY_NO, "0"},
762 {MAP_READONLY_YES, "yes"},
763 {MAP_READONLY_YES, "true"},
764 {MAP_READONLY_YES, "1"},
765 {MAP_READONLY_PERMISSIONS, "permissions"},
766 {MAP_READONLY_PERMISSIONS, "perms"},
770 static const struct enum_list enum_case[] = {
771 {CASE_LOWER, "lower"},
772 {CASE_UPPER, "upper"},
776 static const struct enum_list enum_bool_auto[] = {
787 /* Client-side offline caching policy types */
788 #define CSC_POLICY_MANUAL 0
789 #define CSC_POLICY_DOCUMENTS 1
790 #define CSC_POLICY_PROGRAMS 2
791 #define CSC_POLICY_DISABLE 3
793 static const struct enum_list enum_csc_policy[] = {
794 {CSC_POLICY_MANUAL, "manual"},
795 {CSC_POLICY_DOCUMENTS, "documents"},
796 {CSC_POLICY_PROGRAMS, "programs"},
797 {CSC_POLICY_DISABLE, "disable"},
801 /* SMB signing types. */
802 static const struct enum_list enum_smb_signing_vals[] = {
814 {Required, "required"},
815 {Required, "mandatory"},
817 {Required, "forced"},
818 {Required, "enforced"},
822 /* ACL compatibility options. */
823 static const struct enum_list enum_acl_compat_vals[] = {
824 { ACL_COMPAT_AUTO, "auto" },
825 { ACL_COMPAT_WINNT, "winnt" },
826 { ACL_COMPAT_WIN2K, "win2k" },
831 Do you want session setups at user level security with a invalid
832 password to be rejected or allowed in as guest? WinNT rejects them
833 but it can be a pain as it means "net view" needs to use a password
835 You have 3 choices in the setting of map_to_guest:
837 "Never" means session setups with an invalid password
838 are rejected. This is the default.
840 "Bad User" means session setups with an invalid password
841 are rejected, unless the username does not exist, in which case it
842 is treated as a guest login
844 "Bad Password" means session setups with an invalid password
845 are treated as a guest login
847 Note that map_to_guest only has an effect in user or server
851 static const struct enum_list enum_map_to_guest[] = {
852 {NEVER_MAP_TO_GUEST, "Never"},
853 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
854 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
855 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
859 /* Config backend options */
861 static const struct enum_list enum_config_backend[] = {
862 {CONFIG_BACKEND_FILE, "file"},
863 {CONFIG_BACKEND_REGISTRY, "registry"},
867 /* ADS kerberos ticket verification options */
869 static const struct enum_list enum_kerberos_method[] = {
870 {KERBEROS_VERIFY_SECRETS, "default"},
871 {KERBEROS_VERIFY_SECRETS, "secrets only"},
872 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
873 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
874 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
878 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
880 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
881 * screen in SWAT. This is used to exclude parameters as well as to squash all
882 * parameters that have been duplicated by pseudonyms.
884 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
885 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
886 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
889 * NOTE2: Handling of duplicated (synonym) paramters:
890 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
891 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
892 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
893 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
896 static struct parm_struct parm_table[] = {
897 {N_("Base Options"), P_SEP, P_SEPARATOR},
900 .label = "dos charset",
903 .ptr = &Globals.dos_charset,
904 .special = handle_charset,
906 .flags = FLAG_ADVANCED
909 .label = "unix charset",
912 .ptr = &Globals.unix_charset,
913 .special = handle_charset,
915 .flags = FLAG_ADVANCED
918 .label = "display charset",
921 .ptr = &Globals.display_charset,
922 .special = handle_charset,
924 .flags = FLAG_ADVANCED
930 .ptr = &sDefault.comment,
933 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
939 .ptr = &sDefault.szPath,
942 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
945 .label = "directory",
948 .ptr = &sDefault.szPath,
954 .label = "workgroup",
957 .ptr = &Globals.szWorkgroup,
958 .special = handle_workgroup,
960 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
967 .ptr = &Globals.szRealm,
970 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
974 .label = "netbios name",
977 .ptr = &Globals.szNetbiosName,
978 .special = handle_netbios_name,
980 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
983 .label = "netbios aliases",
986 .ptr = &Globals.szNetbiosAliases,
987 .special = handle_netbios_aliases,
989 .flags = FLAG_ADVANCED,
992 .label = "netbios scope",
995 .ptr = &Globals.szNetbiosScope,
996 .special = handle_netbios_scope,
998 .flags = FLAG_ADVANCED,
1001 .label = "server string",
1003 .p_class = P_GLOBAL,
1004 .ptr = &Globals.szServerString,
1007 .flags = FLAG_BASIC | FLAG_ADVANCED,
1010 .label = "interfaces",
1012 .p_class = P_GLOBAL,
1013 .ptr = &Globals.szInterfaces,
1016 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1019 .label = "bind interfaces only",
1021 .p_class = P_GLOBAL,
1022 .ptr = &Globals.bBindInterfacesOnly,
1025 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1028 .label = "config backend",
1030 .p_class = P_GLOBAL,
1031 .ptr = &Globals.ConfigBackend,
1033 .enum_list = enum_config_backend,
1034 .flags = FLAG_ADVANCED,
1037 {N_("Security Options"), P_SEP, P_SEPARATOR},
1040 .label = "security",
1042 .p_class = P_GLOBAL,
1043 .ptr = &Globals.security,
1045 .enum_list = enum_security,
1046 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1049 .label = "auth methods",
1051 .p_class = P_GLOBAL,
1052 .ptr = &Globals.AuthMethods,
1055 .flags = FLAG_ADVANCED,
1058 .label = "encrypt passwords",
1060 .p_class = P_GLOBAL,
1061 .ptr = &Globals.bEncryptPasswords,
1064 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1067 .label = "update encrypted",
1069 .p_class = P_GLOBAL,
1070 .ptr = &Globals.bUpdateEncrypt,
1073 .flags = FLAG_ADVANCED,
1076 .label = "client schannel",
1078 .p_class = P_GLOBAL,
1079 .ptr = &Globals.clientSchannel,
1081 .enum_list = enum_bool_auto,
1082 .flags = FLAG_BASIC | FLAG_ADVANCED,
1085 .label = "server schannel",
1087 .p_class = P_GLOBAL,
1088 .ptr = &Globals.serverSchannel,
1090 .enum_list = enum_bool_auto,
1091 .flags = FLAG_BASIC | FLAG_ADVANCED,
1094 .label = "allow trusted domains",
1096 .p_class = P_GLOBAL,
1097 .ptr = &Globals.bAllowTrustedDomains,
1100 .flags = FLAG_ADVANCED,
1103 .label = "map to guest",
1105 .p_class = P_GLOBAL,
1106 .ptr = &Globals.map_to_guest,
1108 .enum_list = enum_map_to_guest,
1109 .flags = FLAG_ADVANCED,
1112 .label = "null passwords",
1114 .p_class = P_GLOBAL,
1115 .ptr = &Globals.bNullPasswords,
1118 .flags = FLAG_ADVANCED,
1121 .label = "obey pam restrictions",
1123 .p_class = P_GLOBAL,
1124 .ptr = &Globals.bObeyPamRestrictions,
1127 .flags = FLAG_ADVANCED,
1130 .label = "password server",
1132 .p_class = P_GLOBAL,
1133 .ptr = &Globals.szPasswordServer,
1136 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1139 .label = "smb passwd file",
1141 .p_class = P_GLOBAL,
1142 .ptr = &Globals.szSMBPasswdFile,
1145 .flags = FLAG_ADVANCED,
1148 .label = "private dir",
1150 .p_class = P_GLOBAL,
1151 .ptr = &Globals.szPrivateDir,
1154 .flags = FLAG_ADVANCED,
1157 .label = "passdb backend",
1159 .p_class = P_GLOBAL,
1160 .ptr = &Globals.szPassdbBackend,
1163 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1166 .label = "algorithmic rid base",
1168 .p_class = P_GLOBAL,
1169 .ptr = &Globals.AlgorithmicRidBase,
1172 .flags = FLAG_ADVANCED,
1175 .label = "root directory",
1177 .p_class = P_GLOBAL,
1178 .ptr = &Globals.szRootdir,
1181 .flags = FLAG_ADVANCED,
1184 .label = "root dir",
1186 .p_class = P_GLOBAL,
1187 .ptr = &Globals.szRootdir,
1195 .p_class = P_GLOBAL,
1196 .ptr = &Globals.szRootdir,
1202 .label = "guest account",
1204 .p_class = P_GLOBAL,
1205 .ptr = &Globals.szGuestaccount,
1208 .flags = FLAG_BASIC | FLAG_ADVANCED,
1211 .label = "enable privileges",
1213 .p_class = P_GLOBAL,
1214 .ptr = &Globals.bEnablePrivileges,
1217 .flags = FLAG_ADVANCED,
1221 .label = "pam password change",
1223 .p_class = P_GLOBAL,
1224 .ptr = &Globals.bPamPasswordChange,
1227 .flags = FLAG_ADVANCED,
1230 .label = "passwd program",
1232 .p_class = P_GLOBAL,
1233 .ptr = &Globals.szPasswdProgram,
1236 .flags = FLAG_ADVANCED,
1239 .label = "passwd chat",
1241 .p_class = P_GLOBAL,
1242 .ptr = &Globals.szPasswdChat,
1245 .flags = FLAG_ADVANCED,
1248 .label = "passwd chat debug",
1250 .p_class = P_GLOBAL,
1251 .ptr = &Globals.bPasswdChatDebug,
1254 .flags = FLAG_ADVANCED,
1257 .label = "passwd chat timeout",
1259 .p_class = P_GLOBAL,
1260 .ptr = &Globals.iPasswdChatTimeout,
1263 .flags = FLAG_ADVANCED,
1266 .label = "check password script",
1268 .p_class = P_GLOBAL,
1269 .ptr = &Globals.szCheckPasswordScript,
1272 .flags = FLAG_ADVANCED,
1275 .label = "username map",
1277 .p_class = P_GLOBAL,
1278 .ptr = &Globals.szUsernameMap,
1281 .flags = FLAG_ADVANCED,
1284 .label = "password level",
1286 .p_class = P_GLOBAL,
1287 .ptr = &Globals.pwordlevel,
1290 .flags = FLAG_ADVANCED,
1293 .label = "username level",
1295 .p_class = P_GLOBAL,
1296 .ptr = &Globals.unamelevel,
1299 .flags = FLAG_ADVANCED,
1302 .label = "unix password sync",
1304 .p_class = P_GLOBAL,
1305 .ptr = &Globals.bUnixPasswdSync,
1308 .flags = FLAG_ADVANCED,
1311 .label = "restrict anonymous",
1313 .p_class = P_GLOBAL,
1314 .ptr = &Globals.restrict_anonymous,
1317 .flags = FLAG_ADVANCED,
1320 .label = "lanman auth",
1322 .p_class = P_GLOBAL,
1323 .ptr = &Globals.bLanmanAuth,
1326 .flags = FLAG_ADVANCED,
1329 .label = "ntlm auth",
1331 .p_class = P_GLOBAL,
1332 .ptr = &Globals.bNTLMAuth,
1335 .flags = FLAG_ADVANCED,
1338 .label = "client NTLMv2 auth",
1340 .p_class = P_GLOBAL,
1341 .ptr = &Globals.bClientNTLMv2Auth,
1344 .flags = FLAG_ADVANCED,
1347 .label = "client lanman auth",
1349 .p_class = P_GLOBAL,
1350 .ptr = &Globals.bClientLanManAuth,
1353 .flags = FLAG_ADVANCED,
1356 .label = "client plaintext auth",
1358 .p_class = P_GLOBAL,
1359 .ptr = &Globals.bClientPlaintextAuth,
1362 .flags = FLAG_ADVANCED,
1365 .label = "username",
1368 .ptr = &sDefault.szUsername,
1371 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1377 .ptr = &sDefault.szUsername,
1386 .ptr = &sDefault.szUsername,
1392 .label = "invalid users",
1395 .ptr = &sDefault.szInvalidUsers,
1398 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1401 .label = "valid users",
1404 .ptr = &sDefault.szValidUsers,
1407 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1410 .label = "admin users",
1413 .ptr = &sDefault.szAdminUsers,
1416 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1419 .label = "read list",
1422 .ptr = &sDefault.readlist,
1425 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1428 .label = "write list",
1431 .ptr = &sDefault.writelist,
1434 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1437 .label = "printer admin",
1440 .ptr = &sDefault.printer_admin,
1443 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1446 .label = "force user",
1449 .ptr = &sDefault.force_user,
1452 .flags = FLAG_ADVANCED | FLAG_SHARE,
1455 .label = "force group",
1458 .ptr = &sDefault.force_group,
1461 .flags = FLAG_ADVANCED | FLAG_SHARE,
1467 .ptr = &sDefault.force_group,
1470 .flags = FLAG_ADVANCED,
1473 .label = "read only",
1476 .ptr = &sDefault.bRead_only,
1479 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1482 .label = "write ok",
1485 .ptr = &sDefault.bRead_only,
1491 .label = "writeable",
1494 .ptr = &sDefault.bRead_only,
1500 .label = "writable",
1503 .ptr = &sDefault.bRead_only,
1509 .label = "acl check permissions",
1512 .ptr = &sDefault.bAclCheckPermissions,
1515 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1518 .label = "acl group control",
1521 .ptr = &sDefault.bAclGroupControl,
1524 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1527 .label = "acl map full control",
1530 .ptr = &sDefault.bAclMapFullControl,
1533 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1536 .label = "create mask",
1539 .ptr = &sDefault.iCreate_mask,
1542 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1545 .label = "create mode",
1548 .ptr = &sDefault.iCreate_mask,
1554 .label = "force create mode",
1557 .ptr = &sDefault.iCreate_force_mode,
1560 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1563 .label = "security mask",
1566 .ptr = &sDefault.iSecurity_mask,
1569 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1572 .label = "force security mode",
1575 .ptr = &sDefault.iSecurity_force_mode,
1578 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1581 .label = "directory mask",
1584 .ptr = &sDefault.iDir_mask,
1587 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1590 .label = "directory mode",
1593 .ptr = &sDefault.iDir_mask,
1596 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1599 .label = "force directory mode",
1602 .ptr = &sDefault.iDir_force_mode,
1605 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1608 .label = "directory security mask",
1611 .ptr = &sDefault.iDir_Security_mask,
1614 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1617 .label = "force directory security mode",
1620 .ptr = &sDefault.iDir_Security_force_mode,
1623 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1626 .label = "force unknown acl user",
1629 .ptr = &sDefault.bForceUnknownAclUser,
1632 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1635 .label = "inherit permissions",
1638 .ptr = &sDefault.bInheritPerms,
1641 .flags = FLAG_ADVANCED | FLAG_SHARE,
1644 .label = "inherit acls",
1647 .ptr = &sDefault.bInheritACLS,
1650 .flags = FLAG_ADVANCED | FLAG_SHARE,
1653 .label = "inherit owner",
1656 .ptr = &sDefault.bInheritOwner,
1659 .flags = FLAG_ADVANCED | FLAG_SHARE,
1662 .label = "guest only",
1665 .ptr = &sDefault.bGuest_only,
1668 .flags = FLAG_ADVANCED | FLAG_SHARE,
1671 .label = "only guest",
1674 .ptr = &sDefault.bGuest_only,
1680 .label = "administrative share",
1683 .ptr = &sDefault.bAdministrative_share,
1686 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1690 .label = "guest ok",
1693 .ptr = &sDefault.bGuest_ok,
1696 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1702 .ptr = &sDefault.bGuest_ok,
1708 .label = "only user",
1711 .ptr = &sDefault.bOnlyUser,
1714 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1717 .label = "hosts allow",
1720 .ptr = &sDefault.szHostsallow,
1723 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1726 .label = "allow hosts",
1729 .ptr = &sDefault.szHostsallow,
1735 .label = "hosts deny",
1738 .ptr = &sDefault.szHostsdeny,
1741 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1744 .label = "deny hosts",
1747 .ptr = &sDefault.szHostsdeny,
1753 .label = "preload modules",
1755 .p_class = P_GLOBAL,
1756 .ptr = &Globals.szPreloadModules,
1759 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1762 .label = "dedicated keytab file",
1764 .p_class = P_GLOBAL,
1765 .ptr = &Globals.szDedicatedKeytabFile,
1768 .flags = FLAG_ADVANCED,
1771 .label = "kerberos method",
1773 .p_class = P_GLOBAL,
1774 .ptr = &Globals.iKerberosMethod,
1776 .enum_list = enum_kerberos_method,
1777 .flags = FLAG_ADVANCED,
1781 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1784 .label = "log level",
1786 .p_class = P_GLOBAL,
1787 .ptr = &Globals.szLogLevel,
1788 .special = handle_debug_list,
1790 .flags = FLAG_ADVANCED,
1793 .label = "debuglevel",
1795 .p_class = P_GLOBAL,
1796 .ptr = &Globals.szLogLevel,
1797 .special = handle_debug_list,
1804 .p_class = P_GLOBAL,
1805 .ptr = &Globals.syslog,
1808 .flags = FLAG_ADVANCED,
1811 .label = "syslog only",
1813 .p_class = P_GLOBAL,
1814 .ptr = &Globals.bSyslogOnly,
1817 .flags = FLAG_ADVANCED,
1820 .label = "log file",
1822 .p_class = P_GLOBAL,
1823 .ptr = &Globals.szLogFile,
1826 .flags = FLAG_ADVANCED,
1829 .label = "max log size",
1831 .p_class = P_GLOBAL,
1832 .ptr = &Globals.max_log_size,
1835 .flags = FLAG_ADVANCED,
1838 .label = "debug timestamp",
1840 .p_class = P_GLOBAL,
1841 .ptr = &Globals.bTimestampLogs,
1844 .flags = FLAG_ADVANCED,
1847 .label = "timestamp logs",
1849 .p_class = P_GLOBAL,
1850 .ptr = &Globals.bTimestampLogs,
1853 .flags = FLAG_ADVANCED,
1856 .label = "debug prefix timestamp",
1858 .p_class = P_GLOBAL,
1859 .ptr = &Globals.bDebugPrefixTimestamp,
1862 .flags = FLAG_ADVANCED,
1865 .label = "debug hires timestamp",
1867 .p_class = P_GLOBAL,
1868 .ptr = &Globals.bDebugHiresTimestamp,
1871 .flags = FLAG_ADVANCED,
1874 .label = "debug pid",
1876 .p_class = P_GLOBAL,
1877 .ptr = &Globals.bDebugPid,
1880 .flags = FLAG_ADVANCED,
1883 .label = "debug uid",
1885 .p_class = P_GLOBAL,
1886 .ptr = &Globals.bDebugUid,
1889 .flags = FLAG_ADVANCED,
1892 .label = "debug class",
1894 .p_class = P_GLOBAL,
1895 .ptr = &Globals.bDebugClass,
1898 .flags = FLAG_ADVANCED,
1901 .label = "enable core files",
1903 .p_class = P_GLOBAL,
1904 .ptr = &Globals.bEnableCoreFiles,
1907 .flags = FLAG_ADVANCED,
1910 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1913 .label = "allocation roundup size",
1916 .ptr = &sDefault.iallocation_roundup_size,
1919 .flags = FLAG_ADVANCED,
1922 .label = "aio read size",
1925 .ptr = &sDefault.iAioReadSize,
1928 .flags = FLAG_ADVANCED,
1931 .label = "aio write size",
1934 .ptr = &sDefault.iAioWriteSize,
1937 .flags = FLAG_ADVANCED,
1940 .label = "aio write behind",
1943 .ptr = &sDefault.szAioWriteBehind,
1946 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1949 .label = "smb ports",
1951 .p_class = P_GLOBAL,
1952 .ptr = &Globals.smb_ports,
1955 .flags = FLAG_ADVANCED,
1958 .label = "large readwrite",
1960 .p_class = P_GLOBAL,
1961 .ptr = &Globals.bLargeReadwrite,
1964 .flags = FLAG_ADVANCED,
1967 .label = "max protocol",
1969 .p_class = P_GLOBAL,
1970 .ptr = &Globals.maxprotocol,
1972 .enum_list = enum_protocol,
1973 .flags = FLAG_ADVANCED,
1976 .label = "protocol",
1978 .p_class = P_GLOBAL,
1979 .ptr = &Globals.maxprotocol,
1981 .enum_list = enum_protocol,
1982 .flags = FLAG_ADVANCED,
1985 .label = "min protocol",
1987 .p_class = P_GLOBAL,
1988 .ptr = &Globals.minprotocol,
1990 .enum_list = enum_protocol,
1991 .flags = FLAG_ADVANCED,
1994 .label = "min receivefile size",
1996 .p_class = P_GLOBAL,
1997 .ptr = &Globals.iminreceivefile,
2000 .flags = FLAG_ADVANCED,
2003 .label = "read raw",
2005 .p_class = P_GLOBAL,
2006 .ptr = &Globals.bReadRaw,
2009 .flags = FLAG_ADVANCED,
2012 .label = "write raw",
2014 .p_class = P_GLOBAL,
2015 .ptr = &Globals.bWriteRaw,
2018 .flags = FLAG_ADVANCED,
2021 .label = "disable netbios",
2023 .p_class = P_GLOBAL,
2024 .ptr = &Globals.bDisableNetbios,
2027 .flags = FLAG_ADVANCED,
2030 .label = "reset on zero vc",
2032 .p_class = P_GLOBAL,
2033 .ptr = &Globals.bResetOnZeroVC,
2036 .flags = FLAG_ADVANCED,
2039 .label = "acl compatibility",
2041 .p_class = P_GLOBAL,
2042 .ptr = &Globals.iAclCompat,
2044 .enum_list = enum_acl_compat_vals,
2045 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2048 .label = "defer sharing violations",
2050 .p_class = P_GLOBAL,
2051 .ptr = &Globals.bDeferSharingViolations,
2054 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2057 .label = "ea support",
2060 .ptr = &sDefault.bEASupport,
2063 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2066 .label = "nt acl support",
2069 .ptr = &sDefault.bNTAclSupport,
2072 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2075 .label = "nt pipe support",
2077 .p_class = P_GLOBAL,
2078 .ptr = &Globals.bNTPipeSupport,
2081 .flags = FLAG_ADVANCED,
2084 .label = "nt status support",
2086 .p_class = P_GLOBAL,
2087 .ptr = &Globals.bNTStatusSupport,
2090 .flags = FLAG_ADVANCED,
2093 .label = "profile acls",
2096 .ptr = &sDefault.bProfileAcls,
2099 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2102 .label = "announce version",
2104 .p_class = P_GLOBAL,
2105 .ptr = &Globals.szAnnounceVersion,
2108 .flags = FLAG_ADVANCED,
2111 .label = "announce as",
2113 .p_class = P_GLOBAL,
2114 .ptr = &Globals.announce_as,
2116 .enum_list = enum_announce_as,
2117 .flags = FLAG_ADVANCED,
2120 .label = "map acl inherit",
2123 .ptr = &sDefault.bMap_acl_inherit,
2126 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2129 .label = "afs share",
2132 .ptr = &sDefault.bAfs_Share,
2135 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2140 .p_class = P_GLOBAL,
2141 .ptr = &Globals.max_mux,
2144 .flags = FLAG_ADVANCED,
2147 .label = "max xmit",
2149 .p_class = P_GLOBAL,
2150 .ptr = &Globals.max_xmit,
2153 .flags = FLAG_ADVANCED,
2156 .label = "name resolve order",
2158 .p_class = P_GLOBAL,
2159 .ptr = &Globals.szNameResolveOrder,
2162 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2167 .p_class = P_GLOBAL,
2168 .ptr = &Globals.max_ttl,
2171 .flags = FLAG_ADVANCED,
2174 .label = "max wins ttl",
2176 .p_class = P_GLOBAL,
2177 .ptr = &Globals.max_wins_ttl,
2180 .flags = FLAG_ADVANCED,
2183 .label = "min wins ttl",
2185 .p_class = P_GLOBAL,
2186 .ptr = &Globals.min_wins_ttl,
2189 .flags = FLAG_ADVANCED,
2192 .label = "time server",
2194 .p_class = P_GLOBAL,
2195 .ptr = &Globals.bTimeServer,
2198 .flags = FLAG_ADVANCED,
2201 .label = "unix extensions",
2203 .p_class = P_GLOBAL,
2204 .ptr = &Globals.bUnixExtensions,
2207 .flags = FLAG_ADVANCED,
2210 .label = "use spnego",
2212 .p_class = P_GLOBAL,
2213 .ptr = &Globals.bUseSpnego,
2216 .flags = FLAG_ADVANCED,
2219 .label = "client signing",
2221 .p_class = P_GLOBAL,
2222 .ptr = &Globals.client_signing,
2224 .enum_list = enum_smb_signing_vals,
2225 .flags = FLAG_ADVANCED,
2228 .label = "server signing",
2230 .p_class = P_GLOBAL,
2231 .ptr = &Globals.server_signing,
2233 .enum_list = enum_smb_signing_vals,
2234 .flags = FLAG_ADVANCED,
2237 .label = "smb encrypt",
2240 .ptr = &sDefault.ismb_encrypt,
2242 .enum_list = enum_smb_signing_vals,
2243 .flags = FLAG_ADVANCED,
2246 .label = "client use spnego",
2248 .p_class = P_GLOBAL,
2249 .ptr = &Globals.bClientUseSpnego,
2252 .flags = FLAG_ADVANCED,
2255 .label = "client ldap sasl wrapping",
2257 .p_class = P_GLOBAL,
2258 .ptr = &Globals.client_ldap_sasl_wrapping,
2260 .enum_list = enum_ldap_sasl_wrapping,
2261 .flags = FLAG_ADVANCED,
2264 .label = "enable asu support",
2266 .p_class = P_GLOBAL,
2267 .ptr = &Globals.bASUSupport,
2270 .flags = FLAG_ADVANCED,
2273 .label = "svcctl list",
2275 .p_class = P_GLOBAL,
2276 .ptr = &Globals.szServicesList,
2279 .flags = FLAG_ADVANCED,
2282 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2285 .label = "block size",
2288 .ptr = &sDefault.iBlock_size,
2291 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2294 .label = "deadtime",
2296 .p_class = P_GLOBAL,
2297 .ptr = &Globals.deadtime,
2300 .flags = FLAG_ADVANCED,
2303 .label = "getwd cache",
2305 .p_class = P_GLOBAL,
2306 .ptr = &Globals.getwd_cache,
2309 .flags = FLAG_ADVANCED,
2312 .label = "keepalive",
2314 .p_class = P_GLOBAL,
2315 .ptr = &Globals.iKeepalive,
2318 .flags = FLAG_ADVANCED,
2321 .label = "change notify",
2324 .ptr = &sDefault.bChangeNotify,
2327 .flags = FLAG_ADVANCED | FLAG_SHARE,
2330 .label = "directory name cache size",
2333 .ptr = &sDefault.iDirectoryNameCacheSize,
2336 .flags = FLAG_ADVANCED | FLAG_SHARE,
2339 .label = "kernel change notify",
2342 .ptr = &sDefault.bKernelChangeNotify,
2345 .flags = FLAG_ADVANCED | FLAG_SHARE,
2348 .label = "lpq cache time",
2350 .p_class = P_GLOBAL,
2351 .ptr = &Globals.lpqcachetime,
2354 .flags = FLAG_ADVANCED,
2357 .label = "max smbd processes",
2359 .p_class = P_GLOBAL,
2360 .ptr = &Globals.iMaxSmbdProcesses,
2363 .flags = FLAG_ADVANCED,
2366 .label = "max connections",
2369 .ptr = &sDefault.iMaxConnections,
2372 .flags = FLAG_ADVANCED | FLAG_SHARE,
2375 .label = "paranoid server security",
2377 .p_class = P_GLOBAL,
2378 .ptr = &Globals.paranoid_server_security,
2381 .flags = FLAG_ADVANCED,
2384 .label = "max disk size",
2386 .p_class = P_GLOBAL,
2387 .ptr = &Globals.maxdisksize,
2390 .flags = FLAG_ADVANCED,
2393 .label = "max open files",
2395 .p_class = P_GLOBAL,
2396 .ptr = &Globals.max_open_files,
2399 .flags = FLAG_ADVANCED,
2402 .label = "min print space",
2405 .ptr = &sDefault.iMinPrintSpace,
2408 .flags = FLAG_ADVANCED | FLAG_PRINT,
2411 .label = "socket options",
2413 .p_class = P_GLOBAL,
2414 .ptr = &Globals.szSocketOptions,
2417 .flags = FLAG_ADVANCED,
2420 .label = "strict allocate",
2423 .ptr = &sDefault.bStrictAllocate,
2426 .flags = FLAG_ADVANCED | FLAG_SHARE,
2429 .label = "strict sync",
2432 .ptr = &sDefault.bStrictSync,
2435 .flags = FLAG_ADVANCED | FLAG_SHARE,
2438 .label = "sync always",
2441 .ptr = &sDefault.bSyncAlways,
2444 .flags = FLAG_ADVANCED | FLAG_SHARE,
2447 .label = "use mmap",
2449 .p_class = P_GLOBAL,
2450 .ptr = &Globals.bUseMmap,
2453 .flags = FLAG_ADVANCED,
2456 .label = "use sendfile",
2459 .ptr = &sDefault.bUseSendfile,
2462 .flags = FLAG_ADVANCED | FLAG_SHARE,
2465 .label = "hostname lookups",
2467 .p_class = P_GLOBAL,
2468 .ptr = &Globals.bHostnameLookups,
2471 .flags = FLAG_ADVANCED,
2474 .label = "write cache size",
2477 .ptr = &sDefault.iWriteCacheSize,
2480 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2483 .label = "name cache timeout",
2485 .p_class = P_GLOBAL,
2486 .ptr = &Globals.name_cache_timeout,
2489 .flags = FLAG_ADVANCED,
2492 .label = "ctdbd socket",
2494 .p_class = P_GLOBAL,
2495 .ptr = &Globals.ctdbdSocket,
2498 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2501 .label = "cluster addresses",
2503 .p_class = P_GLOBAL,
2504 .ptr = &Globals.szClusterAddresses,
2507 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2510 .label = "clustering",
2512 .p_class = P_GLOBAL,
2513 .ptr = &Globals.clustering,
2516 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2519 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2522 .label = "max reported print jobs",
2525 .ptr = &sDefault.iMaxReportedPrintJobs,
2528 .flags = FLAG_ADVANCED | FLAG_PRINT,
2531 .label = "max print jobs",
2534 .ptr = &sDefault.iMaxPrintJobs,
2537 .flags = FLAG_ADVANCED | FLAG_PRINT,
2540 .label = "load printers",
2542 .p_class = P_GLOBAL,
2543 .ptr = &Globals.bLoadPrinters,
2546 .flags = FLAG_ADVANCED | FLAG_PRINT,
2549 .label = "printcap cache time",
2551 .p_class = P_GLOBAL,
2552 .ptr = &Globals.PrintcapCacheTime,
2555 .flags = FLAG_ADVANCED | FLAG_PRINT,
2558 .label = "printcap name",
2560 .p_class = P_GLOBAL,
2561 .ptr = &Globals.szPrintcapname,
2564 .flags = FLAG_ADVANCED | FLAG_PRINT,
2567 .label = "printcap",
2569 .p_class = P_GLOBAL,
2570 .ptr = &Globals.szPrintcapname,
2576 .label = "printable",
2579 .ptr = &sDefault.bPrint_ok,
2582 .flags = FLAG_ADVANCED | FLAG_PRINT,
2585 .label = "print ok",
2588 .ptr = &sDefault.bPrint_ok,
2594 .label = "printing",
2597 .ptr = &sDefault.iPrinting,
2598 .special = handle_printing,
2599 .enum_list = enum_printing,
2600 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2603 .label = "cups options",
2606 .ptr = &sDefault.szCupsOptions,
2609 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2612 .label = "cups server",
2614 .p_class = P_GLOBAL,
2615 .ptr = &Globals.szCupsServer,
2618 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2621 .label = "cups connection timeout",
2623 .p_class = P_GLOBAL,
2624 .ptr = &Globals.cups_connection_timeout,
2627 .flags = FLAG_ADVANCED,
2630 .label = "iprint server",
2632 .p_class = P_GLOBAL,
2633 .ptr = &Globals.szIPrintServer,
2636 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2639 .label = "print command",
2642 .ptr = &sDefault.szPrintcommand,
2645 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2648 .label = "disable spoolss",
2650 .p_class = P_GLOBAL,
2651 .ptr = &Globals.bDisableSpoolss,
2654 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2657 .label = "enable spoolss",
2659 .p_class = P_GLOBAL,
2660 .ptr = &Globals.bDisableSpoolss,
2666 .label = "lpq command",
2669 .ptr = &sDefault.szLpqcommand,
2672 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2675 .label = "lprm command",
2678 .ptr = &sDefault.szLprmcommand,
2681 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2684 .label = "lppause command",
2687 .ptr = &sDefault.szLppausecommand,
2690 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2693 .label = "lpresume command",
2696 .ptr = &sDefault.szLpresumecommand,
2699 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2702 .label = "queuepause command",
2705 .ptr = &sDefault.szQueuepausecommand,
2708 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2711 .label = "queueresume command",
2714 .ptr = &sDefault.szQueueresumecommand,
2717 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2720 .label = "addport command",
2722 .p_class = P_GLOBAL,
2723 .ptr = &Globals.szAddPortCommand,
2726 .flags = FLAG_ADVANCED,
2729 .label = "enumports command",
2731 .p_class = P_GLOBAL,
2732 .ptr = &Globals.szEnumPortsCommand,
2735 .flags = FLAG_ADVANCED,
2738 .label = "addprinter command",
2740 .p_class = P_GLOBAL,
2741 .ptr = &Globals.szAddPrinterCommand,
2744 .flags = FLAG_ADVANCED,
2747 .label = "deleteprinter command",
2749 .p_class = P_GLOBAL,
2750 .ptr = &Globals.szDeletePrinterCommand,
2753 .flags = FLAG_ADVANCED,
2756 .label = "show add printer wizard",
2758 .p_class = P_GLOBAL,
2759 .ptr = &Globals.bMsAddPrinterWizard,
2762 .flags = FLAG_ADVANCED,
2765 .label = "os2 driver map",
2767 .p_class = P_GLOBAL,
2768 .ptr = &Globals.szOs2DriverMap,
2771 .flags = FLAG_ADVANCED,
2775 .label = "printer name",
2778 .ptr = &sDefault.szPrintername,
2781 .flags = FLAG_ADVANCED | FLAG_PRINT,
2787 .ptr = &sDefault.szPrintername,
2793 .label = "use client driver",
2796 .ptr = &sDefault.bUseClientDriver,
2799 .flags = FLAG_ADVANCED | FLAG_PRINT,
2802 .label = "default devmode",
2805 .ptr = &sDefault.bDefaultDevmode,
2808 .flags = FLAG_ADVANCED | FLAG_PRINT,
2811 .label = "force printername",
2814 .ptr = &sDefault.bForcePrintername,
2817 .flags = FLAG_ADVANCED | FLAG_PRINT,
2820 .label = "printjob username",
2823 .ptr = &sDefault.szPrintjobUsername,
2826 .flags = FLAG_ADVANCED | FLAG_PRINT,
2829 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2832 .label = "mangling method",
2834 .p_class = P_GLOBAL,
2835 .ptr = &Globals.szManglingMethod,
2838 .flags = FLAG_ADVANCED,
2841 .label = "mangle prefix",
2843 .p_class = P_GLOBAL,
2844 .ptr = &Globals.mangle_prefix,
2847 .flags = FLAG_ADVANCED,
2851 .label = "default case",
2854 .ptr = &sDefault.iDefaultCase,
2856 .enum_list = enum_case,
2857 .flags = FLAG_ADVANCED | FLAG_SHARE,
2860 .label = "case sensitive",
2863 .ptr = &sDefault.iCaseSensitive,
2865 .enum_list = enum_bool_auto,
2866 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2869 .label = "casesignames",
2872 .ptr = &sDefault.iCaseSensitive,
2874 .enum_list = enum_bool_auto,
2875 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2878 .label = "preserve case",
2881 .ptr = &sDefault.bCasePreserve,
2884 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2887 .label = "short preserve case",
2890 .ptr = &sDefault.bShortCasePreserve,
2893 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2896 .label = "mangling char",
2899 .ptr = &sDefault.magic_char,
2902 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2905 .label = "hide dot files",
2908 .ptr = &sDefault.bHideDotFiles,
2911 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2914 .label = "hide special files",
2917 .ptr = &sDefault.bHideSpecialFiles,
2920 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2923 .label = "hide unreadable",
2926 .ptr = &sDefault.bHideUnReadable,
2929 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2932 .label = "hide unwriteable files",
2935 .ptr = &sDefault.bHideUnWriteableFiles,
2938 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2941 .label = "delete veto files",
2944 .ptr = &sDefault.bDeleteVetoFiles,
2947 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2950 .label = "veto files",
2953 .ptr = &sDefault.szVetoFiles,
2956 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2959 .label = "hide files",
2962 .ptr = &sDefault.szHideFiles,
2965 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2968 .label = "veto oplock files",
2971 .ptr = &sDefault.szVetoOplockFiles,
2974 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2977 .label = "map archive",
2980 .ptr = &sDefault.bMap_archive,
2983 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2986 .label = "map hidden",
2989 .ptr = &sDefault.bMap_hidden,
2992 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2995 .label = "map system",
2998 .ptr = &sDefault.bMap_system,
3001 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3004 .label = "map readonly",
3007 .ptr = &sDefault.iMap_readonly,
3009 .enum_list = enum_map_readonly,
3010 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3013 .label = "mangled names",
3016 .ptr = &sDefault.bMangledNames,
3019 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3022 .label = "max stat cache size",
3024 .p_class = P_GLOBAL,
3025 .ptr = &Globals.iMaxStatCacheSize,
3028 .flags = FLAG_ADVANCED,
3031 .label = "stat cache",
3033 .p_class = P_GLOBAL,
3034 .ptr = &Globals.bStatCache,
3037 .flags = FLAG_ADVANCED,
3040 .label = "store dos attributes",
3043 .ptr = &sDefault.bStoreDosAttributes,
3046 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3049 .label = "dmapi support",
3052 .ptr = &sDefault.bDmapiSupport,
3055 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3059 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3062 .label = "machine password timeout",
3064 .p_class = P_GLOBAL,
3065 .ptr = &Globals.machine_password_timeout,
3068 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3071 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3074 .label = "add user script",
3076 .p_class = P_GLOBAL,
3077 .ptr = &Globals.szAddUserScript,
3080 .flags = FLAG_ADVANCED,
3083 .label = "rename user script",
3085 .p_class = P_GLOBAL,
3086 .ptr = &Globals.szRenameUserScript,
3089 .flags = FLAG_ADVANCED,
3092 .label = "delete user script",
3094 .p_class = P_GLOBAL,
3095 .ptr = &Globals.szDelUserScript,
3098 .flags = FLAG_ADVANCED,
3101 .label = "add group script",
3103 .p_class = P_GLOBAL,
3104 .ptr = &Globals.szAddGroupScript,
3107 .flags = FLAG_ADVANCED,
3110 .label = "delete group script",
3112 .p_class = P_GLOBAL,
3113 .ptr = &Globals.szDelGroupScript,
3116 .flags = FLAG_ADVANCED,
3119 .label = "add user to group script",
3121 .p_class = P_GLOBAL,
3122 .ptr = &Globals.szAddUserToGroupScript,
3125 .flags = FLAG_ADVANCED,
3128 .label = "delete user from group script",
3130 .p_class = P_GLOBAL,
3131 .ptr = &Globals.szDelUserFromGroupScript,
3134 .flags = FLAG_ADVANCED,
3137 .label = "set primary group script",
3139 .p_class = P_GLOBAL,
3140 .ptr = &Globals.szSetPrimaryGroupScript,
3143 .flags = FLAG_ADVANCED,
3146 .label = "add machine script",
3148 .p_class = P_GLOBAL,
3149 .ptr = &Globals.szAddMachineScript,
3152 .flags = FLAG_ADVANCED,
3155 .label = "shutdown script",
3157 .p_class = P_GLOBAL,
3158 .ptr = &Globals.szShutdownScript,
3161 .flags = FLAG_ADVANCED,
3164 .label = "abort shutdown script",
3166 .p_class = P_GLOBAL,
3167 .ptr = &Globals.szAbortShutdownScript,
3170 .flags = FLAG_ADVANCED,
3173 .label = "username map script",
3175 .p_class = P_GLOBAL,
3176 .ptr = &Globals.szUsernameMapScript,
3179 .flags = FLAG_ADVANCED,
3182 .label = "logon script",
3184 .p_class = P_GLOBAL,
3185 .ptr = &Globals.szLogonScript,
3188 .flags = FLAG_ADVANCED,
3191 .label = "logon path",
3193 .p_class = P_GLOBAL,
3194 .ptr = &Globals.szLogonPath,
3197 .flags = FLAG_ADVANCED,
3200 .label = "logon drive",
3202 .p_class = P_GLOBAL,
3203 .ptr = &Globals.szLogonDrive,
3206 .flags = FLAG_ADVANCED,
3209 .label = "logon home",
3211 .p_class = P_GLOBAL,
3212 .ptr = &Globals.szLogonHome,
3215 .flags = FLAG_ADVANCED,
3218 .label = "domain logons",
3220 .p_class = P_GLOBAL,
3221 .ptr = &Globals.bDomainLogons,
3224 .flags = FLAG_ADVANCED,
3228 .label = "init logon delayed hosts",
3230 .p_class = P_GLOBAL,
3231 .ptr = &Globals.szInitLogonDelayedHosts,
3232 .flags = FLAG_ADVANCED,
3236 .label = "init logon delay",
3238 .p_class = P_GLOBAL,
3239 .ptr = &Globals.InitLogonDelay,
3240 .flags = FLAG_ADVANCED,
3244 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3247 .label = "os level",
3249 .p_class = P_GLOBAL,
3250 .ptr = &Globals.os_level,
3253 .flags = FLAG_BASIC | FLAG_ADVANCED,
3256 .label = "lm announce",
3258 .p_class = P_GLOBAL,
3259 .ptr = &Globals.lm_announce,
3261 .enum_list = enum_bool_auto,
3262 .flags = FLAG_ADVANCED,
3265 .label = "lm interval",
3267 .p_class = P_GLOBAL,
3268 .ptr = &Globals.lm_interval,
3271 .flags = FLAG_ADVANCED,
3274 .label = "preferred master",
3276 .p_class = P_GLOBAL,
3277 .ptr = &Globals.iPreferredMaster,
3279 .enum_list = enum_bool_auto,
3280 .flags = FLAG_BASIC | FLAG_ADVANCED,
3283 .label = "prefered master",
3285 .p_class = P_GLOBAL,
3286 .ptr = &Globals.iPreferredMaster,
3288 .enum_list = enum_bool_auto,
3292 .label = "local master",
3294 .p_class = P_GLOBAL,
3295 .ptr = &Globals.bLocalMaster,
3298 .flags = FLAG_BASIC | FLAG_ADVANCED,
3301 .label = "domain master",
3303 .p_class = P_GLOBAL,
3304 .ptr = &Globals.iDomainMaster,
3306 .enum_list = enum_bool_auto,
3307 .flags = FLAG_BASIC | FLAG_ADVANCED,
3310 .label = "browse list",
3312 .p_class = P_GLOBAL,
3313 .ptr = &Globals.bBrowseList,
3316 .flags = FLAG_ADVANCED,
3319 .label = "browseable",
3322 .ptr = &sDefault.bBrowseable,
3325 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3328 .label = "access based share enum",
3331 .ptr = &sDefault.bAccessBasedShareEnum,
3334 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3337 .label = "browsable",
3340 .ptr = &sDefault.bBrowseable,
3346 .label = "enhanced browsing",
3348 .p_class = P_GLOBAL,
3349 .ptr = &Globals.enhanced_browsing,
3352 .flags = FLAG_ADVANCED,
3355 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3358 .label = "dns proxy",
3360 .p_class = P_GLOBAL,
3361 .ptr = &Globals.bDNSproxy,
3364 .flags = FLAG_ADVANCED,
3367 .label = "wins proxy",
3369 .p_class = P_GLOBAL,
3370 .ptr = &Globals.bWINSproxy,
3373 .flags = FLAG_ADVANCED,
3376 .label = "wins server",
3378 .p_class = P_GLOBAL,
3379 .ptr = &Globals.szWINSservers,
3382 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3385 .label = "wins support",
3387 .p_class = P_GLOBAL,
3388 .ptr = &Globals.bWINSsupport,
3391 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3394 .label = "wins hook",
3396 .p_class = P_GLOBAL,
3397 .ptr = &Globals.szWINSHook,
3400 .flags = FLAG_ADVANCED,
3403 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3406 .label = "blocking locks",
3409 .ptr = &sDefault.bBlockingLocks,
3412 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3415 .label = "csc policy",
3418 .ptr = &sDefault.iCSCPolicy,
3420 .enum_list = enum_csc_policy,
3421 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3424 .label = "fake oplocks",
3427 .ptr = &sDefault.bFakeOplocks,
3430 .flags = FLAG_ADVANCED | FLAG_SHARE,
3433 .label = "kernel oplocks",
3435 .p_class = P_GLOBAL,
3436 .ptr = &Globals.bKernelOplocks,
3439 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3445 .ptr = &sDefault.bLocking,
3448 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3451 .label = "lock spin time",
3453 .p_class = P_GLOBAL,
3454 .ptr = &Globals.iLockSpinTime,
3457 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3463 .ptr = &sDefault.bOpLocks,
3466 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3469 .label = "level2 oplocks",
3472 .ptr = &sDefault.bLevel2OpLocks,
3475 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3478 .label = "oplock break wait time",
3480 .p_class = P_GLOBAL,
3481 .ptr = &Globals.oplock_break_wait_time,
3484 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3487 .label = "oplock contention limit",
3490 .ptr = &sDefault.iOplockContentionLimit,
3493 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3496 .label = "posix locking",
3499 .ptr = &sDefault.bPosixLocking,
3502 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3505 .label = "strict locking",
3508 .ptr = &sDefault.iStrictLocking,
3510 .enum_list = enum_bool_auto,
3511 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3514 .label = "share modes",
3517 .ptr = &sDefault.bShareModes,
3520 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3523 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3526 .label = "ldap admin dn",
3528 .p_class = P_GLOBAL,
3529 .ptr = &Globals.szLdapAdminDn,
3532 .flags = FLAG_ADVANCED,
3535 .label = "ldap delete dn",
3537 .p_class = P_GLOBAL,
3538 .ptr = &Globals.ldap_delete_dn,
3541 .flags = FLAG_ADVANCED,
3544 .label = "ldap group suffix",
3546 .p_class = P_GLOBAL,
3547 .ptr = &Globals.szLdapGroupSuffix,
3550 .flags = FLAG_ADVANCED,
3553 .label = "ldap idmap suffix",
3555 .p_class = P_GLOBAL,
3556 .ptr = &Globals.szLdapIdmapSuffix,
3559 .flags = FLAG_ADVANCED,
3562 .label = "ldap machine suffix",
3564 .p_class = P_GLOBAL,
3565 .ptr = &Globals.szLdapMachineSuffix,
3568 .flags = FLAG_ADVANCED,
3571 .label = "ldap passwd sync",
3573 .p_class = P_GLOBAL,
3574 .ptr = &Globals.ldap_passwd_sync,
3576 .enum_list = enum_ldap_passwd_sync,
3577 .flags = FLAG_ADVANCED,
3580 .label = "ldap password sync",
3582 .p_class = P_GLOBAL,
3583 .ptr = &Globals.ldap_passwd_sync,
3585 .enum_list = enum_ldap_passwd_sync,
3589 .label = "ldap replication sleep",
3591 .p_class = P_GLOBAL,
3592 .ptr = &Globals.ldap_replication_sleep,
3595 .flags = FLAG_ADVANCED,
3598 .label = "ldap suffix",
3600 .p_class = P_GLOBAL,
3601 .ptr = &Globals.szLdapSuffix,
3604 .flags = FLAG_ADVANCED,
3607 .label = "ldap ssl",
3609 .p_class = P_GLOBAL,
3610 .ptr = &Globals.ldap_ssl,
3612 .enum_list = enum_ldap_ssl,
3613 .flags = FLAG_ADVANCED,
3616 .label = "ldap ssl ads",
3618 .p_class = P_GLOBAL,
3619 .ptr = &Globals.ldap_ssl_ads,
3622 .flags = FLAG_ADVANCED,
3625 .label = "ldap timeout",
3627 .p_class = P_GLOBAL,
3628 .ptr = &Globals.ldap_timeout,
3631 .flags = FLAG_ADVANCED,
3634 .label = "ldap connection timeout",
3636 .p_class = P_GLOBAL,
3637 .ptr = &Globals.ldap_connection_timeout,
3640 .flags = FLAG_ADVANCED,
3643 .label = "ldap page size",
3645 .p_class = P_GLOBAL,
3646 .ptr = &Globals.ldap_page_size,
3649 .flags = FLAG_ADVANCED,
3652 .label = "ldap user suffix",
3654 .p_class = P_GLOBAL,
3655 .ptr = &Globals.szLdapUserSuffix,
3658 .flags = FLAG_ADVANCED,
3661 .label = "ldap debug level",
3663 .p_class = P_GLOBAL,
3664 .ptr = &Globals.ldap_debug_level,
3665 .special = handle_ldap_debug_level,
3667 .flags = FLAG_ADVANCED,
3670 .label = "ldap debug threshold",
3672 .p_class = P_GLOBAL,
3673 .ptr = &Globals.ldap_debug_threshold,
3676 .flags = FLAG_ADVANCED,
3679 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3682 .label = "eventlog list",
3684 .p_class = P_GLOBAL,
3685 .ptr = &Globals.szEventLogs,
3688 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3691 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3694 .label = "add share command",
3696 .p_class = P_GLOBAL,
3697 .ptr = &Globals.szAddShareCommand,
3700 .flags = FLAG_ADVANCED,
3703 .label = "change share command",
3705 .p_class = P_GLOBAL,
3706 .ptr = &Globals.szChangeShareCommand,
3709 .flags = FLAG_ADVANCED,
3712 .label = "delete share command",
3714 .p_class = P_GLOBAL,
3715 .ptr = &Globals.szDeleteShareCommand,
3718 .flags = FLAG_ADVANCED,
3721 .label = "config file",
3723 .p_class = P_GLOBAL,
3724 .ptr = &Globals.szConfigFile,
3732 .p_class = P_GLOBAL,
3733 .ptr = &Globals.szAutoServices,
3736 .flags = FLAG_ADVANCED,
3739 .label = "auto services",
3741 .p_class = P_GLOBAL,
3742 .ptr = &Globals.szAutoServices,
3745 .flags = FLAG_ADVANCED,
3748 .label = "lock directory",
3750 .p_class = P_GLOBAL,
3751 .ptr = &Globals.szLockDir,
3754 .flags = FLAG_ADVANCED,
3757 .label = "lock dir",
3759 .p_class = P_GLOBAL,
3760 .ptr = &Globals.szLockDir,
3766 .label = "state directory",
3768 .p_class = P_GLOBAL,
3769 .ptr = &Globals.szStateDir,
3772 .flags = FLAG_ADVANCED,
3775 .label = "cache directory",
3777 .p_class = P_GLOBAL,
3778 .ptr = &Globals.szCacheDir,
3781 .flags = FLAG_ADVANCED,
3784 .label = "pid directory",
3786 .p_class = P_GLOBAL,
3787 .ptr = &Globals.szPidDir,
3790 .flags = FLAG_ADVANCED,
3794 .label = "utmp directory",
3796 .p_class = P_GLOBAL,
3797 .ptr = &Globals.szUtmpDir,
3800 .flags = FLAG_ADVANCED,
3803 .label = "wtmp directory",
3805 .p_class = P_GLOBAL,
3806 .ptr = &Globals.szWtmpDir,
3809 .flags = FLAG_ADVANCED,
3814 .p_class = P_GLOBAL,
3815 .ptr = &Globals.bUtmp,
3818 .flags = FLAG_ADVANCED,
3822 .label = "default service",
3824 .p_class = P_GLOBAL,
3825 .ptr = &Globals.szDefaultService,
3828 .flags = FLAG_ADVANCED,
3833 .p_class = P_GLOBAL,
3834 .ptr = &Globals.szDefaultService,
3837 .flags = FLAG_ADVANCED,
3840 .label = "message command",
3842 .p_class = P_GLOBAL,
3843 .ptr = &Globals.szMsgCommand,
3846 .flags = FLAG_ADVANCED,
3849 .label = "dfree cache time",
3852 .ptr = &sDefault.iDfreeCacheTime,
3855 .flags = FLAG_ADVANCED,
3858 .label = "dfree command",
3861 .ptr = &sDefault.szDfree,
3864 .flags = FLAG_ADVANCED,
3867 .label = "get quota command",
3869 .p_class = P_GLOBAL,
3870 .ptr = &Globals.szGetQuota,
3873 .flags = FLAG_ADVANCED,
3876 .label = "set quota command",
3878 .p_class = P_GLOBAL,
3879 .ptr = &Globals.szSetQuota,
3882 .flags = FLAG_ADVANCED,
3885 .label = "remote announce",
3887 .p_class = P_GLOBAL,
3888 .ptr = &Globals.szRemoteAnnounce,
3891 .flags = FLAG_ADVANCED,
3894 .label = "remote browse sync",
3896 .p_class = P_GLOBAL,
3897 .ptr = &Globals.szRemoteBrowseSync,
3900 .flags = FLAG_ADVANCED,
3903 .label = "socket address",
3905 .p_class = P_GLOBAL,
3906 .ptr = &Globals.szSocketAddress,
3909 .flags = FLAG_ADVANCED,
3912 .label = "homedir map",
3914 .p_class = P_GLOBAL,
3915 .ptr = &Globals.szNISHomeMapName,
3918 .flags = FLAG_ADVANCED,
3921 .label = "afs username map",
3923 .p_class = P_GLOBAL,
3924 .ptr = &Globals.szAfsUsernameMap,
3927 .flags = FLAG_ADVANCED,
3930 .label = "afs token lifetime",
3932 .p_class = P_GLOBAL,
3933 .ptr = &Globals.iAfsTokenLifetime,
3936 .flags = FLAG_ADVANCED,
3939 .label = "log nt token command",
3941 .p_class = P_GLOBAL,
3942 .ptr = &Globals.szLogNtTokenCommand,
3945 .flags = FLAG_ADVANCED,
3948 .label = "time offset",
3950 .p_class = P_GLOBAL,
3951 .ptr = &extra_time_offset,
3954 .flags = FLAG_ADVANCED,
3957 .label = "NIS homedir",
3959 .p_class = P_GLOBAL,
3960 .ptr = &Globals.bNISHomeMap,
3963 .flags = FLAG_ADVANCED,
3969 .ptr = &sDefault.valid,
3978 .ptr = &sDefault.szCopy,
3979 .special = handle_copy,
3987 .ptr = &sDefault.szInclude,
3988 .special = handle_include,
3996 .ptr = &sDefault.szPreExec,
3999 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4005 .ptr = &sDefault.szPreExec,
4008 .flags = FLAG_ADVANCED,
4011 .label = "preexec close",
4014 .ptr = &sDefault.bPreexecClose,
4017 .flags = FLAG_ADVANCED | FLAG_SHARE,
4020 .label = "postexec",
4023 .ptr = &sDefault.szPostExec,
4026 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4029 .label = "root preexec",
4032 .ptr = &sDefault.szRootPreExec,
4035 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4038 .label = "root preexec close",
4041 .ptr = &sDefault.bRootpreexecClose,
4044 .flags = FLAG_ADVANCED | FLAG_SHARE,
4047 .label = "root postexec",
4050 .ptr = &sDefault.szRootPostExec,
4053 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4056 .label = "available",
4059 .ptr = &sDefault.bAvailable,
4062 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4065 .label = "registry shares",
4067 .p_class = P_GLOBAL,
4068 .ptr = &Globals.bRegistryShares,
4071 .flags = FLAG_ADVANCED,
4074 .label = "usershare allow guests",
4076 .p_class = P_GLOBAL,
4077 .ptr = &Globals.bUsershareAllowGuests,
4080 .flags = FLAG_ADVANCED,
4083 .label = "usershare max shares",
4085 .p_class = P_GLOBAL,
4086 .ptr = &Globals.iUsershareMaxShares,
4089 .flags = FLAG_ADVANCED,
4092 .label = "usershare owner only",
4094 .p_class = P_GLOBAL,
4095 .ptr = &Globals.bUsershareOwnerOnly,
4098 .flags = FLAG_ADVANCED,
4101 .label = "usershare path",
4103 .p_class = P_GLOBAL,
4104 .ptr = &Globals.szUsersharePath,
4107 .flags = FLAG_ADVANCED,
4110 .label = "usershare prefix allow list",
4112 .p_class = P_GLOBAL,
4113 .ptr = &Globals.szUsersharePrefixAllowList,
4116 .flags = FLAG_ADVANCED,
4119 .label = "usershare prefix deny list",
4121 .p_class = P_GLOBAL,
4122 .ptr = &Globals.szUsersharePrefixDenyList,
4125 .flags = FLAG_ADVANCED,
4128 .label = "usershare template share",
4130 .p_class = P_GLOBAL,
4131 .ptr = &Globals.szUsershareTemplateShare,
4134 .flags = FLAG_ADVANCED,
4140 .ptr = &sDefault.volume,
4143 .flags = FLAG_ADVANCED | FLAG_SHARE,
4149 .ptr = &sDefault.fstype,
4152 .flags = FLAG_ADVANCED | FLAG_SHARE,
4155 .label = "set directory",
4158 .ptr = &sDefault.bNo_set_dir,
4161 .flags = FLAG_ADVANCED | FLAG_SHARE,
4164 .label = "wide links",
4167 .ptr = &sDefault.bWidelinks,
4170 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4173 .label = "follow symlinks",
4176 .ptr = &sDefault.bSymlinks,
4179 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4182 .label = "dont descend",
4185 .ptr = &sDefault.szDontdescend,
4188 .flags = FLAG_ADVANCED | FLAG_SHARE,
4191 .label = "magic script",
4194 .ptr = &sDefault.szMagicScript,
4197 .flags = FLAG_ADVANCED | FLAG_SHARE,
4200 .label = "magic output",
4203 .ptr = &sDefault.szMagicOutput,
4206 .flags = FLAG_ADVANCED | FLAG_SHARE,
4209 .label = "delete readonly",
4212 .ptr = &sDefault.bDeleteReadonly,
4215 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4218 .label = "dos filemode",
4221 .ptr = &sDefault.bDosFilemode,
4224 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4227 .label = "dos filetimes",
4230 .ptr = &sDefault.bDosFiletimes,
4233 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4236 .label = "dos filetime resolution",
4239 .ptr = &sDefault.bDosFiletimeResolution,
4242 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4245 .label = "fake directory create times",
4248 .ptr = &sDefault.bFakeDirCreateTimes,
4251 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4254 .label = "panic action",
4256 .p_class = P_GLOBAL,
4257 .ptr = &Globals.szPanicAction,
4260 .flags = FLAG_ADVANCED,
4263 .label = "perfcount module",
4265 .p_class = P_GLOBAL,
4266 .ptr = &Globals.szSMBPerfcountModule,
4269 .flags = FLAG_ADVANCED,
4272 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4275 .label = "vfs objects",
4278 .ptr = &sDefault.szVfsObjects,
4281 .flags = FLAG_ADVANCED | FLAG_SHARE,
4284 .label = "vfs object",
4287 .ptr = &sDefault.szVfsObjects,
4294 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4297 .label = "msdfs root",
4300 .ptr = &sDefault.bMSDfsRoot,
4303 .flags = FLAG_ADVANCED | FLAG_SHARE,
4306 .label = "msdfs proxy",
4309 .ptr = &sDefault.szMSDfsProxy,
4312 .flags = FLAG_ADVANCED | FLAG_SHARE,
4315 .label = "host msdfs",
4317 .p_class = P_GLOBAL,
4318 .ptr = &Globals.bHostMSDfs,
4321 .flags = FLAG_ADVANCED,
4324 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4327 .label = "passdb expand explicit",
4329 .p_class = P_GLOBAL,
4330 .ptr = &Globals.bPassdbExpandExplicit,
4333 .flags = FLAG_ADVANCED,
4336 .label = "idmap backend",
4338 .p_class = P_GLOBAL,
4339 .ptr = &Globals.szIdmapBackend,
4342 .flags = FLAG_ADVANCED,
4345 .label = "idmap alloc backend",
4347 .p_class = P_GLOBAL,
4348 .ptr = &Globals.szIdmapAllocBackend,
4351 .flags = FLAG_ADVANCED,
4354 .label = "idmap cache time",
4356 .p_class = P_GLOBAL,
4357 .ptr = &Globals.iIdmapCacheTime,
4360 .flags = FLAG_ADVANCED,
4363 .label = "idmap negative cache time",
4365 .p_class = P_GLOBAL,
4366 .ptr = &Globals.iIdmapNegativeCacheTime,
4369 .flags = FLAG_ADVANCED,
4372 .label = "idmap uid",
4374 .p_class = P_GLOBAL,
4375 .ptr = &Globals.szIdmapUID,
4376 .special = handle_idmap_uid,
4378 .flags = FLAG_ADVANCED,
4381 .label = "winbind uid",
4383 .p_class = P_GLOBAL,
4384 .ptr = &Globals.szIdmapUID,
4385 .special = handle_idmap_uid,
4390 .label = "idmap gid",
4392 .p_class = P_GLOBAL,
4393 .ptr = &Globals.szIdmapGID,
4394 .special = handle_idmap_gid,
4396 .flags = FLAG_ADVANCED,
4399 .label = "winbind gid",
4401 .p_class = P_GLOBAL,
4402 .ptr = &Globals.szIdmapGID,
4403 .special = handle_idmap_gid,
4408 .label = "template homedir",
4410 .p_class = P_GLOBAL,
4411 .ptr = &Globals.szTemplateHomedir,
4414 .flags = FLAG_ADVANCED,
4417 .label = "template shell",
4419 .p_class = P_GLOBAL,
4420 .ptr = &Globals.szTemplateShell,
4423 .flags = FLAG_ADVANCED,
4426 .label = "winbind separator",
4428 .p_class = P_GLOBAL,
4429 .ptr = &Globals.szWinbindSeparator,
4432 .flags = FLAG_ADVANCED,
4435 .label = "winbind cache time",
4437 .p_class = P_GLOBAL,
4438 .ptr = &Globals.winbind_cache_time,
4441 .flags = FLAG_ADVANCED,
4444 .label = "winbind reconnect delay",
4446 .p_class = P_GLOBAL,
4447 .ptr = &Globals.winbind_reconnect_delay,
4450 .flags = FLAG_ADVANCED,
4453 .label = "winbind enum users",
4455 .p_class = P_GLOBAL,
4456 .ptr = &Globals.bWinbindEnumUsers,
4459 .flags = FLAG_ADVANCED,
4462 .label = "winbind enum groups",
4464 .p_class = P_GLOBAL,
4465 .ptr = &Globals.bWinbindEnumGroups,
4468 .flags = FLAG_ADVANCED,
4471 .label = "winbind use default domain",
4473 .p_class = P_GLOBAL,
4474 .ptr = &Globals.bWinbindUseDefaultDomain,
4477 .flags = FLAG_ADVANCED,
4480 .label = "winbind trusted domains only",
4482 .p_class = P_GLOBAL,
4483 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4486 .flags = FLAG_ADVANCED,
4489 .label = "winbind nested groups",
4491 .p_class = P_GLOBAL,
4492 .ptr = &Globals.bWinbindNestedGroups,
4495 .flags = FLAG_ADVANCED,
4498 .label = "winbind expand groups",
4500 .p_class = P_GLOBAL,
4501 .ptr = &Globals.winbind_expand_groups,
4504 .flags = FLAG_ADVANCED,
4507 .label = "winbind nss info",
4509 .p_class = P_GLOBAL,
4510 .ptr = &Globals.szWinbindNssInfo,
4513 .flags = FLAG_ADVANCED,
4516 .label = "winbind refresh tickets",
4518 .p_class = P_GLOBAL,
4519 .ptr = &Globals.bWinbindRefreshTickets,
4522 .flags = FLAG_ADVANCED,
4525 .label = "winbind offline logon",
4527 .p_class = P_GLOBAL,
4528 .ptr = &Globals.bWinbindOfflineLogon,
4531 .flags = FLAG_ADVANCED,
4534 .label = "winbind normalize names",
4536 .p_class = P_GLOBAL,
4537 .ptr = &Globals.bWinbindNormalizeNames,
4540 .flags = FLAG_ADVANCED,
4543 .label = "winbind rpc only",
4545 .p_class = P_GLOBAL,
4546 .ptr = &Globals.bWinbindRpcOnly,
4549 .flags = FLAG_ADVANCED,
4552 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4555 /***************************************************************************
4556 Initialise the sDefault parameter structure for the printer values.
4557 ***************************************************************************/
4559 static void init_printer_values(struct service *pService)
4561 /* choose defaults depending on the type of printing */
4562 switch (pService->iPrinting) {
4567 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4568 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4569 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4574 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4575 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4576 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4577 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4578 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4579 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4580 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4586 /* set the lpq command to contain the destination printer
4587 name only. This is used by cups_queue_get() */
4588 string_set(&pService->szLpqcommand, "%p");
4589 string_set(&pService->szLprmcommand, "");
4590 string_set(&pService->szPrintcommand, "");
4591 string_set(&pService->szLppausecommand, "");
4592 string_set(&pService->szLpresumecommand, "");
4593 string_set(&pService->szQueuepausecommand, "");
4594 string_set(&pService->szQueueresumecommand, "");
4596 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4597 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4598 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4599 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4600 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4601 string_set(&pService->szQueuepausecommand, "disable '%p'");
4602 string_set(&pService->szQueueresumecommand, "enable '%p'");
4603 #endif /* HAVE_CUPS */
4608 string_set(&pService->szLpqcommand, "lpstat -o%p");
4609 string_set(&pService->szLprmcommand, "cancel %p-%j");
4610 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4611 string_set(&pService->szQueuepausecommand, "disable %p");
4612 string_set(&pService->szQueueresumecommand, "enable %p");
4614 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4615 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4620 string_set(&pService->szLpqcommand, "lpq -P%p");
4621 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4622 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4628 string_set(&pService->szPrintcommand, "vlp print %p %s");
4629 string_set(&pService->szLpqcommand, "vlp lpq %p");
4630 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4631 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4632 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4633 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4634 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4636 #endif /* DEVELOPER */
4642 * Common part of freeing allocated data for one parameter.
4644 static void free_one_parameter_common(void *parm_ptr,
4645 struct parm_struct parm)
4647 if ((parm.type == P_STRING) ||
4648 (parm.type == P_USTRING))
4650 string_free((char**)parm_ptr);
4651 } else if (parm.type == P_LIST) {
4652 TALLOC_FREE(*((char***)parm_ptr));
4657 * Free the allocated data for one parameter for a share
4658 * given as a service struct.
4660 static void free_one_parameter(struct service *service,
4661 struct parm_struct parm)
4665 if (parm.p_class != P_LOCAL) {
4669 parm_ptr = lp_local_ptr(service, parm.ptr);
4671 free_one_parameter_common(parm_ptr, parm);
4675 * Free the allocated parameter data of a share given
4676 * as a service struct.
4678 static void free_parameters(struct service *service)
4682 for (i=0; parm_table[i].label; i++) {
4683 free_one_parameter(service, parm_table[i]);
4688 * Free the allocated data for one parameter for a given share
4689 * specified by an snum.
4691 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4695 if (parm.ptr == NULL) {
4700 parm_ptr = parm.ptr;
4701 } else if (parm.p_class != P_LOCAL) {
4704 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4707 free_one_parameter_common(parm_ptr, parm);
4711 * Free the allocated parameter data for a share specified
4714 static void free_parameters_by_snum(int snum)
4718 for (i=0; parm_table[i].label; i++) {
4719 free_one_parameter_by_snum(snum, parm_table[i]);
4724 * Free the allocated global parameters.
4726 static void free_global_parameters(void)
4728 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4731 /***************************************************************************
4732 Initialise the global parameter structure.
4733 ***************************************************************************/
4735 static void init_globals(bool first_time_only)
4737 static bool done_init = False;
4741 /* If requested to initialize only once and we've already done it... */
4742 if (first_time_only && done_init) {
4743 /* ... then we have nothing more to do */
4748 /* The logfile can be set before this is invoked. Free it if so. */
4749 if (Globals.szLogFile != NULL) {
4750 string_free(&Globals.szLogFile);
4751 Globals.szLogFile = NULL;
4755 free_global_parameters();
4758 memset((void *)&Globals, '\0', sizeof(Globals));
4760 for (i = 0; parm_table[i].label; i++) {
4761 if ((parm_table[i].type == P_STRING ||
4762 parm_table[i].type == P_USTRING) &&
4765 string_set((char **)parm_table[i].ptr, "");
4769 string_set(&sDefault.fstype, FSTYPE_STRING);
4770 string_set(&sDefault.szPrintjobUsername, "%U");
4772 init_printer_values(&sDefault);
4775 DEBUG(3, ("Initialising global parameters\n"));
4777 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4778 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4780 /* use the new 'hash2' method by default, with a prefix of 1 */
4781 string_set(&Globals.szManglingMethod, "hash2");
4782 Globals.mangle_prefix = 1;
4784 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4786 /* using UTF8 by default allows us to support all chars */
4787 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4789 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4790 /* If the system supports nl_langinfo(), try to grab the value
4791 from the user's locale */
4792 string_set(&Globals.display_charset, "LOCALE");
4794 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4797 /* Use codepage 850 as a default for the dos character set */
4798 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4801 * Allow the default PASSWD_CHAT to be overridden in local.h.
4803 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4805 set_global_myname(myhostname());
4806 string_set(&Globals.szNetbiosName,global_myname());
4808 set_global_myworkgroup(WORKGROUP);
4809 string_set(&Globals.szWorkgroup, lp_workgroup());
4811 string_set(&Globals.szPasswdProgram, "");
4812 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4813 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4814 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4815 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4816 string_set(&Globals.szSocketAddress, "0.0.0.0");
4818 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4819 smb_panic("init_globals: ENOMEM");
4821 string_set(&Globals.szServerString, s);
4823 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4824 DEFAULT_MINOR_VERSION) < 0) {
4825 smb_panic("init_globals: ENOMEM");
4827 string_set(&Globals.szAnnounceVersion, s);
4830 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4833 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4835 string_set(&Globals.szLogonDrive, "");
4836 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4837 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4838 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4840 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4841 string_set(&Globals.szPasswordServer, "*");
4843 Globals.AlgorithmicRidBase = BASE_RID;
4845 Globals.bLoadPrinters = True;
4846 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4848 Globals.ConfigBackend = config_backend;
4850 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4851 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4852 Globals.max_xmit = 0x4104;
4853 Globals.max_mux = 50; /* This is *needed* for profile support. */
4854 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4855 Globals.bDisableSpoolss = False;
4856 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4857 Globals.pwordlevel = 0;
4858 Globals.unamelevel = 0;
4859 Globals.deadtime = 0;
4860 Globals.getwd_cache = true;
4861 Globals.bLargeReadwrite = True;
4862 Globals.max_log_size = 5000;
4863 Globals.max_open_files = MAX_OPEN_FILES;
4864 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4865 Globals.maxprotocol = PROTOCOL_NT1;
4866 Globals.minprotocol = PROTOCOL_CORE;
4867 Globals.security = SEC_USER;
4868 Globals.paranoid_server_security = True;
4869 Globals.bEncryptPasswords = True;
4870 Globals.bUpdateEncrypt = False;
4871 Globals.clientSchannel = Auto;
4872 Globals.serverSchannel = Auto;
4873 Globals.bReadRaw = True;
4874 Globals.bWriteRaw = True;
4875 Globals.bNullPasswords = False;
4876 Globals.bObeyPamRestrictions = False;
4878 Globals.bSyslogOnly = False;
4879 Globals.bTimestampLogs = True;
4880 string_set(&Globals.szLogLevel, "0");
4881 Globals.bDebugPrefixTimestamp = False;
4882 Globals.bDebugHiresTimestamp = False;
4883 Globals.bDebugPid = False;
4884 Globals.bDebugUid = False;
4885 Globals.bDebugClass = False;
4886 Globals.bEnableCoreFiles = True;
4887 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4888 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4889 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4890 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4891 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4892 Globals.lm_interval = 60;
4893 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4894 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4895 Globals.bNISHomeMap = False;
4896 #ifdef WITH_NISPLUS_HOME
4897 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4899 string_set(&Globals.szNISHomeMapName, "auto.home");
4902 Globals.bTimeServer = False;
4903 Globals.bBindInterfacesOnly = False;
4904 Globals.bUnixPasswdSync = False;
4905 Globals.bPamPasswordChange = False;
4906 Globals.bPasswdChatDebug = False;
4907 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4908 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4909 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4910 Globals.bStatCache = True; /* use stat cache by default */
4911 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4912 Globals.restrict_anonymous = 0;
4913 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4914 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4915 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4916 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4917 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4918 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4920 Globals.map_to_guest = 0; /* By Default, "Never" */
4921 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4922 Globals.enhanced_browsing = true;
4923 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4924 #ifdef MMAP_BLACKLIST
4925 Globals.bUseMmap = False;
4927 Globals.bUseMmap = True;
4929 Globals.bUnixExtensions = True;
4930 Globals.bResetOnZeroVC = False;
4932 /* hostname lookups can be very expensive and are broken on
4933 a large number of sites (tridge) */
4934 Globals.bHostnameLookups = False;
4936 string_set(&Globals.szPassdbBackend, "smbpasswd");
4937 string_set(&Globals.szLdapSuffix, "");
4938 string_set(&Globals.szLdapMachineSuffix, "");
4939 string_set(&Globals.szLdapUserSuffix, "");
4940 string_set(&Globals.szLdapGroupSuffix, "");
4941 string_set(&Globals.szLdapIdmapSuffix, "");
4943 string_set(&Globals.szLdapAdminDn, "");
4944 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4945 Globals.ldap_ssl_ads = False;
4946 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4947 Globals.ldap_delete_dn = False;
4948 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4949 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4950 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4951 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4953 Globals.ldap_debug_level = 0;
4954 Globals.ldap_debug_threshold = 10;
4956 /* This is what we tell the afs client. in reality we set the token
4957 * to never expire, though, when this runs out the afs client will
4958 * forget the token. Set to 0 to get NEVERDATE.*/
4959 Globals.iAfsTokenLifetime = 604800;
4960 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
4962 /* these parameters are set to defaults that are more appropriate
4963 for the increasing samba install base:
4965 as a member of the workgroup, that will possibly become a
4966 _local_ master browser (lm = True). this is opposed to a forced
4967 local master browser startup (pm = True).
4969 doesn't provide WINS server service by default (wsupp = False),
4970 and doesn't provide domain master browser services by default, either.
4974 Globals.bMsAddPrinterWizard = True;
4975 Globals.os_level = 20;
4976 Globals.bLocalMaster = True;
4977 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4978 Globals.bDomainLogons = False;
4979 Globals.bBrowseList = True;
4980 Globals.bWINSsupport = False;
4981 Globals.bWINSproxy = False;
4983 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
4984 Globals.InitLogonDelay = 100; /* 100 ms default delay */
4986 Globals.bDNSproxy = True;
4988 /* this just means to use them if they exist */
4989 Globals.bKernelOplocks = True;
4991 Globals.bAllowTrustedDomains = True;
4992 string_set(&Globals.szIdmapBackend, "tdb");
4994 string_set(&Globals.szTemplateShell, "/bin/false");
4995 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4996 string_set(&Globals.szWinbindSeparator, "\\");
4998 string_set(&Globals.szCupsServer, "");
4999 string_set(&Globals.szIPrintServer, "");
5001 string_set(&Globals.ctdbdSocket, "");
5002 Globals.szClusterAddresses = NULL;
5003 Globals.clustering = False;
5005 Globals.winbind_cache_time = 300; /* 5 minutes */
5006 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5007 Globals.bWinbindEnumUsers = False;
5008 Globals.bWinbindEnumGroups = False;
5009 Globals.bWinbindUseDefaultDomain = False;
5010 Globals.bWinbindTrustedDomainsOnly = False;
5011 Globals.bWinbindNestedGroups = True;
5012 Globals.winbind_expand_groups = 1;
5013 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5014 Globals.bWinbindRefreshTickets = False;
5015 Globals.bWinbindOfflineLogon = False;
5017 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5018 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5020 Globals.bPassdbExpandExplicit = False;
5022 Globals.name_cache_timeout = 660; /* In seconds */
5024 Globals.bUseSpnego = True;
5025 Globals.bClientUseSpnego = True;
5027 Globals.client_signing = Auto;
5028 Globals.server_signing = False;
5030 Globals.bDeferSharingViolations = True;
5031 string_set(&Globals.smb_ports, SMB_PORTS);
5033 Globals.bEnablePrivileges = True;
5034 Globals.bHostMSDfs = True;
5035 Globals.bASUSupport = False;
5037 /* User defined shares. */
5038 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5039 smb_panic("init_globals: ENOMEM");
5041 string_set(&Globals.szUsersharePath, s);
5043 string_set(&Globals.szUsershareTemplateShare, "");
5044 Globals.iUsershareMaxShares = 0;
5045 /* By default disallow sharing of directories not owned by the sharer. */
5046 Globals.bUsershareOwnerOnly = True;
5047 /* By default disallow guest access to usershares. */
5048 Globals.bUsershareAllowGuests = False;
5050 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5052 /* By default no shares out of the registry */
5053 Globals.bRegistryShares = False;
5055 Globals.iminreceivefile = 0;
5058 /*******************************************************************
5059 Convenience routine to grab string parameters into temporary memory
5060 and run standard_sub_basic on them. The buffers can be written to by
5061 callers without affecting the source string.
5062 ********************************************************************/
5064 static char *lp_string(const char *s)
5067 TALLOC_CTX *ctx = talloc_tos();
5069 /* The follow debug is useful for tracking down memory problems
5070 especially if you have an inner loop that is calling a lp_*()
5071 function that returns a string. Perhaps this debug should be
5072 present all the time? */
5075 DEBUG(10, ("lp_string(%s)\n", s));
5078 ret = talloc_sub_basic(ctx,
5079 get_current_username(),
5080 current_user_info.domain,
5082 if (trim_char(ret, '\"', '\"')) {
5083 if (strchr(ret,'\"') != NULL) {
5085 ret = talloc_sub_basic(ctx,
5086 get_current_username(),
5087 current_user_info.domain,
5095 In this section all the functions that are used to access the
5096 parameters from the rest of the program are defined
5099 #define FN_GLOBAL_STRING(fn_name,ptr) \
5100 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5101 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5102 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5103 #define FN_GLOBAL_LIST(fn_name,ptr) \
5104 const char **fn_name(void) {return(*(const char ***)(ptr));}
5105 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5106 bool fn_name(void) {return(*(bool *)(ptr));}
5107 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5108 char fn_name(void) {return(*(char *)(ptr));}
5109 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5110 int fn_name(void) {return(*(int *)(ptr));}
5112 #define FN_LOCAL_STRING(fn_name,val) \
5113 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5114 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5115 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5116 #define FN_LOCAL_LIST(fn_name,val) \
5117 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5118 #define FN_LOCAL_BOOL(fn_name,val) \
5119 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5120 #define FN_LOCAL_INTEGER(fn_name,val) \
5121 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5123 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5124 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5125 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5126 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5127 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5128 char *fn_name(const struct share_params *p) {return(lp_string((LP_SNUM_OK(p->service) && ServicePtrs[(p->service)]->val) ? ServicePtrs[(p->service)]->val : sDefault.val));}
5129 #define FN_LOCAL_CHAR(fn_name,val) \
5130 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5132 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5133 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5134 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5135 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5136 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5137 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5138 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5139 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5140 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5141 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5142 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5143 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5144 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5145 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5146 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5147 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5148 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5149 * build process or in smb.conf, we use that value. Otherwise they
5150 * default to the value of lp_lockdir(). */
5151 char *lp_statedir(void) {
5152 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5153 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5154 return(lp_string(*(char **)(&Globals.szStateDir) ?
5155 *(char **)(&Globals.szStateDir) : ""));
5157 return(lp_string(*(char **)(&Globals.szLockDir) ?
5158 *(char **)(&Globals.szLockDir) : ""));
5160 char *lp_cachedir(void) {
5161 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5162 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5163 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5164 *(char **)(&Globals.szCacheDir) : ""));
5166 return(lp_string(*(char **)(&Globals.szLockDir) ?
5167 *(char **)(&Globals.szLockDir) : ""));
5169 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5170 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5171 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5172 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5173 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5174 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5175 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5176 FN_GLOBAL_STRING(lp_smb_perfcount_module, &Globals.szSMBPerfcountModule)
5177 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5178 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5179 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5180 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5181 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5182 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5183 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5184 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5185 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5186 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5187 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5188 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5189 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5190 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5191 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5192 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5193 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5194 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5195 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5196 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5197 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5198 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5199 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5200 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5201 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5202 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5203 * lp_passdb_backend() should be replace by the this macro again after
5206 const char *lp_passdb_backend(void)
5208 char *delim, *quote;
5210 delim = strchr( Globals.szPassdbBackend, ' ');
5211 /* no space at all */
5212 if (delim == NULL) {
5216 quote = strchr(Globals.szPassdbBackend, '"');
5217 /* no quote char or non in the first part */
5218 if (quote == NULL || quote > delim) {
5223 quote = strchr(quote+1, '"');
5224 if (quote == NULL) {
5225 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5227 } else if (*(quote+1) == '\0') {
5228 /* space, fitting quote char, and one backend only */
5231 /* terminate string after the fitting quote char */
5236 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5237 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5238 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5239 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5242 return Globals.szPassdbBackend;
5244 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5245 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5246 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5247 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5248 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5250 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5251 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5252 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5253 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5254 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5255 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5257 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5259 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5260 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5261 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5263 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5265 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5266 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5267 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5268 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5269 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5270 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5271 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5272 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5273 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5274 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5275 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5276 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5277 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5278 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5279 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5281 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5282 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5283 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5284 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5285 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5286 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5288 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5289 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5290 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5291 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5292 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5293 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5294 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5295 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5296 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5297 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5298 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5299 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5300 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5301 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5302 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5303 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5304 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5305 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5307 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5309 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5310 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5311 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5312 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5313 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5314 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5315 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5316 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5317 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5318 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5319 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5320 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5321 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5322 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5323 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5324 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5325 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5326 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5327 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5328 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5329 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5330 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5331 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5332 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5333 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5334 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5335 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5336 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5337 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5338 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5339 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5340 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5341 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5342 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5343 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5344 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5345 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5346 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5347 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5348 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5349 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5350 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5351 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5352 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5353 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5354 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5355 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5356 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5357 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5358 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5359 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5360 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5361 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5362 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5363 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5364 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5365 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5366 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5367 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5368 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5369 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5370 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5371 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5372 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5373 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5374 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5375 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5376 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5377 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5378 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5379 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5380 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5381 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5382 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5383 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5384 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5385 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5386 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5387 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5388 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5389 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5390 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5391 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5392 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5393 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5394 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5395 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5396 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5397 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5398 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5399 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5400 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5401 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5402 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5403 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5404 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5405 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5406 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5407 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5409 FN_LOCAL_STRING(lp_preexec, szPreExec)
5410 FN_LOCAL_STRING(lp_postexec, szPostExec)
5411 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5412 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5413 FN_LOCAL_STRING(lp_servicename, szService)
5414 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5415 FN_LOCAL_STRING(lp_pathname, szPath)
5416 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5417 FN_LOCAL_STRING(lp_username, szUsername)
5418 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5419 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5420 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5421 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5422 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5423 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5424 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5425 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5426 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5427 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5428 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5429 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5430 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5431 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5432 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5433 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5434 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5435 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5436 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5437 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5438 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5439 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5440 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5441 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5442 FN_LOCAL_STRING(lp_comment, comment)
5443 FN_LOCAL_STRING(lp_force_user, force_user)
5444 FN_LOCAL_STRING(lp_force_group, force_group)
5445 FN_LOCAL_LIST(lp_readlist, readlist)
5446 FN_LOCAL_LIST(lp_writelist, writelist)
5447 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5448 FN_LOCAL_STRING(lp_fstype, fstype)
5449 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5450 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5451 static FN_LOCAL_STRING(lp_volume, volume)
5452 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5453 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5454 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5455 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5456 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5457 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5458 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5459 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5460 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5461 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5462 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5463 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5464 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5465 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5466 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5467 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5468 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5469 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5470 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5471 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5472 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5473 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5474 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5475 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5476 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5477 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5478 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5479 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5480 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5481 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5482 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5483 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5484 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5485 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5486 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5487 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5488 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5489 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5490 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5491 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5492 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5493 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5494 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5495 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5496 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5497 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5498 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5499 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5500 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5501 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5502 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5503 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5504 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5505 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5506 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5507 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5508 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5509 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5510 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5511 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5512 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5513 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5514 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5515 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5516 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5517 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5518 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5519 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5520 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5521 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5522 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5523 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5524 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5525 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5526 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5527 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5528 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5529 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5530 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5531 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5532 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5533 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5534 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5535 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5536 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5537 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5538 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5539 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5540 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5541 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5542 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5543 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5544 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5545 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5546 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5547 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5548 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5549 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5550 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5552 /* local prototypes */
5554 static int map_parameter(const char *pszParmName);
5555 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5556 static const char *get_boolean(bool bool_value);
5557 static int getservicebyname(const char *pszServiceName,
5558 struct service *pserviceDest);
5559 static void copy_service(struct service *pserviceDest,
5560 struct service *pserviceSource,
5561 struct bitmap *pcopymapDest);
5562 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5564 static bool do_section(const char *pszSectionName, void *userdata);
5565 static void init_copymap(struct service *pservice);
5566 static bool hash_a_service(const char *name, int number);
5567 static void free_service_byindex(int iService);
5568 static void free_param_opts(struct param_opt_struct **popts);
5569 static char * canonicalize_servicename(const char *name);
5570 static void show_parameter(int parmIndex);
5571 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5574 * This is a helper function for parametrical options support. It returns a
5575 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5576 * parametrical functions are quite simple
5578 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5581 bool global_section = False;
5583 struct param_opt_struct *data;
5585 if (snum >= iNumServices) return NULL;
5588 data = Globals.param_opt;
5589 global_section = True;
5591 data = ServicePtrs[snum]->param_opt;
5594 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5595 DEBUG(0,("asprintf failed!\n"));
5600 if (strwicmp(data->key, param_key) == 0) {
5601 string_free(¶m_key);
5607 if (!global_section) {
5608 /* Try to fetch the same option but from globals */
5609 /* but only if we are not already working with Globals */
5610 data = Globals.param_opt;
5612 if (strwicmp(data->key, param_key) == 0) {
5613 string_free(¶m_key);
5620 string_free(¶m_key);
5626 #define MISSING_PARAMETER(name) \
5627 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5629 /*******************************************************************
5630 convenience routine to return int parameters.
5631 ********************************************************************/
5632 static int lp_int(const char *s)
5636 MISSING_PARAMETER(lp_int);
5640 return (int)strtol(s, NULL, 0);
5643 /*******************************************************************
5644 convenience routine to return unsigned long parameters.
5645 ********************************************************************/
5646 static unsigned long lp_ulong(const char *s)
5650 MISSING_PARAMETER(lp_ulong);
5654 return strtoul(s, NULL, 0);
5657 /*******************************************************************
5658 convenience routine to return boolean parameters.
5659 ********************************************************************/
5660 static bool lp_bool(const char *s)
5665 MISSING_PARAMETER(lp_bool);
5669 if (!set_boolean(s, &ret)) {
5670 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5677 /*******************************************************************
5678 convenience routine to return enum parameters.
5679 ********************************************************************/
5680 static int lp_enum(const char *s,const struct enum_list *_enum)
5684 if (!s || !*s || !_enum) {
5685 MISSING_PARAMETER(lp_enum);
5689 for (i=0; _enum[i].name; i++) {
5690 if (strequal(_enum[i].name,s))
5691 return _enum[i].value;
5694 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5698 #undef MISSING_PARAMETER
5700 /* DO NOT USE lp_parm_string ANYMORE!!!!
5701 * use lp_parm_const_string or lp_parm_talloc_string
5703 * lp_parm_string is only used to let old modules find this symbol
5705 #undef lp_parm_string
5706 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5707 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5709 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5712 /* Return parametric option from a given service. Type is a part of option before ':' */
5713 /* Parametric option has following syntax: 'Type: option = value' */
5714 /* the returned value is talloced on the talloc_tos() */
5715 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5717 struct param_opt_struct *data = get_parametrics(snum, type, option);
5719 if (data == NULL||data->value==NULL) {
5721 return lp_string(def);
5727 return lp_string(data->value);
5730 /* Return parametric option from a given service. Type is a part of option before ':' */
5731 /* Parametric option has following syntax: 'Type: option = value' */
5732 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5734 struct param_opt_struct *data = get_parametrics(snum, type, option);
5736 if (data == NULL||data->value==NULL)
5742 /* Return parametric option from a given service. Type is a part of option before ':' */
5743 /* Parametric option has following syntax: 'Type: option = value' */
5745 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5747 struct param_opt_struct *data = get_parametrics(snum, type, option);
5749 if (data == NULL||data->value==NULL)
5750 return (const char **)def;
5752 if (data->list==NULL) {
5753 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5756 return (const char **)data->list;
5759 /* Return parametric option from a given service. Type is a part of option before ':' */
5760 /* Parametric option has following syntax: 'Type: option = value' */
5762 int lp_parm_int(int snum, const char *type, const char *option, int def)
5764 struct param_opt_struct *data = get_parametrics(snum, type, option);
5766 if (data && data->value && *data->value)
5767 return lp_int(data->value);
5772 /* Return parametric option from a given service. Type is a part of option before ':' */
5773 /* Parametric option has following syntax: 'Type: option = value' */
5775 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5777 struct param_opt_struct *data = get_parametrics(snum, type, option);
5779 if (data && data->value && *data->value)
5780 return lp_ulong(data->value);
5785 /* Return parametric option from a given service. Type is a part of option before ':' */
5786 /* Parametric option has following syntax: 'Type: option = value' */
5788 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5790 struct param_opt_struct *data = get_parametrics(snum, type, option);
5792 if (data && data->value && *data->value)
5793 return lp_bool(data->value);
5798 /* Return parametric option from a given service. Type is a part of option before ':' */
5799 /* Parametric option has following syntax: 'Type: option = value' */
5801 int lp_parm_enum(int snum, const char *type, const char *option,
5802 const struct enum_list *_enum, int def)
5804 struct param_opt_struct *data = get_parametrics(snum, type, option);
5806 if (data && data->value && *data->value && _enum)
5807 return lp_enum(data->value, _enum);
5813 /***************************************************************************
5814 Initialise a service to the defaults.
5815 ***************************************************************************/
5817 static void init_service(struct service *pservice)
5819 memset((char *)pservice, '\0', sizeof(struct service));
5820 copy_service(pservice, &sDefault, NULL);
5825 * free a param_opts structure.
5826 * param_opts handling should be moved to talloc;
5827 * then this whole functions reduces to a TALLOC_FREE().
5830 static void free_param_opts(struct param_opt_struct **popts)
5832 struct param_opt_struct *opt, *next_opt;
5834 if (popts == NULL) {
5838 if (*popts != NULL) {
5839 DEBUG(5, ("Freeing parametrics:\n"));
5842 while (opt != NULL) {
5843 string_free(&opt->key);
5844 string_free(&opt->value);
5845 TALLOC_FREE(opt->list);
5846 next_opt = opt->next;
5853 /***************************************************************************
5854 Free the dynamically allocated parts of a service struct.
5855 ***************************************************************************/
5857 static void free_service(struct service *pservice)
5862 if (pservice->szService)
5863 DEBUG(5, ("free_service: Freeing service %s\n",
5864 pservice->szService));
5866 free_parameters(pservice);
5868 string_free(&pservice->szService);
5869 bitmap_free(pservice->copymap);
5871 free_param_opts(&pservice->param_opt);
5873 ZERO_STRUCTP(pservice);
5877 /***************************************************************************
5878 remove a service indexed in the ServicePtrs array from the ServiceHash
5879 and free the dynamically allocated parts
5880 ***************************************************************************/
5882 static void free_service_byindex(int idx)
5884 if ( !LP_SNUM_OK(idx) )
5887 ServicePtrs[idx]->valid = False;
5888 invalid_services[num_invalid_services++] = idx;
5890 /* we have to cleanup the hash record */
5892 if (ServicePtrs[idx]->szService) {
5893 char *canon_name = canonicalize_servicename(
5894 ServicePtrs[idx]->szService );
5896 dbwrap_delete_bystring(ServiceHash, canon_name );
5897 TALLOC_FREE(canon_name);
5900 free_service(ServicePtrs[idx]);
5903 /***************************************************************************
5904 Add a new service to the services array initialising it with the given
5906 ***************************************************************************/
5908 static int add_a_service(const struct service *pservice, const char *name)
5911 struct service tservice;
5912 int num_to_alloc = iNumServices + 1;
5914 tservice = *pservice;
5916 /* it might already exist */
5918 i = getservicebyname(name, NULL);
5920 /* Clean all parametric options for service */
5921 /* They will be added during parsing again */
5922 free_param_opts(&ServicePtrs[i]->param_opt);
5927 /* find an invalid one */
5929 if (num_invalid_services > 0) {
5930 i = invalid_services[--num_invalid_services];
5933 /* if not, then create one */
5934 if (i == iNumServices) {
5935 struct service **tsp;
5938 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5940 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5944 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5945 if (!ServicePtrs[iNumServices]) {
5946 DEBUG(0,("add_a_service: out of memory!\n"));
5951 /* enlarge invalid_services here for now... */
5952 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5954 if (tinvalid == NULL) {
5955 DEBUG(0,("add_a_service: failed to enlarge "
5956 "invalid_services!\n"));
5959 invalid_services = tinvalid;
5961 free_service_byindex(i);
5964 ServicePtrs[i]->valid = True;
5966 init_service(ServicePtrs[i]);
5967 copy_service(ServicePtrs[i], &tservice, NULL);
5969 string_set(&ServicePtrs[i]->szService, name);
5971 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5972 i, ServicePtrs[i]->szService));
5974 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5981 /***************************************************************************
5982 Convert a string to uppercase and remove whitespaces.
5983 ***************************************************************************/
5985 static char *canonicalize_servicename(const char *src)
5990 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5994 result = talloc_strdup(talloc_tos(), src);
5995 SMB_ASSERT(result != NULL);
6001 /***************************************************************************
6002 Add a name/index pair for the services array to the hash table.
6003 ***************************************************************************/
6005 static bool hash_a_service(const char *name, int idx)
6009 if ( !ServiceHash ) {
6010 DEBUG(10,("hash_a_service: creating servicehash\n"));
6011 ServiceHash = db_open_rbt(NULL);
6012 if ( !ServiceHash ) {
6013 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6018 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6021 canon_name = canonicalize_servicename( name );
6023 dbwrap_store_bystring(ServiceHash, canon_name,
6024 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6027 TALLOC_FREE(canon_name);
6032 /***************************************************************************
6033 Add a new home service, with the specified home directory, defaults coming
6035 ***************************************************************************/
6037 bool lp_add_home(const char *pszHomename, int iDefaultService,
6038 const char *user, const char *pszHomedir)
6042 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6047 if (!(*(ServicePtrs[iDefaultService]->szPath))
6048 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6049 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6052 if (!(*(ServicePtrs[i]->comment))) {
6053 char *comment = NULL;
6054 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6057 string_set(&ServicePtrs[i]->comment, comment);
6061 /* set the browseable flag from the global default */
6063 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6064 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6066 ServicePtrs[i]->autoloaded = True;
6068 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6069 user, ServicePtrs[i]->szPath ));
6074 /***************************************************************************
6075 Add a new service, based on an old one.
6076 ***************************************************************************/
6078 int lp_add_service(const char *pszService, int iDefaultService)
6080 if (iDefaultService < 0) {
6081 return add_a_service(&sDefault, pszService);
6084 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6087 /***************************************************************************
6088 Add the IPC service.
6089 ***************************************************************************/
6091 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6093 char *comment = NULL;
6094 int i = add_a_service(&sDefault, ipc_name);
6099 if (asprintf(&comment, "IPC Service (%s)",
6100 Globals.szServerString) < 0) {
6104 string_set(&ServicePtrs[i]->szPath, tmpdir());
6105 string_set(&ServicePtrs[i]->szUsername, "");
6106 string_set(&ServicePtrs[i]->comment, comment);
6107 string_set(&ServicePtrs[i]->fstype, "IPC");
6108 ServicePtrs[i]->iMaxConnections = 0;
6109 ServicePtrs[i]->bAvailable = True;
6110 ServicePtrs[i]->bRead_only = True;
6111 ServicePtrs[i]->bGuest_only = False;
6112 ServicePtrs[i]->bAdministrative_share = True;
6113 ServicePtrs[i]->bGuest_ok = guest_ok;
6114 ServicePtrs[i]->bPrint_ok = False;
6115 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6117 DEBUG(3, ("adding IPC service\n"));
6123 /***************************************************************************
6124 Add a new printer service, with defaults coming from service iFrom.
6125 ***************************************************************************/
6127 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6129 const char *comment = "From Printcap";
6130 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6135 /* note that we do NOT default the availability flag to True - */
6136 /* we take it from the default service passed. This allows all */
6137 /* dynamic printers to be disabled by disabling the [printers] */
6138 /* entry (if/when the 'available' keyword is implemented!). */
6140 /* the printer name is set to the service name. */
6141 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6142 string_set(&ServicePtrs[i]->comment, comment);
6144 /* set the browseable flag from the gloabl default */
6145 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6147 /* Printers cannot be read_only. */
6148 ServicePtrs[i]->bRead_only = False;
6149 /* No share modes on printer services. */
6150 ServicePtrs[i]->bShareModes = False;
6151 /* No oplocks on printer services. */
6152 ServicePtrs[i]->bOpLocks = False;
6153 /* Printer services must be printable. */
6154 ServicePtrs[i]->bPrint_ok = True;
6156 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6162 /***************************************************************************
6163 Check whether the given parameter name is valid.
6164 Parametric options (names containing a colon) are considered valid.
6165 ***************************************************************************/
6167 bool lp_parameter_is_valid(const char *pszParmName)
6169 return ((map_parameter(pszParmName) != -1) ||
6170 (strchr(pszParmName, ':') != NULL));
6173 /***************************************************************************
6174 Check whether the given name is the name of a global parameter.
6175 Returns True for strings belonging to parameters of class
6176 P_GLOBAL, False for all other strings, also for parametric options
6177 and strings not belonging to any option.
6178 ***************************************************************************/
6180 bool lp_parameter_is_global(const char *pszParmName)
6182 int num = map_parameter(pszParmName);
6185 return (parm_table[num].p_class == P_GLOBAL);
6191 /**************************************************************************
6192 Check whether the given name is the canonical name of a parameter.
6193 Returns False if it is not a valid parameter Name.
6194 For parametric options, True is returned.
6195 **************************************************************************/
6197 bool lp_parameter_is_canonical(const char *parm_name)
6199 if (!lp_parameter_is_valid(parm_name)) {
6203 return (map_parameter(parm_name) ==
6204 map_parameter_canonical(parm_name, NULL));
6207 /**************************************************************************
6208 Determine the canonical name for a parameter.
6209 Indicate when it is an inverse (boolean) synonym instead of a
6211 **************************************************************************/
6213 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6218 if (!lp_parameter_is_valid(parm_name)) {
6223 num = map_parameter_canonical(parm_name, inverse);
6225 /* parametric option */
6226 *canon_parm = parm_name;
6228 *canon_parm = parm_table[num].label;
6235 /**************************************************************************
6236 Determine the canonical name for a parameter.
6237 Turn the value given into the inverse boolean expression when
6238 the synonym is an invers boolean synonym.
6240 Return True if parm_name is a valid parameter name and
6241 in case it is an invers boolean synonym, if the val string could
6242 successfully be converted to the reverse bool.
6243 Return false in all other cases.
6244 **************************************************************************/
6246 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6248 const char **canon_parm,
6249 const char **canon_val)
6254 if (!lp_parameter_is_valid(parm_name)) {
6260 num = map_parameter_canonical(parm_name, &inverse);
6262 /* parametric option */
6263 *canon_parm = parm_name;
6266 *canon_parm = parm_table[num].label;
6268 if (!lp_invert_boolean(val, canon_val)) {
6280 /***************************************************************************
6281 Map a parameter's string representation to something we can use.
6282 Returns False if the parameter string is not recognised, else TRUE.
6283 ***************************************************************************/
6285 static int map_parameter(const char *pszParmName)
6289 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6292 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6293 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6296 /* Warn only if it isn't parametric option */
6297 if (strchr(pszParmName, ':') == NULL)
6298 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6299 /* We do return 'fail' for parametric options as well because they are
6300 stored in different storage
6305 /***************************************************************************
6306 Map a parameter's string representation to the index of the canonical
6307 form of the parameter (it might be a synonym).
6308 Returns -1 if the parameter string is not recognised.
6309 ***************************************************************************/
6311 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6313 int parm_num, canon_num;
6314 bool loc_inverse = False;
6316 parm_num = map_parameter(pszParmName);
6317 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6318 /* invalid, parametric or no canidate for synonyms ... */
6322 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6323 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6324 parm_num = canon_num;
6330 if (inverse != NULL) {
6331 *inverse = loc_inverse;
6336 /***************************************************************************
6337 return true if parameter number parm1 is a synonym of parameter
6338 number parm2 (parm2 being the principal name).
6339 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6341 ***************************************************************************/
6343 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6345 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6346 (parm_table[parm1].flags & FLAG_HIDE) &&
6347 !(parm_table[parm2].flags & FLAG_HIDE))
6349 if (inverse != NULL) {
6350 if ((parm_table[parm1].type == P_BOOLREV) &&
6351 (parm_table[parm2].type == P_BOOL))
6363 /***************************************************************************
6364 Show one parameter's name, type, [values,] and flags.
6365 (helper functions for show_parameter_list)
6366 ***************************************************************************/
6368 static void show_parameter(int parmIndex)
6370 int enumIndex, flagIndex;
6375 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6376 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6378 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6379 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6380 FLAG_HIDE, FLAG_DOS_STRING};
6381 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6382 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6383 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6385 printf("%s=%s", parm_table[parmIndex].label,
6386 type[parm_table[parmIndex].type]);
6387 if (parm_table[parmIndex].type == P_ENUM) {
6390 parm_table[parmIndex].enum_list[enumIndex].name;
6394 enumIndex ? "|" : "",
6395 parm_table[parmIndex].enum_list[enumIndex].name);
6400 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6401 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6404 flag_names[flagIndex]);
6409 /* output synonyms */
6411 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6412 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6413 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6414 parm_table[parmIndex2].label);
6415 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6417 printf(" (synonyms: ");
6422 printf("%s%s", parm_table[parmIndex2].label,
6423 inverse ? "[i]" : "");
6433 /***************************************************************************
6434 Show all parameter's name, type, [values,] and flags.
6435 ***************************************************************************/
6437 void show_parameter_list(void)
6439 int classIndex, parmIndex;
6440 const char *section_names[] = { "local", "global", NULL};
6442 for (classIndex=0; section_names[classIndex]; classIndex++) {
6443 printf("[%s]\n", section_names[classIndex]);
6444 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6445 if (parm_table[parmIndex].p_class == classIndex) {
6446 show_parameter(parmIndex);
6452 /***************************************************************************
6453 Check if a given string correctly represents a boolean value.
6454 ***************************************************************************/
6456 bool lp_string_is_valid_boolean(const char *parm_value)
6458 return set_boolean(parm_value, NULL);
6461 /***************************************************************************
6462 Get the standard string representation of a boolean value ("yes" or "no")
6463 ***************************************************************************/
6465 static const char *get_boolean(bool bool_value)
6467 static const char *yes_str = "yes";
6468 static const char *no_str = "no";
6470 return (bool_value ? yes_str : no_str);
6473 /***************************************************************************
6474 Provide the string of the negated boolean value associated to the boolean
6475 given as a string. Returns False if the passed string does not correctly
6476 represent a boolean.
6477 ***************************************************************************/
6479 bool lp_invert_boolean(const char *str, const char **inverse_str)
6483 if (!set_boolean(str, &val)) {
6487 *inverse_str = get_boolean(!val);
6491 /***************************************************************************
6492 Provide the canonical string representation of a boolean value given
6493 as a string. Return True on success, False if the string given does
6494 not correctly represent a boolean.
6495 ***************************************************************************/
6497 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6501 if (!set_boolean(str, &val)) {
6505 *canon_str = get_boolean(val);
6509 /***************************************************************************
6510 Find a service by name. Otherwise works like get_service.
6511 ***************************************************************************/
6513 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6519 if (ServiceHash == NULL) {
6523 canon_name = canonicalize_servicename(pszServiceName);
6525 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6527 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6528 iService = *(int *)data.dptr;
6531 TALLOC_FREE(canon_name);
6533 if ((iService != -1) && (LP_SNUM_OK(iService))
6534 && (pserviceDest != NULL)) {
6535 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6541 /***************************************************************************
6542 Copy a service structure to another.
6543 If pcopymapDest is NULL then copy all fields
6544 ***************************************************************************/
6547 * Add a parametric option to a param_opt_struct,
6548 * replacing old value, if already present.
6550 static void set_param_opt(struct param_opt_struct **opt_list,
6551 const char *opt_name,
6552 const char *opt_value)
6554 struct param_opt_struct *new_opt, *opt;
6557 if (opt_list == NULL) {
6564 /* Traverse destination */
6566 /* If we already have same option, override it */
6567 if (strwicmp(opt->key, opt_name) == 0) {
6568 string_free(&opt->value);
6569 TALLOC_FREE(opt->list);
6570 opt->value = SMB_STRDUP(opt_value);
6577 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6578 new_opt->key = SMB_STRDUP(opt_name);
6579 new_opt->value = SMB_STRDUP(opt_value);
6580 new_opt->list = NULL;
6581 DLIST_ADD(*opt_list, new_opt);
6585 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6586 struct bitmap *pcopymapDest)
6589 bool bcopyall = (pcopymapDest == NULL);
6590 struct param_opt_struct *data;
6592 for (i = 0; parm_table[i].label; i++)
6593 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6594 (bcopyall || bitmap_query(pcopymapDest,i))) {
6595 void *def_ptr = parm_table[i].ptr;
6597 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6600 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6603 switch (parm_table[i].type) {
6606 *(bool *)dest_ptr = *(bool *)src_ptr;
6612 *(int *)dest_ptr = *(int *)src_ptr;
6616 *(char *)dest_ptr = *(char *)src_ptr;
6620 string_set((char **)dest_ptr,
6625 string_set((char **)dest_ptr,
6627 strupper_m(*(char **)dest_ptr);
6630 TALLOC_FREE(*((char ***)dest_ptr));
6631 *((char ***)dest_ptr) = str_list_copy(NULL,
6632 *(const char ***)src_ptr);
6640 init_copymap(pserviceDest);
6641 if (pserviceSource->copymap)
6642 bitmap_copy(pserviceDest->copymap,
6643 pserviceSource->copymap);
6646 data = pserviceSource->param_opt;
6648 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6653 /***************************************************************************
6654 Check a service for consistency. Return False if the service is in any way
6655 incomplete or faulty, else True.
6656 ***************************************************************************/
6658 bool service_ok(int iService)
6663 if (ServicePtrs[iService]->szService[0] == '\0') {
6664 DEBUG(0, ("The following message indicates an internal error:\n"));
6665 DEBUG(0, ("No service name in service entry.\n"));
6669 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6670 /* I can't see why you'd want a non-printable printer service... */
6671 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6672 if (!ServicePtrs[iService]->bPrint_ok) {
6673 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6674 ServicePtrs[iService]->szService));
6675 ServicePtrs[iService]->bPrint_ok = True;
6677 /* [printers] service must also be non-browsable. */
6678 if (ServicePtrs[iService]->bBrowseable)
6679 ServicePtrs[iService]->bBrowseable = False;
6682 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6683 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6684 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6686 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6687 ServicePtrs[iService]->szService));
6688 ServicePtrs[iService]->bAvailable = False;
6691 /* If a service is flagged unavailable, log the fact at level 1. */
6692 if (!ServicePtrs[iService]->bAvailable)
6693 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6694 ServicePtrs[iService]->szService));
6699 static struct smbconf_ctx *lp_smbconf_ctx(void)
6702 static struct smbconf_ctx *conf_ctx = NULL;
6704 if (conf_ctx == NULL) {
6705 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6706 if (!W_ERROR_IS_OK(werr)) {
6707 DEBUG(1, ("error initializing registry configuration: "
6708 "%s\n", win_errstr(werr)));
6716 static bool process_smbconf_service(struct smbconf_service *service)
6721 if (service == NULL) {
6725 ret = do_section(service->name, NULL);
6729 for (count = 0; count < service->num_params; count++) {
6730 ret = do_parameter(service->param_names[count],
6731 service->param_values[count],
6741 * process_registry_globals
6743 static bool process_registry_globals(void)
6746 struct smbconf_service *service = NULL;
6747 TALLOC_CTX *mem_ctx = talloc_stackframe();
6748 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6751 if (conf_ctx == NULL) {
6755 ret = do_parameter("registry shares", "yes", NULL);
6760 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6761 /* nothing to read from the registry yet but make sure lp_load
6762 * doesn't return false */
6767 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6768 if (!W_ERROR_IS_OK(werr)) {
6772 ret = process_smbconf_service(service);
6778 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6781 TALLOC_FREE(mem_ctx);
6785 static bool process_registry_shares(void)
6789 struct smbconf_service **service = NULL;
6790 uint32_t num_shares = 0;
6791 TALLOC_CTX *mem_ctx = talloc_stackframe();
6792 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6795 if (conf_ctx == NULL) {
6799 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6800 if (!W_ERROR_IS_OK(werr)) {
6806 for (count = 0; count < num_shares; count++) {
6807 if (strequal(service[count]->name, GLOBAL_NAME)) {
6810 ret = process_smbconf_service(service[count]);
6817 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6820 TALLOC_FREE(mem_ctx);
6824 static struct file_lists {
6825 struct file_lists *next;
6829 } *file_lists = NULL;
6831 /*******************************************************************
6832 Keep a linked list of all config files so we know when one has changed
6833 it's date and needs to be reloaded.
6834 ********************************************************************/
6836 static void add_to_file_list(const char *fname, const char *subfname)
6838 struct file_lists *f = file_lists;
6841 if (f->name && !strcmp(f->name, fname))
6847 f = SMB_MALLOC_P(struct file_lists);
6850 f->next = file_lists;
6851 f->name = SMB_STRDUP(fname);
6856 f->subfname = SMB_STRDUP(subfname);
6862 f->modtime = file_modtime(subfname);
6864 time_t t = file_modtime(subfname);
6871 * Utility function for outsiders to check if we're running on registry.
6873 bool lp_config_backend_is_registry(void)
6875 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6879 * Utility function to check if the config backend is FILE.
6881 bool lp_config_backend_is_file(void)
6883 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6886 /*******************************************************************
6887 Check if a config file has changed date.
6888 ********************************************************************/
6890 bool lp_file_list_changed(void)
6892 struct file_lists *f = file_lists;
6894 DEBUG(6, ("lp_file_list_changed()\n"));
6896 if (lp_config_backend_is_registry()) {
6897 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6899 if (conf_ctx == NULL) {
6902 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6903 DEBUGADD(6, ("registry config changed\n"));
6912 n2 = alloc_sub_basic(get_current_username(),
6913 current_user_info.domain,
6918 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6919 f->name, n2, ctime(&f->modtime)));
6921 mod_time = file_modtime(n2);
6923 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6925 ("file %s modified: %s\n", n2,
6927 f->modtime = mod_time;
6928 SAFE_FREE(f->subfname);
6929 f->subfname = n2; /* Passing ownership of
6930 return from alloc_sub_basic
6941 /***************************************************************************
6942 Run standard_sub_basic on netbios name... needed because global_myname
6943 is not accessed through any lp_ macro.
6944 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6945 ***************************************************************************/
6947 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6950 char *netbios_name = alloc_sub_basic(get_current_username(),
6951 current_user_info.domain,
6954 ret = set_global_myname(netbios_name);
6955 SAFE_FREE(netbios_name);
6956 string_set(&Globals.szNetbiosName,global_myname());
6958 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6964 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6966 if (strcmp(*ptr, pszParmValue) != 0) {
6967 string_set(ptr, pszParmValue);
6975 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6979 ret = set_global_myworkgroup(pszParmValue);
6980 string_set(&Globals.szWorkgroup,lp_workgroup());
6985 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6989 ret = set_global_scope(pszParmValue);
6990 string_set(&Globals.szNetbiosScope,global_scope());
6995 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6997 TALLOC_FREE(Globals.szNetbiosAliases);
6998 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
6999 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7002 /***************************************************************************
7003 Handle the include operation.
7004 ***************************************************************************/
7005 static bool bAllowIncludeRegistry = true;
7007 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7011 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7012 if (!bAllowIncludeRegistry) {
7015 if (bInGlobalSection) {
7016 return process_registry_globals();
7018 DEBUG(1, ("\"include = registry\" only effective "
7019 "in %s section\n", GLOBAL_NAME));
7024 fname = alloc_sub_basic(get_current_username(),
7025 current_user_info.domain,
7028 add_to_file_list(pszParmValue, fname);
7030 string_set(ptr, fname);
7032 if (file_exist(fname)) {
7033 bool ret = pm_process(fname, do_section, do_parameter, NULL);
7038 DEBUG(2, ("Can't find include file %s\n", fname));
7043 /***************************************************************************
7044 Handle the interpretation of the copy parameter.
7045 ***************************************************************************/
7047 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7051 struct service serviceTemp;
7053 string_set(ptr, pszParmValue);
7055 init_service(&serviceTemp);
7059 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7061 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7062 if (iTemp == iServiceIndex) {
7063 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7065 copy_service(ServicePtrs[iServiceIndex],
7067 ServicePtrs[iServiceIndex]->copymap);
7071 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7075 free_service(&serviceTemp);
7079 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7081 Globals.ldap_debug_level = lp_int(pszParmValue);
7082 init_ldap_debugging();
7086 /***************************************************************************
7087 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7092 idmap uid = 1000-1999
7095 We only do simple parsing checks here. The strings are parsed into useful
7096 structures in the idmap daemon code.
7098 ***************************************************************************/
7100 /* Some lp_ routines to return idmap [ug]id information */
7102 static uid_t idmap_uid_low, idmap_uid_high;
7103 static gid_t idmap_gid_low, idmap_gid_high;
7105 bool lp_idmap_uid(uid_t *low, uid_t *high)
7107 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7111 *low = idmap_uid_low;
7114 *high = idmap_uid_high;
7119 bool lp_idmap_gid(gid_t *low, gid_t *high)
7121 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7125 *low = idmap_gid_low;
7128 *high = idmap_gid_high;
7133 /* Do some simple checks on "idmap [ug]id" parameter values */
7135 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7139 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7144 string_set(ptr, pszParmValue);
7146 idmap_uid_low = low;
7147 idmap_uid_high = high;
7152 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7156 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7161 string_set(ptr, pszParmValue);
7163 idmap_gid_low = low;
7164 idmap_gid_high = high;
7169 /***************************************************************************
7170 Handle the DEBUG level list.
7171 ***************************************************************************/
7173 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7175 string_set(ptr, pszParmValueIn);
7176 return debug_parse_levels(pszParmValueIn);
7179 /***************************************************************************
7180 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7181 ***************************************************************************/
7183 static const char *append_ldap_suffix( const char *str )
7185 const char *suffix_string;
7188 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7189 Globals.szLdapSuffix );
7190 if ( !suffix_string ) {
7191 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7195 return suffix_string;
7198 const char *lp_ldap_machine_suffix(void)
7200 if (Globals.szLdapMachineSuffix[0])
7201 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7203 return lp_string(Globals.szLdapSuffix);
7206 const char *lp_ldap_user_suffix(void)
7208 if (Globals.szLdapUserSuffix[0])
7209 return append_ldap_suffix(Globals.szLdapUserSuffix);
7211 return lp_string(Globals.szLdapSuffix);
7214 const char *lp_ldap_group_suffix(void)
7216 if (Globals.szLdapGroupSuffix[0])
7217 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7219 return lp_string(Globals.szLdapSuffix);
7222 const char *lp_ldap_idmap_suffix(void)
7224 if (Globals.szLdapIdmapSuffix[0])
7225 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7227 return lp_string(Globals.szLdapSuffix);
7230 /****************************************************************************
7231 set the value for a P_ENUM
7232 ***************************************************************************/
7234 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7239 for (i = 0; parm->enum_list[i].name; i++) {
7240 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7241 *ptr = parm->enum_list[i].value;
7245 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7246 pszParmValue, parm->label));
7249 /***************************************************************************
7250 ***************************************************************************/
7252 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7254 static int parm_num = -1;
7257 if ( parm_num == -1 )
7258 parm_num = map_parameter( "printing" );
7260 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7265 s = ServicePtrs[snum];
7267 init_printer_values( s );
7273 /***************************************************************************
7274 Initialise a copymap.
7275 ***************************************************************************/
7277 static void init_copymap(struct service *pservice)
7280 if (pservice->copymap) {
7281 bitmap_free(pservice->copymap);
7283 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7284 if (!pservice->copymap)
7286 ("Couldn't allocate copymap!! (size %d)\n",
7287 (int)NUMPARAMETERS));
7289 for (i = 0; i < NUMPARAMETERS; i++)
7290 bitmap_set(pservice->copymap, i);
7293 /***************************************************************************
7294 Return the local pointer to a parameter given a service struct and the
7295 pointer into the default structure.
7296 ***************************************************************************/
7298 static void *lp_local_ptr(struct service *service, void *ptr)
7300 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7303 /***************************************************************************
7304 Return the local pointer to a parameter given the service number and the
7305 pointer into the default structure.
7306 ***************************************************************************/
7308 void *lp_local_ptr_by_snum(int snum, void *ptr)
7310 return lp_local_ptr(ServicePtrs[snum], ptr);
7313 /***************************************************************************
7314 Process a parameter for a particular service number. If snum < 0
7315 then assume we are in the globals.
7316 ***************************************************************************/
7318 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7321 void *parm_ptr = NULL; /* where we are going to store the result */
7322 void *def_ptr = NULL;
7323 struct param_opt_struct **opt_list;
7325 parmnum = map_parameter(pszParmName);
7328 if (strchr(pszParmName, ':') == NULL) {
7329 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7335 * We've got a parametric option
7338 opt_list = (snum < 0)
7339 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7340 set_param_opt(opt_list, pszParmName, pszParmValue);
7345 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7346 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7350 def_ptr = parm_table[parmnum].ptr;
7352 /* we might point at a service, the default service or a global */
7356 if (parm_table[parmnum].p_class == P_GLOBAL) {
7358 ("Global parameter %s found in service section!\n",
7362 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7366 if (!ServicePtrs[snum]->copymap)
7367 init_copymap(ServicePtrs[snum]);
7369 /* this handles the aliases - set the copymap for other entries with
7370 the same data pointer */
7371 for (i = 0; parm_table[i].label; i++)
7372 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7373 bitmap_clear(ServicePtrs[snum]->copymap, i);
7376 /* if it is a special case then go ahead */
7377 if (parm_table[parmnum].special) {
7378 return parm_table[parmnum].special(snum, pszParmValue,
7382 /* now switch on the type of variable it is */
7383 switch (parm_table[parmnum].type)
7386 *(bool *)parm_ptr = lp_bool(pszParmValue);
7390 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7394 *(int *)parm_ptr = lp_int(pszParmValue);
7398 *(char *)parm_ptr = *pszParmValue;
7402 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7404 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7409 TALLOC_FREE(*((char ***)parm_ptr));
7410 *(char ***)parm_ptr = str_list_make_v3(
7411 talloc_autofree_context(), pszParmValue, NULL);
7415 string_set((char **)parm_ptr, pszParmValue);
7419 string_set((char **)parm_ptr, pszParmValue);
7420 strupper_m(*(char **)parm_ptr);
7424 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7433 /***************************************************************************
7434 Process a parameter.
7435 ***************************************************************************/
7437 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7440 if (!bInGlobalSection && bGlobalOnly)
7443 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7445 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7446 pszParmName, pszParmValue));
7449 /***************************************************************************
7450 Print a parameter of the specified type.
7451 ***************************************************************************/
7453 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7459 for (i = 0; p->enum_list[i].name; i++) {
7460 if (*(int *)ptr == p->enum_list[i].value) {
7462 p->enum_list[i].name);
7469 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7473 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7477 fprintf(f, "%d", *(int *)ptr);
7481 fprintf(f, "%c", *(char *)ptr);
7485 char *o = octal_string(*(int *)ptr);
7486 fprintf(f, "%s", o);
7492 if ((char ***)ptr && *(char ***)ptr) {
7493 char **list = *(char ***)ptr;
7494 for (; *list; list++) {
7495 /* surround strings with whitespace in double quotes */
7496 if ( strchr_m( *list, ' ' ) )
7497 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7499 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7506 if (*(char **)ptr) {
7507 fprintf(f, "%s", *(char **)ptr);
7515 /***************************************************************************
7516 Check if two parameters are equal.
7517 ***************************************************************************/
7519 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7524 return (*((bool *)ptr1) == *((bool *)ptr2));
7529 return (*((int *)ptr1) == *((int *)ptr2));
7532 return (*((char *)ptr1) == *((char *)ptr2));
7535 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7540 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7545 return (p1 == p2 || strequal(p1, p2));
7553 /***************************************************************************
7554 Initialize any local varients in the sDefault table.
7555 ***************************************************************************/
7557 void init_locals(void)
7562 /***************************************************************************
7563 Process a new section (service). At this stage all sections are services.
7564 Later we'll have special sections that permit server parameters to be set.
7565 Returns True on success, False on failure.
7566 ***************************************************************************/
7568 static bool do_section(const char *pszSectionName, void *userdata)
7571 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7572 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7575 /* if we were in a global section then do the local inits */
7576 if (bInGlobalSection && !isglobal)
7579 /* if we've just struck a global section, note the fact. */
7580 bInGlobalSection = isglobal;
7582 /* check for multiple global sections */
7583 if (bInGlobalSection) {
7584 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7588 if (!bInGlobalSection && bGlobalOnly)
7591 /* if we have a current service, tidy it up before moving on */
7594 if (iServiceIndex >= 0)
7595 bRetval = service_ok(iServiceIndex);
7597 /* if all is still well, move to the next record in the services array */
7599 /* We put this here to avoid an odd message order if messages are */
7600 /* issued by the post-processing of a previous section. */
7601 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7603 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7605 DEBUG(0, ("Failed to add a new service\n"));
7614 /***************************************************************************
7615 Determine if a partcular base parameter is currentl set to the default value.
7616 ***************************************************************************/
7618 static bool is_default(int i)
7620 if (!defaults_saved)
7622 switch (parm_table[i].type) {
7624 return str_list_equal((const char **)parm_table[i].def.lvalue,
7625 *(const char ***)parm_table[i].ptr);
7628 return strequal(parm_table[i].def.svalue,
7629 *(char **)parm_table[i].ptr);
7632 return parm_table[i].def.bvalue ==
7633 *(bool *)parm_table[i].ptr;
7635 return parm_table[i].def.cvalue ==
7636 *(char *)parm_table[i].ptr;
7640 return parm_table[i].def.ivalue ==
7641 *(int *)parm_table[i].ptr;
7648 /***************************************************************************
7649 Display the contents of the global structure.
7650 ***************************************************************************/
7652 static void dump_globals(FILE *f)
7655 struct param_opt_struct *data;
7657 fprintf(f, "[global]\n");
7659 for (i = 0; parm_table[i].label; i++)
7660 if (parm_table[i].p_class == P_GLOBAL &&
7661 parm_table[i].ptr &&
7662 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7663 if (defaults_saved && is_default(i))
7665 fprintf(f, "\t%s = ", parm_table[i].label);
7666 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7669 if (Globals.param_opt != NULL) {
7670 data = Globals.param_opt;
7672 fprintf(f, "\t%s = %s\n", data->key, data->value);
7679 /***************************************************************************
7680 Return True if a local parameter is currently set to the global default.
7681 ***************************************************************************/
7683 bool lp_is_default(int snum, struct parm_struct *parm)
7685 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7687 return equal_parameter(parm->type,
7688 ((char *)ServicePtrs[snum]) + pdiff,
7689 ((char *)&sDefault) + pdiff);
7692 /***************************************************************************
7693 Display the contents of a single services record.
7694 ***************************************************************************/
7696 static void dump_a_service(struct service *pService, FILE * f)
7699 struct param_opt_struct *data;
7701 if (pService != &sDefault)
7702 fprintf(f, "[%s]\n", pService->szService);
7704 for (i = 0; parm_table[i].label; i++) {
7706 if (parm_table[i].p_class == P_LOCAL &&
7707 parm_table[i].ptr &&
7708 (*parm_table[i].label != '-') &&
7709 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7712 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7714 if (pService == &sDefault) {
7715 if (defaults_saved && is_default(i))
7718 if (equal_parameter(parm_table[i].type,
7719 ((char *)pService) +
7721 ((char *)&sDefault) +
7726 fprintf(f, "\t%s = ", parm_table[i].label);
7727 print_parameter(&parm_table[i],
7728 ((char *)pService) + pdiff, f);
7733 if (pService->param_opt != NULL) {
7734 data = pService->param_opt;
7736 fprintf(f, "\t%s = %s\n", data->key, data->value);
7742 /***************************************************************************
7743 Display the contents of a parameter of a single services record.
7744 ***************************************************************************/
7746 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7749 bool result = False;
7752 fstring local_parm_name;
7754 const char *parm_opt_value;
7756 /* check for parametrical option */
7757 fstrcpy( local_parm_name, parm_name);
7758 parm_opt = strchr( local_parm_name, ':');
7763 if (strlen(parm_opt)) {
7764 parm_opt_value = lp_parm_const_string( snum,
7765 local_parm_name, parm_opt, NULL);
7766 if (parm_opt_value) {
7767 printf( "%s\n", parm_opt_value);
7774 /* check for a key and print the value */
7781 for (i = 0; parm_table[i].label; i++) {
7782 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7783 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7784 parm_table[i].ptr &&
7785 (*parm_table[i].label != '-') &&
7786 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7791 ptr = parm_table[i].ptr;
7793 struct service *pService = ServicePtrs[snum];
7794 ptr = ((char *)pService) +
7795 PTR_DIFF(parm_table[i].ptr, &sDefault);
7798 print_parameter(&parm_table[i],
7809 /***************************************************************************
7810 Return info about the requested parameter (given as a string).
7811 Return NULL when the string is not a valid parameter name.
7812 ***************************************************************************/
7814 struct parm_struct *lp_get_parameter(const char *param_name)
7816 int num = map_parameter(param_name);
7822 return &parm_table[num];
7825 /***************************************************************************
7826 Return info about the next parameter in a service.
7827 snum==GLOBAL_SECTION_SNUM gives the globals.
7828 Return NULL when out of parameters.
7829 ***************************************************************************/
7831 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7834 /* do the globals */
7835 for (; parm_table[*i].label; (*i)++) {
7836 if (parm_table[*i].p_class == P_SEPARATOR)
7837 return &parm_table[(*i)++];
7839 if (!parm_table[*i].ptr
7840 || (*parm_table[*i].label == '-'))
7844 && (parm_table[*i].ptr ==
7845 parm_table[(*i) - 1].ptr))
7848 if (is_default(*i) && !allparameters)
7851 return &parm_table[(*i)++];
7854 struct service *pService = ServicePtrs[snum];
7856 for (; parm_table[*i].label; (*i)++) {
7857 if (parm_table[*i].p_class == P_SEPARATOR)
7858 return &parm_table[(*i)++];
7860 if (parm_table[*i].p_class == P_LOCAL &&
7861 parm_table[*i].ptr &&
7862 (*parm_table[*i].label != '-') &&
7864 (parm_table[*i].ptr !=
7865 parm_table[(*i) - 1].ptr)))
7868 PTR_DIFF(parm_table[*i].ptr,
7871 if (allparameters ||
7872 !equal_parameter(parm_table[*i].type,
7873 ((char *)pService) +
7875 ((char *)&sDefault) +
7878 return &parm_table[(*i)++];
7889 /***************************************************************************
7890 Display the contents of a single copy structure.
7891 ***************************************************************************/
7892 static void dump_copy_map(bool *pcopymap)
7898 printf("\n\tNon-Copied parameters:\n");
7900 for (i = 0; parm_table[i].label; i++)
7901 if (parm_table[i].p_class == P_LOCAL &&
7902 parm_table[i].ptr && !pcopymap[i] &&
7903 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7905 printf("\t\t%s\n", parm_table[i].label);
7910 /***************************************************************************
7911 Return TRUE if the passed service number is within range.
7912 ***************************************************************************/
7914 bool lp_snum_ok(int iService)
7916 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7919 /***************************************************************************
7920 Auto-load some home services.
7921 ***************************************************************************/
7923 static void lp_add_auto_services(char *str)
7933 s = SMB_STRDUP(str);
7937 homes = lp_servicenumber(HOMES_NAME);
7939 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7940 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7943 if (lp_servicenumber(p) >= 0)
7946 home = get_user_home_dir(talloc_tos(), p);
7948 if (home && homes >= 0)
7949 lp_add_home(p, homes, p, home);
7956 /***************************************************************************
7957 Auto-load one printer.
7958 ***************************************************************************/
7960 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7962 int printers = lp_servicenumber(PRINTERS_NAME);
7965 if (lp_servicenumber(name) < 0) {
7966 lp_add_printer(name, printers);
7967 if ((i = lp_servicenumber(name)) >= 0) {
7968 string_set(&ServicePtrs[i]->comment, comment);
7969 ServicePtrs[i]->autoloaded = True;
7974 /***************************************************************************
7975 Have we loaded a services file yet?
7976 ***************************************************************************/
7978 bool lp_loaded(void)
7983 /***************************************************************************
7984 Unload unused services.
7985 ***************************************************************************/
7987 void lp_killunused(bool (*snumused) (int))
7990 for (i = 0; i < iNumServices; i++) {
7994 /* don't kill autoloaded or usershare services */
7995 if ( ServicePtrs[i]->autoloaded ||
7996 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8000 if (!snumused || !snumused(i)) {
8001 free_service_byindex(i);
8007 * Kill all except autoloaded and usershare services - convenience wrapper
8009 void lp_kill_all_services(void)
8011 lp_killunused(NULL);
8014 /***************************************************************************
8016 ***************************************************************************/
8018 void lp_killservice(int iServiceIn)
8020 if (VALID(iServiceIn)) {
8021 free_service_byindex(iServiceIn);
8025 /***************************************************************************
8026 Save the curent values of all global and sDefault parameters into the
8027 defaults union. This allows swat and testparm to show only the
8028 changed (ie. non-default) parameters.
8029 ***************************************************************************/
8031 static void lp_save_defaults(void)
8034 for (i = 0; parm_table[i].label; i++) {
8035 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8037 switch (parm_table[i].type) {
8039 parm_table[i].def.lvalue = str_list_copy(
8040 NULL, *(const char ***)parm_table[i].ptr);
8044 if (parm_table[i].ptr) {
8045 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8047 parm_table[i].def.svalue = NULL;
8052 parm_table[i].def.bvalue =
8053 *(bool *)parm_table[i].ptr;
8056 parm_table[i].def.cvalue =
8057 *(char *)parm_table[i].ptr;
8062 parm_table[i].def.ivalue =
8063 *(int *)parm_table[i].ptr;
8069 defaults_saved = True;
8072 /*******************************************************************
8073 Set the server type we will announce as via nmbd.
8074 ********************************************************************/
8076 static const struct srv_role_tab {
8078 const char *role_str;
8079 } srv_role_tab [] = {
8080 { ROLE_STANDALONE, "ROLE_STANDALONE" },
8081 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8082 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8083 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8087 const char* server_role_str(uint32 role)
8090 for (i=0; srv_role_tab[i].role_str; i++) {
8091 if (role == srv_role_tab[i].role) {
8092 return srv_role_tab[i].role_str;
8098 static void set_server_role(void)
8100 server_role = ROLE_STANDALONE;
8102 switch (lp_security()) {
8104 if (lp_domain_logons())
8105 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8108 if (lp_domain_logons())
8109 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8110 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8111 server_role = ROLE_STANDALONE;
8114 if (lp_domain_logons()) {
8115 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8116 server_role = ROLE_DOMAIN_BDC;
8119 server_role = ROLE_DOMAIN_MEMBER;
8122 if (lp_domain_logons()) {
8123 server_role = ROLE_DOMAIN_PDC;
8126 server_role = ROLE_DOMAIN_MEMBER;
8129 if (lp_domain_logons()) {
8131 if (Globals.iDomainMaster) /* auto or yes */
8132 server_role = ROLE_DOMAIN_PDC;
8134 server_role = ROLE_DOMAIN_BDC;
8138 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8142 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8145 /***********************************************************
8146 If we should send plaintext/LANMAN passwords in the clinet
8147 ************************************************************/
8149 static void set_allowed_client_auth(void)
8151 if (Globals.bClientNTLMv2Auth) {
8152 Globals.bClientLanManAuth = False;
8154 if (!Globals.bClientLanManAuth) {
8155 Globals.bClientPlaintextAuth = False;
8159 /***************************************************************************
8161 The following code allows smbd to read a user defined share file.
8162 Yes, this is my intent. Yes, I'm comfortable with that...
8164 THE FOLLOWING IS SECURITY CRITICAL CODE.
8166 It washes your clothes, it cleans your house, it guards you while you sleep...
8167 Do not f%^k with it....
8168 ***************************************************************************/
8170 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8172 /***************************************************************************
8173 Check allowed stat state of a usershare file.
8174 Ensure we print out who is dicking with us so the admin can
8175 get their sorry ass fired.
8176 ***************************************************************************/
8178 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8180 if (!S_ISREG(psbuf->st_mode)) {
8181 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8182 "not a regular file\n",
8183 fname, (unsigned int)psbuf->st_uid ));
8187 /* Ensure this doesn't have the other write bit set. */
8188 if (psbuf->st_mode & S_IWOTH) {
8189 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8190 "public write. Refusing to allow as a usershare file.\n",
8191 fname, (unsigned int)psbuf->st_uid ));
8195 /* Should be 10k or less. */
8196 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8197 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8198 "too large (%u) to be a user share file.\n",
8199 fname, (unsigned int)psbuf->st_uid,
8200 (unsigned int)psbuf->st_size ));
8207 /***************************************************************************
8208 Parse the contents of a usershare file.
8209 ***************************************************************************/
8211 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8212 SMB_STRUCT_STAT *psbuf,
8213 const char *servicename,
8217 char **pp_sharepath,
8222 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8223 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8226 SMB_STRUCT_STAT sbuf;
8227 char *sharepath = NULL;
8228 char *comment = NULL;
8230 *pp_sharepath = NULL;
8233 *pallow_guest = False;
8236 return USERSHARE_MALFORMED_FILE;
8239 if (strcmp(lines[0], "#VERSION 1") == 0) {
8241 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8244 return USERSHARE_MALFORMED_FILE;
8247 return USERSHARE_BAD_VERSION;
8250 if (strncmp(lines[1], "path=", 5) != 0) {
8251 return USERSHARE_MALFORMED_PATH;
8254 sharepath = talloc_strdup(ctx, &lines[1][5]);
8256 return USERSHARE_POSIX_ERR;
8258 trim_string(sharepath, " ", " ");
8260 if (strncmp(lines[2], "comment=", 8) != 0) {
8261 return USERSHARE_MALFORMED_COMMENT_DEF;
8264 comment = talloc_strdup(ctx, &lines[2][8]);
8266 return USERSHARE_POSIX_ERR;
8268 trim_string(comment, " ", " ");
8269 trim_char(comment, '"', '"');
8271 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8272 return USERSHARE_MALFORMED_ACL_DEF;
8275 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8276 return USERSHARE_ACL_ERR;
8280 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8281 return USERSHARE_MALFORMED_ACL_DEF;
8283 if (lines[4][9] == 'y') {
8284 *pallow_guest = True;
8288 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8289 /* Path didn't change, no checks needed. */
8290 *pp_sharepath = sharepath;
8291 *pp_comment = comment;
8292 return USERSHARE_OK;
8295 /* The path *must* be absolute. */
8296 if (sharepath[0] != '/') {
8297 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8298 servicename, sharepath));
8299 return USERSHARE_PATH_NOT_ABSOLUTE;
8302 /* If there is a usershare prefix deny list ensure one of these paths
8303 doesn't match the start of the user given path. */
8304 if (prefixdenylist) {
8306 for ( i=0; prefixdenylist[i]; i++ ) {
8307 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8308 servicename, i, prefixdenylist[i], sharepath ));
8309 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8310 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8311 "usershare prefix deny list entries.\n",
8312 servicename, sharepath));
8313 return USERSHARE_PATH_IS_DENIED;
8318 /* If there is a usershare prefix allow list ensure one of these paths
8319 does match the start of the user given path. */
8321 if (prefixallowlist) {
8323 for ( i=0; prefixallowlist[i]; i++ ) {
8324 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8325 servicename, i, prefixallowlist[i], sharepath ));
8326 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8330 if (prefixallowlist[i] == NULL) {
8331 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8332 "usershare prefix allow list entries.\n",
8333 servicename, sharepath));
8334 return USERSHARE_PATH_NOT_ALLOWED;
8338 /* Ensure this is pointing to a directory. */
8339 dp = sys_opendir(sharepath);
8342 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8343 servicename, sharepath));
8344 return USERSHARE_PATH_NOT_DIRECTORY;
8347 /* Ensure the owner of the usershare file has permission to share
8350 if (sys_stat(sharepath, &sbuf) == -1) {
8351 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8352 servicename, sharepath, strerror(errno) ));
8354 return USERSHARE_POSIX_ERR;
8359 if (!S_ISDIR(sbuf.st_mode)) {
8360 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8361 servicename, sharepath ));
8362 return USERSHARE_PATH_NOT_DIRECTORY;
8365 /* Check if sharing is restricted to owner-only. */
8366 /* psbuf is the stat of the usershare definition file,
8367 sbuf is the stat of the target directory to be shared. */
8369 if (lp_usershare_owner_only()) {
8370 /* root can share anything. */
8371 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8372 return USERSHARE_PATH_NOT_ALLOWED;
8376 *pp_sharepath = sharepath;
8377 *pp_comment = comment;
8378 return USERSHARE_OK;
8381 /***************************************************************************
8382 Deal with a usershare file.
8385 -1 - Bad name, invalid contents.
8386 - service name already existed and not a usershare, problem
8387 with permissions to share directory etc.
8388 ***************************************************************************/
8390 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8392 SMB_STRUCT_STAT sbuf;
8393 SMB_STRUCT_STAT lsbuf;
8395 char *sharepath = NULL;
8396 char *comment = NULL;
8397 fstring service_name;
8398 char **lines = NULL;
8402 TALLOC_CTX *ctx = NULL;
8403 SEC_DESC *psd = NULL;
8404 bool guest_ok = False;
8406 /* Ensure share name doesn't contain invalid characters. */
8407 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8408 DEBUG(0,("process_usershare_file: share name %s contains "
8409 "invalid characters (any of %s)\n",
8410 file_name, INVALID_SHARENAME_CHARS ));
8414 fstrcpy(service_name, file_name);
8416 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8419 /* Minimize the race condition by doing an lstat before we
8420 open and fstat. Ensure this isn't a symlink link. */
8422 if (sys_lstat(fname, &lsbuf) != 0) {
8423 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8424 fname, strerror(errno) ));
8429 /* This must be a regular file, not a symlink, directory or
8430 other strange filetype. */
8431 if (!check_usershare_stat(fname, &lsbuf)) {
8437 char *canon_name = canonicalize_servicename(service_name);
8438 TDB_DATA data = dbwrap_fetch_bystring(
8439 ServiceHash, canon_name, canon_name);
8443 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8444 iService = *(int *)data.dptr;
8446 TALLOC_FREE(canon_name);
8449 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8450 /* Nothing changed - Mark valid and return. */
8451 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8453 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8458 /* Try and open the file read only - no symlinks allowed. */
8460 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8462 fd = sys_open(fname, O_RDONLY, 0);
8466 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8467 fname, strerror(errno) ));
8472 /* Now fstat to be *SURE* it's a regular file. */
8473 if (sys_fstat(fd, &sbuf) != 0) {
8475 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8476 fname, strerror(errno) ));
8481 /* Is it the same dev/inode as was lstated ? */
8482 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8484 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8485 "Symlink spoofing going on ?\n", fname ));
8490 /* This must be a regular file, not a symlink, directory or
8491 other strange filetype. */
8492 if (!check_usershare_stat(fname, &sbuf)) {
8497 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8500 if (lines == NULL) {
8501 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8502 fname, (unsigned int)sbuf.st_uid ));
8509 /* Should we allow printers to be shared... ? */
8510 ctx = talloc_init("usershare_sd_xctx");
8516 if (parse_usershare_file(ctx, &sbuf, service_name,
8517 iService, lines, numlines, &sharepath,
8518 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8519 talloc_destroy(ctx);
8526 /* Everything ok - add the service possibly using a template. */
8528 const struct service *sp = &sDefault;
8529 if (snum_template != -1) {
8530 sp = ServicePtrs[snum_template];
8533 if ((iService = add_a_service(sp, service_name)) < 0) {
8534 DEBUG(0, ("process_usershare_file: Failed to add "
8535 "new service %s\n", service_name));
8536 talloc_destroy(ctx);
8540 /* Read only is controlled by usershare ACL below. */
8541 ServicePtrs[iService]->bRead_only = False;
8544 /* Write the ACL of the new/modified share. */
8545 if (!set_share_security(service_name, psd)) {
8546 DEBUG(0, ("process_usershare_file: Failed to set share "
8547 "security for user share %s\n",
8549 lp_remove_service(iService);
8550 talloc_destroy(ctx);
8554 /* If from a template it may be marked invalid. */
8555 ServicePtrs[iService]->valid = True;
8557 /* Set the service as a valid usershare. */
8558 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8560 /* Set guest access. */
8561 if (lp_usershare_allow_guests()) {
8562 ServicePtrs[iService]->bGuest_ok = guest_ok;
8565 /* And note when it was loaded. */
8566 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8567 string_set(&ServicePtrs[iService]->szPath, sharepath);
8568 string_set(&ServicePtrs[iService]->comment, comment);
8570 talloc_destroy(ctx);
8575 /***************************************************************************
8576 Checks if a usershare entry has been modified since last load.
8577 ***************************************************************************/
8579 static bool usershare_exists(int iService, time_t *last_mod)
8581 SMB_STRUCT_STAT lsbuf;
8582 const char *usersharepath = Globals.szUsersharePath;
8585 if (asprintf(&fname, "%s/%s",
8587 ServicePtrs[iService]->szService) < 0) {
8591 if (sys_lstat(fname, &lsbuf) != 0) {
8596 if (!S_ISREG(lsbuf.st_mode)) {
8602 *last_mod = lsbuf.st_mtime;
8606 /***************************************************************************
8607 Load a usershare service by name. Returns a valid servicenumber or -1.
8608 ***************************************************************************/
8610 int load_usershare_service(const char *servicename)
8612 SMB_STRUCT_STAT sbuf;
8613 const char *usersharepath = Globals.szUsersharePath;
8614 int max_user_shares = Globals.iUsershareMaxShares;
8615 int snum_template = -1;
8617 if (*usersharepath == 0 || max_user_shares == 0) {
8621 if (sys_stat(usersharepath, &sbuf) != 0) {
8622 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8623 usersharepath, strerror(errno) ));
8627 if (!S_ISDIR(sbuf.st_mode)) {
8628 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8634 * This directory must be owned by root, and have the 't' bit set.
8635 * It also must not be writable by "other".
8639 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8641 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8643 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8644 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8649 /* Ensure the template share exists if it's set. */
8650 if (Globals.szUsershareTemplateShare[0]) {
8651 /* We can't use lp_servicenumber here as we are recommending that
8652 template shares have -valid=False set. */
8653 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8654 if (ServicePtrs[snum_template]->szService &&
8655 strequal(ServicePtrs[snum_template]->szService,
8656 Globals.szUsershareTemplateShare)) {
8661 if (snum_template == -1) {
8662 DEBUG(0,("load_usershare_service: usershare template share %s "
8663 "does not exist.\n",
8664 Globals.szUsershareTemplateShare ));
8669 return process_usershare_file(usersharepath, servicename, snum_template);
8672 /***************************************************************************
8673 Load all user defined shares from the user share directory.
8674 We only do this if we're enumerating the share list.
8675 This is the function that can delete usershares that have
8677 ***************************************************************************/
8679 int load_usershare_shares(void)
8682 SMB_STRUCT_STAT sbuf;
8683 SMB_STRUCT_DIRENT *de;
8684 int num_usershares = 0;
8685 int max_user_shares = Globals.iUsershareMaxShares;
8686 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8687 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8688 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8690 int snum_template = -1;
8691 const char *usersharepath = Globals.szUsersharePath;
8692 int ret = lp_numservices();
8694 if (max_user_shares == 0 || *usersharepath == '\0') {
8695 return lp_numservices();
8698 if (sys_stat(usersharepath, &sbuf) != 0) {
8699 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8700 usersharepath, strerror(errno) ));
8705 * This directory must be owned by root, and have the 't' bit set.
8706 * It also must not be writable by "other".
8710 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8712 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8714 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8715 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8720 /* Ensure the template share exists if it's set. */
8721 if (Globals.szUsershareTemplateShare[0]) {
8722 /* We can't use lp_servicenumber here as we are recommending that
8723 template shares have -valid=False set. */
8724 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8725 if (ServicePtrs[snum_template]->szService &&
8726 strequal(ServicePtrs[snum_template]->szService,
8727 Globals.szUsershareTemplateShare)) {
8732 if (snum_template == -1) {
8733 DEBUG(0,("load_usershare_shares: usershare template share %s "
8734 "does not exist.\n",
8735 Globals.szUsershareTemplateShare ));
8740 /* Mark all existing usershares as pending delete. */
8741 for (iService = iNumServices - 1; iService >= 0; iService--) {
8742 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8743 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8747 dp = sys_opendir(usersharepath);
8749 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8750 usersharepath, strerror(errno) ));
8754 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8755 (de = sys_readdir(dp));
8756 num_dir_entries++ ) {
8758 const char *n = de->d_name;
8760 /* Ignore . and .. */
8762 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8768 /* Temporary file used when creating a share. */
8769 num_tmp_dir_entries++;
8772 /* Allow 20% tmp entries. */
8773 if (num_tmp_dir_entries > allowed_tmp_entries) {
8774 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8775 "in directory %s\n",
8776 num_tmp_dir_entries, usersharepath));
8780 r = process_usershare_file(usersharepath, n, snum_template);
8782 /* Update the services count. */
8784 if (num_usershares >= max_user_shares) {
8785 DEBUG(0,("load_usershare_shares: max user shares reached "
8786 "on file %s in directory %s\n",
8787 n, usersharepath ));
8790 } else if (r == -1) {
8791 num_bad_dir_entries++;
8794 /* Allow 20% bad entries. */
8795 if (num_bad_dir_entries > allowed_bad_entries) {
8796 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8797 "in directory %s\n",
8798 num_bad_dir_entries, usersharepath));
8802 /* Allow 20% bad entries. */
8803 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8804 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8805 "in directory %s\n",
8806 num_dir_entries, usersharepath));
8813 /* Sweep through and delete any non-refreshed usershares that are
8814 not currently in use. */
8815 for (iService = iNumServices - 1; iService >= 0; iService--) {
8816 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8817 if (conn_snum_used(iService)) {
8820 /* Remove from the share ACL db. */
8821 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8822 lp_servicename(iService) ));
8823 delete_share_security(lp_servicename(iService));
8824 free_service_byindex(iService);
8828 return lp_numservices();
8831 /********************************************************
8832 Destroy global resources allocated in this file
8833 ********************************************************/
8835 void gfree_loadparm(void)
8837 struct file_lists *f;
8838 struct file_lists *next;
8841 /* Free the file lists */
8846 SAFE_FREE( f->name );
8847 SAFE_FREE( f->subfname );
8853 /* Free resources allocated to services */
8855 for ( i = 0; i < iNumServices; i++ ) {
8857 free_service_byindex(i);
8861 SAFE_FREE( ServicePtrs );
8864 /* Now release all resources allocated to global
8865 parameters and the default service */
8867 free_global_parameters();
8871 /***************************************************************************
8872 Allow client apps to specify that they are a client
8873 ***************************************************************************/
8874 void lp_set_in_client(bool b)
8880 /***************************************************************************
8881 Determine if we're running in a client app
8882 ***************************************************************************/
8883 bool lp_is_in_client(void)
8888 /***************************************************************************
8889 Load the services array from the services file. Return True on success,
8891 ***************************************************************************/
8893 bool lp_load_ex(const char *pszFname,
8897 bool initialize_globals,
8898 bool allow_include_registry,
8899 bool allow_registry_shares)
8906 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8908 bInGlobalSection = True;
8909 bGlobalOnly = global_only;
8910 bAllowIncludeRegistry = allow_include_registry;
8912 init_globals(! initialize_globals);
8915 if (save_defaults) {
8920 free_param_opts(&Globals.param_opt);
8922 /* We get sections first, so have to start 'behind' to make up */
8925 if (lp_config_backend_is_file()) {
8926 n2 = alloc_sub_basic(get_current_username(),
8927 current_user_info.domain,
8930 smb_panic("lp_load_ex: out of memory");
8933 add_to_file_list(pszFname, n2);
8935 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8938 /* finish up the last section */
8939 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8941 if (iServiceIndex >= 0) {
8942 bRetval = service_ok(iServiceIndex);
8946 if (lp_config_backend_is_registry()) {
8947 /* config backend changed to registry in config file */
8949 * We need to use this extra global variable here to
8950 * survive restart: init_globals uses this as a default
8951 * for ConfigBackend. Otherwise, init_globals would
8952 * send us into an endless loop here.
8954 config_backend = CONFIG_BACKEND_REGISTRY;
8956 DEBUG(1, ("lp_load_ex: changing to config backend "
8958 init_globals(false);
8959 lp_kill_all_services();
8960 return lp_load_ex(pszFname, global_only, save_defaults,
8961 add_ipc, initialize_globals,
8962 allow_include_registry,
8963 allow_registry_shares);
8965 } else if (lp_config_backend_is_registry()) {
8966 bRetval = process_registry_globals();
8968 DEBUG(0, ("Illegal config backend given: %d\n",
8969 lp_config_backend()));
8973 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8974 bRetval = process_registry_shares();
8977 lp_add_auto_services(lp_auto_services());
8980 /* When 'restrict anonymous = 2' guest connections to ipc$
8982 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8983 if ( lp_enable_asu_support() ) {
8984 lp_add_ipc("ADMIN$", false);
8989 set_default_server_announce_type();
8990 set_allowed_client_auth();
8994 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8995 /* if bWINSsupport is true and we are in the client */
8996 if (lp_is_in_client() && Globals.bWINSsupport) {
8997 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9002 bAllowIncludeRegistry = true;
9007 bool lp_load(const char *pszFname,
9011 bool initialize_globals)
9013 return lp_load_ex(pszFname,
9021 bool lp_load_initial_only(const char *pszFname)
9023 return lp_load_ex(pszFname,
9032 bool lp_load_with_registry_shares(const char *pszFname,
9036 bool initialize_globals)
9038 return lp_load_ex(pszFname,
9047 /***************************************************************************
9048 Return the max number of services.
9049 ***************************************************************************/
9051 int lp_numservices(void)
9053 return (iNumServices);
9056 /***************************************************************************
9057 Display the contents of the services array in human-readable form.
9058 ***************************************************************************/
9060 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9065 defaults_saved = False;
9069 dump_a_service(&sDefault, f);
9071 for (iService = 0; iService < maxtoprint; iService++) {
9073 lp_dump_one(f, show_defaults, iService);
9077 /***************************************************************************
9078 Display the contents of one service in human-readable form.
9079 ***************************************************************************/
9081 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9084 if (ServicePtrs[snum]->szService[0] == '\0')
9086 dump_a_service(ServicePtrs[snum], f);
9090 /***************************************************************************
9091 Return the number of the service with the given name, or -1 if it doesn't
9092 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9093 getservicebyname()! This works ONLY if all services have been loaded, and
9094 does not copy the found service.
9095 ***************************************************************************/
9097 int lp_servicenumber(const char *pszServiceName)
9100 fstring serviceName;
9102 if (!pszServiceName) {
9103 return GLOBAL_SECTION_SNUM;
9106 for (iService = iNumServices - 1; iService >= 0; iService--) {
9107 if (VALID(iService) && ServicePtrs[iService]->szService) {
9109 * The substitution here is used to support %U is
9112 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9113 standard_sub_basic(get_current_username(),
9114 current_user_info.domain,
9115 serviceName,sizeof(serviceName));
9116 if (strequal(serviceName, pszServiceName)) {
9122 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9125 if (!usershare_exists(iService, &last_mod)) {
9126 /* Remove the share security tdb entry for it. */
9127 delete_share_security(lp_servicename(iService));
9128 /* Remove it from the array. */
9129 free_service_byindex(iService);
9130 /* Doesn't exist anymore. */
9131 return GLOBAL_SECTION_SNUM;
9134 /* Has it been modified ? If so delete and reload. */
9135 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9136 /* Remove it from the array. */
9137 free_service_byindex(iService);
9138 /* and now reload it. */
9139 iService = load_usershare_service(pszServiceName);
9144 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9145 return GLOBAL_SECTION_SNUM;
9151 bool share_defined(const char *service_name)
9153 return (lp_servicenumber(service_name) != -1);
9156 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9157 const char *sharename)
9159 struct share_params *result;
9163 if (!(sname = SMB_STRDUP(sharename))) {
9167 snum = find_service(sname);
9174 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9175 DEBUG(0, ("talloc failed\n"));
9179 result->service = snum;
9183 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9185 struct share_iterator *result;
9187 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9188 DEBUG(0, ("talloc failed\n"));
9192 result->next_id = 0;
9196 struct share_params *next_share(struct share_iterator *list)
9198 struct share_params *result;
9200 while (!lp_snum_ok(list->next_id) &&
9201 (list->next_id < lp_numservices())) {
9205 if (list->next_id >= lp_numservices()) {
9209 if (!(result = TALLOC_P(list, struct share_params))) {
9210 DEBUG(0, ("talloc failed\n"));
9214 result->service = list->next_id;
9219 struct share_params *next_printer(struct share_iterator *list)
9221 struct share_params *result;
9223 while ((result = next_share(list)) != NULL) {
9224 if (lp_print_ok(result->service)) {
9232 * This is a hack for a transition period until we transformed all code from
9233 * service numbers to struct share_params.
9236 struct share_params *snum2params_static(int snum)
9238 static struct share_params result;
9239 result.service = snum;
9243 /*******************************************************************
9244 A useful volume label function.
9245 ********************************************************************/
9247 const char *volume_label(int snum)
9250 const char *label = lp_volume(snum);
9252 label = lp_servicename(snum);
9255 /* This returns a 33 byte guarenteed null terminated string. */
9256 ret = talloc_strndup(talloc_tos(), label, 32);
9263 /*******************************************************************
9264 Set the server type we will announce as via nmbd.
9265 ********************************************************************/
9267 static void set_default_server_announce_type(void)
9269 default_server_announce = 0;
9270 default_server_announce |= SV_TYPE_WORKSTATION;
9271 default_server_announce |= SV_TYPE_SERVER;
9272 default_server_announce |= SV_TYPE_SERVER_UNIX;
9274 /* note that the flag should be set only if we have a
9275 printer service but nmbd doesn't actually load the
9276 services so we can't tell --jerry */
9278 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9280 switch (lp_announce_as()) {
9281 case ANNOUNCE_AS_NT_SERVER:
9282 default_server_announce |= SV_TYPE_SERVER_NT;
9283 /* fall through... */
9284 case ANNOUNCE_AS_NT_WORKSTATION:
9285 default_server_announce |= SV_TYPE_NT;
9287 case ANNOUNCE_AS_WIN95:
9288 default_server_announce |= SV_TYPE_WIN95_PLUS;
9290 case ANNOUNCE_AS_WFW:
9291 default_server_announce |= SV_TYPE_WFW;
9297 switch (lp_server_role()) {
9298 case ROLE_DOMAIN_MEMBER:
9299 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9301 case ROLE_DOMAIN_PDC:
9302 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9304 case ROLE_DOMAIN_BDC:
9305 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9307 case ROLE_STANDALONE:
9311 if (lp_time_server())
9312 default_server_announce |= SV_TYPE_TIME_SOURCE;
9314 if (lp_host_msdfs())
9315 default_server_announce |= SV_TYPE_DFS_SERVER;
9318 /***********************************************************
9319 returns role of Samba server
9320 ************************************************************/
9322 int lp_server_role(void)
9327 /***********************************************************
9328 If we are PDC then prefer us as DMB
9329 ************************************************************/
9331 bool lp_domain_master(void)
9333 if (Globals.iDomainMaster == Auto)
9334 return (lp_server_role() == ROLE_DOMAIN_PDC);
9336 return (bool)Globals.iDomainMaster;
9339 /***********************************************************
9340 If we are DMB then prefer us as LMB
9341 ************************************************************/
9343 bool lp_preferred_master(void)
9345 if (Globals.iPreferredMaster == Auto)
9346 return (lp_local_master() && lp_domain_master());
9348 return (bool)Globals.iPreferredMaster;
9351 /*******************************************************************
9353 ********************************************************************/
9355 void lp_remove_service(int snum)
9357 ServicePtrs[snum]->valid = False;
9358 invalid_services[num_invalid_services++] = snum;
9361 /*******************************************************************
9363 ********************************************************************/
9365 void lp_copy_service(int snum, const char *new_name)
9367 do_section(new_name, NULL);
9369 snum = lp_servicenumber(new_name);
9371 lp_do_parameter(snum, "copy", lp_servicename(snum));
9376 /*******************************************************************
9377 Get the default server type we will announce as via nmbd.
9378 ********************************************************************/
9380 int lp_default_server_announce(void)
9382 return default_server_announce;
9385 /*******************************************************************
9386 Split the announce version into major and minor numbers.
9387 ********************************************************************/
9389 int lp_major_announce_version(void)
9391 static bool got_major = False;
9392 static int major_version = DEFAULT_MAJOR_VERSION;
9397 return major_version;
9400 if ((vers = lp_announce_version()) == NULL)
9401 return major_version;
9403 if ((p = strchr_m(vers, '.')) == 0)
9404 return major_version;
9407 major_version = atoi(vers);
9408 return major_version;
9411 int lp_minor_announce_version(void)
9413 static bool got_minor = False;
9414 static int minor_version = DEFAULT_MINOR_VERSION;
9419 return minor_version;
9422 if ((vers = lp_announce_version()) == NULL)
9423 return minor_version;
9425 if ((p = strchr_m(vers, '.')) == 0)
9426 return minor_version;
9429 minor_version = atoi(p);
9430 return minor_version;
9433 /***********************************************************
9434 Set the global name resolution order (used in smbclient).
9435 ************************************************************/
9437 void lp_set_name_resolve_order(const char *new_order)
9439 string_set(&Globals.szNameResolveOrder, new_order);
9442 const char *lp_printername(int snum)
9444 const char *ret = _lp_printername(snum);
9445 if (ret == NULL || (ret != NULL && *ret == '\0'))
9446 ret = lp_const_servicename(snum);
9452 /***********************************************************
9453 Allow daemons such as winbindd to fix their logfile name.
9454 ************************************************************/
9456 void lp_set_logfile(const char *name)
9458 string_set(&Globals.szLogFile, name);
9459 debug_set_logfile(name);
9462 /*******************************************************************
9463 Return the max print jobs per queue.
9464 ********************************************************************/
9466 int lp_maxprintjobs(int snum)
9468 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9469 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9470 maxjobs = PRINT_MAX_JOBID - 1;
9475 const char *lp_printcapname(void)
9477 if ((Globals.szPrintcapname != NULL) &&
9478 (Globals.szPrintcapname[0] != '\0'))
9479 return Globals.szPrintcapname;
9481 if (sDefault.iPrinting == PRINT_CUPS) {
9489 if (sDefault.iPrinting == PRINT_BSD)
9490 return "/etc/printcap";
9492 return PRINTCAP_NAME;
9495 /*******************************************************************
9496 Ensure we don't use sendfile if server smb signing is active.
9497 ********************************************************************/
9499 static uint32 spoolss_state;
9501 bool lp_disable_spoolss( void )
9503 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9504 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9506 return spoolss_state == SVCCTL_STOPPED ? True : False;
9509 void lp_set_spoolss_state( uint32 state )
9511 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9513 spoolss_state = state;
9516 uint32 lp_get_spoolss_state( void )
9518 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9521 /*******************************************************************
9522 Ensure we don't use sendfile if server smb signing is active.
9523 ********************************************************************/
9525 bool lp_use_sendfile(int snum)
9527 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9528 if (Protocol < PROTOCOL_NT1) {
9531 return (_lp_use_sendfile(snum) &&
9532 (get_remote_arch() != RA_WIN95) &&
9533 !srv_is_signing_active());
9536 /*******************************************************************
9537 Turn off sendfile if we find the underlying OS doesn't support it.
9538 ********************************************************************/
9540 void set_use_sendfile(int snum, bool val)
9542 if (LP_SNUM_OK(snum))
9543 ServicePtrs[snum]->bUseSendfile = val;
9545 sDefault.bUseSendfile = val;
9548 /*******************************************************************
9549 Turn off storing DOS attributes if this share doesn't support it.
9550 ********************************************************************/
9552 void set_store_dos_attributes(int snum, bool val)
9554 if (!LP_SNUM_OK(snum))
9556 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9559 void lp_set_mangling_method(const char *new_method)
9561 string_set(&Globals.szManglingMethod, new_method);
9564 /*******************************************************************
9565 Global state for POSIX pathname processing.
9566 ********************************************************************/
9568 static bool posix_pathnames;
9570 bool lp_posix_pathnames(void)
9572 return posix_pathnames;
9575 /*******************************************************************
9576 Change everything needed to ensure POSIX pathname processing (currently
9578 ********************************************************************/
9580 void lp_set_posix_pathnames(void)
9582 posix_pathnames = True;
9585 /*******************************************************************
9586 Global state for POSIX lock processing - CIFS unix extensions.
9587 ********************************************************************/
9589 bool posix_default_lock_was_set;
9590 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9592 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9594 if (posix_default_lock_was_set) {
9595 return posix_cifsx_locktype;
9597 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9601 /*******************************************************************
9602 ********************************************************************/
9604 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9606 posix_default_lock_was_set = True;
9607 posix_cifsx_locktype = val;
9610 int lp_min_receive_file_size(void)
9612 if (Globals.iminreceivefile < 0) {
9615 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9618 /*******************************************************************
9619 If socket address is an empty character string, it is necessary to
9620 define it as "0.0.0.0".
9621 ********************************************************************/
9623 const char *lp_socket_address(void)
9625 char *sock_addr = Globals.szSocketAddress;
9627 if (sock_addr[0] == '\0'){
9628 string_set(&Globals.szSocketAddress, "0.0.0.0");
9630 return Globals.szSocketAddress;