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;
147 bool bForceUsernameMap;
152 char **szWINSservers;
154 char *szRemoteAnnounce;
155 char *szRemoteBrowseSync;
156 char *szSocketAddress;
157 char *szNISHomeMapName;
158 char *szAnnounceVersion; /* This is initialised in init_globals */
161 char **szNetbiosAliases;
162 char *szNetbiosScope;
163 char *szNameResolveOrder;
165 char *szAddUserScript;
166 char *szRenameUserScript;
167 char *szDelUserScript;
168 char *szAddGroupScript;
169 char *szDelGroupScript;
170 char *szAddUserToGroupScript;
171 char *szDelUserFromGroupScript;
172 char *szSetPrimaryGroupScript;
173 char *szAddMachineScript;
174 char *szShutdownScript;
175 char *szAbortShutdownScript;
176 char *szUsernameMapScript;
177 char *szCheckPasswordScript;
184 bool bPassdbExpandExplicit;
185 int AlgorithmicRidBase;
186 char *szTemplateHomedir;
187 char *szTemplateShell;
188 char *szWinbindSeparator;
189 bool bWinbindEnumUsers;
190 bool bWinbindEnumGroups;
191 bool bWinbindUseDefaultDomain;
192 bool bWinbindTrustedDomainsOnly;
193 bool bWinbindNestedGroups;
194 int winbind_expand_groups;
195 bool bWinbindRefreshTickets;
196 bool bWinbindOfflineLogon;
197 bool bWinbindNormalizeNames;
198 bool bWinbindRpcOnly;
199 char *szIdmapBackend;
200 char *szIdmapAllocBackend;
201 char *szAddShareCommand;
202 char *szChangeShareCommand;
203 char *szDeleteShareCommand;
205 char *szGuestaccount;
206 char *szManglingMethod;
207 char **szServicesList;
208 char *szUsersharePath;
209 char *szUsershareTemplateShare;
210 char **szUsersharePrefixAllowList;
211 char **szUsersharePrefixDenyList;
218 int open_files_db_hash_size;
227 bool paranoid_server_security;
230 int iMaxSmbdProcesses;
231 bool bDisableSpoolss;
234 bool enhanced_browsing;
240 int announce_as; /* This is initialised in init_globals */
241 int machine_password_timeout;
243 int oplock_break_wait_time;
244 int winbind_cache_time;
245 int winbind_reconnect_delay;
246 int winbind_max_idle_children;
247 char **szWinbindNssInfo;
249 char *szLdapMachineSuffix;
250 char *szLdapUserSuffix;
251 char *szLdapIdmapSuffix;
252 char *szLdapGroupSuffix;
257 int ldap_debug_level;
258 int ldap_debug_threshold;
261 char *szIPrintServer;
263 char **szClusterAddresses;
265 int ldap_passwd_sync;
266 int ldap_replication_sleep;
267 int ldap_timeout; /* This is initialised in init_globals */
268 int ldap_connection_timeout;
271 bool bMsAddPrinterWizard;
276 int iPreferredMaster;
279 char **szInitLogonDelayedHosts;
281 bool bEncryptPasswords;
286 bool bObeyPamRestrictions;
288 int PrintcapCacheTime;
289 bool bLargeReadwrite;
296 bool bBindInterfacesOnly;
297 bool bPamPasswordChange;
298 bool bUnixPasswdSync;
299 bool bPasswdChatDebug;
300 int iPasswdChatTimeout;
304 bool bNTStatusSupport;
306 int iMaxStatCacheSize;
308 bool bAllowTrustedDomains;
312 bool bClientLanManAuth;
313 bool bClientNTLMv2Auth;
314 bool bClientPlaintextAuth;
315 bool bClientUseSpnego;
316 bool bDebugPrefixTimestamp;
317 bool bDebugHiresTimestamp;
321 bool bEnableCoreFiles;
324 bool bHostnameLookups;
325 bool bUnixExtensions;
326 bool bDisableNetbios;
327 char * szDedicatedKeytabFile;
329 bool bDeferSharingViolations;
330 bool bEnablePrivileges;
332 bool bUsershareOwnerOnly;
333 bool bUsershareAllowGuests;
334 bool bRegistryShares;
335 int restrict_anonymous;
336 int name_cache_timeout;
339 int client_ldap_sasl_wrapping;
340 int iUsershareMaxShares;
342 int iIdmapNegativeCacheTime;
346 struct param_opt_struct *param_opt;
347 int cups_connection_timeout;
348 char *szSMBPerfcountModule;
349 bool bMapUntrustedToDomain;
352 static struct global Globals;
355 * This structure describes a single service.
361 time_t usershare_last_mod;
365 char **szInvalidUsers;
373 char *szRootPostExec;
375 char *szPrintcommand;
378 char *szLppausecommand;
379 char *szLpresumecommand;
380 char *szQueuepausecommand;
381 char *szQueueresumecommand;
383 char *szPrintjobUsername;
391 char *szVetoOplockFiles;
397 char **printer_admin;
402 char *szAioWriteBehind;
406 int iMaxReportedPrintJobs;
409 int iCreate_force_mode;
411 int iSecurity_force_mode;
414 int iDir_Security_mask;
415 int iDir_Security_force_mode;
419 int iOplockContentionLimit;
424 bool bRootpreexecClose;
427 bool bShortCasePreserve;
429 bool bHideSpecialFiles;
430 bool bHideUnReadable;
431 bool bHideUnWriteableFiles;
433 bool bAccessBasedShareEnum;
438 bool bAdministrative_share;
444 bool bStoreDosAttributes;
457 bool bStrictAllocate;
460 struct bitmap *copymap;
461 bool bDeleteReadonly;
463 bool bDeleteVetoFiles;
466 bool bDosFiletimeResolution;
467 bool bFakeDirCreateTimes;
473 bool bUseClientDriver;
474 bool bDefaultDevmode;
475 bool bForcePrintername;
477 bool bForceUnknownAclUser;
480 bool bMap_acl_inherit;
483 bool bAclCheckPermissions;
484 bool bAclMapFullControl;
485 bool bAclGroupControl;
487 bool bKernelChangeNotify;
488 int iallocation_roundup_size;
492 int iDirectoryNameCacheSize;
494 struct param_opt_struct *param_opt;
496 char dummy[3]; /* for alignment */
500 /* This is a default service used to prime a services structure */
501 static struct service sDefault = {
503 False, /* not autoloaded */
504 0, /* not a usershare */
505 (time_t)0, /* No last mod time */
506 NULL, /* szService */
508 NULL, /* szUsername */
509 NULL, /* szInvalidUsers */
510 NULL, /* szValidUsers */
511 NULL, /* szAdminUsers */
513 NULL, /* szInclude */
514 NULL, /* szPreExec */
515 NULL, /* szPostExec */
516 NULL, /* szRootPreExec */
517 NULL, /* szRootPostExec */
518 NULL, /* szCupsOptions */
519 NULL, /* szPrintcommand */
520 NULL, /* szLpqcommand */
521 NULL, /* szLprmcommand */
522 NULL, /* szLppausecommand */
523 NULL, /* szLpresumecommand */
524 NULL, /* szQueuepausecommand */
525 NULL, /* szQueueresumecommand */
526 NULL, /* szPrintername */
527 NULL, /* szPrintjobUsername */
528 NULL, /* szDontdescend */
529 NULL, /* szHostsallow */
530 NULL, /* szHostsdeny */
531 NULL, /* szMagicScript */
532 NULL, /* szMagicOutput */
533 NULL, /* szVetoFiles */
534 NULL, /* szHideFiles */
535 NULL, /* szVetoOplockFiles */
537 NULL, /* force user */
538 NULL, /* force group */
540 NULL, /* writelist */
541 NULL, /* printer admin */
544 NULL, /* vfs objects */
545 NULL, /* szMSDfsProxy */
546 NULL, /* szAioWriteBehind */
548 0, /* iMinPrintSpace */
549 1000, /* iMaxPrintJobs */
550 0, /* iMaxReportedPrintJobs */
551 0, /* iWriteCacheSize */
552 0744, /* iCreate_mask */
553 0000, /* iCreate_force_mode */
554 0777, /* iSecurity_mask */
555 0, /* iSecurity_force_mode */
556 0755, /* iDir_mask */
557 0000, /* iDir_force_mode */
558 0777, /* iDir_Security_mask */
559 0, /* iDir_Security_force_mode */
560 0, /* iMaxConnections */
561 CASE_LOWER, /* iDefaultCase */
562 DEFAULT_PRINTING, /* iPrinting */
563 2, /* iOplockContentionLimit */
565 1024, /* iBlock_size */
566 0, /* iDfreeCacheTime */
567 False, /* bPreexecClose */
568 False, /* bRootpreexecClose */
569 Auto, /* case sensitive */
570 True, /* case preserve */
571 True, /* short case preserve */
572 True, /* bHideDotFiles */
573 False, /* bHideSpecialFiles */
574 False, /* bHideUnReadable */
575 False, /* bHideUnWriteableFiles */
576 True, /* bBrowseable */
577 False, /* bAccessBasedShareEnum */
578 True, /* bAvailable */
579 True, /* bRead_only */
580 True, /* bNo_set_dir */
581 False, /* bGuest_only */
582 False, /* bAdministrative_share */
583 False, /* bGuest_ok */
584 False, /* bPrint_ok */
585 False, /* bMap_system */
586 False, /* bMap_hidden */
587 True, /* bMap_archive */
588 False, /* bStoreDosAttributes */
589 False, /* bDmapiSupport */
591 Auto, /* iStrictLocking */
592 True, /* bPosixLocking */
593 True, /* bShareModes */
595 True, /* bLevel2OpLocks */
596 False, /* bOnlyUser */
597 True, /* bMangledNames */
598 True, /* bWidelinks */
599 True, /* bSymlinks */
600 False, /* bSyncAlways */
601 False, /* bStrictAllocate */
602 False, /* bStrictSync */
603 '~', /* magic char */
605 False, /* bDeleteReadonly */
606 False, /* bFakeOplocks */
607 False, /* bDeleteVetoFiles */
608 False, /* bDosFilemode */
609 True, /* bDosFiletimes */
610 False, /* bDosFiletimeResolution */
611 False, /* bFakeDirCreateTimes */
612 True, /* bBlockingLocks */
613 False, /* bInheritPerms */
614 False, /* bInheritACLS */
615 False, /* bInheritOwner */
616 False, /* bMSDfsRoot */
617 False, /* bUseClientDriver */
618 True, /* bDefaultDevmode */
619 False, /* bForcePrintername */
620 True, /* bNTAclSupport */
621 False, /* bForceUnknownAclUser */
622 False, /* bUseSendfile */
623 False, /* bProfileAcls */
624 False, /* bMap_acl_inherit */
625 False, /* bAfs_Share */
626 False, /* bEASupport */
627 True, /* bAclCheckPermissions */
628 True, /* bAclMapFullControl */
629 False, /* bAclGroupControl */
630 True, /* bChangeNotify */
631 True, /* bKernelChangeNotify */
632 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
633 0, /* iAioReadSize */
634 0, /* iAioWriteSize */
635 MAP_READONLY_YES, /* iMap_readonly */
636 #ifdef BROKEN_DIRECTORY_HANDLING
637 0, /* iDirectoryNameCacheSize */
639 100, /* iDirectoryNameCacheSize */
641 Auto, /* ismb_encrypt */
642 NULL, /* Parametric options */
647 /* local variables */
648 static struct service **ServicePtrs = NULL;
649 static int iNumServices = 0;
650 static int iServiceIndex = 0;
651 static struct db_context *ServiceHash;
652 static int *invalid_services = NULL;
653 static int num_invalid_services = 0;
654 static bool bInGlobalSection = True;
655 static bool bGlobalOnly = False;
656 static int server_role;
657 static int default_server_announce;
659 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
661 /* prototypes for the special type handlers */
662 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
663 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
664 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
665 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
666 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
667 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
668 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
669 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
670 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
671 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
672 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
673 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
675 static void set_server_role(void);
676 static void set_default_server_announce_type(void);
677 static void set_allowed_client_auth(void);
679 static void *lp_local_ptr(struct service *service, void *ptr);
681 static const struct enum_list enum_protocol[] = {
682 {PROTOCOL_NT1, "NT1"},
683 {PROTOCOL_LANMAN2, "LANMAN2"},
684 {PROTOCOL_LANMAN1, "LANMAN1"},
685 {PROTOCOL_CORE, "CORE"},
686 {PROTOCOL_COREPLUS, "COREPLUS"},
687 {PROTOCOL_COREPLUS, "CORE+"},
691 static const struct enum_list enum_security[] = {
692 {SEC_SHARE, "SHARE"},
694 {SEC_SERVER, "SERVER"},
695 {SEC_DOMAIN, "DOMAIN"},
702 static const struct enum_list enum_printing[] = {
703 {PRINT_SYSV, "sysv"},
705 {PRINT_HPUX, "hpux"},
709 {PRINT_LPRNG, "lprng"},
710 {PRINT_CUPS, "cups"},
711 {PRINT_IPRINT, "iprint"},
713 {PRINT_LPROS2, "os2"},
715 {PRINT_TEST, "test"},
717 #endif /* DEVELOPER */
721 static const struct enum_list enum_ldap_sasl_wrapping[] = {
723 {ADS_AUTH_SASL_SIGN, "sign"},
724 {ADS_AUTH_SASL_SEAL, "seal"},
728 static const struct enum_list enum_ldap_ssl[] = {
729 {LDAP_SSL_OFF, "no"},
730 {LDAP_SSL_OFF, "off"},
731 {LDAP_SSL_START_TLS, "start tls"},
732 {LDAP_SSL_START_TLS, "start_tls"},
736 static const struct enum_list enum_ldap_passwd_sync[] = {
737 {LDAP_PASSWD_SYNC_OFF, "no"},
738 {LDAP_PASSWD_SYNC_OFF, "off"},
739 {LDAP_PASSWD_SYNC_ON, "yes"},
740 {LDAP_PASSWD_SYNC_ON, "on"},
741 {LDAP_PASSWD_SYNC_ONLY, "only"},
745 /* Types of machine we can announce as. */
746 #define ANNOUNCE_AS_NT_SERVER 1
747 #define ANNOUNCE_AS_WIN95 2
748 #define ANNOUNCE_AS_WFW 3
749 #define ANNOUNCE_AS_NT_WORKSTATION 4
751 static const struct enum_list enum_announce_as[] = {
752 {ANNOUNCE_AS_NT_SERVER, "NT"},
753 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
754 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
755 {ANNOUNCE_AS_WIN95, "win95"},
756 {ANNOUNCE_AS_WFW, "WfW"},
760 static const struct enum_list enum_map_readonly[] = {
761 {MAP_READONLY_NO, "no"},
762 {MAP_READONLY_NO, "false"},
763 {MAP_READONLY_NO, "0"},
764 {MAP_READONLY_YES, "yes"},
765 {MAP_READONLY_YES, "true"},
766 {MAP_READONLY_YES, "1"},
767 {MAP_READONLY_PERMISSIONS, "permissions"},
768 {MAP_READONLY_PERMISSIONS, "perms"},
772 static const struct enum_list enum_case[] = {
773 {CASE_LOWER, "lower"},
774 {CASE_UPPER, "upper"},
778 static const struct enum_list enum_bool_auto[] = {
789 /* Client-side offline caching policy types */
790 #define CSC_POLICY_MANUAL 0
791 #define CSC_POLICY_DOCUMENTS 1
792 #define CSC_POLICY_PROGRAMS 2
793 #define CSC_POLICY_DISABLE 3
795 static const struct enum_list enum_csc_policy[] = {
796 {CSC_POLICY_MANUAL, "manual"},
797 {CSC_POLICY_DOCUMENTS, "documents"},
798 {CSC_POLICY_PROGRAMS, "programs"},
799 {CSC_POLICY_DISABLE, "disable"},
803 /* SMB signing types. */
804 static const struct enum_list enum_smb_signing_vals[] = {
816 {Required, "required"},
817 {Required, "mandatory"},
819 {Required, "forced"},
820 {Required, "enforced"},
824 /* ACL compatibility options. */
825 static const struct enum_list enum_acl_compat_vals[] = {
826 { ACL_COMPAT_AUTO, "auto" },
827 { ACL_COMPAT_WINNT, "winnt" },
828 { ACL_COMPAT_WIN2K, "win2k" },
833 Do you want session setups at user level security with a invalid
834 password to be rejected or allowed in as guest? WinNT rejects them
835 but it can be a pain as it means "net view" needs to use a password
837 You have 3 choices in the setting of map_to_guest:
839 "Never" means session setups with an invalid password
840 are rejected. This is the default.
842 "Bad User" means session setups with an invalid password
843 are rejected, unless the username does not exist, in which case it
844 is treated as a guest login
846 "Bad Password" means session setups with an invalid password
847 are treated as a guest login
849 Note that map_to_guest only has an effect in user or server
853 static const struct enum_list enum_map_to_guest[] = {
854 {NEVER_MAP_TO_GUEST, "Never"},
855 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
856 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
857 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
861 /* Config backend options */
863 static const struct enum_list enum_config_backend[] = {
864 {CONFIG_BACKEND_FILE, "file"},
865 {CONFIG_BACKEND_REGISTRY, "registry"},
869 /* ADS kerberos ticket verification options */
871 static const struct enum_list enum_kerberos_method[] = {
872 {KERBEROS_VERIFY_SECRETS, "default"},
873 {KERBEROS_VERIFY_SECRETS, "secrets only"},
874 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
875 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
876 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
880 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
882 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
883 * screen in SWAT. This is used to exclude parameters as well as to squash all
884 * parameters that have been duplicated by pseudonyms.
886 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
887 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
888 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
891 * NOTE2: Handling of duplicated (synonym) paramters:
892 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
893 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
894 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
895 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
898 static struct parm_struct parm_table[] = {
899 {N_("Base Options"), P_SEP, P_SEPARATOR},
902 .label = "dos charset",
905 .ptr = &Globals.dos_charset,
906 .special = handle_charset,
908 .flags = FLAG_ADVANCED
911 .label = "unix charset",
914 .ptr = &Globals.unix_charset,
915 .special = handle_charset,
917 .flags = FLAG_ADVANCED
920 .label = "display charset",
923 .ptr = &Globals.display_charset,
924 .special = handle_charset,
926 .flags = FLAG_ADVANCED
932 .ptr = &sDefault.comment,
935 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
941 .ptr = &sDefault.szPath,
944 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
947 .label = "directory",
950 .ptr = &sDefault.szPath,
956 .label = "workgroup",
959 .ptr = &Globals.szWorkgroup,
960 .special = handle_workgroup,
962 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
969 .ptr = &Globals.szRealm,
972 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
976 .label = "netbios name",
979 .ptr = &Globals.szNetbiosName,
980 .special = handle_netbios_name,
982 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
985 .label = "netbios aliases",
988 .ptr = &Globals.szNetbiosAliases,
989 .special = handle_netbios_aliases,
991 .flags = FLAG_ADVANCED,
994 .label = "netbios scope",
997 .ptr = &Globals.szNetbiosScope,
998 .special = handle_netbios_scope,
1000 .flags = FLAG_ADVANCED,
1003 .label = "server string",
1005 .p_class = P_GLOBAL,
1006 .ptr = &Globals.szServerString,
1009 .flags = FLAG_BASIC | FLAG_ADVANCED,
1012 .label = "interfaces",
1014 .p_class = P_GLOBAL,
1015 .ptr = &Globals.szInterfaces,
1018 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1021 .label = "bind interfaces only",
1023 .p_class = P_GLOBAL,
1024 .ptr = &Globals.bBindInterfacesOnly,
1027 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1030 .label = "config backend",
1032 .p_class = P_GLOBAL,
1033 .ptr = &Globals.ConfigBackend,
1035 .enum_list = enum_config_backend,
1036 .flags = FLAG_ADVANCED,
1039 {N_("Security Options"), P_SEP, P_SEPARATOR},
1042 .label = "security",
1044 .p_class = P_GLOBAL,
1045 .ptr = &Globals.security,
1047 .enum_list = enum_security,
1048 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1051 .label = "auth methods",
1053 .p_class = P_GLOBAL,
1054 .ptr = &Globals.AuthMethods,
1057 .flags = FLAG_ADVANCED,
1060 .label = "encrypt passwords",
1062 .p_class = P_GLOBAL,
1063 .ptr = &Globals.bEncryptPasswords,
1066 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1069 .label = "update encrypted",
1071 .p_class = P_GLOBAL,
1072 .ptr = &Globals.bUpdateEncrypt,
1075 .flags = FLAG_ADVANCED,
1078 .label = "client schannel",
1080 .p_class = P_GLOBAL,
1081 .ptr = &Globals.clientSchannel,
1083 .enum_list = enum_bool_auto,
1084 .flags = FLAG_BASIC | FLAG_ADVANCED,
1087 .label = "server schannel",
1089 .p_class = P_GLOBAL,
1090 .ptr = &Globals.serverSchannel,
1092 .enum_list = enum_bool_auto,
1093 .flags = FLAG_BASIC | FLAG_ADVANCED,
1096 .label = "allow trusted domains",
1098 .p_class = P_GLOBAL,
1099 .ptr = &Globals.bAllowTrustedDomains,
1102 .flags = FLAG_ADVANCED,
1105 .label = "map to guest",
1107 .p_class = P_GLOBAL,
1108 .ptr = &Globals.map_to_guest,
1110 .enum_list = enum_map_to_guest,
1111 .flags = FLAG_ADVANCED,
1114 .label = "null passwords",
1116 .p_class = P_GLOBAL,
1117 .ptr = &Globals.bNullPasswords,
1120 .flags = FLAG_ADVANCED,
1123 .label = "obey pam restrictions",
1125 .p_class = P_GLOBAL,
1126 .ptr = &Globals.bObeyPamRestrictions,
1129 .flags = FLAG_ADVANCED,
1132 .label = "password server",
1134 .p_class = P_GLOBAL,
1135 .ptr = &Globals.szPasswordServer,
1138 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1141 .label = "smb passwd file",
1143 .p_class = P_GLOBAL,
1144 .ptr = &Globals.szSMBPasswdFile,
1147 .flags = FLAG_ADVANCED,
1150 .label = "private dir",
1152 .p_class = P_GLOBAL,
1153 .ptr = &Globals.szPrivateDir,
1156 .flags = FLAG_ADVANCED,
1159 .label = "passdb backend",
1161 .p_class = P_GLOBAL,
1162 .ptr = &Globals.szPassdbBackend,
1165 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1168 .label = "algorithmic rid base",
1170 .p_class = P_GLOBAL,
1171 .ptr = &Globals.AlgorithmicRidBase,
1174 .flags = FLAG_ADVANCED,
1177 .label = "root directory",
1179 .p_class = P_GLOBAL,
1180 .ptr = &Globals.szRootdir,
1183 .flags = FLAG_ADVANCED,
1186 .label = "root dir",
1188 .p_class = P_GLOBAL,
1189 .ptr = &Globals.szRootdir,
1197 .p_class = P_GLOBAL,
1198 .ptr = &Globals.szRootdir,
1204 .label = "guest account",
1206 .p_class = P_GLOBAL,
1207 .ptr = &Globals.szGuestaccount,
1210 .flags = FLAG_BASIC | FLAG_ADVANCED,
1213 .label = "enable privileges",
1215 .p_class = P_GLOBAL,
1216 .ptr = &Globals.bEnablePrivileges,
1219 .flags = FLAG_ADVANCED,
1223 .label = "pam password change",
1225 .p_class = P_GLOBAL,
1226 .ptr = &Globals.bPamPasswordChange,
1229 .flags = FLAG_ADVANCED,
1232 .label = "passwd program",
1234 .p_class = P_GLOBAL,
1235 .ptr = &Globals.szPasswdProgram,
1238 .flags = FLAG_ADVANCED,
1241 .label = "passwd chat",
1243 .p_class = P_GLOBAL,
1244 .ptr = &Globals.szPasswdChat,
1247 .flags = FLAG_ADVANCED,
1250 .label = "passwd chat debug",
1252 .p_class = P_GLOBAL,
1253 .ptr = &Globals.bPasswdChatDebug,
1256 .flags = FLAG_ADVANCED,
1259 .label = "passwd chat timeout",
1261 .p_class = P_GLOBAL,
1262 .ptr = &Globals.iPasswdChatTimeout,
1265 .flags = FLAG_ADVANCED,
1268 .label = "check password script",
1270 .p_class = P_GLOBAL,
1271 .ptr = &Globals.szCheckPasswordScript,
1274 .flags = FLAG_ADVANCED,
1277 .label = "username map",
1279 .p_class = P_GLOBAL,
1280 .ptr = &Globals.szUsernameMap,
1283 .flags = FLAG_ADVANCED,
1286 .label = "force username map",
1288 .p_class = P_GLOBAL,
1289 .ptr = &Globals.bForceUsernameMap,
1292 .flags = FLAG_ADVANCED,
1295 .label = "password level",
1297 .p_class = P_GLOBAL,
1298 .ptr = &Globals.pwordlevel,
1301 .flags = FLAG_ADVANCED,
1304 .label = "username level",
1306 .p_class = P_GLOBAL,
1307 .ptr = &Globals.unamelevel,
1310 .flags = FLAG_ADVANCED,
1313 .label = "unix password sync",
1315 .p_class = P_GLOBAL,
1316 .ptr = &Globals.bUnixPasswdSync,
1319 .flags = FLAG_ADVANCED,
1322 .label = "restrict anonymous",
1324 .p_class = P_GLOBAL,
1325 .ptr = &Globals.restrict_anonymous,
1328 .flags = FLAG_ADVANCED,
1331 .label = "lanman auth",
1333 .p_class = P_GLOBAL,
1334 .ptr = &Globals.bLanmanAuth,
1337 .flags = FLAG_ADVANCED,
1340 .label = "ntlm auth",
1342 .p_class = P_GLOBAL,
1343 .ptr = &Globals.bNTLMAuth,
1346 .flags = FLAG_ADVANCED,
1349 .label = "client NTLMv2 auth",
1351 .p_class = P_GLOBAL,
1352 .ptr = &Globals.bClientNTLMv2Auth,
1355 .flags = FLAG_ADVANCED,
1358 .label = "client lanman auth",
1360 .p_class = P_GLOBAL,
1361 .ptr = &Globals.bClientLanManAuth,
1364 .flags = FLAG_ADVANCED,
1367 .label = "client plaintext auth",
1369 .p_class = P_GLOBAL,
1370 .ptr = &Globals.bClientPlaintextAuth,
1373 .flags = FLAG_ADVANCED,
1376 .label = "username",
1379 .ptr = &sDefault.szUsername,
1382 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1388 .ptr = &sDefault.szUsername,
1397 .ptr = &sDefault.szUsername,
1403 .label = "invalid users",
1406 .ptr = &sDefault.szInvalidUsers,
1409 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1412 .label = "valid users",
1415 .ptr = &sDefault.szValidUsers,
1418 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1421 .label = "admin users",
1424 .ptr = &sDefault.szAdminUsers,
1427 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1430 .label = "read list",
1433 .ptr = &sDefault.readlist,
1436 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1439 .label = "write list",
1442 .ptr = &sDefault.writelist,
1445 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1448 .label = "printer admin",
1451 .ptr = &sDefault.printer_admin,
1454 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1457 .label = "force user",
1460 .ptr = &sDefault.force_user,
1463 .flags = FLAG_ADVANCED | FLAG_SHARE,
1466 .label = "force group",
1469 .ptr = &sDefault.force_group,
1472 .flags = FLAG_ADVANCED | FLAG_SHARE,
1478 .ptr = &sDefault.force_group,
1481 .flags = FLAG_ADVANCED,
1484 .label = "read only",
1487 .ptr = &sDefault.bRead_only,
1490 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1493 .label = "write ok",
1496 .ptr = &sDefault.bRead_only,
1502 .label = "writeable",
1505 .ptr = &sDefault.bRead_only,
1511 .label = "writable",
1514 .ptr = &sDefault.bRead_only,
1520 .label = "acl check permissions",
1523 .ptr = &sDefault.bAclCheckPermissions,
1526 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1529 .label = "acl group control",
1532 .ptr = &sDefault.bAclGroupControl,
1535 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1538 .label = "acl map full control",
1541 .ptr = &sDefault.bAclMapFullControl,
1544 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1547 .label = "create mask",
1550 .ptr = &sDefault.iCreate_mask,
1553 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1556 .label = "create mode",
1559 .ptr = &sDefault.iCreate_mask,
1565 .label = "force create mode",
1568 .ptr = &sDefault.iCreate_force_mode,
1571 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1574 .label = "security mask",
1577 .ptr = &sDefault.iSecurity_mask,
1580 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1583 .label = "force security mode",
1586 .ptr = &sDefault.iSecurity_force_mode,
1589 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1592 .label = "directory mask",
1595 .ptr = &sDefault.iDir_mask,
1598 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1601 .label = "directory mode",
1604 .ptr = &sDefault.iDir_mask,
1607 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1610 .label = "force directory mode",
1613 .ptr = &sDefault.iDir_force_mode,
1616 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1619 .label = "directory security mask",
1622 .ptr = &sDefault.iDir_Security_mask,
1625 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1628 .label = "force directory security mode",
1631 .ptr = &sDefault.iDir_Security_force_mode,
1634 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1637 .label = "force unknown acl user",
1640 .ptr = &sDefault.bForceUnknownAclUser,
1643 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1646 .label = "inherit permissions",
1649 .ptr = &sDefault.bInheritPerms,
1652 .flags = FLAG_ADVANCED | FLAG_SHARE,
1655 .label = "inherit acls",
1658 .ptr = &sDefault.bInheritACLS,
1661 .flags = FLAG_ADVANCED | FLAG_SHARE,
1664 .label = "inherit owner",
1667 .ptr = &sDefault.bInheritOwner,
1670 .flags = FLAG_ADVANCED | FLAG_SHARE,
1673 .label = "guest only",
1676 .ptr = &sDefault.bGuest_only,
1679 .flags = FLAG_ADVANCED | FLAG_SHARE,
1682 .label = "only guest",
1685 .ptr = &sDefault.bGuest_only,
1691 .label = "administrative share",
1694 .ptr = &sDefault.bAdministrative_share,
1697 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1701 .label = "guest ok",
1704 .ptr = &sDefault.bGuest_ok,
1707 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1713 .ptr = &sDefault.bGuest_ok,
1719 .label = "only user",
1722 .ptr = &sDefault.bOnlyUser,
1725 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1728 .label = "hosts allow",
1731 .ptr = &sDefault.szHostsallow,
1734 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1737 .label = "allow hosts",
1740 .ptr = &sDefault.szHostsallow,
1746 .label = "hosts deny",
1749 .ptr = &sDefault.szHostsdeny,
1752 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1755 .label = "deny hosts",
1758 .ptr = &sDefault.szHostsdeny,
1764 .label = "preload modules",
1766 .p_class = P_GLOBAL,
1767 .ptr = &Globals.szPreloadModules,
1770 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1773 .label = "dedicated keytab file",
1775 .p_class = P_GLOBAL,
1776 .ptr = &Globals.szDedicatedKeytabFile,
1779 .flags = FLAG_ADVANCED,
1782 .label = "kerberos method",
1784 .p_class = P_GLOBAL,
1785 .ptr = &Globals.iKerberosMethod,
1787 .enum_list = enum_kerberos_method,
1788 .flags = FLAG_ADVANCED,
1791 .label = "map untrusted to domain",
1793 .p_class = P_GLOBAL,
1794 .ptr = &Globals.bMapUntrustedToDomain,
1797 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1801 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1804 .label = "log level",
1806 .p_class = P_GLOBAL,
1807 .ptr = &Globals.szLogLevel,
1808 .special = handle_debug_list,
1810 .flags = FLAG_ADVANCED,
1813 .label = "debuglevel",
1815 .p_class = P_GLOBAL,
1816 .ptr = &Globals.szLogLevel,
1817 .special = handle_debug_list,
1824 .p_class = P_GLOBAL,
1825 .ptr = &Globals.syslog,
1828 .flags = FLAG_ADVANCED,
1831 .label = "syslog only",
1833 .p_class = P_GLOBAL,
1834 .ptr = &Globals.bSyslogOnly,
1837 .flags = FLAG_ADVANCED,
1840 .label = "log file",
1842 .p_class = P_GLOBAL,
1843 .ptr = &Globals.szLogFile,
1846 .flags = FLAG_ADVANCED,
1849 .label = "max log size",
1851 .p_class = P_GLOBAL,
1852 .ptr = &Globals.max_log_size,
1855 .flags = FLAG_ADVANCED,
1858 .label = "debug timestamp",
1860 .p_class = P_GLOBAL,
1861 .ptr = &Globals.bTimestampLogs,
1864 .flags = FLAG_ADVANCED,
1867 .label = "timestamp logs",
1869 .p_class = P_GLOBAL,
1870 .ptr = &Globals.bTimestampLogs,
1873 .flags = FLAG_ADVANCED,
1876 .label = "debug prefix timestamp",
1878 .p_class = P_GLOBAL,
1879 .ptr = &Globals.bDebugPrefixTimestamp,
1882 .flags = FLAG_ADVANCED,
1885 .label = "debug hires timestamp",
1887 .p_class = P_GLOBAL,
1888 .ptr = &Globals.bDebugHiresTimestamp,
1891 .flags = FLAG_ADVANCED,
1894 .label = "debug pid",
1896 .p_class = P_GLOBAL,
1897 .ptr = &Globals.bDebugPid,
1900 .flags = FLAG_ADVANCED,
1903 .label = "debug uid",
1905 .p_class = P_GLOBAL,
1906 .ptr = &Globals.bDebugUid,
1909 .flags = FLAG_ADVANCED,
1912 .label = "debug class",
1914 .p_class = P_GLOBAL,
1915 .ptr = &Globals.bDebugClass,
1918 .flags = FLAG_ADVANCED,
1921 .label = "enable core files",
1923 .p_class = P_GLOBAL,
1924 .ptr = &Globals.bEnableCoreFiles,
1927 .flags = FLAG_ADVANCED,
1930 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1933 .label = "allocation roundup size",
1936 .ptr = &sDefault.iallocation_roundup_size,
1939 .flags = FLAG_ADVANCED,
1942 .label = "aio read size",
1945 .ptr = &sDefault.iAioReadSize,
1948 .flags = FLAG_ADVANCED,
1951 .label = "aio write size",
1954 .ptr = &sDefault.iAioWriteSize,
1957 .flags = FLAG_ADVANCED,
1960 .label = "aio write behind",
1963 .ptr = &sDefault.szAioWriteBehind,
1966 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1969 .label = "smb ports",
1971 .p_class = P_GLOBAL,
1972 .ptr = &Globals.smb_ports,
1975 .flags = FLAG_ADVANCED,
1978 .label = "large readwrite",
1980 .p_class = P_GLOBAL,
1981 .ptr = &Globals.bLargeReadwrite,
1984 .flags = FLAG_ADVANCED,
1987 .label = "max protocol",
1989 .p_class = P_GLOBAL,
1990 .ptr = &Globals.maxprotocol,
1992 .enum_list = enum_protocol,
1993 .flags = FLAG_ADVANCED,
1996 .label = "protocol",
1998 .p_class = P_GLOBAL,
1999 .ptr = &Globals.maxprotocol,
2001 .enum_list = enum_protocol,
2002 .flags = FLAG_ADVANCED,
2005 .label = "min protocol",
2007 .p_class = P_GLOBAL,
2008 .ptr = &Globals.minprotocol,
2010 .enum_list = enum_protocol,
2011 .flags = FLAG_ADVANCED,
2014 .label = "min receivefile size",
2016 .p_class = P_GLOBAL,
2017 .ptr = &Globals.iminreceivefile,
2020 .flags = FLAG_ADVANCED,
2023 .label = "read raw",
2025 .p_class = P_GLOBAL,
2026 .ptr = &Globals.bReadRaw,
2029 .flags = FLAG_ADVANCED,
2032 .label = "write raw",
2034 .p_class = P_GLOBAL,
2035 .ptr = &Globals.bWriteRaw,
2038 .flags = FLAG_ADVANCED,
2041 .label = "disable netbios",
2043 .p_class = P_GLOBAL,
2044 .ptr = &Globals.bDisableNetbios,
2047 .flags = FLAG_ADVANCED,
2050 .label = "reset on zero vc",
2052 .p_class = P_GLOBAL,
2053 .ptr = &Globals.bResetOnZeroVC,
2056 .flags = FLAG_ADVANCED,
2059 .label = "acl compatibility",
2061 .p_class = P_GLOBAL,
2062 .ptr = &Globals.iAclCompat,
2064 .enum_list = enum_acl_compat_vals,
2065 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2068 .label = "defer sharing violations",
2070 .p_class = P_GLOBAL,
2071 .ptr = &Globals.bDeferSharingViolations,
2074 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2077 .label = "ea support",
2080 .ptr = &sDefault.bEASupport,
2083 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2086 .label = "nt acl support",
2089 .ptr = &sDefault.bNTAclSupport,
2092 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2095 .label = "nt pipe support",
2097 .p_class = P_GLOBAL,
2098 .ptr = &Globals.bNTPipeSupport,
2101 .flags = FLAG_ADVANCED,
2104 .label = "nt status support",
2106 .p_class = P_GLOBAL,
2107 .ptr = &Globals.bNTStatusSupport,
2110 .flags = FLAG_ADVANCED,
2113 .label = "profile acls",
2116 .ptr = &sDefault.bProfileAcls,
2119 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2122 .label = "announce version",
2124 .p_class = P_GLOBAL,
2125 .ptr = &Globals.szAnnounceVersion,
2128 .flags = FLAG_ADVANCED,
2131 .label = "announce as",
2133 .p_class = P_GLOBAL,
2134 .ptr = &Globals.announce_as,
2136 .enum_list = enum_announce_as,
2137 .flags = FLAG_ADVANCED,
2140 .label = "map acl inherit",
2143 .ptr = &sDefault.bMap_acl_inherit,
2146 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2149 .label = "afs share",
2152 .ptr = &sDefault.bAfs_Share,
2155 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2160 .p_class = P_GLOBAL,
2161 .ptr = &Globals.max_mux,
2164 .flags = FLAG_ADVANCED,
2167 .label = "max xmit",
2169 .p_class = P_GLOBAL,
2170 .ptr = &Globals.max_xmit,
2173 .flags = FLAG_ADVANCED,
2176 .label = "name resolve order",
2178 .p_class = P_GLOBAL,
2179 .ptr = &Globals.szNameResolveOrder,
2182 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2187 .p_class = P_GLOBAL,
2188 .ptr = &Globals.max_ttl,
2191 .flags = FLAG_ADVANCED,
2194 .label = "max wins ttl",
2196 .p_class = P_GLOBAL,
2197 .ptr = &Globals.max_wins_ttl,
2200 .flags = FLAG_ADVANCED,
2203 .label = "min wins ttl",
2205 .p_class = P_GLOBAL,
2206 .ptr = &Globals.min_wins_ttl,
2209 .flags = FLAG_ADVANCED,
2212 .label = "time server",
2214 .p_class = P_GLOBAL,
2215 .ptr = &Globals.bTimeServer,
2218 .flags = FLAG_ADVANCED,
2221 .label = "unix extensions",
2223 .p_class = P_GLOBAL,
2224 .ptr = &Globals.bUnixExtensions,
2227 .flags = FLAG_ADVANCED,
2230 .label = "use spnego",
2232 .p_class = P_GLOBAL,
2233 .ptr = &Globals.bUseSpnego,
2236 .flags = FLAG_ADVANCED,
2239 .label = "client signing",
2241 .p_class = P_GLOBAL,
2242 .ptr = &Globals.client_signing,
2244 .enum_list = enum_smb_signing_vals,
2245 .flags = FLAG_ADVANCED,
2248 .label = "server signing",
2250 .p_class = P_GLOBAL,
2251 .ptr = &Globals.server_signing,
2253 .enum_list = enum_smb_signing_vals,
2254 .flags = FLAG_ADVANCED,
2257 .label = "smb encrypt",
2260 .ptr = &sDefault.ismb_encrypt,
2262 .enum_list = enum_smb_signing_vals,
2263 .flags = FLAG_ADVANCED,
2266 .label = "client use spnego",
2268 .p_class = P_GLOBAL,
2269 .ptr = &Globals.bClientUseSpnego,
2272 .flags = FLAG_ADVANCED,
2275 .label = "client ldap sasl wrapping",
2277 .p_class = P_GLOBAL,
2278 .ptr = &Globals.client_ldap_sasl_wrapping,
2280 .enum_list = enum_ldap_sasl_wrapping,
2281 .flags = FLAG_ADVANCED,
2284 .label = "enable asu support",
2286 .p_class = P_GLOBAL,
2287 .ptr = &Globals.bASUSupport,
2290 .flags = FLAG_ADVANCED,
2293 .label = "svcctl list",
2295 .p_class = P_GLOBAL,
2296 .ptr = &Globals.szServicesList,
2299 .flags = FLAG_ADVANCED,
2302 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2305 .label = "block size",
2308 .ptr = &sDefault.iBlock_size,
2311 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2314 .label = "deadtime",
2316 .p_class = P_GLOBAL,
2317 .ptr = &Globals.deadtime,
2320 .flags = FLAG_ADVANCED,
2323 .label = "getwd cache",
2325 .p_class = P_GLOBAL,
2326 .ptr = &Globals.getwd_cache,
2329 .flags = FLAG_ADVANCED,
2332 .label = "keepalive",
2334 .p_class = P_GLOBAL,
2335 .ptr = &Globals.iKeepalive,
2338 .flags = FLAG_ADVANCED,
2341 .label = "change notify",
2344 .ptr = &sDefault.bChangeNotify,
2347 .flags = FLAG_ADVANCED | FLAG_SHARE,
2350 .label = "directory name cache size",
2353 .ptr = &sDefault.iDirectoryNameCacheSize,
2356 .flags = FLAG_ADVANCED | FLAG_SHARE,
2359 .label = "kernel change notify",
2362 .ptr = &sDefault.bKernelChangeNotify,
2365 .flags = FLAG_ADVANCED | FLAG_SHARE,
2368 .label = "lpq cache time",
2370 .p_class = P_GLOBAL,
2371 .ptr = &Globals.lpqcachetime,
2374 .flags = FLAG_ADVANCED,
2377 .label = "max smbd processes",
2379 .p_class = P_GLOBAL,
2380 .ptr = &Globals.iMaxSmbdProcesses,
2383 .flags = FLAG_ADVANCED,
2386 .label = "max connections",
2389 .ptr = &sDefault.iMaxConnections,
2392 .flags = FLAG_ADVANCED | FLAG_SHARE,
2395 .label = "paranoid server security",
2397 .p_class = P_GLOBAL,
2398 .ptr = &Globals.paranoid_server_security,
2401 .flags = FLAG_ADVANCED,
2404 .label = "max disk size",
2406 .p_class = P_GLOBAL,
2407 .ptr = &Globals.maxdisksize,
2410 .flags = FLAG_ADVANCED,
2413 .label = "max open files",
2415 .p_class = P_GLOBAL,
2416 .ptr = &Globals.max_open_files,
2419 .flags = FLAG_ADVANCED,
2422 .label = "min print space",
2425 .ptr = &sDefault.iMinPrintSpace,
2428 .flags = FLAG_ADVANCED | FLAG_PRINT,
2431 .label = "socket options",
2433 .p_class = P_GLOBAL,
2434 .ptr = &Globals.szSocketOptions,
2437 .flags = FLAG_ADVANCED,
2440 .label = "strict allocate",
2443 .ptr = &sDefault.bStrictAllocate,
2446 .flags = FLAG_ADVANCED | FLAG_SHARE,
2449 .label = "strict sync",
2452 .ptr = &sDefault.bStrictSync,
2455 .flags = FLAG_ADVANCED | FLAG_SHARE,
2458 .label = "sync always",
2461 .ptr = &sDefault.bSyncAlways,
2464 .flags = FLAG_ADVANCED | FLAG_SHARE,
2467 .label = "use mmap",
2469 .p_class = P_GLOBAL,
2470 .ptr = &Globals.bUseMmap,
2473 .flags = FLAG_ADVANCED,
2476 .label = "use sendfile",
2479 .ptr = &sDefault.bUseSendfile,
2482 .flags = FLAG_ADVANCED | FLAG_SHARE,
2485 .label = "hostname lookups",
2487 .p_class = P_GLOBAL,
2488 .ptr = &Globals.bHostnameLookups,
2491 .flags = FLAG_ADVANCED,
2494 .label = "write cache size",
2497 .ptr = &sDefault.iWriteCacheSize,
2500 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2503 .label = "name cache timeout",
2505 .p_class = P_GLOBAL,
2506 .ptr = &Globals.name_cache_timeout,
2509 .flags = FLAG_ADVANCED,
2512 .label = "ctdbd socket",
2514 .p_class = P_GLOBAL,
2515 .ptr = &Globals.ctdbdSocket,
2518 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2521 .label = "cluster addresses",
2523 .p_class = P_GLOBAL,
2524 .ptr = &Globals.szClusterAddresses,
2527 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2530 .label = "clustering",
2532 .p_class = P_GLOBAL,
2533 .ptr = &Globals.clustering,
2536 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2539 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2542 .label = "max reported print jobs",
2545 .ptr = &sDefault.iMaxReportedPrintJobs,
2548 .flags = FLAG_ADVANCED | FLAG_PRINT,
2551 .label = "max print jobs",
2554 .ptr = &sDefault.iMaxPrintJobs,
2557 .flags = FLAG_ADVANCED | FLAG_PRINT,
2560 .label = "load printers",
2562 .p_class = P_GLOBAL,
2563 .ptr = &Globals.bLoadPrinters,
2566 .flags = FLAG_ADVANCED | FLAG_PRINT,
2569 .label = "printcap cache time",
2571 .p_class = P_GLOBAL,
2572 .ptr = &Globals.PrintcapCacheTime,
2575 .flags = FLAG_ADVANCED | FLAG_PRINT,
2578 .label = "printcap name",
2580 .p_class = P_GLOBAL,
2581 .ptr = &Globals.szPrintcapname,
2584 .flags = FLAG_ADVANCED | FLAG_PRINT,
2587 .label = "printcap",
2589 .p_class = P_GLOBAL,
2590 .ptr = &Globals.szPrintcapname,
2596 .label = "printable",
2599 .ptr = &sDefault.bPrint_ok,
2602 .flags = FLAG_ADVANCED | FLAG_PRINT,
2605 .label = "print ok",
2608 .ptr = &sDefault.bPrint_ok,
2614 .label = "printing",
2617 .ptr = &sDefault.iPrinting,
2618 .special = handle_printing,
2619 .enum_list = enum_printing,
2620 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2623 .label = "cups options",
2626 .ptr = &sDefault.szCupsOptions,
2629 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2632 .label = "cups server",
2634 .p_class = P_GLOBAL,
2635 .ptr = &Globals.szCupsServer,
2638 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2641 .label = "cups connection timeout",
2643 .p_class = P_GLOBAL,
2644 .ptr = &Globals.cups_connection_timeout,
2647 .flags = FLAG_ADVANCED,
2650 .label = "iprint server",
2652 .p_class = P_GLOBAL,
2653 .ptr = &Globals.szIPrintServer,
2656 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2659 .label = "print command",
2662 .ptr = &sDefault.szPrintcommand,
2665 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2668 .label = "disable spoolss",
2670 .p_class = P_GLOBAL,
2671 .ptr = &Globals.bDisableSpoolss,
2674 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2677 .label = "enable spoolss",
2679 .p_class = P_GLOBAL,
2680 .ptr = &Globals.bDisableSpoolss,
2686 .label = "lpq command",
2689 .ptr = &sDefault.szLpqcommand,
2692 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2695 .label = "lprm command",
2698 .ptr = &sDefault.szLprmcommand,
2701 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2704 .label = "lppause command",
2707 .ptr = &sDefault.szLppausecommand,
2710 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2713 .label = "lpresume command",
2716 .ptr = &sDefault.szLpresumecommand,
2719 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2722 .label = "queuepause command",
2725 .ptr = &sDefault.szQueuepausecommand,
2728 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2731 .label = "queueresume command",
2734 .ptr = &sDefault.szQueueresumecommand,
2737 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2740 .label = "addport command",
2742 .p_class = P_GLOBAL,
2743 .ptr = &Globals.szAddPortCommand,
2746 .flags = FLAG_ADVANCED,
2749 .label = "enumports command",
2751 .p_class = P_GLOBAL,
2752 .ptr = &Globals.szEnumPortsCommand,
2755 .flags = FLAG_ADVANCED,
2758 .label = "addprinter command",
2760 .p_class = P_GLOBAL,
2761 .ptr = &Globals.szAddPrinterCommand,
2764 .flags = FLAG_ADVANCED,
2767 .label = "deleteprinter command",
2769 .p_class = P_GLOBAL,
2770 .ptr = &Globals.szDeletePrinterCommand,
2773 .flags = FLAG_ADVANCED,
2776 .label = "show add printer wizard",
2778 .p_class = P_GLOBAL,
2779 .ptr = &Globals.bMsAddPrinterWizard,
2782 .flags = FLAG_ADVANCED,
2785 .label = "os2 driver map",
2787 .p_class = P_GLOBAL,
2788 .ptr = &Globals.szOs2DriverMap,
2791 .flags = FLAG_ADVANCED,
2795 .label = "printer name",
2798 .ptr = &sDefault.szPrintername,
2801 .flags = FLAG_ADVANCED | FLAG_PRINT,
2807 .ptr = &sDefault.szPrintername,
2813 .label = "use client driver",
2816 .ptr = &sDefault.bUseClientDriver,
2819 .flags = FLAG_ADVANCED | FLAG_PRINT,
2822 .label = "default devmode",
2825 .ptr = &sDefault.bDefaultDevmode,
2828 .flags = FLAG_ADVANCED | FLAG_PRINT,
2831 .label = "force printername",
2834 .ptr = &sDefault.bForcePrintername,
2837 .flags = FLAG_ADVANCED | FLAG_PRINT,
2840 .label = "printjob username",
2843 .ptr = &sDefault.szPrintjobUsername,
2846 .flags = FLAG_ADVANCED | FLAG_PRINT,
2849 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2852 .label = "mangling method",
2854 .p_class = P_GLOBAL,
2855 .ptr = &Globals.szManglingMethod,
2858 .flags = FLAG_ADVANCED,
2861 .label = "mangle prefix",
2863 .p_class = P_GLOBAL,
2864 .ptr = &Globals.mangle_prefix,
2867 .flags = FLAG_ADVANCED,
2871 .label = "default case",
2874 .ptr = &sDefault.iDefaultCase,
2876 .enum_list = enum_case,
2877 .flags = FLAG_ADVANCED | FLAG_SHARE,
2880 .label = "case sensitive",
2883 .ptr = &sDefault.iCaseSensitive,
2885 .enum_list = enum_bool_auto,
2886 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2889 .label = "casesignames",
2892 .ptr = &sDefault.iCaseSensitive,
2894 .enum_list = enum_bool_auto,
2895 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2898 .label = "preserve case",
2901 .ptr = &sDefault.bCasePreserve,
2904 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2907 .label = "short preserve case",
2910 .ptr = &sDefault.bShortCasePreserve,
2913 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2916 .label = "mangling char",
2919 .ptr = &sDefault.magic_char,
2922 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2925 .label = "hide dot files",
2928 .ptr = &sDefault.bHideDotFiles,
2931 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2934 .label = "hide special files",
2937 .ptr = &sDefault.bHideSpecialFiles,
2940 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2943 .label = "hide unreadable",
2946 .ptr = &sDefault.bHideUnReadable,
2949 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2952 .label = "hide unwriteable files",
2955 .ptr = &sDefault.bHideUnWriteableFiles,
2958 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2961 .label = "delete veto files",
2964 .ptr = &sDefault.bDeleteVetoFiles,
2967 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2970 .label = "veto files",
2973 .ptr = &sDefault.szVetoFiles,
2976 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2979 .label = "hide files",
2982 .ptr = &sDefault.szHideFiles,
2985 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2988 .label = "veto oplock files",
2991 .ptr = &sDefault.szVetoOplockFiles,
2994 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2997 .label = "map archive",
3000 .ptr = &sDefault.bMap_archive,
3003 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3006 .label = "map hidden",
3009 .ptr = &sDefault.bMap_hidden,
3012 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3015 .label = "map system",
3018 .ptr = &sDefault.bMap_system,
3021 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3024 .label = "map readonly",
3027 .ptr = &sDefault.iMap_readonly,
3029 .enum_list = enum_map_readonly,
3030 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3033 .label = "mangled names",
3036 .ptr = &sDefault.bMangledNames,
3039 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3042 .label = "max stat cache size",
3044 .p_class = P_GLOBAL,
3045 .ptr = &Globals.iMaxStatCacheSize,
3048 .flags = FLAG_ADVANCED,
3051 .label = "stat cache",
3053 .p_class = P_GLOBAL,
3054 .ptr = &Globals.bStatCache,
3057 .flags = FLAG_ADVANCED,
3060 .label = "store dos attributes",
3063 .ptr = &sDefault.bStoreDosAttributes,
3066 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3069 .label = "dmapi support",
3072 .ptr = &sDefault.bDmapiSupport,
3075 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3079 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3082 .label = "machine password timeout",
3084 .p_class = P_GLOBAL,
3085 .ptr = &Globals.machine_password_timeout,
3088 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3091 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3094 .label = "add user script",
3096 .p_class = P_GLOBAL,
3097 .ptr = &Globals.szAddUserScript,
3100 .flags = FLAG_ADVANCED,
3103 .label = "rename user script",
3105 .p_class = P_GLOBAL,
3106 .ptr = &Globals.szRenameUserScript,
3109 .flags = FLAG_ADVANCED,
3112 .label = "delete user script",
3114 .p_class = P_GLOBAL,
3115 .ptr = &Globals.szDelUserScript,
3118 .flags = FLAG_ADVANCED,
3121 .label = "add group script",
3123 .p_class = P_GLOBAL,
3124 .ptr = &Globals.szAddGroupScript,
3127 .flags = FLAG_ADVANCED,
3130 .label = "delete group script",
3132 .p_class = P_GLOBAL,
3133 .ptr = &Globals.szDelGroupScript,
3136 .flags = FLAG_ADVANCED,
3139 .label = "add user to group script",
3141 .p_class = P_GLOBAL,
3142 .ptr = &Globals.szAddUserToGroupScript,
3145 .flags = FLAG_ADVANCED,
3148 .label = "delete user from group script",
3150 .p_class = P_GLOBAL,
3151 .ptr = &Globals.szDelUserFromGroupScript,
3154 .flags = FLAG_ADVANCED,
3157 .label = "set primary group script",
3159 .p_class = P_GLOBAL,
3160 .ptr = &Globals.szSetPrimaryGroupScript,
3163 .flags = FLAG_ADVANCED,
3166 .label = "add machine script",
3168 .p_class = P_GLOBAL,
3169 .ptr = &Globals.szAddMachineScript,
3172 .flags = FLAG_ADVANCED,
3175 .label = "shutdown script",
3177 .p_class = P_GLOBAL,
3178 .ptr = &Globals.szShutdownScript,
3181 .flags = FLAG_ADVANCED,
3184 .label = "abort shutdown script",
3186 .p_class = P_GLOBAL,
3187 .ptr = &Globals.szAbortShutdownScript,
3190 .flags = FLAG_ADVANCED,
3193 .label = "username map script",
3195 .p_class = P_GLOBAL,
3196 .ptr = &Globals.szUsernameMapScript,
3199 .flags = FLAG_ADVANCED,
3202 .label = "logon script",
3204 .p_class = P_GLOBAL,
3205 .ptr = &Globals.szLogonScript,
3208 .flags = FLAG_ADVANCED,
3211 .label = "logon path",
3213 .p_class = P_GLOBAL,
3214 .ptr = &Globals.szLogonPath,
3217 .flags = FLAG_ADVANCED,
3220 .label = "logon drive",
3222 .p_class = P_GLOBAL,
3223 .ptr = &Globals.szLogonDrive,
3226 .flags = FLAG_ADVANCED,
3229 .label = "logon home",
3231 .p_class = P_GLOBAL,
3232 .ptr = &Globals.szLogonHome,
3235 .flags = FLAG_ADVANCED,
3238 .label = "domain logons",
3240 .p_class = P_GLOBAL,
3241 .ptr = &Globals.bDomainLogons,
3244 .flags = FLAG_ADVANCED,
3248 .label = "init logon delayed hosts",
3250 .p_class = P_GLOBAL,
3251 .ptr = &Globals.szInitLogonDelayedHosts,
3252 .flags = FLAG_ADVANCED,
3256 .label = "init logon delay",
3258 .p_class = P_GLOBAL,
3259 .ptr = &Globals.InitLogonDelay,
3260 .flags = FLAG_ADVANCED,
3264 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3267 .label = "os level",
3269 .p_class = P_GLOBAL,
3270 .ptr = &Globals.os_level,
3273 .flags = FLAG_BASIC | FLAG_ADVANCED,
3276 .label = "lm announce",
3278 .p_class = P_GLOBAL,
3279 .ptr = &Globals.lm_announce,
3281 .enum_list = enum_bool_auto,
3282 .flags = FLAG_ADVANCED,
3285 .label = "lm interval",
3287 .p_class = P_GLOBAL,
3288 .ptr = &Globals.lm_interval,
3291 .flags = FLAG_ADVANCED,
3294 .label = "preferred master",
3296 .p_class = P_GLOBAL,
3297 .ptr = &Globals.iPreferredMaster,
3299 .enum_list = enum_bool_auto,
3300 .flags = FLAG_BASIC | FLAG_ADVANCED,
3303 .label = "prefered master",
3305 .p_class = P_GLOBAL,
3306 .ptr = &Globals.iPreferredMaster,
3308 .enum_list = enum_bool_auto,
3312 .label = "local master",
3314 .p_class = P_GLOBAL,
3315 .ptr = &Globals.bLocalMaster,
3318 .flags = FLAG_BASIC | FLAG_ADVANCED,
3321 .label = "domain master",
3323 .p_class = P_GLOBAL,
3324 .ptr = &Globals.iDomainMaster,
3326 .enum_list = enum_bool_auto,
3327 .flags = FLAG_BASIC | FLAG_ADVANCED,
3330 .label = "browse list",
3332 .p_class = P_GLOBAL,
3333 .ptr = &Globals.bBrowseList,
3336 .flags = FLAG_ADVANCED,
3339 .label = "browseable",
3342 .ptr = &sDefault.bBrowseable,
3345 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3348 .label = "access based share enum",
3351 .ptr = &sDefault.bAccessBasedShareEnum,
3354 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3357 .label = "browsable",
3360 .ptr = &sDefault.bBrowseable,
3366 .label = "enhanced browsing",
3368 .p_class = P_GLOBAL,
3369 .ptr = &Globals.enhanced_browsing,
3372 .flags = FLAG_ADVANCED,
3375 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3378 .label = "dns proxy",
3380 .p_class = P_GLOBAL,
3381 .ptr = &Globals.bDNSproxy,
3384 .flags = FLAG_ADVANCED,
3387 .label = "wins proxy",
3389 .p_class = P_GLOBAL,
3390 .ptr = &Globals.bWINSproxy,
3393 .flags = FLAG_ADVANCED,
3396 .label = "wins server",
3398 .p_class = P_GLOBAL,
3399 .ptr = &Globals.szWINSservers,
3402 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3405 .label = "wins support",
3407 .p_class = P_GLOBAL,
3408 .ptr = &Globals.bWINSsupport,
3411 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3414 .label = "wins hook",
3416 .p_class = P_GLOBAL,
3417 .ptr = &Globals.szWINSHook,
3420 .flags = FLAG_ADVANCED,
3423 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3426 .label = "blocking locks",
3429 .ptr = &sDefault.bBlockingLocks,
3432 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3435 .label = "csc policy",
3438 .ptr = &sDefault.iCSCPolicy,
3440 .enum_list = enum_csc_policy,
3441 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3444 .label = "fake oplocks",
3447 .ptr = &sDefault.bFakeOplocks,
3450 .flags = FLAG_ADVANCED | FLAG_SHARE,
3453 .label = "kernel oplocks",
3455 .p_class = P_GLOBAL,
3456 .ptr = &Globals.bKernelOplocks,
3459 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3465 .ptr = &sDefault.bLocking,
3468 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3471 .label = "lock spin time",
3473 .p_class = P_GLOBAL,
3474 .ptr = &Globals.iLockSpinTime,
3477 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3483 .ptr = &sDefault.bOpLocks,
3486 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3489 .label = "level2 oplocks",
3492 .ptr = &sDefault.bLevel2OpLocks,
3495 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3498 .label = "oplock break wait time",
3500 .p_class = P_GLOBAL,
3501 .ptr = &Globals.oplock_break_wait_time,
3504 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3507 .label = "oplock contention limit",
3510 .ptr = &sDefault.iOplockContentionLimit,
3513 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3516 .label = "posix locking",
3519 .ptr = &sDefault.bPosixLocking,
3522 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3525 .label = "strict locking",
3528 .ptr = &sDefault.iStrictLocking,
3530 .enum_list = enum_bool_auto,
3531 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3534 .label = "share modes",
3537 .ptr = &sDefault.bShareModes,
3540 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3543 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3546 .label = "ldap admin dn",
3548 .p_class = P_GLOBAL,
3549 .ptr = &Globals.szLdapAdminDn,
3552 .flags = FLAG_ADVANCED,
3555 .label = "ldap delete dn",
3557 .p_class = P_GLOBAL,
3558 .ptr = &Globals.ldap_delete_dn,
3561 .flags = FLAG_ADVANCED,
3564 .label = "ldap group suffix",
3566 .p_class = P_GLOBAL,
3567 .ptr = &Globals.szLdapGroupSuffix,
3570 .flags = FLAG_ADVANCED,
3573 .label = "ldap idmap suffix",
3575 .p_class = P_GLOBAL,
3576 .ptr = &Globals.szLdapIdmapSuffix,
3579 .flags = FLAG_ADVANCED,
3582 .label = "ldap machine suffix",
3584 .p_class = P_GLOBAL,
3585 .ptr = &Globals.szLdapMachineSuffix,
3588 .flags = FLAG_ADVANCED,
3591 .label = "ldap passwd sync",
3593 .p_class = P_GLOBAL,
3594 .ptr = &Globals.ldap_passwd_sync,
3596 .enum_list = enum_ldap_passwd_sync,
3597 .flags = FLAG_ADVANCED,
3600 .label = "ldap password sync",
3602 .p_class = P_GLOBAL,
3603 .ptr = &Globals.ldap_passwd_sync,
3605 .enum_list = enum_ldap_passwd_sync,
3609 .label = "ldap replication sleep",
3611 .p_class = P_GLOBAL,
3612 .ptr = &Globals.ldap_replication_sleep,
3615 .flags = FLAG_ADVANCED,
3618 .label = "ldap suffix",
3620 .p_class = P_GLOBAL,
3621 .ptr = &Globals.szLdapSuffix,
3624 .flags = FLAG_ADVANCED,
3627 .label = "ldap ssl",
3629 .p_class = P_GLOBAL,
3630 .ptr = &Globals.ldap_ssl,
3632 .enum_list = enum_ldap_ssl,
3633 .flags = FLAG_ADVANCED,
3636 .label = "ldap ssl ads",
3638 .p_class = P_GLOBAL,
3639 .ptr = &Globals.ldap_ssl_ads,
3642 .flags = FLAG_ADVANCED,
3645 .label = "ldap timeout",
3647 .p_class = P_GLOBAL,
3648 .ptr = &Globals.ldap_timeout,
3651 .flags = FLAG_ADVANCED,
3654 .label = "ldap connection timeout",
3656 .p_class = P_GLOBAL,
3657 .ptr = &Globals.ldap_connection_timeout,
3660 .flags = FLAG_ADVANCED,
3663 .label = "ldap page size",
3665 .p_class = P_GLOBAL,
3666 .ptr = &Globals.ldap_page_size,
3669 .flags = FLAG_ADVANCED,
3672 .label = "ldap user suffix",
3674 .p_class = P_GLOBAL,
3675 .ptr = &Globals.szLdapUserSuffix,
3678 .flags = FLAG_ADVANCED,
3681 .label = "ldap debug level",
3683 .p_class = P_GLOBAL,
3684 .ptr = &Globals.ldap_debug_level,
3685 .special = handle_ldap_debug_level,
3687 .flags = FLAG_ADVANCED,
3690 .label = "ldap debug threshold",
3692 .p_class = P_GLOBAL,
3693 .ptr = &Globals.ldap_debug_threshold,
3696 .flags = FLAG_ADVANCED,
3699 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3702 .label = "eventlog list",
3704 .p_class = P_GLOBAL,
3705 .ptr = &Globals.szEventLogs,
3708 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3711 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3714 .label = "add share command",
3716 .p_class = P_GLOBAL,
3717 .ptr = &Globals.szAddShareCommand,
3720 .flags = FLAG_ADVANCED,
3723 .label = "change share command",
3725 .p_class = P_GLOBAL,
3726 .ptr = &Globals.szChangeShareCommand,
3729 .flags = FLAG_ADVANCED,
3732 .label = "delete share command",
3734 .p_class = P_GLOBAL,
3735 .ptr = &Globals.szDeleteShareCommand,
3738 .flags = FLAG_ADVANCED,
3741 .label = "config file",
3743 .p_class = P_GLOBAL,
3744 .ptr = &Globals.szConfigFile,
3752 .p_class = P_GLOBAL,
3753 .ptr = &Globals.szAutoServices,
3756 .flags = FLAG_ADVANCED,
3759 .label = "auto services",
3761 .p_class = P_GLOBAL,
3762 .ptr = &Globals.szAutoServices,
3765 .flags = FLAG_ADVANCED,
3768 .label = "lock directory",
3770 .p_class = P_GLOBAL,
3771 .ptr = &Globals.szLockDir,
3774 .flags = FLAG_ADVANCED,
3777 .label = "lock dir",
3779 .p_class = P_GLOBAL,
3780 .ptr = &Globals.szLockDir,
3786 .label = "state directory",
3788 .p_class = P_GLOBAL,
3789 .ptr = &Globals.szStateDir,
3792 .flags = FLAG_ADVANCED,
3795 .label = "cache directory",
3797 .p_class = P_GLOBAL,
3798 .ptr = &Globals.szCacheDir,
3801 .flags = FLAG_ADVANCED,
3804 .label = "pid directory",
3806 .p_class = P_GLOBAL,
3807 .ptr = &Globals.szPidDir,
3810 .flags = FLAG_ADVANCED,
3814 .label = "utmp directory",
3816 .p_class = P_GLOBAL,
3817 .ptr = &Globals.szUtmpDir,
3820 .flags = FLAG_ADVANCED,
3823 .label = "wtmp directory",
3825 .p_class = P_GLOBAL,
3826 .ptr = &Globals.szWtmpDir,
3829 .flags = FLAG_ADVANCED,
3834 .p_class = P_GLOBAL,
3835 .ptr = &Globals.bUtmp,
3838 .flags = FLAG_ADVANCED,
3842 .label = "default service",
3844 .p_class = P_GLOBAL,
3845 .ptr = &Globals.szDefaultService,
3848 .flags = FLAG_ADVANCED,
3853 .p_class = P_GLOBAL,
3854 .ptr = &Globals.szDefaultService,
3857 .flags = FLAG_ADVANCED,
3860 .label = "message command",
3862 .p_class = P_GLOBAL,
3863 .ptr = &Globals.szMsgCommand,
3866 .flags = FLAG_ADVANCED,
3869 .label = "dfree cache time",
3872 .ptr = &sDefault.iDfreeCacheTime,
3875 .flags = FLAG_ADVANCED,
3878 .label = "dfree command",
3881 .ptr = &sDefault.szDfree,
3884 .flags = FLAG_ADVANCED,
3887 .label = "get quota command",
3889 .p_class = P_GLOBAL,
3890 .ptr = &Globals.szGetQuota,
3893 .flags = FLAG_ADVANCED,
3896 .label = "set quota command",
3898 .p_class = P_GLOBAL,
3899 .ptr = &Globals.szSetQuota,
3902 .flags = FLAG_ADVANCED,
3905 .label = "remote announce",
3907 .p_class = P_GLOBAL,
3908 .ptr = &Globals.szRemoteAnnounce,
3911 .flags = FLAG_ADVANCED,
3914 .label = "remote browse sync",
3916 .p_class = P_GLOBAL,
3917 .ptr = &Globals.szRemoteBrowseSync,
3920 .flags = FLAG_ADVANCED,
3923 .label = "socket address",
3925 .p_class = P_GLOBAL,
3926 .ptr = &Globals.szSocketAddress,
3929 .flags = FLAG_ADVANCED,
3932 .label = "homedir map",
3934 .p_class = P_GLOBAL,
3935 .ptr = &Globals.szNISHomeMapName,
3938 .flags = FLAG_ADVANCED,
3941 .label = "afs username map",
3943 .p_class = P_GLOBAL,
3944 .ptr = &Globals.szAfsUsernameMap,
3947 .flags = FLAG_ADVANCED,
3950 .label = "afs token lifetime",
3952 .p_class = P_GLOBAL,
3953 .ptr = &Globals.iAfsTokenLifetime,
3956 .flags = FLAG_ADVANCED,
3959 .label = "log nt token command",
3961 .p_class = P_GLOBAL,
3962 .ptr = &Globals.szLogNtTokenCommand,
3965 .flags = FLAG_ADVANCED,
3968 .label = "time offset",
3970 .p_class = P_GLOBAL,
3971 .ptr = &extra_time_offset,
3974 .flags = FLAG_ADVANCED,
3977 .label = "NIS homedir",
3979 .p_class = P_GLOBAL,
3980 .ptr = &Globals.bNISHomeMap,
3983 .flags = FLAG_ADVANCED,
3989 .ptr = &sDefault.valid,
3998 .ptr = &sDefault.szCopy,
3999 .special = handle_copy,
4007 .ptr = &sDefault.szInclude,
4008 .special = handle_include,
4016 .ptr = &sDefault.szPreExec,
4019 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4025 .ptr = &sDefault.szPreExec,
4028 .flags = FLAG_ADVANCED,
4031 .label = "preexec close",
4034 .ptr = &sDefault.bPreexecClose,
4037 .flags = FLAG_ADVANCED | FLAG_SHARE,
4040 .label = "postexec",
4043 .ptr = &sDefault.szPostExec,
4046 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4049 .label = "root preexec",
4052 .ptr = &sDefault.szRootPreExec,
4055 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4058 .label = "root preexec close",
4061 .ptr = &sDefault.bRootpreexecClose,
4064 .flags = FLAG_ADVANCED | FLAG_SHARE,
4067 .label = "root postexec",
4070 .ptr = &sDefault.szRootPostExec,
4073 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4076 .label = "available",
4079 .ptr = &sDefault.bAvailable,
4082 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4085 .label = "registry shares",
4087 .p_class = P_GLOBAL,
4088 .ptr = &Globals.bRegistryShares,
4091 .flags = FLAG_ADVANCED,
4094 .label = "usershare allow guests",
4096 .p_class = P_GLOBAL,
4097 .ptr = &Globals.bUsershareAllowGuests,
4100 .flags = FLAG_ADVANCED,
4103 .label = "usershare max shares",
4105 .p_class = P_GLOBAL,
4106 .ptr = &Globals.iUsershareMaxShares,
4109 .flags = FLAG_ADVANCED,
4112 .label = "usershare owner only",
4114 .p_class = P_GLOBAL,
4115 .ptr = &Globals.bUsershareOwnerOnly,
4118 .flags = FLAG_ADVANCED,
4121 .label = "usershare path",
4123 .p_class = P_GLOBAL,
4124 .ptr = &Globals.szUsersharePath,
4127 .flags = FLAG_ADVANCED,
4130 .label = "usershare prefix allow list",
4132 .p_class = P_GLOBAL,
4133 .ptr = &Globals.szUsersharePrefixAllowList,
4136 .flags = FLAG_ADVANCED,
4139 .label = "usershare prefix deny list",
4141 .p_class = P_GLOBAL,
4142 .ptr = &Globals.szUsersharePrefixDenyList,
4145 .flags = FLAG_ADVANCED,
4148 .label = "usershare template share",
4150 .p_class = P_GLOBAL,
4151 .ptr = &Globals.szUsershareTemplateShare,
4154 .flags = FLAG_ADVANCED,
4160 .ptr = &sDefault.volume,
4163 .flags = FLAG_ADVANCED | FLAG_SHARE,
4169 .ptr = &sDefault.fstype,
4172 .flags = FLAG_ADVANCED | FLAG_SHARE,
4175 .label = "set directory",
4178 .ptr = &sDefault.bNo_set_dir,
4181 .flags = FLAG_ADVANCED | FLAG_SHARE,
4184 .label = "wide links",
4187 .ptr = &sDefault.bWidelinks,
4190 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4193 .label = "follow symlinks",
4196 .ptr = &sDefault.bSymlinks,
4199 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4202 .label = "dont descend",
4205 .ptr = &sDefault.szDontdescend,
4208 .flags = FLAG_ADVANCED | FLAG_SHARE,
4211 .label = "magic script",
4214 .ptr = &sDefault.szMagicScript,
4217 .flags = FLAG_ADVANCED | FLAG_SHARE,
4220 .label = "magic output",
4223 .ptr = &sDefault.szMagicOutput,
4226 .flags = FLAG_ADVANCED | FLAG_SHARE,
4229 .label = "delete readonly",
4232 .ptr = &sDefault.bDeleteReadonly,
4235 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4238 .label = "dos filemode",
4241 .ptr = &sDefault.bDosFilemode,
4244 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4247 .label = "dos filetimes",
4250 .ptr = &sDefault.bDosFiletimes,
4253 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4256 .label = "dos filetime resolution",
4259 .ptr = &sDefault.bDosFiletimeResolution,
4262 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4265 .label = "fake directory create times",
4268 .ptr = &sDefault.bFakeDirCreateTimes,
4271 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4274 .label = "panic action",
4276 .p_class = P_GLOBAL,
4277 .ptr = &Globals.szPanicAction,
4280 .flags = FLAG_ADVANCED,
4283 .label = "perfcount module",
4285 .p_class = P_GLOBAL,
4286 .ptr = &Globals.szSMBPerfcountModule,
4289 .flags = FLAG_ADVANCED,
4292 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4295 .label = "vfs objects",
4298 .ptr = &sDefault.szVfsObjects,
4301 .flags = FLAG_ADVANCED | FLAG_SHARE,
4304 .label = "vfs object",
4307 .ptr = &sDefault.szVfsObjects,
4314 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4317 .label = "msdfs root",
4320 .ptr = &sDefault.bMSDfsRoot,
4323 .flags = FLAG_ADVANCED | FLAG_SHARE,
4326 .label = "msdfs proxy",
4329 .ptr = &sDefault.szMSDfsProxy,
4332 .flags = FLAG_ADVANCED | FLAG_SHARE,
4335 .label = "host msdfs",
4337 .p_class = P_GLOBAL,
4338 .ptr = &Globals.bHostMSDfs,
4341 .flags = FLAG_ADVANCED,
4344 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4347 .label = "passdb expand explicit",
4349 .p_class = P_GLOBAL,
4350 .ptr = &Globals.bPassdbExpandExplicit,
4353 .flags = FLAG_ADVANCED,
4356 .label = "idmap backend",
4358 .p_class = P_GLOBAL,
4359 .ptr = &Globals.szIdmapBackend,
4362 .flags = FLAG_ADVANCED,
4365 .label = "idmap alloc backend",
4367 .p_class = P_GLOBAL,
4368 .ptr = &Globals.szIdmapAllocBackend,
4371 .flags = FLAG_ADVANCED,
4374 .label = "idmap cache time",
4376 .p_class = P_GLOBAL,
4377 .ptr = &Globals.iIdmapCacheTime,
4380 .flags = FLAG_ADVANCED,
4383 .label = "idmap negative cache time",
4385 .p_class = P_GLOBAL,
4386 .ptr = &Globals.iIdmapNegativeCacheTime,
4389 .flags = FLAG_ADVANCED,
4392 .label = "idmap uid",
4394 .p_class = P_GLOBAL,
4395 .ptr = &Globals.szIdmapUID,
4396 .special = handle_idmap_uid,
4398 .flags = FLAG_ADVANCED,
4401 .label = "winbind uid",
4403 .p_class = P_GLOBAL,
4404 .ptr = &Globals.szIdmapUID,
4405 .special = handle_idmap_uid,
4410 .label = "idmap gid",
4412 .p_class = P_GLOBAL,
4413 .ptr = &Globals.szIdmapGID,
4414 .special = handle_idmap_gid,
4416 .flags = FLAG_ADVANCED,
4419 .label = "winbind gid",
4421 .p_class = P_GLOBAL,
4422 .ptr = &Globals.szIdmapGID,
4423 .special = handle_idmap_gid,
4428 .label = "template homedir",
4430 .p_class = P_GLOBAL,
4431 .ptr = &Globals.szTemplateHomedir,
4434 .flags = FLAG_ADVANCED,
4437 .label = "template shell",
4439 .p_class = P_GLOBAL,
4440 .ptr = &Globals.szTemplateShell,
4443 .flags = FLAG_ADVANCED,
4446 .label = "winbind separator",
4448 .p_class = P_GLOBAL,
4449 .ptr = &Globals.szWinbindSeparator,
4452 .flags = FLAG_ADVANCED,
4455 .label = "winbind cache time",
4457 .p_class = P_GLOBAL,
4458 .ptr = &Globals.winbind_cache_time,
4461 .flags = FLAG_ADVANCED,
4464 .label = "winbind reconnect delay",
4466 .p_class = P_GLOBAL,
4467 .ptr = &Globals.winbind_reconnect_delay,
4470 .flags = FLAG_ADVANCED,
4473 .label = "winbind enum users",
4475 .p_class = P_GLOBAL,
4476 .ptr = &Globals.bWinbindEnumUsers,
4479 .flags = FLAG_ADVANCED,
4482 .label = "winbind enum groups",
4484 .p_class = P_GLOBAL,
4485 .ptr = &Globals.bWinbindEnumGroups,
4488 .flags = FLAG_ADVANCED,
4491 .label = "winbind use default domain",
4493 .p_class = P_GLOBAL,
4494 .ptr = &Globals.bWinbindUseDefaultDomain,
4497 .flags = FLAG_ADVANCED,
4500 .label = "winbind trusted domains only",
4502 .p_class = P_GLOBAL,
4503 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4506 .flags = FLAG_ADVANCED,
4509 .label = "winbind nested groups",
4511 .p_class = P_GLOBAL,
4512 .ptr = &Globals.bWinbindNestedGroups,
4515 .flags = FLAG_ADVANCED,
4518 .label = "winbind expand groups",
4520 .p_class = P_GLOBAL,
4521 .ptr = &Globals.winbind_expand_groups,
4524 .flags = FLAG_ADVANCED,
4527 .label = "winbind nss info",
4529 .p_class = P_GLOBAL,
4530 .ptr = &Globals.szWinbindNssInfo,
4533 .flags = FLAG_ADVANCED,
4536 .label = "winbind refresh tickets",
4538 .p_class = P_GLOBAL,
4539 .ptr = &Globals.bWinbindRefreshTickets,
4542 .flags = FLAG_ADVANCED,
4545 .label = "winbind offline logon",
4547 .p_class = P_GLOBAL,
4548 .ptr = &Globals.bWinbindOfflineLogon,
4551 .flags = FLAG_ADVANCED,
4554 .label = "winbind normalize names",
4556 .p_class = P_GLOBAL,
4557 .ptr = &Globals.bWinbindNormalizeNames,
4560 .flags = FLAG_ADVANCED,
4563 .label = "winbind rpc only",
4565 .p_class = P_GLOBAL,
4566 .ptr = &Globals.bWinbindRpcOnly,
4569 .flags = FLAG_ADVANCED,
4572 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4575 /***************************************************************************
4576 Initialise the sDefault parameter structure for the printer values.
4577 ***************************************************************************/
4579 static void init_printer_values(struct service *pService)
4581 /* choose defaults depending on the type of printing */
4582 switch (pService->iPrinting) {
4587 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4588 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4589 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4594 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4595 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4596 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4597 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4598 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4599 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4600 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4606 /* set the lpq command to contain the destination printer
4607 name only. This is used by cups_queue_get() */
4608 string_set(&pService->szLpqcommand, "%p");
4609 string_set(&pService->szLprmcommand, "");
4610 string_set(&pService->szPrintcommand, "");
4611 string_set(&pService->szLppausecommand, "");
4612 string_set(&pService->szLpresumecommand, "");
4613 string_set(&pService->szQueuepausecommand, "");
4614 string_set(&pService->szQueueresumecommand, "");
4616 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4617 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4618 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4619 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4620 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4621 string_set(&pService->szQueuepausecommand, "disable '%p'");
4622 string_set(&pService->szQueueresumecommand, "enable '%p'");
4623 #endif /* HAVE_CUPS */
4628 string_set(&pService->szLpqcommand, "lpstat -o%p");
4629 string_set(&pService->szLprmcommand, "cancel %p-%j");
4630 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4631 string_set(&pService->szQueuepausecommand, "disable %p");
4632 string_set(&pService->szQueueresumecommand, "enable %p");
4634 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4635 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4640 string_set(&pService->szLpqcommand, "lpq -P%p");
4641 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4642 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4648 string_set(&pService->szPrintcommand, "vlp print %p %s");
4649 string_set(&pService->szLpqcommand, "vlp lpq %p");
4650 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4651 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4652 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4653 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4654 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4656 #endif /* DEVELOPER */
4662 * Common part of freeing allocated data for one parameter.
4664 static void free_one_parameter_common(void *parm_ptr,
4665 struct parm_struct parm)
4667 if ((parm.type == P_STRING) ||
4668 (parm.type == P_USTRING))
4670 string_free((char**)parm_ptr);
4671 } else if (parm.type == P_LIST) {
4672 TALLOC_FREE(*((char***)parm_ptr));
4677 * Free the allocated data for one parameter for a share
4678 * given as a service struct.
4680 static void free_one_parameter(struct service *service,
4681 struct parm_struct parm)
4685 if (parm.p_class != P_LOCAL) {
4689 parm_ptr = lp_local_ptr(service, parm.ptr);
4691 free_one_parameter_common(parm_ptr, parm);
4695 * Free the allocated parameter data of a share given
4696 * as a service struct.
4698 static void free_parameters(struct service *service)
4702 for (i=0; parm_table[i].label; i++) {
4703 free_one_parameter(service, parm_table[i]);
4708 * Free the allocated data for one parameter for a given share
4709 * specified by an snum.
4711 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4715 if (parm.ptr == NULL) {
4720 parm_ptr = parm.ptr;
4721 } else if (parm.p_class != P_LOCAL) {
4724 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4727 free_one_parameter_common(parm_ptr, parm);
4731 * Free the allocated parameter data for a share specified
4734 static void free_parameters_by_snum(int snum)
4738 for (i=0; parm_table[i].label; i++) {
4739 free_one_parameter_by_snum(snum, parm_table[i]);
4744 * Free the allocated global parameters.
4746 static void free_global_parameters(void)
4748 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4751 /***************************************************************************
4752 Initialise the global parameter structure.
4753 ***************************************************************************/
4755 static void init_globals(bool first_time_only)
4757 static bool done_init = False;
4761 /* If requested to initialize only once and we've already done it... */
4762 if (first_time_only && done_init) {
4763 /* ... then we have nothing more to do */
4768 /* The logfile can be set before this is invoked. Free it if so. */
4769 if (Globals.szLogFile != NULL) {
4770 string_free(&Globals.szLogFile);
4771 Globals.szLogFile = NULL;
4775 free_global_parameters();
4778 memset((void *)&Globals, '\0', sizeof(Globals));
4780 for (i = 0; parm_table[i].label; i++) {
4781 if ((parm_table[i].type == P_STRING ||
4782 parm_table[i].type == P_USTRING) &&
4785 string_set((char **)parm_table[i].ptr, "");
4789 string_set(&sDefault.fstype, FSTYPE_STRING);
4790 string_set(&sDefault.szPrintjobUsername, "%U");
4792 init_printer_values(&sDefault);
4795 DEBUG(3, ("Initialising global parameters\n"));
4797 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4798 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4800 /* use the new 'hash2' method by default, with a prefix of 1 */
4801 string_set(&Globals.szManglingMethod, "hash2");
4802 Globals.mangle_prefix = 1;
4804 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4806 /* using UTF8 by default allows us to support all chars */
4807 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4809 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4810 /* If the system supports nl_langinfo(), try to grab the value
4811 from the user's locale */
4812 string_set(&Globals.display_charset, "LOCALE");
4814 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4817 /* Use codepage 850 as a default for the dos character set */
4818 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4821 * Allow the default PASSWD_CHAT to be overridden in local.h.
4823 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4825 set_global_myname(myhostname());
4826 string_set(&Globals.szNetbiosName,global_myname());
4828 set_global_myworkgroup(WORKGROUP);
4829 string_set(&Globals.szWorkgroup, lp_workgroup());
4831 string_set(&Globals.szPasswdProgram, "");
4832 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4833 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4834 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4835 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4836 string_set(&Globals.szSocketAddress, "0.0.0.0");
4838 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4839 smb_panic("init_globals: ENOMEM");
4841 string_set(&Globals.szServerString, s);
4843 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4844 DEFAULT_MINOR_VERSION) < 0) {
4845 smb_panic("init_globals: ENOMEM");
4847 string_set(&Globals.szAnnounceVersion, s);
4850 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4853 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4855 string_set(&Globals.szLogonDrive, "");
4856 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4857 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4858 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4860 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4861 string_set(&Globals.szPasswordServer, "*");
4863 Globals.AlgorithmicRidBase = BASE_RID;
4865 Globals.bLoadPrinters = True;
4866 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4868 Globals.ConfigBackend = config_backend;
4870 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4871 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4872 Globals.max_xmit = 0x4104;
4873 Globals.max_mux = 50; /* This is *needed* for profile support. */
4874 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4875 Globals.bDisableSpoolss = False;
4876 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4877 Globals.pwordlevel = 0;
4878 Globals.unamelevel = 0;
4879 Globals.deadtime = 0;
4880 Globals.getwd_cache = true;
4881 Globals.bLargeReadwrite = True;
4882 Globals.max_log_size = 5000;
4883 Globals.max_open_files = MAX_OPEN_FILES;
4884 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4885 Globals.maxprotocol = PROTOCOL_NT1;
4886 Globals.minprotocol = PROTOCOL_CORE;
4887 Globals.security = SEC_USER;
4888 Globals.paranoid_server_security = True;
4889 Globals.bEncryptPasswords = True;
4890 Globals.bUpdateEncrypt = False;
4891 Globals.clientSchannel = Auto;
4892 Globals.serverSchannel = Auto;
4893 Globals.bReadRaw = True;
4894 Globals.bWriteRaw = True;
4895 Globals.bNullPasswords = False;
4896 Globals.bObeyPamRestrictions = False;
4898 Globals.bSyslogOnly = False;
4899 Globals.bTimestampLogs = True;
4900 string_set(&Globals.szLogLevel, "0");
4901 Globals.bDebugPrefixTimestamp = False;
4902 Globals.bDebugHiresTimestamp = False;
4903 Globals.bDebugPid = False;
4904 Globals.bDebugUid = False;
4905 Globals.bDebugClass = False;
4906 Globals.bEnableCoreFiles = True;
4907 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4908 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4909 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4910 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4911 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4912 Globals.lm_interval = 60;
4913 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4914 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4915 Globals.bNISHomeMap = False;
4916 #ifdef WITH_NISPLUS_HOME
4917 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4919 string_set(&Globals.szNISHomeMapName, "auto.home");
4922 Globals.bTimeServer = False;
4923 Globals.bBindInterfacesOnly = False;
4924 Globals.bUnixPasswdSync = False;
4925 Globals.bPamPasswordChange = False;
4926 Globals.bPasswdChatDebug = False;
4927 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4928 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4929 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4930 Globals.bStatCache = True; /* use stat cache by default */
4931 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4932 Globals.restrict_anonymous = 0;
4933 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4934 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4935 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4936 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4937 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4938 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4940 Globals.map_to_guest = 0; /* By Default, "Never" */
4941 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4942 Globals.enhanced_browsing = true;
4943 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4944 #ifdef MMAP_BLACKLIST
4945 Globals.bUseMmap = False;
4947 Globals.bUseMmap = True;
4949 Globals.bUnixExtensions = True;
4950 Globals.bResetOnZeroVC = False;
4952 /* hostname lookups can be very expensive and are broken on
4953 a large number of sites (tridge) */
4954 Globals.bHostnameLookups = False;
4956 string_set(&Globals.szPassdbBackend, "smbpasswd");
4957 string_set(&Globals.szLdapSuffix, "");
4958 string_set(&Globals.szLdapMachineSuffix, "");
4959 string_set(&Globals.szLdapUserSuffix, "");
4960 string_set(&Globals.szLdapGroupSuffix, "");
4961 string_set(&Globals.szLdapIdmapSuffix, "");
4963 string_set(&Globals.szLdapAdminDn, "");
4964 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4965 Globals.ldap_ssl_ads = False;
4966 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4967 Globals.ldap_delete_dn = False;
4968 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4969 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4970 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4971 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4973 Globals.ldap_debug_level = 0;
4974 Globals.ldap_debug_threshold = 10;
4976 /* This is what we tell the afs client. in reality we set the token
4977 * to never expire, though, when this runs out the afs client will
4978 * forget the token. Set to 0 to get NEVERDATE.*/
4979 Globals.iAfsTokenLifetime = 604800;
4980 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
4982 /* these parameters are set to defaults that are more appropriate
4983 for the increasing samba install base:
4985 as a member of the workgroup, that will possibly become a
4986 _local_ master browser (lm = True). this is opposed to a forced
4987 local master browser startup (pm = True).
4989 doesn't provide WINS server service by default (wsupp = False),
4990 and doesn't provide domain master browser services by default, either.
4994 Globals.bMsAddPrinterWizard = True;
4995 Globals.os_level = 20;
4996 Globals.bLocalMaster = True;
4997 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4998 Globals.bDomainLogons = False;
4999 Globals.bBrowseList = True;
5000 Globals.bWINSsupport = False;
5001 Globals.bWINSproxy = False;
5003 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5004 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5006 Globals.bDNSproxy = True;
5008 /* this just means to use them if they exist */
5009 Globals.bKernelOplocks = True;
5011 Globals.bAllowTrustedDomains = True;
5012 string_set(&Globals.szIdmapBackend, "tdb");
5014 string_set(&Globals.szTemplateShell, "/bin/false");
5015 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5016 string_set(&Globals.szWinbindSeparator, "\\");
5018 string_set(&Globals.szCupsServer, "");
5019 string_set(&Globals.szIPrintServer, "");
5021 string_set(&Globals.ctdbdSocket, "");
5022 Globals.szClusterAddresses = NULL;
5023 Globals.clustering = False;
5025 Globals.winbind_cache_time = 300; /* 5 minutes */
5026 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5027 Globals.bWinbindEnumUsers = False;
5028 Globals.bWinbindEnumGroups = False;
5029 Globals.bWinbindUseDefaultDomain = False;
5030 Globals.bWinbindTrustedDomainsOnly = False;
5031 Globals.bWinbindNestedGroups = True;
5032 Globals.winbind_expand_groups = 1;
5033 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5034 Globals.bWinbindRefreshTickets = False;
5035 Globals.bWinbindOfflineLogon = False;
5037 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5038 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5040 Globals.bPassdbExpandExplicit = False;
5042 Globals.name_cache_timeout = 660; /* In seconds */
5044 Globals.bUseSpnego = True;
5045 Globals.bClientUseSpnego = True;
5047 Globals.client_signing = Auto;
5048 Globals.server_signing = False;
5050 Globals.bDeferSharingViolations = True;
5051 string_set(&Globals.smb_ports, SMB_PORTS);
5053 Globals.bEnablePrivileges = True;
5054 Globals.bHostMSDfs = True;
5055 Globals.bASUSupport = False;
5057 /* User defined shares. */
5058 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5059 smb_panic("init_globals: ENOMEM");
5061 string_set(&Globals.szUsersharePath, s);
5063 string_set(&Globals.szUsershareTemplateShare, "");
5064 Globals.iUsershareMaxShares = 0;
5065 /* By default disallow sharing of directories not owned by the sharer. */
5066 Globals.bUsershareOwnerOnly = True;
5067 /* By default disallow guest access to usershares. */
5068 Globals.bUsershareAllowGuests = False;
5070 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5072 /* By default no shares out of the registry */
5073 Globals.bRegistryShares = False;
5075 Globals.iminreceivefile = 0;
5077 Globals.bMapUntrustedToDomain = false;
5080 /*******************************************************************
5081 Convenience routine to grab string parameters into temporary memory
5082 and run standard_sub_basic on them. The buffers can be written to by
5083 callers without affecting the source string.
5084 ********************************************************************/
5086 static char *lp_string(const char *s)
5089 TALLOC_CTX *ctx = talloc_tos();
5091 /* The follow debug is useful for tracking down memory problems
5092 especially if you have an inner loop that is calling a lp_*()
5093 function that returns a string. Perhaps this debug should be
5094 present all the time? */
5097 DEBUG(10, ("lp_string(%s)\n", s));
5100 ret = talloc_sub_basic(ctx,
5101 get_current_username(),
5102 current_user_info.domain,
5104 if (trim_char(ret, '\"', '\"')) {
5105 if (strchr(ret,'\"') != NULL) {
5107 ret = talloc_sub_basic(ctx,
5108 get_current_username(),
5109 current_user_info.domain,
5117 In this section all the functions that are used to access the
5118 parameters from the rest of the program are defined
5121 #define FN_GLOBAL_STRING(fn_name,ptr) \
5122 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5123 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5124 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5125 #define FN_GLOBAL_LIST(fn_name,ptr) \
5126 const char **fn_name(void) {return(*(const char ***)(ptr));}
5127 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5128 bool fn_name(void) {return(*(bool *)(ptr));}
5129 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5130 char fn_name(void) {return(*(char *)(ptr));}
5131 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5132 int fn_name(void) {return(*(int *)(ptr));}
5134 #define FN_LOCAL_STRING(fn_name,val) \
5135 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5136 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5137 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5138 #define FN_LOCAL_LIST(fn_name,val) \
5139 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5140 #define FN_LOCAL_BOOL(fn_name,val) \
5141 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5142 #define FN_LOCAL_INTEGER(fn_name,val) \
5143 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5145 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5146 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5147 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5148 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5149 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5150 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));}
5151 #define FN_LOCAL_CHAR(fn_name,val) \
5152 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5154 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5155 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5156 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5157 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5158 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5159 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5160 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5161 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5162 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5163 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5164 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5165 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5166 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5167 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5168 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5169 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5170 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5171 * build process or in smb.conf, we use that value. Otherwise they
5172 * default to the value of lp_lockdir(). */
5173 char *lp_statedir(void) {
5174 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5175 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5176 return(lp_string(*(char **)(&Globals.szStateDir) ?
5177 *(char **)(&Globals.szStateDir) : ""));
5179 return(lp_string(*(char **)(&Globals.szLockDir) ?
5180 *(char **)(&Globals.szLockDir) : ""));
5182 char *lp_cachedir(void) {
5183 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5184 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5185 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5186 *(char **)(&Globals.szCacheDir) : ""));
5188 return(lp_string(*(char **)(&Globals.szLockDir) ?
5189 *(char **)(&Globals.szLockDir) : ""));
5191 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5192 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5193 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5194 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5195 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5196 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5197 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5198 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5199 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5200 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5201 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5202 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5203 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5204 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5205 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5206 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5207 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5208 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5209 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5210 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5211 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5212 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5213 FN_GLOBAL_BOOL(lp_force_username_map, &Globals.bForceUsernameMap)
5214 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5215 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5216 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5217 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5218 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5219 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5220 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5221 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5222 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5223 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5224 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5225 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5226 * lp_passdb_backend() should be replace by the this macro again after
5229 const char *lp_passdb_backend(void)
5231 char *delim, *quote;
5233 delim = strchr( Globals.szPassdbBackend, ' ');
5234 /* no space at all */
5235 if (delim == NULL) {
5239 quote = strchr(Globals.szPassdbBackend, '"');
5240 /* no quote char or non in the first part */
5241 if (quote == NULL || quote > delim) {
5246 quote = strchr(quote+1, '"');
5247 if (quote == NULL) {
5248 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5250 } else if (*(quote+1) == '\0') {
5251 /* space, fitting quote char, and one backend only */
5254 /* terminate string after the fitting quote char */
5259 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5260 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5261 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5262 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5265 return Globals.szPassdbBackend;
5267 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5268 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5269 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5270 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5271 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5273 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5274 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5275 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5276 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5277 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5278 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5280 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5282 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5283 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5284 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5286 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5288 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5289 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5290 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5291 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5292 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5293 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5294 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5295 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5296 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5297 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5298 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5299 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5300 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5301 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5302 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5304 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5305 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5306 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5307 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5308 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5309 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5311 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5312 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5313 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5314 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5315 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5316 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5317 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5318 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5319 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5320 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5321 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5322 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5323 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5324 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5325 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5326 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5327 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5328 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5330 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5332 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5333 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5334 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5335 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5336 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5337 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5338 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5339 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5340 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5341 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5342 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5343 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5344 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5345 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5346 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5347 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5348 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5349 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5350 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5351 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5352 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5353 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5354 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5355 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5356 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5357 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5358 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5359 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5360 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5361 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5362 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5363 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5364 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5365 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5366 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5367 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5368 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5369 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5370 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5371 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5372 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5373 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5374 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5375 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5376 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5377 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5378 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5379 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5380 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5381 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5382 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5383 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5384 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5385 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5386 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5387 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5388 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5389 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5390 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5391 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5392 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5393 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5394 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5395 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5396 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5397 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5398 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5399 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5400 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5401 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5402 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5403 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5404 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5405 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5406 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5407 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5408 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5409 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5410 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5411 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5412 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5413 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5414 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5415 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5416 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5417 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5418 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5419 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5420 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5421 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5422 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5423 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5424 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5425 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5426 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5427 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5428 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5429 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5430 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5431 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5433 FN_LOCAL_STRING(lp_preexec, szPreExec)
5434 FN_LOCAL_STRING(lp_postexec, szPostExec)
5435 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5436 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5437 FN_LOCAL_STRING(lp_servicename, szService)
5438 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5439 FN_LOCAL_STRING(lp_pathname, szPath)
5440 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5441 FN_LOCAL_STRING(lp_username, szUsername)
5442 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5443 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5444 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5445 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5446 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5447 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5448 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5449 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5450 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5451 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5452 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5453 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5454 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5455 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5456 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5457 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5458 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5459 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5460 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5461 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5462 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5463 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5464 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5465 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5466 FN_LOCAL_STRING(lp_comment, comment)
5467 FN_LOCAL_STRING(lp_force_user, force_user)
5468 FN_LOCAL_STRING(lp_force_group, force_group)
5469 FN_LOCAL_LIST(lp_readlist, readlist)
5470 FN_LOCAL_LIST(lp_writelist, writelist)
5471 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5472 FN_LOCAL_STRING(lp_fstype, fstype)
5473 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5474 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5475 static FN_LOCAL_STRING(lp_volume, volume)
5476 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5477 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5478 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5479 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5480 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5481 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5482 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5483 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5484 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5485 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5486 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5487 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5488 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5489 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5490 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5491 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5492 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5493 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5494 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5495 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5496 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5497 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5498 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5499 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5500 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5501 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5502 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5503 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5504 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5505 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5506 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5507 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5508 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5509 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5510 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5511 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5512 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5513 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5514 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5515 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5516 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5517 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5518 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5519 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5520 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5521 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5522 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5523 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5524 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5525 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5526 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5527 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5528 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5529 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5530 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5531 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5532 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5533 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5534 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5535 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5536 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5537 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5538 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5539 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5540 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5541 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5542 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5543 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5544 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5545 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5546 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5547 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5548 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5549 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5550 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5551 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5552 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5553 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5554 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5555 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5556 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5557 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5558 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5559 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5560 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5561 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5562 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5563 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5564 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5565 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5566 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5567 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5568 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5569 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5570 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5571 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5572 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5573 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5574 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5576 /* local prototypes */
5578 static int map_parameter(const char *pszParmName);
5579 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5580 static const char *get_boolean(bool bool_value);
5581 static int getservicebyname(const char *pszServiceName,
5582 struct service *pserviceDest);
5583 static void copy_service(struct service *pserviceDest,
5584 struct service *pserviceSource,
5585 struct bitmap *pcopymapDest);
5586 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5588 static bool do_section(const char *pszSectionName, void *userdata);
5589 static void init_copymap(struct service *pservice);
5590 static bool hash_a_service(const char *name, int number);
5591 static void free_service_byindex(int iService);
5592 static void free_param_opts(struct param_opt_struct **popts);
5593 static char * canonicalize_servicename(const char *name);
5594 static void show_parameter(int parmIndex);
5595 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5598 * This is a helper function for parametrical options support. It returns a
5599 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5600 * parametrical functions are quite simple
5602 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5605 bool global_section = False;
5607 struct param_opt_struct *data;
5609 if (snum >= iNumServices) return NULL;
5612 data = Globals.param_opt;
5613 global_section = True;
5615 data = ServicePtrs[snum]->param_opt;
5618 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5619 DEBUG(0,("asprintf failed!\n"));
5624 if (strwicmp(data->key, param_key) == 0) {
5625 string_free(¶m_key);
5631 if (!global_section) {
5632 /* Try to fetch the same option but from globals */
5633 /* but only if we are not already working with Globals */
5634 data = Globals.param_opt;
5636 if (strwicmp(data->key, param_key) == 0) {
5637 string_free(¶m_key);
5644 string_free(¶m_key);
5650 #define MISSING_PARAMETER(name) \
5651 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5653 /*******************************************************************
5654 convenience routine to return int parameters.
5655 ********************************************************************/
5656 static int lp_int(const char *s)
5660 MISSING_PARAMETER(lp_int);
5664 return (int)strtol(s, NULL, 0);
5667 /*******************************************************************
5668 convenience routine to return unsigned long parameters.
5669 ********************************************************************/
5670 static unsigned long lp_ulong(const char *s)
5674 MISSING_PARAMETER(lp_ulong);
5678 return strtoul(s, NULL, 0);
5681 /*******************************************************************
5682 convenience routine to return boolean parameters.
5683 ********************************************************************/
5684 static bool lp_bool(const char *s)
5689 MISSING_PARAMETER(lp_bool);
5693 if (!set_boolean(s, &ret)) {
5694 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5701 /*******************************************************************
5702 convenience routine to return enum parameters.
5703 ********************************************************************/
5704 static int lp_enum(const char *s,const struct enum_list *_enum)
5708 if (!s || !*s || !_enum) {
5709 MISSING_PARAMETER(lp_enum);
5713 for (i=0; _enum[i].name; i++) {
5714 if (strequal(_enum[i].name,s))
5715 return _enum[i].value;
5718 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5722 #undef MISSING_PARAMETER
5724 /* DO NOT USE lp_parm_string ANYMORE!!!!
5725 * use lp_parm_const_string or lp_parm_talloc_string
5727 * lp_parm_string is only used to let old modules find this symbol
5729 #undef lp_parm_string
5730 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5731 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5733 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5736 /* Return parametric option from a given service. Type is a part of option before ':' */
5737 /* Parametric option has following syntax: 'Type: option = value' */
5738 /* the returned value is talloced on the talloc_tos() */
5739 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5741 struct param_opt_struct *data = get_parametrics(snum, type, option);
5743 if (data == NULL||data->value==NULL) {
5745 return lp_string(def);
5751 return lp_string(data->value);
5754 /* Return parametric option from a given service. Type is a part of option before ':' */
5755 /* Parametric option has following syntax: 'Type: option = value' */
5756 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5758 struct param_opt_struct *data = get_parametrics(snum, type, option);
5760 if (data == NULL||data->value==NULL)
5766 /* Return parametric option from a given service. Type is a part of option before ':' */
5767 /* Parametric option has following syntax: 'Type: option = value' */
5769 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5771 struct param_opt_struct *data = get_parametrics(snum, type, option);
5773 if (data == NULL||data->value==NULL)
5774 return (const char **)def;
5776 if (data->list==NULL) {
5777 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5780 return (const char **)data->list;
5783 /* Return parametric option from a given service. Type is a part of option before ':' */
5784 /* Parametric option has following syntax: 'Type: option = value' */
5786 int lp_parm_int(int snum, const char *type, const char *option, int def)
5788 struct param_opt_struct *data = get_parametrics(snum, type, option);
5790 if (data && data->value && *data->value)
5791 return lp_int(data->value);
5796 /* Return parametric option from a given service. Type is a part of option before ':' */
5797 /* Parametric option has following syntax: 'Type: option = value' */
5799 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5801 struct param_opt_struct *data = get_parametrics(snum, type, option);
5803 if (data && data->value && *data->value)
5804 return lp_ulong(data->value);
5809 /* Return parametric option from a given service. Type is a part of option before ':' */
5810 /* Parametric option has following syntax: 'Type: option = value' */
5812 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5814 struct param_opt_struct *data = get_parametrics(snum, type, option);
5816 if (data && data->value && *data->value)
5817 return lp_bool(data->value);
5822 /* Return parametric option from a given service. Type is a part of option before ':' */
5823 /* Parametric option has following syntax: 'Type: option = value' */
5825 int lp_parm_enum(int snum, const char *type, const char *option,
5826 const struct enum_list *_enum, int def)
5828 struct param_opt_struct *data = get_parametrics(snum, type, option);
5830 if (data && data->value && *data->value && _enum)
5831 return lp_enum(data->value, _enum);
5837 /***************************************************************************
5838 Initialise a service to the defaults.
5839 ***************************************************************************/
5841 static void init_service(struct service *pservice)
5843 memset((char *)pservice, '\0', sizeof(struct service));
5844 copy_service(pservice, &sDefault, NULL);
5849 * free a param_opts structure.
5850 * param_opts handling should be moved to talloc;
5851 * then this whole functions reduces to a TALLOC_FREE().
5854 static void free_param_opts(struct param_opt_struct **popts)
5856 struct param_opt_struct *opt, *next_opt;
5858 if (popts == NULL) {
5862 if (*popts != NULL) {
5863 DEBUG(5, ("Freeing parametrics:\n"));
5866 while (opt != NULL) {
5867 string_free(&opt->key);
5868 string_free(&opt->value);
5869 TALLOC_FREE(opt->list);
5870 next_opt = opt->next;
5877 /***************************************************************************
5878 Free the dynamically allocated parts of a service struct.
5879 ***************************************************************************/
5881 static void free_service(struct service *pservice)
5886 if (pservice->szService)
5887 DEBUG(5, ("free_service: Freeing service %s\n",
5888 pservice->szService));
5890 free_parameters(pservice);
5892 string_free(&pservice->szService);
5893 bitmap_free(pservice->copymap);
5895 free_param_opts(&pservice->param_opt);
5897 ZERO_STRUCTP(pservice);
5901 /***************************************************************************
5902 remove a service indexed in the ServicePtrs array from the ServiceHash
5903 and free the dynamically allocated parts
5904 ***************************************************************************/
5906 static void free_service_byindex(int idx)
5908 if ( !LP_SNUM_OK(idx) )
5911 ServicePtrs[idx]->valid = False;
5912 invalid_services[num_invalid_services++] = idx;
5914 /* we have to cleanup the hash record */
5916 if (ServicePtrs[idx]->szService) {
5917 char *canon_name = canonicalize_servicename(
5918 ServicePtrs[idx]->szService );
5920 dbwrap_delete_bystring(ServiceHash, canon_name );
5921 TALLOC_FREE(canon_name);
5924 free_service(ServicePtrs[idx]);
5927 /***************************************************************************
5928 Add a new service to the services array initialising it with the given
5930 ***************************************************************************/
5932 static int add_a_service(const struct service *pservice, const char *name)
5935 struct service tservice;
5936 int num_to_alloc = iNumServices + 1;
5938 tservice = *pservice;
5940 /* it might already exist */
5942 i = getservicebyname(name, NULL);
5944 /* Clean all parametric options for service */
5945 /* They will be added during parsing again */
5946 free_param_opts(&ServicePtrs[i]->param_opt);
5951 /* find an invalid one */
5953 if (num_invalid_services > 0) {
5954 i = invalid_services[--num_invalid_services];
5957 /* if not, then create one */
5958 if (i == iNumServices) {
5959 struct service **tsp;
5962 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5964 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5968 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5969 if (!ServicePtrs[iNumServices]) {
5970 DEBUG(0,("add_a_service: out of memory!\n"));
5975 /* enlarge invalid_services here for now... */
5976 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5978 if (tinvalid == NULL) {
5979 DEBUG(0,("add_a_service: failed to enlarge "
5980 "invalid_services!\n"));
5983 invalid_services = tinvalid;
5985 free_service_byindex(i);
5988 ServicePtrs[i]->valid = True;
5990 init_service(ServicePtrs[i]);
5991 copy_service(ServicePtrs[i], &tservice, NULL);
5993 string_set(&ServicePtrs[i]->szService, name);
5995 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5996 i, ServicePtrs[i]->szService));
5998 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6005 /***************************************************************************
6006 Convert a string to uppercase and remove whitespaces.
6007 ***************************************************************************/
6009 static char *canonicalize_servicename(const char *src)
6014 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6018 result = talloc_strdup(talloc_tos(), src);
6019 SMB_ASSERT(result != NULL);
6025 /***************************************************************************
6026 Add a name/index pair for the services array to the hash table.
6027 ***************************************************************************/
6029 static bool hash_a_service(const char *name, int idx)
6033 if ( !ServiceHash ) {
6034 DEBUG(10,("hash_a_service: creating servicehash\n"));
6035 ServiceHash = db_open_rbt(NULL);
6036 if ( !ServiceHash ) {
6037 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6042 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6045 canon_name = canonicalize_servicename( name );
6047 dbwrap_store_bystring(ServiceHash, canon_name,
6048 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6051 TALLOC_FREE(canon_name);
6056 /***************************************************************************
6057 Add a new home service, with the specified home directory, defaults coming
6059 ***************************************************************************/
6061 bool lp_add_home(const char *pszHomename, int iDefaultService,
6062 const char *user, const char *pszHomedir)
6066 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6071 if (!(*(ServicePtrs[iDefaultService]->szPath))
6072 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6073 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6076 if (!(*(ServicePtrs[i]->comment))) {
6077 char *comment = NULL;
6078 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6081 string_set(&ServicePtrs[i]->comment, comment);
6085 /* set the browseable flag from the global default */
6087 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6088 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6090 ServicePtrs[i]->autoloaded = True;
6092 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6093 user, ServicePtrs[i]->szPath ));
6098 /***************************************************************************
6099 Add a new service, based on an old one.
6100 ***************************************************************************/
6102 int lp_add_service(const char *pszService, int iDefaultService)
6104 if (iDefaultService < 0) {
6105 return add_a_service(&sDefault, pszService);
6108 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6111 /***************************************************************************
6112 Add the IPC service.
6113 ***************************************************************************/
6115 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6117 char *comment = NULL;
6118 int i = add_a_service(&sDefault, ipc_name);
6123 if (asprintf(&comment, "IPC Service (%s)",
6124 Globals.szServerString) < 0) {
6128 string_set(&ServicePtrs[i]->szPath, tmpdir());
6129 string_set(&ServicePtrs[i]->szUsername, "");
6130 string_set(&ServicePtrs[i]->comment, comment);
6131 string_set(&ServicePtrs[i]->fstype, "IPC");
6132 ServicePtrs[i]->iMaxConnections = 0;
6133 ServicePtrs[i]->bAvailable = True;
6134 ServicePtrs[i]->bRead_only = True;
6135 ServicePtrs[i]->bGuest_only = False;
6136 ServicePtrs[i]->bAdministrative_share = True;
6137 ServicePtrs[i]->bGuest_ok = guest_ok;
6138 ServicePtrs[i]->bPrint_ok = False;
6139 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6141 DEBUG(3, ("adding IPC service\n"));
6147 /***************************************************************************
6148 Add a new printer service, with defaults coming from service iFrom.
6149 ***************************************************************************/
6151 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6153 const char *comment = "From Printcap";
6154 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6159 /* note that we do NOT default the availability flag to True - */
6160 /* we take it from the default service passed. This allows all */
6161 /* dynamic printers to be disabled by disabling the [printers] */
6162 /* entry (if/when the 'available' keyword is implemented!). */
6164 /* the printer name is set to the service name. */
6165 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6166 string_set(&ServicePtrs[i]->comment, comment);
6168 /* set the browseable flag from the gloabl default */
6169 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6171 /* Printers cannot be read_only. */
6172 ServicePtrs[i]->bRead_only = False;
6173 /* No share modes on printer services. */
6174 ServicePtrs[i]->bShareModes = False;
6175 /* No oplocks on printer services. */
6176 ServicePtrs[i]->bOpLocks = False;
6177 /* Printer services must be printable. */
6178 ServicePtrs[i]->bPrint_ok = True;
6180 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6186 /***************************************************************************
6187 Check whether the given parameter name is valid.
6188 Parametric options (names containing a colon) are considered valid.
6189 ***************************************************************************/
6191 bool lp_parameter_is_valid(const char *pszParmName)
6193 return ((map_parameter(pszParmName) != -1) ||
6194 (strchr(pszParmName, ':') != NULL));
6197 /***************************************************************************
6198 Check whether the given name is the name of a global parameter.
6199 Returns True for strings belonging to parameters of class
6200 P_GLOBAL, False for all other strings, also for parametric options
6201 and strings not belonging to any option.
6202 ***************************************************************************/
6204 bool lp_parameter_is_global(const char *pszParmName)
6206 int num = map_parameter(pszParmName);
6209 return (parm_table[num].p_class == P_GLOBAL);
6215 /**************************************************************************
6216 Check whether the given name is the canonical name of a parameter.
6217 Returns False if it is not a valid parameter Name.
6218 For parametric options, True is returned.
6219 **************************************************************************/
6221 bool lp_parameter_is_canonical(const char *parm_name)
6223 if (!lp_parameter_is_valid(parm_name)) {
6227 return (map_parameter(parm_name) ==
6228 map_parameter_canonical(parm_name, NULL));
6231 /**************************************************************************
6232 Determine the canonical name for a parameter.
6233 Indicate when it is an inverse (boolean) synonym instead of a
6235 **************************************************************************/
6237 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6242 if (!lp_parameter_is_valid(parm_name)) {
6247 num = map_parameter_canonical(parm_name, inverse);
6249 /* parametric option */
6250 *canon_parm = parm_name;
6252 *canon_parm = parm_table[num].label;
6259 /**************************************************************************
6260 Determine the canonical name for a parameter.
6261 Turn the value given into the inverse boolean expression when
6262 the synonym is an invers boolean synonym.
6264 Return True if parm_name is a valid parameter name and
6265 in case it is an invers boolean synonym, if the val string could
6266 successfully be converted to the reverse bool.
6267 Return false in all other cases.
6268 **************************************************************************/
6270 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6272 const char **canon_parm,
6273 const char **canon_val)
6278 if (!lp_parameter_is_valid(parm_name)) {
6284 num = map_parameter_canonical(parm_name, &inverse);
6286 /* parametric option */
6287 *canon_parm = parm_name;
6290 *canon_parm = parm_table[num].label;
6292 if (!lp_invert_boolean(val, canon_val)) {
6304 /***************************************************************************
6305 Map a parameter's string representation to something we can use.
6306 Returns False if the parameter string is not recognised, else TRUE.
6307 ***************************************************************************/
6309 static int map_parameter(const char *pszParmName)
6313 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6316 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6317 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6320 /* Warn only if it isn't parametric option */
6321 if (strchr(pszParmName, ':') == NULL)
6322 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6323 /* We do return 'fail' for parametric options as well because they are
6324 stored in different storage
6329 /***************************************************************************
6330 Map a parameter's string representation to the index of the canonical
6331 form of the parameter (it might be a synonym).
6332 Returns -1 if the parameter string is not recognised.
6333 ***************************************************************************/
6335 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6337 int parm_num, canon_num;
6338 bool loc_inverse = False;
6340 parm_num = map_parameter(pszParmName);
6341 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6342 /* invalid, parametric or no canidate for synonyms ... */
6346 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6347 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6348 parm_num = canon_num;
6354 if (inverse != NULL) {
6355 *inverse = loc_inverse;
6360 /***************************************************************************
6361 return true if parameter number parm1 is a synonym of parameter
6362 number parm2 (parm2 being the principal name).
6363 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6365 ***************************************************************************/
6367 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6369 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6370 (parm_table[parm1].flags & FLAG_HIDE) &&
6371 !(parm_table[parm2].flags & FLAG_HIDE))
6373 if (inverse != NULL) {
6374 if ((parm_table[parm1].type == P_BOOLREV) &&
6375 (parm_table[parm2].type == P_BOOL))
6387 /***************************************************************************
6388 Show one parameter's name, type, [values,] and flags.
6389 (helper functions for show_parameter_list)
6390 ***************************************************************************/
6392 static void show_parameter(int parmIndex)
6394 int enumIndex, flagIndex;
6399 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6400 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6402 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6403 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6404 FLAG_HIDE, FLAG_DOS_STRING};
6405 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6406 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6407 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6409 printf("%s=%s", parm_table[parmIndex].label,
6410 type[parm_table[parmIndex].type]);
6411 if (parm_table[parmIndex].type == P_ENUM) {
6414 parm_table[parmIndex].enum_list[enumIndex].name;
6418 enumIndex ? "|" : "",
6419 parm_table[parmIndex].enum_list[enumIndex].name);
6424 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6425 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6428 flag_names[flagIndex]);
6433 /* output synonyms */
6435 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6436 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6437 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6438 parm_table[parmIndex2].label);
6439 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6441 printf(" (synonyms: ");
6446 printf("%s%s", parm_table[parmIndex2].label,
6447 inverse ? "[i]" : "");
6457 /***************************************************************************
6458 Show all parameter's name, type, [values,] and flags.
6459 ***************************************************************************/
6461 void show_parameter_list(void)
6463 int classIndex, parmIndex;
6464 const char *section_names[] = { "local", "global", NULL};
6466 for (classIndex=0; section_names[classIndex]; classIndex++) {
6467 printf("[%s]\n", section_names[classIndex]);
6468 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6469 if (parm_table[parmIndex].p_class == classIndex) {
6470 show_parameter(parmIndex);
6476 /***************************************************************************
6477 Check if a given string correctly represents a boolean value.
6478 ***************************************************************************/
6480 bool lp_string_is_valid_boolean(const char *parm_value)
6482 return set_boolean(parm_value, NULL);
6485 /***************************************************************************
6486 Get the standard string representation of a boolean value ("yes" or "no")
6487 ***************************************************************************/
6489 static const char *get_boolean(bool bool_value)
6491 static const char *yes_str = "yes";
6492 static const char *no_str = "no";
6494 return (bool_value ? yes_str : no_str);
6497 /***************************************************************************
6498 Provide the string of the negated boolean value associated to the boolean
6499 given as a string. Returns False if the passed string does not correctly
6500 represent a boolean.
6501 ***************************************************************************/
6503 bool lp_invert_boolean(const char *str, const char **inverse_str)
6507 if (!set_boolean(str, &val)) {
6511 *inverse_str = get_boolean(!val);
6515 /***************************************************************************
6516 Provide the canonical string representation of a boolean value given
6517 as a string. Return True on success, False if the string given does
6518 not correctly represent a boolean.
6519 ***************************************************************************/
6521 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6525 if (!set_boolean(str, &val)) {
6529 *canon_str = get_boolean(val);
6533 /***************************************************************************
6534 Find a service by name. Otherwise works like get_service.
6535 ***************************************************************************/
6537 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6543 if (ServiceHash == NULL) {
6547 canon_name = canonicalize_servicename(pszServiceName);
6549 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6551 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6552 iService = *(int *)data.dptr;
6555 TALLOC_FREE(canon_name);
6557 if ((iService != -1) && (LP_SNUM_OK(iService))
6558 && (pserviceDest != NULL)) {
6559 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6565 /***************************************************************************
6566 Copy a service structure to another.
6567 If pcopymapDest is NULL then copy all fields
6568 ***************************************************************************/
6571 * Add a parametric option to a param_opt_struct,
6572 * replacing old value, if already present.
6574 static void set_param_opt(struct param_opt_struct **opt_list,
6575 const char *opt_name,
6576 const char *opt_value)
6578 struct param_opt_struct *new_opt, *opt;
6581 if (opt_list == NULL) {
6588 /* Traverse destination */
6590 /* If we already have same option, override it */
6591 if (strwicmp(opt->key, opt_name) == 0) {
6592 string_free(&opt->value);
6593 TALLOC_FREE(opt->list);
6594 opt->value = SMB_STRDUP(opt_value);
6601 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6602 new_opt->key = SMB_STRDUP(opt_name);
6603 new_opt->value = SMB_STRDUP(opt_value);
6604 new_opt->list = NULL;
6605 DLIST_ADD(*opt_list, new_opt);
6609 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6610 struct bitmap *pcopymapDest)
6613 bool bcopyall = (pcopymapDest == NULL);
6614 struct param_opt_struct *data;
6616 for (i = 0; parm_table[i].label; i++)
6617 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6618 (bcopyall || bitmap_query(pcopymapDest,i))) {
6619 void *def_ptr = parm_table[i].ptr;
6621 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6624 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6627 switch (parm_table[i].type) {
6630 *(bool *)dest_ptr = *(bool *)src_ptr;
6636 *(int *)dest_ptr = *(int *)src_ptr;
6640 *(char *)dest_ptr = *(char *)src_ptr;
6644 string_set((char **)dest_ptr,
6649 string_set((char **)dest_ptr,
6651 strupper_m(*(char **)dest_ptr);
6654 TALLOC_FREE(*((char ***)dest_ptr));
6655 *((char ***)dest_ptr) = str_list_copy(NULL,
6656 *(const char ***)src_ptr);
6664 init_copymap(pserviceDest);
6665 if (pserviceSource->copymap)
6666 bitmap_copy(pserviceDest->copymap,
6667 pserviceSource->copymap);
6670 data = pserviceSource->param_opt;
6672 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6677 /***************************************************************************
6678 Check a service for consistency. Return False if the service is in any way
6679 incomplete or faulty, else True.
6680 ***************************************************************************/
6682 bool service_ok(int iService)
6687 if (ServicePtrs[iService]->szService[0] == '\0') {
6688 DEBUG(0, ("The following message indicates an internal error:\n"));
6689 DEBUG(0, ("No service name in service entry.\n"));
6693 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6694 /* I can't see why you'd want a non-printable printer service... */
6695 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6696 if (!ServicePtrs[iService]->bPrint_ok) {
6697 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6698 ServicePtrs[iService]->szService));
6699 ServicePtrs[iService]->bPrint_ok = True;
6701 /* [printers] service must also be non-browsable. */
6702 if (ServicePtrs[iService]->bBrowseable)
6703 ServicePtrs[iService]->bBrowseable = False;
6706 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6707 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6708 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6710 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6711 ServicePtrs[iService]->szService));
6712 ServicePtrs[iService]->bAvailable = False;
6715 /* If a service is flagged unavailable, log the fact at level 1. */
6716 if (!ServicePtrs[iService]->bAvailable)
6717 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6718 ServicePtrs[iService]->szService));
6723 static struct smbconf_ctx *lp_smbconf_ctx(void)
6726 static struct smbconf_ctx *conf_ctx = NULL;
6728 if (conf_ctx == NULL) {
6729 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6730 if (!W_ERROR_IS_OK(werr)) {
6731 DEBUG(1, ("error initializing registry configuration: "
6732 "%s\n", win_errstr(werr)));
6740 static bool process_smbconf_service(struct smbconf_service *service)
6745 if (service == NULL) {
6749 ret = do_section(service->name, NULL);
6753 for (count = 0; count < service->num_params; count++) {
6754 ret = do_parameter(service->param_names[count],
6755 service->param_values[count],
6765 * process_registry_globals
6767 static bool process_registry_globals(void)
6770 struct smbconf_service *service = NULL;
6771 TALLOC_CTX *mem_ctx = talloc_stackframe();
6772 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6775 if (conf_ctx == NULL) {
6779 ret = do_parameter("registry shares", "yes", NULL);
6784 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6785 /* nothing to read from the registry yet but make sure lp_load
6786 * doesn't return false */
6791 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6792 if (!W_ERROR_IS_OK(werr)) {
6796 ret = process_smbconf_service(service);
6802 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6805 TALLOC_FREE(mem_ctx);
6809 static bool process_registry_shares(void)
6813 struct smbconf_service **service = NULL;
6814 uint32_t num_shares = 0;
6815 TALLOC_CTX *mem_ctx = talloc_stackframe();
6816 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6819 if (conf_ctx == NULL) {
6823 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6824 if (!W_ERROR_IS_OK(werr)) {
6830 for (count = 0; count < num_shares; count++) {
6831 if (strequal(service[count]->name, GLOBAL_NAME)) {
6834 ret = process_smbconf_service(service[count]);
6841 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6844 TALLOC_FREE(mem_ctx);
6848 static struct file_lists {
6849 struct file_lists *next;
6853 } *file_lists = NULL;
6855 /*******************************************************************
6856 Keep a linked list of all config files so we know when one has changed
6857 it's date and needs to be reloaded.
6858 ********************************************************************/
6860 static void add_to_file_list(const char *fname, const char *subfname)
6862 struct file_lists *f = file_lists;
6865 if (f->name && !strcmp(f->name, fname))
6871 f = SMB_MALLOC_P(struct file_lists);
6874 f->next = file_lists;
6875 f->name = SMB_STRDUP(fname);
6880 f->subfname = SMB_STRDUP(subfname);
6886 f->modtime = file_modtime(subfname);
6888 time_t t = file_modtime(subfname);
6895 * Utility function for outsiders to check if we're running on registry.
6897 bool lp_config_backend_is_registry(void)
6899 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6903 * Utility function to check if the config backend is FILE.
6905 bool lp_config_backend_is_file(void)
6907 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6910 /*******************************************************************
6911 Check if a config file has changed date.
6912 ********************************************************************/
6914 bool lp_file_list_changed(void)
6916 struct file_lists *f = file_lists;
6918 DEBUG(6, ("lp_file_list_changed()\n"));
6920 if (lp_config_backend_is_registry()) {
6921 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6923 if (conf_ctx == NULL) {
6926 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6927 DEBUGADD(6, ("registry config changed\n"));
6936 n2 = alloc_sub_basic(get_current_username(),
6937 current_user_info.domain,
6942 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6943 f->name, n2, ctime(&f->modtime)));
6945 mod_time = file_modtime(n2);
6947 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6949 ("file %s modified: %s\n", n2,
6951 f->modtime = mod_time;
6952 SAFE_FREE(f->subfname);
6953 f->subfname = n2; /* Passing ownership of
6954 return from alloc_sub_basic
6965 /***************************************************************************
6966 Run standard_sub_basic on netbios name... needed because global_myname
6967 is not accessed through any lp_ macro.
6968 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6969 ***************************************************************************/
6971 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6974 char *netbios_name = alloc_sub_basic(get_current_username(),
6975 current_user_info.domain,
6978 ret = set_global_myname(netbios_name);
6979 SAFE_FREE(netbios_name);
6980 string_set(&Globals.szNetbiosName,global_myname());
6982 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6988 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6990 if (strcmp(*ptr, pszParmValue) != 0) {
6991 string_set(ptr, pszParmValue);
6999 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7003 ret = set_global_myworkgroup(pszParmValue);
7004 string_set(&Globals.szWorkgroup,lp_workgroup());
7009 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7013 ret = set_global_scope(pszParmValue);
7014 string_set(&Globals.szNetbiosScope,global_scope());
7019 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7021 TALLOC_FREE(Globals.szNetbiosAliases);
7022 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7023 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7026 /***************************************************************************
7027 Handle the include operation.
7028 ***************************************************************************/
7029 static bool bAllowIncludeRegistry = true;
7031 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7035 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7036 if (!bAllowIncludeRegistry) {
7039 if (bInGlobalSection) {
7040 return process_registry_globals();
7042 DEBUG(1, ("\"include = registry\" only effective "
7043 "in %s section\n", GLOBAL_NAME));
7048 fname = alloc_sub_basic(get_current_username(),
7049 current_user_info.domain,
7052 add_to_file_list(pszParmValue, fname);
7054 string_set(ptr, fname);
7056 if (file_exist(fname)) {
7057 bool ret = pm_process(fname, do_section, do_parameter, NULL);
7062 DEBUG(2, ("Can't find include file %s\n", fname));
7067 /***************************************************************************
7068 Handle the interpretation of the copy parameter.
7069 ***************************************************************************/
7071 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7075 struct service serviceTemp;
7077 string_set(ptr, pszParmValue);
7079 init_service(&serviceTemp);
7083 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7085 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7086 if (iTemp == iServiceIndex) {
7087 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7089 copy_service(ServicePtrs[iServiceIndex],
7091 ServicePtrs[iServiceIndex]->copymap);
7095 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7099 free_service(&serviceTemp);
7103 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7105 Globals.ldap_debug_level = lp_int(pszParmValue);
7106 init_ldap_debugging();
7110 /***************************************************************************
7111 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7116 idmap uid = 1000-1999
7119 We only do simple parsing checks here. The strings are parsed into useful
7120 structures in the idmap daemon code.
7122 ***************************************************************************/
7124 /* Some lp_ routines to return idmap [ug]id information */
7126 static uid_t idmap_uid_low, idmap_uid_high;
7127 static gid_t idmap_gid_low, idmap_gid_high;
7129 bool lp_idmap_uid(uid_t *low, uid_t *high)
7131 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7135 *low = idmap_uid_low;
7138 *high = idmap_uid_high;
7143 bool lp_idmap_gid(gid_t *low, gid_t *high)
7145 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7149 *low = idmap_gid_low;
7152 *high = idmap_gid_high;
7157 /* Do some simple checks on "idmap [ug]id" parameter values */
7159 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7163 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7168 string_set(ptr, pszParmValue);
7170 idmap_uid_low = low;
7171 idmap_uid_high = high;
7176 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7180 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7185 string_set(ptr, pszParmValue);
7187 idmap_gid_low = low;
7188 idmap_gid_high = high;
7193 /***************************************************************************
7194 Handle the DEBUG level list.
7195 ***************************************************************************/
7197 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7199 string_set(ptr, pszParmValueIn);
7200 return debug_parse_levels(pszParmValueIn);
7203 /***************************************************************************
7204 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7205 ***************************************************************************/
7207 static const char *append_ldap_suffix( const char *str )
7209 const char *suffix_string;
7212 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7213 Globals.szLdapSuffix );
7214 if ( !suffix_string ) {
7215 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7219 return suffix_string;
7222 const char *lp_ldap_machine_suffix(void)
7224 if (Globals.szLdapMachineSuffix[0])
7225 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7227 return lp_string(Globals.szLdapSuffix);
7230 const char *lp_ldap_user_suffix(void)
7232 if (Globals.szLdapUserSuffix[0])
7233 return append_ldap_suffix(Globals.szLdapUserSuffix);
7235 return lp_string(Globals.szLdapSuffix);
7238 const char *lp_ldap_group_suffix(void)
7240 if (Globals.szLdapGroupSuffix[0])
7241 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7243 return lp_string(Globals.szLdapSuffix);
7246 const char *lp_ldap_idmap_suffix(void)
7248 if (Globals.szLdapIdmapSuffix[0])
7249 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7251 return lp_string(Globals.szLdapSuffix);
7254 /****************************************************************************
7255 set the value for a P_ENUM
7256 ***************************************************************************/
7258 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7263 for (i = 0; parm->enum_list[i].name; i++) {
7264 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7265 *ptr = parm->enum_list[i].value;
7269 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7270 pszParmValue, parm->label));
7273 /***************************************************************************
7274 ***************************************************************************/
7276 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7278 static int parm_num = -1;
7281 if ( parm_num == -1 )
7282 parm_num = map_parameter( "printing" );
7284 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7289 s = ServicePtrs[snum];
7291 init_printer_values( s );
7297 /***************************************************************************
7298 Initialise a copymap.
7299 ***************************************************************************/
7301 static void init_copymap(struct service *pservice)
7304 if (pservice->copymap) {
7305 bitmap_free(pservice->copymap);
7307 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7308 if (!pservice->copymap)
7310 ("Couldn't allocate copymap!! (size %d)\n",
7311 (int)NUMPARAMETERS));
7313 for (i = 0; i < NUMPARAMETERS; i++)
7314 bitmap_set(pservice->copymap, i);
7317 /***************************************************************************
7318 Return the local pointer to a parameter given a service struct and the
7319 pointer into the default structure.
7320 ***************************************************************************/
7322 static void *lp_local_ptr(struct service *service, void *ptr)
7324 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7327 /***************************************************************************
7328 Return the local pointer to a parameter given the service number and the
7329 pointer into the default structure.
7330 ***************************************************************************/
7332 void *lp_local_ptr_by_snum(int snum, void *ptr)
7334 return lp_local_ptr(ServicePtrs[snum], ptr);
7337 /***************************************************************************
7338 Process a parameter for a particular service number. If snum < 0
7339 then assume we are in the globals.
7340 ***************************************************************************/
7342 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7345 void *parm_ptr = NULL; /* where we are going to store the result */
7346 void *def_ptr = NULL;
7347 struct param_opt_struct **opt_list;
7349 parmnum = map_parameter(pszParmName);
7352 if (strchr(pszParmName, ':') == NULL) {
7353 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7359 * We've got a parametric option
7362 opt_list = (snum < 0)
7363 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7364 set_param_opt(opt_list, pszParmName, pszParmValue);
7369 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7370 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7374 def_ptr = parm_table[parmnum].ptr;
7376 /* we might point at a service, the default service or a global */
7380 if (parm_table[parmnum].p_class == P_GLOBAL) {
7382 ("Global parameter %s found in service section!\n",
7386 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7390 if (!ServicePtrs[snum]->copymap)
7391 init_copymap(ServicePtrs[snum]);
7393 /* this handles the aliases - set the copymap for other entries with
7394 the same data pointer */
7395 for (i = 0; parm_table[i].label; i++)
7396 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7397 bitmap_clear(ServicePtrs[snum]->copymap, i);
7400 /* if it is a special case then go ahead */
7401 if (parm_table[parmnum].special) {
7402 return parm_table[parmnum].special(snum, pszParmValue,
7406 /* now switch on the type of variable it is */
7407 switch (parm_table[parmnum].type)
7410 *(bool *)parm_ptr = lp_bool(pszParmValue);
7414 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7418 *(int *)parm_ptr = lp_int(pszParmValue);
7422 *(char *)parm_ptr = *pszParmValue;
7426 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7428 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7433 TALLOC_FREE(*((char ***)parm_ptr));
7434 *(char ***)parm_ptr = str_list_make_v3(
7435 talloc_autofree_context(), pszParmValue, NULL);
7439 string_set((char **)parm_ptr, pszParmValue);
7443 string_set((char **)parm_ptr, pszParmValue);
7444 strupper_m(*(char **)parm_ptr);
7448 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7457 /***************************************************************************
7458 Process a parameter.
7459 ***************************************************************************/
7461 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7464 if (!bInGlobalSection && bGlobalOnly)
7467 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7469 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7470 pszParmName, pszParmValue));
7473 /***************************************************************************
7474 Print a parameter of the specified type.
7475 ***************************************************************************/
7477 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7483 for (i = 0; p->enum_list[i].name; i++) {
7484 if (*(int *)ptr == p->enum_list[i].value) {
7486 p->enum_list[i].name);
7493 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7497 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7501 fprintf(f, "%d", *(int *)ptr);
7505 fprintf(f, "%c", *(char *)ptr);
7509 char *o = octal_string(*(int *)ptr);
7510 fprintf(f, "%s", o);
7516 if ((char ***)ptr && *(char ***)ptr) {
7517 char **list = *(char ***)ptr;
7518 for (; *list; list++) {
7519 /* surround strings with whitespace in double quotes */
7520 if ( strchr_m( *list, ' ' ) )
7521 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7523 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7530 if (*(char **)ptr) {
7531 fprintf(f, "%s", *(char **)ptr);
7539 /***************************************************************************
7540 Check if two parameters are equal.
7541 ***************************************************************************/
7543 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7548 return (*((bool *)ptr1) == *((bool *)ptr2));
7553 return (*((int *)ptr1) == *((int *)ptr2));
7556 return (*((char *)ptr1) == *((char *)ptr2));
7559 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7564 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7569 return (p1 == p2 || strequal(p1, p2));
7577 /***************************************************************************
7578 Initialize any local varients in the sDefault table.
7579 ***************************************************************************/
7581 void init_locals(void)
7586 /***************************************************************************
7587 Process a new section (service). At this stage all sections are services.
7588 Later we'll have special sections that permit server parameters to be set.
7589 Returns True on success, False on failure.
7590 ***************************************************************************/
7592 static bool do_section(const char *pszSectionName, void *userdata)
7595 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7596 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7599 /* if we were in a global section then do the local inits */
7600 if (bInGlobalSection && !isglobal)
7603 /* if we've just struck a global section, note the fact. */
7604 bInGlobalSection = isglobal;
7606 /* check for multiple global sections */
7607 if (bInGlobalSection) {
7608 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7612 if (!bInGlobalSection && bGlobalOnly)
7615 /* if we have a current service, tidy it up before moving on */
7618 if (iServiceIndex >= 0)
7619 bRetval = service_ok(iServiceIndex);
7621 /* if all is still well, move to the next record in the services array */
7623 /* We put this here to avoid an odd message order if messages are */
7624 /* issued by the post-processing of a previous section. */
7625 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7627 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7629 DEBUG(0, ("Failed to add a new service\n"));
7638 /***************************************************************************
7639 Determine if a partcular base parameter is currentl set to the default value.
7640 ***************************************************************************/
7642 static bool is_default(int i)
7644 if (!defaults_saved)
7646 switch (parm_table[i].type) {
7648 return str_list_equal((const char **)parm_table[i].def.lvalue,
7649 *(const char ***)parm_table[i].ptr);
7652 return strequal(parm_table[i].def.svalue,
7653 *(char **)parm_table[i].ptr);
7656 return parm_table[i].def.bvalue ==
7657 *(bool *)parm_table[i].ptr;
7659 return parm_table[i].def.cvalue ==
7660 *(char *)parm_table[i].ptr;
7664 return parm_table[i].def.ivalue ==
7665 *(int *)parm_table[i].ptr;
7672 /***************************************************************************
7673 Display the contents of the global structure.
7674 ***************************************************************************/
7676 static void dump_globals(FILE *f)
7679 struct param_opt_struct *data;
7681 fprintf(f, "[global]\n");
7683 for (i = 0; parm_table[i].label; i++)
7684 if (parm_table[i].p_class == P_GLOBAL &&
7685 parm_table[i].ptr &&
7686 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7687 if (defaults_saved && is_default(i))
7689 fprintf(f, "\t%s = ", parm_table[i].label);
7690 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7693 if (Globals.param_opt != NULL) {
7694 data = Globals.param_opt;
7696 fprintf(f, "\t%s = %s\n", data->key, data->value);
7703 /***************************************************************************
7704 Return True if a local parameter is currently set to the global default.
7705 ***************************************************************************/
7707 bool lp_is_default(int snum, struct parm_struct *parm)
7709 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7711 return equal_parameter(parm->type,
7712 ((char *)ServicePtrs[snum]) + pdiff,
7713 ((char *)&sDefault) + pdiff);
7716 /***************************************************************************
7717 Display the contents of a single services record.
7718 ***************************************************************************/
7720 static void dump_a_service(struct service *pService, FILE * f)
7723 struct param_opt_struct *data;
7725 if (pService != &sDefault)
7726 fprintf(f, "[%s]\n", pService->szService);
7728 for (i = 0; parm_table[i].label; i++) {
7730 if (parm_table[i].p_class == P_LOCAL &&
7731 parm_table[i].ptr &&
7732 (*parm_table[i].label != '-') &&
7733 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7736 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7738 if (pService == &sDefault) {
7739 if (defaults_saved && is_default(i))
7742 if (equal_parameter(parm_table[i].type,
7743 ((char *)pService) +
7745 ((char *)&sDefault) +
7750 fprintf(f, "\t%s = ", parm_table[i].label);
7751 print_parameter(&parm_table[i],
7752 ((char *)pService) + pdiff, f);
7757 if (pService->param_opt != NULL) {
7758 data = pService->param_opt;
7760 fprintf(f, "\t%s = %s\n", data->key, data->value);
7766 /***************************************************************************
7767 Display the contents of a parameter of a single services record.
7768 ***************************************************************************/
7770 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7773 bool result = False;
7776 fstring local_parm_name;
7778 const char *parm_opt_value;
7780 /* check for parametrical option */
7781 fstrcpy( local_parm_name, parm_name);
7782 parm_opt = strchr( local_parm_name, ':');
7787 if (strlen(parm_opt)) {
7788 parm_opt_value = lp_parm_const_string( snum,
7789 local_parm_name, parm_opt, NULL);
7790 if (parm_opt_value) {
7791 printf( "%s\n", parm_opt_value);
7798 /* check for a key and print the value */
7805 for (i = 0; parm_table[i].label; i++) {
7806 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7807 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7808 parm_table[i].ptr &&
7809 (*parm_table[i].label != '-') &&
7810 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7815 ptr = parm_table[i].ptr;
7817 struct service *pService = ServicePtrs[snum];
7818 ptr = ((char *)pService) +
7819 PTR_DIFF(parm_table[i].ptr, &sDefault);
7822 print_parameter(&parm_table[i],
7833 /***************************************************************************
7834 Return info about the requested parameter (given as a string).
7835 Return NULL when the string is not a valid parameter name.
7836 ***************************************************************************/
7838 struct parm_struct *lp_get_parameter(const char *param_name)
7840 int num = map_parameter(param_name);
7846 return &parm_table[num];
7849 /***************************************************************************
7850 Return info about the next parameter in a service.
7851 snum==GLOBAL_SECTION_SNUM gives the globals.
7852 Return NULL when out of parameters.
7853 ***************************************************************************/
7855 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7858 /* do the globals */
7859 for (; parm_table[*i].label; (*i)++) {
7860 if (parm_table[*i].p_class == P_SEPARATOR)
7861 return &parm_table[(*i)++];
7863 if (!parm_table[*i].ptr
7864 || (*parm_table[*i].label == '-'))
7868 && (parm_table[*i].ptr ==
7869 parm_table[(*i) - 1].ptr))
7872 if (is_default(*i) && !allparameters)
7875 return &parm_table[(*i)++];
7878 struct service *pService = ServicePtrs[snum];
7880 for (; parm_table[*i].label; (*i)++) {
7881 if (parm_table[*i].p_class == P_SEPARATOR)
7882 return &parm_table[(*i)++];
7884 if (parm_table[*i].p_class == P_LOCAL &&
7885 parm_table[*i].ptr &&
7886 (*parm_table[*i].label != '-') &&
7888 (parm_table[*i].ptr !=
7889 parm_table[(*i) - 1].ptr)))
7892 PTR_DIFF(parm_table[*i].ptr,
7895 if (allparameters ||
7896 !equal_parameter(parm_table[*i].type,
7897 ((char *)pService) +
7899 ((char *)&sDefault) +
7902 return &parm_table[(*i)++];
7913 /***************************************************************************
7914 Display the contents of a single copy structure.
7915 ***************************************************************************/
7916 static void dump_copy_map(bool *pcopymap)
7922 printf("\n\tNon-Copied parameters:\n");
7924 for (i = 0; parm_table[i].label; i++)
7925 if (parm_table[i].p_class == P_LOCAL &&
7926 parm_table[i].ptr && !pcopymap[i] &&
7927 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7929 printf("\t\t%s\n", parm_table[i].label);
7934 /***************************************************************************
7935 Return TRUE if the passed service number is within range.
7936 ***************************************************************************/
7938 bool lp_snum_ok(int iService)
7940 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7943 /***************************************************************************
7944 Auto-load some home services.
7945 ***************************************************************************/
7947 static void lp_add_auto_services(char *str)
7957 s = SMB_STRDUP(str);
7961 homes = lp_servicenumber(HOMES_NAME);
7963 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7964 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7967 if (lp_servicenumber(p) >= 0)
7970 home = get_user_home_dir(talloc_tos(), p);
7972 if (home && homes >= 0)
7973 lp_add_home(p, homes, p, home);
7980 /***************************************************************************
7981 Auto-load one printer.
7982 ***************************************************************************/
7984 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7986 int printers = lp_servicenumber(PRINTERS_NAME);
7989 if (lp_servicenumber(name) < 0) {
7990 lp_add_printer(name, printers);
7991 if ((i = lp_servicenumber(name)) >= 0) {
7992 string_set(&ServicePtrs[i]->comment, comment);
7993 ServicePtrs[i]->autoloaded = True;
7998 /***************************************************************************
7999 Have we loaded a services file yet?
8000 ***************************************************************************/
8002 bool lp_loaded(void)
8007 /***************************************************************************
8008 Unload unused services.
8009 ***************************************************************************/
8011 void lp_killunused(bool (*snumused) (int))
8014 for (i = 0; i < iNumServices; i++) {
8018 /* don't kill autoloaded or usershare services */
8019 if ( ServicePtrs[i]->autoloaded ||
8020 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8024 if (!snumused || !snumused(i)) {
8025 free_service_byindex(i);
8031 * Kill all except autoloaded and usershare services - convenience wrapper
8033 void lp_kill_all_services(void)
8035 lp_killunused(NULL);
8038 /***************************************************************************
8040 ***************************************************************************/
8042 void lp_killservice(int iServiceIn)
8044 if (VALID(iServiceIn)) {
8045 free_service_byindex(iServiceIn);
8049 /***************************************************************************
8050 Save the curent values of all global and sDefault parameters into the
8051 defaults union. This allows swat and testparm to show only the
8052 changed (ie. non-default) parameters.
8053 ***************************************************************************/
8055 static void lp_save_defaults(void)
8058 for (i = 0; parm_table[i].label; i++) {
8059 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8061 switch (parm_table[i].type) {
8063 parm_table[i].def.lvalue = str_list_copy(
8064 NULL, *(const char ***)parm_table[i].ptr);
8068 if (parm_table[i].ptr) {
8069 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8071 parm_table[i].def.svalue = NULL;
8076 parm_table[i].def.bvalue =
8077 *(bool *)parm_table[i].ptr;
8080 parm_table[i].def.cvalue =
8081 *(char *)parm_table[i].ptr;
8086 parm_table[i].def.ivalue =
8087 *(int *)parm_table[i].ptr;
8093 defaults_saved = True;
8096 /*******************************************************************
8097 Set the server type we will announce as via nmbd.
8098 ********************************************************************/
8100 static const struct srv_role_tab {
8102 const char *role_str;
8103 } srv_role_tab [] = {
8104 { ROLE_STANDALONE, "ROLE_STANDALONE" },
8105 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8106 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8107 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8111 const char* server_role_str(uint32 role)
8114 for (i=0; srv_role_tab[i].role_str; i++) {
8115 if (role == srv_role_tab[i].role) {
8116 return srv_role_tab[i].role_str;
8122 static void set_server_role(void)
8124 server_role = ROLE_STANDALONE;
8126 switch (lp_security()) {
8128 if (lp_domain_logons())
8129 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8132 if (lp_domain_logons())
8133 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8134 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8135 server_role = ROLE_STANDALONE;
8138 if (lp_domain_logons()) {
8139 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8140 server_role = ROLE_DOMAIN_BDC;
8143 server_role = ROLE_DOMAIN_MEMBER;
8146 if (lp_domain_logons()) {
8147 server_role = ROLE_DOMAIN_PDC;
8150 server_role = ROLE_DOMAIN_MEMBER;
8153 if (lp_domain_logons()) {
8155 if (Globals.iDomainMaster) /* auto or yes */
8156 server_role = ROLE_DOMAIN_PDC;
8158 server_role = ROLE_DOMAIN_BDC;
8162 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8166 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8169 /***********************************************************
8170 If we should send plaintext/LANMAN passwords in the clinet
8171 ************************************************************/
8173 static void set_allowed_client_auth(void)
8175 if (Globals.bClientNTLMv2Auth) {
8176 Globals.bClientLanManAuth = False;
8178 if (!Globals.bClientLanManAuth) {
8179 Globals.bClientPlaintextAuth = False;
8183 /***************************************************************************
8185 The following code allows smbd to read a user defined share file.
8186 Yes, this is my intent. Yes, I'm comfortable with that...
8188 THE FOLLOWING IS SECURITY CRITICAL CODE.
8190 It washes your clothes, it cleans your house, it guards you while you sleep...
8191 Do not f%^k with it....
8192 ***************************************************************************/
8194 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8196 /***************************************************************************
8197 Check allowed stat state of a usershare file.
8198 Ensure we print out who is dicking with us so the admin can
8199 get their sorry ass fired.
8200 ***************************************************************************/
8202 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8204 if (!S_ISREG(psbuf->st_mode)) {
8205 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8206 "not a regular file\n",
8207 fname, (unsigned int)psbuf->st_uid ));
8211 /* Ensure this doesn't have the other write bit set. */
8212 if (psbuf->st_mode & S_IWOTH) {
8213 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8214 "public write. Refusing to allow as a usershare file.\n",
8215 fname, (unsigned int)psbuf->st_uid ));
8219 /* Should be 10k or less. */
8220 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8221 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8222 "too large (%u) to be a user share file.\n",
8223 fname, (unsigned int)psbuf->st_uid,
8224 (unsigned int)psbuf->st_size ));
8231 /***************************************************************************
8232 Parse the contents of a usershare file.
8233 ***************************************************************************/
8235 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8236 SMB_STRUCT_STAT *psbuf,
8237 const char *servicename,
8241 char **pp_sharepath,
8246 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8247 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8250 SMB_STRUCT_STAT sbuf;
8251 char *sharepath = NULL;
8252 char *comment = NULL;
8254 *pp_sharepath = NULL;
8257 *pallow_guest = False;
8260 return USERSHARE_MALFORMED_FILE;
8263 if (strcmp(lines[0], "#VERSION 1") == 0) {
8265 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8268 return USERSHARE_MALFORMED_FILE;
8271 return USERSHARE_BAD_VERSION;
8274 if (strncmp(lines[1], "path=", 5) != 0) {
8275 return USERSHARE_MALFORMED_PATH;
8278 sharepath = talloc_strdup(ctx, &lines[1][5]);
8280 return USERSHARE_POSIX_ERR;
8282 trim_string(sharepath, " ", " ");
8284 if (strncmp(lines[2], "comment=", 8) != 0) {
8285 return USERSHARE_MALFORMED_COMMENT_DEF;
8288 comment = talloc_strdup(ctx, &lines[2][8]);
8290 return USERSHARE_POSIX_ERR;
8292 trim_string(comment, " ", " ");
8293 trim_char(comment, '"', '"');
8295 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8296 return USERSHARE_MALFORMED_ACL_DEF;
8299 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8300 return USERSHARE_ACL_ERR;
8304 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8305 return USERSHARE_MALFORMED_ACL_DEF;
8307 if (lines[4][9] == 'y') {
8308 *pallow_guest = True;
8312 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8313 /* Path didn't change, no checks needed. */
8314 *pp_sharepath = sharepath;
8315 *pp_comment = comment;
8316 return USERSHARE_OK;
8319 /* The path *must* be absolute. */
8320 if (sharepath[0] != '/') {
8321 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8322 servicename, sharepath));
8323 return USERSHARE_PATH_NOT_ABSOLUTE;
8326 /* If there is a usershare prefix deny list ensure one of these paths
8327 doesn't match the start of the user given path. */
8328 if (prefixdenylist) {
8330 for ( i=0; prefixdenylist[i]; i++ ) {
8331 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8332 servicename, i, prefixdenylist[i], sharepath ));
8333 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8334 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8335 "usershare prefix deny list entries.\n",
8336 servicename, sharepath));
8337 return USERSHARE_PATH_IS_DENIED;
8342 /* If there is a usershare prefix allow list ensure one of these paths
8343 does match the start of the user given path. */
8345 if (prefixallowlist) {
8347 for ( i=0; prefixallowlist[i]; i++ ) {
8348 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8349 servicename, i, prefixallowlist[i], sharepath ));
8350 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8354 if (prefixallowlist[i] == NULL) {
8355 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8356 "usershare prefix allow list entries.\n",
8357 servicename, sharepath));
8358 return USERSHARE_PATH_NOT_ALLOWED;
8362 /* Ensure this is pointing to a directory. */
8363 dp = sys_opendir(sharepath);
8366 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8367 servicename, sharepath));
8368 return USERSHARE_PATH_NOT_DIRECTORY;
8371 /* Ensure the owner of the usershare file has permission to share
8374 if (sys_stat(sharepath, &sbuf) == -1) {
8375 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8376 servicename, sharepath, strerror(errno) ));
8378 return USERSHARE_POSIX_ERR;
8383 if (!S_ISDIR(sbuf.st_mode)) {
8384 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8385 servicename, sharepath ));
8386 return USERSHARE_PATH_NOT_DIRECTORY;
8389 /* Check if sharing is restricted to owner-only. */
8390 /* psbuf is the stat of the usershare definition file,
8391 sbuf is the stat of the target directory to be shared. */
8393 if (lp_usershare_owner_only()) {
8394 /* root can share anything. */
8395 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8396 return USERSHARE_PATH_NOT_ALLOWED;
8400 *pp_sharepath = sharepath;
8401 *pp_comment = comment;
8402 return USERSHARE_OK;
8405 /***************************************************************************
8406 Deal with a usershare file.
8409 -1 - Bad name, invalid contents.
8410 - service name already existed and not a usershare, problem
8411 with permissions to share directory etc.
8412 ***************************************************************************/
8414 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8416 SMB_STRUCT_STAT sbuf;
8417 SMB_STRUCT_STAT lsbuf;
8419 char *sharepath = NULL;
8420 char *comment = NULL;
8421 fstring service_name;
8422 char **lines = NULL;
8426 TALLOC_CTX *ctx = NULL;
8427 SEC_DESC *psd = NULL;
8428 bool guest_ok = False;
8430 /* Ensure share name doesn't contain invalid characters. */
8431 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8432 DEBUG(0,("process_usershare_file: share name %s contains "
8433 "invalid characters (any of %s)\n",
8434 file_name, INVALID_SHARENAME_CHARS ));
8438 fstrcpy(service_name, file_name);
8440 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8443 /* Minimize the race condition by doing an lstat before we
8444 open and fstat. Ensure this isn't a symlink link. */
8446 if (sys_lstat(fname, &lsbuf) != 0) {
8447 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8448 fname, strerror(errno) ));
8453 /* This must be a regular file, not a symlink, directory or
8454 other strange filetype. */
8455 if (!check_usershare_stat(fname, &lsbuf)) {
8461 char *canon_name = canonicalize_servicename(service_name);
8462 TDB_DATA data = dbwrap_fetch_bystring(
8463 ServiceHash, canon_name, canon_name);
8467 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8468 iService = *(int *)data.dptr;
8470 TALLOC_FREE(canon_name);
8473 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8474 /* Nothing changed - Mark valid and return. */
8475 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8477 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8482 /* Try and open the file read only - no symlinks allowed. */
8484 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8486 fd = sys_open(fname, O_RDONLY, 0);
8490 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8491 fname, strerror(errno) ));
8496 /* Now fstat to be *SURE* it's a regular file. */
8497 if (sys_fstat(fd, &sbuf) != 0) {
8499 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8500 fname, strerror(errno) ));
8505 /* Is it the same dev/inode as was lstated ? */
8506 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8508 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8509 "Symlink spoofing going on ?\n", fname ));
8514 /* This must be a regular file, not a symlink, directory or
8515 other strange filetype. */
8516 if (!check_usershare_stat(fname, &sbuf)) {
8521 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8524 if (lines == NULL) {
8525 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8526 fname, (unsigned int)sbuf.st_uid ));
8533 /* Should we allow printers to be shared... ? */
8534 ctx = talloc_init("usershare_sd_xctx");
8540 if (parse_usershare_file(ctx, &sbuf, service_name,
8541 iService, lines, numlines, &sharepath,
8542 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8543 talloc_destroy(ctx);
8550 /* Everything ok - add the service possibly using a template. */
8552 const struct service *sp = &sDefault;
8553 if (snum_template != -1) {
8554 sp = ServicePtrs[snum_template];
8557 if ((iService = add_a_service(sp, service_name)) < 0) {
8558 DEBUG(0, ("process_usershare_file: Failed to add "
8559 "new service %s\n", service_name));
8560 talloc_destroy(ctx);
8564 /* Read only is controlled by usershare ACL below. */
8565 ServicePtrs[iService]->bRead_only = False;
8568 /* Write the ACL of the new/modified share. */
8569 if (!set_share_security(service_name, psd)) {
8570 DEBUG(0, ("process_usershare_file: Failed to set share "
8571 "security for user share %s\n",
8573 lp_remove_service(iService);
8574 talloc_destroy(ctx);
8578 /* If from a template it may be marked invalid. */
8579 ServicePtrs[iService]->valid = True;
8581 /* Set the service as a valid usershare. */
8582 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8584 /* Set guest access. */
8585 if (lp_usershare_allow_guests()) {
8586 ServicePtrs[iService]->bGuest_ok = guest_ok;
8589 /* And note when it was loaded. */
8590 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8591 string_set(&ServicePtrs[iService]->szPath, sharepath);
8592 string_set(&ServicePtrs[iService]->comment, comment);
8594 talloc_destroy(ctx);
8599 /***************************************************************************
8600 Checks if a usershare entry has been modified since last load.
8601 ***************************************************************************/
8603 static bool usershare_exists(int iService, time_t *last_mod)
8605 SMB_STRUCT_STAT lsbuf;
8606 const char *usersharepath = Globals.szUsersharePath;
8609 if (asprintf(&fname, "%s/%s",
8611 ServicePtrs[iService]->szService) < 0) {
8615 if (sys_lstat(fname, &lsbuf) != 0) {
8620 if (!S_ISREG(lsbuf.st_mode)) {
8626 *last_mod = lsbuf.st_mtime;
8630 /***************************************************************************
8631 Load a usershare service by name. Returns a valid servicenumber or -1.
8632 ***************************************************************************/
8634 int load_usershare_service(const char *servicename)
8636 SMB_STRUCT_STAT sbuf;
8637 const char *usersharepath = Globals.szUsersharePath;
8638 int max_user_shares = Globals.iUsershareMaxShares;
8639 int snum_template = -1;
8641 if (*usersharepath == 0 || max_user_shares == 0) {
8645 if (sys_stat(usersharepath, &sbuf) != 0) {
8646 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8647 usersharepath, strerror(errno) ));
8651 if (!S_ISDIR(sbuf.st_mode)) {
8652 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8658 * This directory must be owned by root, and have the 't' bit set.
8659 * It also must not be writable by "other".
8663 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8665 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8667 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8668 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8673 /* Ensure the template share exists if it's set. */
8674 if (Globals.szUsershareTemplateShare[0]) {
8675 /* We can't use lp_servicenumber here as we are recommending that
8676 template shares have -valid=False set. */
8677 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8678 if (ServicePtrs[snum_template]->szService &&
8679 strequal(ServicePtrs[snum_template]->szService,
8680 Globals.szUsershareTemplateShare)) {
8685 if (snum_template == -1) {
8686 DEBUG(0,("load_usershare_service: usershare template share %s "
8687 "does not exist.\n",
8688 Globals.szUsershareTemplateShare ));
8693 return process_usershare_file(usersharepath, servicename, snum_template);
8696 /***************************************************************************
8697 Load all user defined shares from the user share directory.
8698 We only do this if we're enumerating the share list.
8699 This is the function that can delete usershares that have
8701 ***************************************************************************/
8703 int load_usershare_shares(void)
8706 SMB_STRUCT_STAT sbuf;
8707 SMB_STRUCT_DIRENT *de;
8708 int num_usershares = 0;
8709 int max_user_shares = Globals.iUsershareMaxShares;
8710 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8711 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8712 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8714 int snum_template = -1;
8715 const char *usersharepath = Globals.szUsersharePath;
8716 int ret = lp_numservices();
8718 if (max_user_shares == 0 || *usersharepath == '\0') {
8719 return lp_numservices();
8722 if (sys_stat(usersharepath, &sbuf) != 0) {
8723 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8724 usersharepath, strerror(errno) ));
8729 * This directory must be owned by root, and have the 't' bit set.
8730 * It also must not be writable by "other".
8734 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8736 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8738 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8739 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8744 /* Ensure the template share exists if it's set. */
8745 if (Globals.szUsershareTemplateShare[0]) {
8746 /* We can't use lp_servicenumber here as we are recommending that
8747 template shares have -valid=False set. */
8748 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8749 if (ServicePtrs[snum_template]->szService &&
8750 strequal(ServicePtrs[snum_template]->szService,
8751 Globals.szUsershareTemplateShare)) {
8756 if (snum_template == -1) {
8757 DEBUG(0,("load_usershare_shares: usershare template share %s "
8758 "does not exist.\n",
8759 Globals.szUsershareTemplateShare ));
8764 /* Mark all existing usershares as pending delete. */
8765 for (iService = iNumServices - 1; iService >= 0; iService--) {
8766 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8767 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8771 dp = sys_opendir(usersharepath);
8773 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8774 usersharepath, strerror(errno) ));
8778 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8779 (de = sys_readdir(dp));
8780 num_dir_entries++ ) {
8782 const char *n = de->d_name;
8784 /* Ignore . and .. */
8786 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8792 /* Temporary file used when creating a share. */
8793 num_tmp_dir_entries++;
8796 /* Allow 20% tmp entries. */
8797 if (num_tmp_dir_entries > allowed_tmp_entries) {
8798 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8799 "in directory %s\n",
8800 num_tmp_dir_entries, usersharepath));
8804 r = process_usershare_file(usersharepath, n, snum_template);
8806 /* Update the services count. */
8808 if (num_usershares >= max_user_shares) {
8809 DEBUG(0,("load_usershare_shares: max user shares reached "
8810 "on file %s in directory %s\n",
8811 n, usersharepath ));
8814 } else if (r == -1) {
8815 num_bad_dir_entries++;
8818 /* Allow 20% bad entries. */
8819 if (num_bad_dir_entries > allowed_bad_entries) {
8820 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8821 "in directory %s\n",
8822 num_bad_dir_entries, usersharepath));
8826 /* Allow 20% bad entries. */
8827 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8828 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8829 "in directory %s\n",
8830 num_dir_entries, usersharepath));
8837 /* Sweep through and delete any non-refreshed usershares that are
8838 not currently in use. */
8839 for (iService = iNumServices - 1; iService >= 0; iService--) {
8840 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8841 if (conn_snum_used(iService)) {
8844 /* Remove from the share ACL db. */
8845 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8846 lp_servicename(iService) ));
8847 delete_share_security(lp_servicename(iService));
8848 free_service_byindex(iService);
8852 return lp_numservices();
8855 /********************************************************
8856 Destroy global resources allocated in this file
8857 ********************************************************/
8859 void gfree_loadparm(void)
8861 struct file_lists *f;
8862 struct file_lists *next;
8865 /* Free the file lists */
8870 SAFE_FREE( f->name );
8871 SAFE_FREE( f->subfname );
8877 /* Free resources allocated to services */
8879 for ( i = 0; i < iNumServices; i++ ) {
8881 free_service_byindex(i);
8885 SAFE_FREE( ServicePtrs );
8888 /* Now release all resources allocated to global
8889 parameters and the default service */
8891 free_global_parameters();
8895 /***************************************************************************
8896 Allow client apps to specify that they are a client
8897 ***************************************************************************/
8898 void lp_set_in_client(bool b)
8904 /***************************************************************************
8905 Determine if we're running in a client app
8906 ***************************************************************************/
8907 bool lp_is_in_client(void)
8912 /***************************************************************************
8913 Load the services array from the services file. Return True on success,
8915 ***************************************************************************/
8917 bool lp_load_ex(const char *pszFname,
8921 bool initialize_globals,
8922 bool allow_include_registry,
8923 bool allow_registry_shares)
8930 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8932 bInGlobalSection = True;
8933 bGlobalOnly = global_only;
8934 bAllowIncludeRegistry = allow_include_registry;
8936 init_globals(! initialize_globals);
8939 if (save_defaults) {
8944 free_param_opts(&Globals.param_opt);
8946 /* We get sections first, so have to start 'behind' to make up */
8949 if (lp_config_backend_is_file()) {
8950 n2 = alloc_sub_basic(get_current_username(),
8951 current_user_info.domain,
8954 smb_panic("lp_load_ex: out of memory");
8957 add_to_file_list(pszFname, n2);
8959 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8962 /* finish up the last section */
8963 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8965 if (iServiceIndex >= 0) {
8966 bRetval = service_ok(iServiceIndex);
8970 if (lp_config_backend_is_registry()) {
8971 /* config backend changed to registry in config file */
8973 * We need to use this extra global variable here to
8974 * survive restart: init_globals uses this as a default
8975 * for ConfigBackend. Otherwise, init_globals would
8976 * send us into an endless loop here.
8978 config_backend = CONFIG_BACKEND_REGISTRY;
8980 DEBUG(1, ("lp_load_ex: changing to config backend "
8982 init_globals(false);
8983 lp_kill_all_services();
8984 return lp_load_ex(pszFname, global_only, save_defaults,
8985 add_ipc, initialize_globals,
8986 allow_include_registry,
8987 allow_registry_shares);
8989 } else if (lp_config_backend_is_registry()) {
8990 bRetval = process_registry_globals();
8992 DEBUG(0, ("Illegal config backend given: %d\n",
8993 lp_config_backend()));
8997 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8998 bRetval = process_registry_shares();
9001 lp_add_auto_services(lp_auto_services());
9004 /* When 'restrict anonymous = 2' guest connections to ipc$
9006 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9007 if ( lp_enable_asu_support() ) {
9008 lp_add_ipc("ADMIN$", false);
9013 set_default_server_announce_type();
9014 set_allowed_client_auth();
9018 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9019 /* if bWINSsupport is true and we are in the client */
9020 if (lp_is_in_client() && Globals.bWINSsupport) {
9021 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9026 bAllowIncludeRegistry = true;
9031 bool lp_load(const char *pszFname,
9035 bool initialize_globals)
9037 return lp_load_ex(pszFname,
9045 bool lp_load_initial_only(const char *pszFname)
9047 return lp_load_ex(pszFname,
9056 bool lp_load_with_registry_shares(const char *pszFname,
9060 bool initialize_globals)
9062 return lp_load_ex(pszFname,
9071 /***************************************************************************
9072 Return the max number of services.
9073 ***************************************************************************/
9075 int lp_numservices(void)
9077 return (iNumServices);
9080 /***************************************************************************
9081 Display the contents of the services array in human-readable form.
9082 ***************************************************************************/
9084 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9089 defaults_saved = False;
9093 dump_a_service(&sDefault, f);
9095 for (iService = 0; iService < maxtoprint; iService++) {
9097 lp_dump_one(f, show_defaults, iService);
9101 /***************************************************************************
9102 Display the contents of one service in human-readable form.
9103 ***************************************************************************/
9105 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9108 if (ServicePtrs[snum]->szService[0] == '\0')
9110 dump_a_service(ServicePtrs[snum], f);
9114 /***************************************************************************
9115 Return the number of the service with the given name, or -1 if it doesn't
9116 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9117 getservicebyname()! This works ONLY if all services have been loaded, and
9118 does not copy the found service.
9119 ***************************************************************************/
9121 int lp_servicenumber(const char *pszServiceName)
9124 fstring serviceName;
9126 if (!pszServiceName) {
9127 return GLOBAL_SECTION_SNUM;
9130 for (iService = iNumServices - 1; iService >= 0; iService--) {
9131 if (VALID(iService) && ServicePtrs[iService]->szService) {
9133 * The substitution here is used to support %U is
9136 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9137 standard_sub_basic(get_current_username(),
9138 current_user_info.domain,
9139 serviceName,sizeof(serviceName));
9140 if (strequal(serviceName, pszServiceName)) {
9146 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9149 if (!usershare_exists(iService, &last_mod)) {
9150 /* Remove the share security tdb entry for it. */
9151 delete_share_security(lp_servicename(iService));
9152 /* Remove it from the array. */
9153 free_service_byindex(iService);
9154 /* Doesn't exist anymore. */
9155 return GLOBAL_SECTION_SNUM;
9158 /* Has it been modified ? If so delete and reload. */
9159 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9160 /* Remove it from the array. */
9161 free_service_byindex(iService);
9162 /* and now reload it. */
9163 iService = load_usershare_service(pszServiceName);
9168 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9169 return GLOBAL_SECTION_SNUM;
9175 bool share_defined(const char *service_name)
9177 return (lp_servicenumber(service_name) != -1);
9180 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9181 const char *sharename)
9183 struct share_params *result;
9187 if (!(sname = SMB_STRDUP(sharename))) {
9191 snum = find_service(sname);
9198 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9199 DEBUG(0, ("talloc failed\n"));
9203 result->service = snum;
9207 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9209 struct share_iterator *result;
9211 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9212 DEBUG(0, ("talloc failed\n"));
9216 result->next_id = 0;
9220 struct share_params *next_share(struct share_iterator *list)
9222 struct share_params *result;
9224 while (!lp_snum_ok(list->next_id) &&
9225 (list->next_id < lp_numservices())) {
9229 if (list->next_id >= lp_numservices()) {
9233 if (!(result = TALLOC_P(list, struct share_params))) {
9234 DEBUG(0, ("talloc failed\n"));
9238 result->service = list->next_id;
9243 struct share_params *next_printer(struct share_iterator *list)
9245 struct share_params *result;
9247 while ((result = next_share(list)) != NULL) {
9248 if (lp_print_ok(result->service)) {
9256 * This is a hack for a transition period until we transformed all code from
9257 * service numbers to struct share_params.
9260 struct share_params *snum2params_static(int snum)
9262 static struct share_params result;
9263 result.service = snum;
9267 /*******************************************************************
9268 A useful volume label function.
9269 ********************************************************************/
9271 const char *volume_label(int snum)
9274 const char *label = lp_volume(snum);
9276 label = lp_servicename(snum);
9279 /* This returns a 33 byte guarenteed null terminated string. */
9280 ret = talloc_strndup(talloc_tos(), label, 32);
9287 /*******************************************************************
9288 Set the server type we will announce as via nmbd.
9289 ********************************************************************/
9291 static void set_default_server_announce_type(void)
9293 default_server_announce = 0;
9294 default_server_announce |= SV_TYPE_WORKSTATION;
9295 default_server_announce |= SV_TYPE_SERVER;
9296 default_server_announce |= SV_TYPE_SERVER_UNIX;
9298 /* note that the flag should be set only if we have a
9299 printer service but nmbd doesn't actually load the
9300 services so we can't tell --jerry */
9302 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9304 switch (lp_announce_as()) {
9305 case ANNOUNCE_AS_NT_SERVER:
9306 default_server_announce |= SV_TYPE_SERVER_NT;
9307 /* fall through... */
9308 case ANNOUNCE_AS_NT_WORKSTATION:
9309 default_server_announce |= SV_TYPE_NT;
9311 case ANNOUNCE_AS_WIN95:
9312 default_server_announce |= SV_TYPE_WIN95_PLUS;
9314 case ANNOUNCE_AS_WFW:
9315 default_server_announce |= SV_TYPE_WFW;
9321 switch (lp_server_role()) {
9322 case ROLE_DOMAIN_MEMBER:
9323 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9325 case ROLE_DOMAIN_PDC:
9326 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9328 case ROLE_DOMAIN_BDC:
9329 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9331 case ROLE_STANDALONE:
9335 if (lp_time_server())
9336 default_server_announce |= SV_TYPE_TIME_SOURCE;
9338 if (lp_host_msdfs())
9339 default_server_announce |= SV_TYPE_DFS_SERVER;
9342 /***********************************************************
9343 returns role of Samba server
9344 ************************************************************/
9346 int lp_server_role(void)
9351 /***********************************************************
9352 If we are PDC then prefer us as DMB
9353 ************************************************************/
9355 bool lp_domain_master(void)
9357 if (Globals.iDomainMaster == Auto)
9358 return (lp_server_role() == ROLE_DOMAIN_PDC);
9360 return (bool)Globals.iDomainMaster;
9363 /***********************************************************
9364 If we are DMB then prefer us as LMB
9365 ************************************************************/
9367 bool lp_preferred_master(void)
9369 if (Globals.iPreferredMaster == Auto)
9370 return (lp_local_master() && lp_domain_master());
9372 return (bool)Globals.iPreferredMaster;
9375 /*******************************************************************
9377 ********************************************************************/
9379 void lp_remove_service(int snum)
9381 ServicePtrs[snum]->valid = False;
9382 invalid_services[num_invalid_services++] = snum;
9385 /*******************************************************************
9387 ********************************************************************/
9389 void lp_copy_service(int snum, const char *new_name)
9391 do_section(new_name, NULL);
9393 snum = lp_servicenumber(new_name);
9395 lp_do_parameter(snum, "copy", lp_servicename(snum));
9400 /*******************************************************************
9401 Get the default server type we will announce as via nmbd.
9402 ********************************************************************/
9404 int lp_default_server_announce(void)
9406 return default_server_announce;
9409 /*******************************************************************
9410 Split the announce version into major and minor numbers.
9411 ********************************************************************/
9413 int lp_major_announce_version(void)
9415 static bool got_major = False;
9416 static int major_version = DEFAULT_MAJOR_VERSION;
9421 return major_version;
9424 if ((vers = lp_announce_version()) == NULL)
9425 return major_version;
9427 if ((p = strchr_m(vers, '.')) == 0)
9428 return major_version;
9431 major_version = atoi(vers);
9432 return major_version;
9435 int lp_minor_announce_version(void)
9437 static bool got_minor = False;
9438 static int minor_version = DEFAULT_MINOR_VERSION;
9443 return minor_version;
9446 if ((vers = lp_announce_version()) == NULL)
9447 return minor_version;
9449 if ((p = strchr_m(vers, '.')) == 0)
9450 return minor_version;
9453 minor_version = atoi(p);
9454 return minor_version;
9457 /***********************************************************
9458 Set the global name resolution order (used in smbclient).
9459 ************************************************************/
9461 void lp_set_name_resolve_order(const char *new_order)
9463 string_set(&Globals.szNameResolveOrder, new_order);
9466 const char *lp_printername(int snum)
9468 const char *ret = _lp_printername(snum);
9469 if (ret == NULL || (ret != NULL && *ret == '\0'))
9470 ret = lp_const_servicename(snum);
9476 /***********************************************************
9477 Allow daemons such as winbindd to fix their logfile name.
9478 ************************************************************/
9480 void lp_set_logfile(const char *name)
9482 string_set(&Globals.szLogFile, name);
9483 debug_set_logfile(name);
9486 /*******************************************************************
9487 Return the max print jobs per queue.
9488 ********************************************************************/
9490 int lp_maxprintjobs(int snum)
9492 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9493 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9494 maxjobs = PRINT_MAX_JOBID - 1;
9499 const char *lp_printcapname(void)
9501 if ((Globals.szPrintcapname != NULL) &&
9502 (Globals.szPrintcapname[0] != '\0'))
9503 return Globals.szPrintcapname;
9505 if (sDefault.iPrinting == PRINT_CUPS) {
9513 if (sDefault.iPrinting == PRINT_BSD)
9514 return "/etc/printcap";
9516 return PRINTCAP_NAME;
9519 /*******************************************************************
9520 Ensure we don't use sendfile if server smb signing is active.
9521 ********************************************************************/
9523 static uint32 spoolss_state;
9525 bool lp_disable_spoolss( void )
9527 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9528 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9530 return spoolss_state == SVCCTL_STOPPED ? True : False;
9533 void lp_set_spoolss_state( uint32 state )
9535 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9537 spoolss_state = state;
9540 uint32 lp_get_spoolss_state( void )
9542 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9545 /*******************************************************************
9546 Ensure we don't use sendfile if server smb signing is active.
9547 ********************************************************************/
9549 bool lp_use_sendfile(int snum)
9551 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9552 if (Protocol < PROTOCOL_NT1) {
9555 return (_lp_use_sendfile(snum) &&
9556 (get_remote_arch() != RA_WIN95) &&
9557 !srv_is_signing_active());
9560 /*******************************************************************
9561 Turn off sendfile if we find the underlying OS doesn't support it.
9562 ********************************************************************/
9564 void set_use_sendfile(int snum, bool val)
9566 if (LP_SNUM_OK(snum))
9567 ServicePtrs[snum]->bUseSendfile = val;
9569 sDefault.bUseSendfile = val;
9572 /*******************************************************************
9573 Turn off storing DOS attributes if this share doesn't support it.
9574 ********************************************************************/
9576 void set_store_dos_attributes(int snum, bool val)
9578 if (!LP_SNUM_OK(snum))
9580 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9583 void lp_set_mangling_method(const char *new_method)
9585 string_set(&Globals.szManglingMethod, new_method);
9588 /*******************************************************************
9589 Global state for POSIX pathname processing.
9590 ********************************************************************/
9592 static bool posix_pathnames;
9594 bool lp_posix_pathnames(void)
9596 return posix_pathnames;
9599 /*******************************************************************
9600 Change everything needed to ensure POSIX pathname processing (currently
9602 ********************************************************************/
9604 void lp_set_posix_pathnames(void)
9606 posix_pathnames = True;
9609 /*******************************************************************
9610 Global state for POSIX lock processing - CIFS unix extensions.
9611 ********************************************************************/
9613 bool posix_default_lock_was_set;
9614 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9616 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9618 if (posix_default_lock_was_set) {
9619 return posix_cifsx_locktype;
9621 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9625 /*******************************************************************
9626 ********************************************************************/
9628 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9630 posix_default_lock_was_set = True;
9631 posix_cifsx_locktype = val;
9634 int lp_min_receive_file_size(void)
9636 if (Globals.iminreceivefile < 0) {
9639 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9642 /*******************************************************************
9643 If socket address is an empty character string, it is necessary to
9644 define it as "0.0.0.0".
9645 ********************************************************************/
9647 const char *lp_socket_address(void)
9649 char *sock_addr = Globals.szSocketAddress;
9651 if (sock_addr[0] == '\0'){
9652 string_set(&Globals.szSocketAddress, "0.0.0.0");
9654 return Globals.szSocketAddress;