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 */
4661 * Function to return the default value for the maximum number of open
4662 * file descriptors permitted. This function tries to consult the
4663 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4664 * the smaller of those.
4666 static int max_open_files(void)
4670 bool sysctl_worked = false, rlimit_worked = false;
4672 #ifdef HAVE_SYSCTLBYNAME
4673 size_t size = sizeof(sysctl_max);
4674 if (sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,0)==0)
4675 sysctl_worked = true;
4678 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4679 rlimit_worked = true;
4681 if (sysctl_worked) {
4682 if ((!rlimit_worked) ||
4683 (rl.rlim_cur == RLIM_INFINITY) ||
4684 (rl.rlim_cur > sysctl_max))
4689 if ((!rlimit_worked) ||
4690 (rl.rlim_cur == RLIM_INFINITY))
4691 return MAX_OPEN_FILES;
4698 * Common part of freeing allocated data for one parameter.
4700 static void free_one_parameter_common(void *parm_ptr,
4701 struct parm_struct parm)
4703 if ((parm.type == P_STRING) ||
4704 (parm.type == P_USTRING))
4706 string_free((char**)parm_ptr);
4707 } else if (parm.type == P_LIST) {
4708 TALLOC_FREE(*((char***)parm_ptr));
4713 * Free the allocated data for one parameter for a share
4714 * given as a service struct.
4716 static void free_one_parameter(struct service *service,
4717 struct parm_struct parm)
4721 if (parm.p_class != P_LOCAL) {
4725 parm_ptr = lp_local_ptr(service, parm.ptr);
4727 free_one_parameter_common(parm_ptr, parm);
4731 * Free the allocated parameter data of a share given
4732 * as a service struct.
4734 static void free_parameters(struct service *service)
4738 for (i=0; parm_table[i].label; i++) {
4739 free_one_parameter(service, parm_table[i]);
4744 * Free the allocated data for one parameter for a given share
4745 * specified by an snum.
4747 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4751 if (parm.ptr == NULL) {
4756 parm_ptr = parm.ptr;
4757 } else if (parm.p_class != P_LOCAL) {
4760 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4763 free_one_parameter_common(parm_ptr, parm);
4767 * Free the allocated parameter data for a share specified
4770 static void free_parameters_by_snum(int snum)
4774 for (i=0; parm_table[i].label; i++) {
4775 free_one_parameter_by_snum(snum, parm_table[i]);
4780 * Free the allocated global parameters.
4782 static void free_global_parameters(void)
4784 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4787 /***************************************************************************
4788 Initialise the global parameter structure.
4789 ***************************************************************************/
4791 static void init_globals(bool first_time_only)
4793 static bool done_init = False;
4797 /* If requested to initialize only once and we've already done it... */
4798 if (first_time_only && done_init) {
4799 /* ... then we have nothing more to do */
4804 /* The logfile can be set before this is invoked. Free it if so. */
4805 if (Globals.szLogFile != NULL) {
4806 string_free(&Globals.szLogFile);
4807 Globals.szLogFile = NULL;
4811 free_global_parameters();
4814 memset((void *)&Globals, '\0', sizeof(Globals));
4816 for (i = 0; parm_table[i].label; i++) {
4817 if ((parm_table[i].type == P_STRING ||
4818 parm_table[i].type == P_USTRING) &&
4821 string_set((char **)parm_table[i].ptr, "");
4825 string_set(&sDefault.fstype, FSTYPE_STRING);
4826 string_set(&sDefault.szPrintjobUsername, "%U");
4828 init_printer_values(&sDefault);
4831 DEBUG(3, ("Initialising global parameters\n"));
4833 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4834 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4836 /* use the new 'hash2' method by default, with a prefix of 1 */
4837 string_set(&Globals.szManglingMethod, "hash2");
4838 Globals.mangle_prefix = 1;
4840 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4842 /* using UTF8 by default allows us to support all chars */
4843 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4845 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4846 /* If the system supports nl_langinfo(), try to grab the value
4847 from the user's locale */
4848 string_set(&Globals.display_charset, "LOCALE");
4850 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4853 /* Use codepage 850 as a default for the dos character set */
4854 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4857 * Allow the default PASSWD_CHAT to be overridden in local.h.
4859 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4861 set_global_myname(myhostname());
4862 string_set(&Globals.szNetbiosName,global_myname());
4864 set_global_myworkgroup(WORKGROUP);
4865 string_set(&Globals.szWorkgroup, lp_workgroup());
4867 string_set(&Globals.szPasswdProgram, "");
4868 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4869 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4870 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4871 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4872 string_set(&Globals.szSocketAddress, "0.0.0.0");
4874 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4875 smb_panic("init_globals: ENOMEM");
4877 string_set(&Globals.szServerString, s);
4879 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4880 DEFAULT_MINOR_VERSION) < 0) {
4881 smb_panic("init_globals: ENOMEM");
4883 string_set(&Globals.szAnnounceVersion, s);
4886 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4889 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4891 string_set(&Globals.szLogonDrive, "");
4892 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4893 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4894 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4896 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4897 string_set(&Globals.szPasswordServer, "*");
4899 Globals.AlgorithmicRidBase = BASE_RID;
4901 Globals.bLoadPrinters = True;
4902 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4904 Globals.ConfigBackend = config_backend;
4906 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4907 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4908 Globals.max_xmit = 0x4104;
4909 Globals.max_mux = 50; /* This is *needed* for profile support. */
4910 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4911 Globals.bDisableSpoolss = False;
4912 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4913 Globals.pwordlevel = 0;
4914 Globals.unamelevel = 0;
4915 Globals.deadtime = 0;
4916 Globals.getwd_cache = true;
4917 Globals.bLargeReadwrite = True;
4918 Globals.max_log_size = 5000;
4919 Globals.max_open_files = max_open_files();
4920 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4921 Globals.maxprotocol = PROTOCOL_NT1;
4922 Globals.minprotocol = PROTOCOL_CORE;
4923 Globals.security = SEC_USER;
4924 Globals.paranoid_server_security = True;
4925 Globals.bEncryptPasswords = True;
4926 Globals.bUpdateEncrypt = False;
4927 Globals.clientSchannel = Auto;
4928 Globals.serverSchannel = Auto;
4929 Globals.bReadRaw = True;
4930 Globals.bWriteRaw = True;
4931 Globals.bNullPasswords = False;
4932 Globals.bObeyPamRestrictions = False;
4934 Globals.bSyslogOnly = False;
4935 Globals.bTimestampLogs = True;
4936 string_set(&Globals.szLogLevel, "0");
4937 Globals.bDebugPrefixTimestamp = False;
4938 Globals.bDebugHiresTimestamp = False;
4939 Globals.bDebugPid = False;
4940 Globals.bDebugUid = False;
4941 Globals.bDebugClass = False;
4942 Globals.bEnableCoreFiles = True;
4943 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4944 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4945 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4946 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4947 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4948 Globals.lm_interval = 60;
4949 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4950 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4951 Globals.bNISHomeMap = False;
4952 #ifdef WITH_NISPLUS_HOME
4953 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4955 string_set(&Globals.szNISHomeMapName, "auto.home");
4958 Globals.bTimeServer = False;
4959 Globals.bBindInterfacesOnly = False;
4960 Globals.bUnixPasswdSync = False;
4961 Globals.bPamPasswordChange = False;
4962 Globals.bPasswdChatDebug = False;
4963 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4964 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4965 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4966 Globals.bStatCache = True; /* use stat cache by default */
4967 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4968 Globals.restrict_anonymous = 0;
4969 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4970 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4971 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4972 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4973 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4974 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4976 Globals.map_to_guest = 0; /* By Default, "Never" */
4977 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4978 Globals.enhanced_browsing = true;
4979 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4980 #ifdef MMAP_BLACKLIST
4981 Globals.bUseMmap = False;
4983 Globals.bUseMmap = True;
4985 Globals.bUnixExtensions = True;
4986 Globals.bResetOnZeroVC = False;
4988 /* hostname lookups can be very expensive and are broken on
4989 a large number of sites (tridge) */
4990 Globals.bHostnameLookups = False;
4992 string_set(&Globals.szPassdbBackend, "smbpasswd");
4993 string_set(&Globals.szLdapSuffix, "");
4994 string_set(&Globals.szLdapMachineSuffix, "");
4995 string_set(&Globals.szLdapUserSuffix, "");
4996 string_set(&Globals.szLdapGroupSuffix, "");
4997 string_set(&Globals.szLdapIdmapSuffix, "");
4999 string_set(&Globals.szLdapAdminDn, "");
5000 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5001 Globals.ldap_ssl_ads = False;
5002 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5003 Globals.ldap_delete_dn = False;
5004 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5005 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5006 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5007 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5009 Globals.ldap_debug_level = 0;
5010 Globals.ldap_debug_threshold = 10;
5012 /* This is what we tell the afs client. in reality we set the token
5013 * to never expire, though, when this runs out the afs client will
5014 * forget the token. Set to 0 to get NEVERDATE.*/
5015 Globals.iAfsTokenLifetime = 604800;
5016 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5018 /* these parameters are set to defaults that are more appropriate
5019 for the increasing samba install base:
5021 as a member of the workgroup, that will possibly become a
5022 _local_ master browser (lm = True). this is opposed to a forced
5023 local master browser startup (pm = True).
5025 doesn't provide WINS server service by default (wsupp = False),
5026 and doesn't provide domain master browser services by default, either.
5030 Globals.bMsAddPrinterWizard = True;
5031 Globals.os_level = 20;
5032 Globals.bLocalMaster = True;
5033 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5034 Globals.bDomainLogons = False;
5035 Globals.bBrowseList = True;
5036 Globals.bWINSsupport = False;
5037 Globals.bWINSproxy = False;
5039 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5040 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5042 Globals.bDNSproxy = True;
5044 /* this just means to use them if they exist */
5045 Globals.bKernelOplocks = True;
5047 Globals.bAllowTrustedDomains = True;
5048 string_set(&Globals.szIdmapBackend, "tdb");
5050 string_set(&Globals.szTemplateShell, "/bin/false");
5051 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5052 string_set(&Globals.szWinbindSeparator, "\\");
5054 string_set(&Globals.szCupsServer, "");
5055 string_set(&Globals.szIPrintServer, "");
5057 string_set(&Globals.ctdbdSocket, "");
5058 Globals.szClusterAddresses = NULL;
5059 Globals.clustering = False;
5061 Globals.winbind_cache_time = 300; /* 5 minutes */
5062 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5063 Globals.bWinbindEnumUsers = False;
5064 Globals.bWinbindEnumGroups = False;
5065 Globals.bWinbindUseDefaultDomain = False;
5066 Globals.bWinbindTrustedDomainsOnly = False;
5067 Globals.bWinbindNestedGroups = True;
5068 Globals.winbind_expand_groups = 1;
5069 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5070 Globals.bWinbindRefreshTickets = False;
5071 Globals.bWinbindOfflineLogon = False;
5073 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5074 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5076 Globals.bPassdbExpandExplicit = False;
5078 Globals.name_cache_timeout = 660; /* In seconds */
5080 Globals.bUseSpnego = True;
5081 Globals.bClientUseSpnego = True;
5083 Globals.client_signing = Auto;
5084 Globals.server_signing = False;
5086 Globals.bDeferSharingViolations = True;
5087 string_set(&Globals.smb_ports, SMB_PORTS);
5089 Globals.bEnablePrivileges = True;
5090 Globals.bHostMSDfs = True;
5091 Globals.bASUSupport = False;
5093 /* User defined shares. */
5094 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5095 smb_panic("init_globals: ENOMEM");
5097 string_set(&Globals.szUsersharePath, s);
5099 string_set(&Globals.szUsershareTemplateShare, "");
5100 Globals.iUsershareMaxShares = 0;
5101 /* By default disallow sharing of directories not owned by the sharer. */
5102 Globals.bUsershareOwnerOnly = True;
5103 /* By default disallow guest access to usershares. */
5104 Globals.bUsershareAllowGuests = False;
5106 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5108 /* By default no shares out of the registry */
5109 Globals.bRegistryShares = False;
5111 Globals.iminreceivefile = 0;
5113 Globals.bMapUntrustedToDomain = false;
5116 /*******************************************************************
5117 Convenience routine to grab string parameters into temporary memory
5118 and run standard_sub_basic on them. The buffers can be written to by
5119 callers without affecting the source string.
5120 ********************************************************************/
5122 static char *lp_string(const char *s)
5125 TALLOC_CTX *ctx = talloc_tos();
5127 /* The follow debug is useful for tracking down memory problems
5128 especially if you have an inner loop that is calling a lp_*()
5129 function that returns a string. Perhaps this debug should be
5130 present all the time? */
5133 DEBUG(10, ("lp_string(%s)\n", s));
5136 ret = talloc_sub_basic(ctx,
5137 get_current_username(),
5138 current_user_info.domain,
5140 if (trim_char(ret, '\"', '\"')) {
5141 if (strchr(ret,'\"') != NULL) {
5143 ret = talloc_sub_basic(ctx,
5144 get_current_username(),
5145 current_user_info.domain,
5153 In this section all the functions that are used to access the
5154 parameters from the rest of the program are defined
5157 #define FN_GLOBAL_STRING(fn_name,ptr) \
5158 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5159 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5160 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5161 #define FN_GLOBAL_LIST(fn_name,ptr) \
5162 const char **fn_name(void) {return(*(const char ***)(ptr));}
5163 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5164 bool fn_name(void) {return(*(bool *)(ptr));}
5165 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5166 char fn_name(void) {return(*(char *)(ptr));}
5167 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5168 int fn_name(void) {return(*(int *)(ptr));}
5170 #define FN_LOCAL_STRING(fn_name,val) \
5171 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5172 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5173 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5174 #define FN_LOCAL_LIST(fn_name,val) \
5175 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5176 #define FN_LOCAL_BOOL(fn_name,val) \
5177 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5178 #define FN_LOCAL_INTEGER(fn_name,val) \
5179 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5181 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5182 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5183 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5184 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5185 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5186 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));}
5187 #define FN_LOCAL_CHAR(fn_name,val) \
5188 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5190 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5191 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5192 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5193 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5194 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5195 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5196 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5197 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5198 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5199 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5200 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5201 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5202 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5203 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5204 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5205 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5206 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5207 * build process or in smb.conf, we use that value. Otherwise they
5208 * default to the value of lp_lockdir(). */
5209 char *lp_statedir(void) {
5210 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5211 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5212 return(lp_string(*(char **)(&Globals.szStateDir) ?
5213 *(char **)(&Globals.szStateDir) : ""));
5215 return(lp_string(*(char **)(&Globals.szLockDir) ?
5216 *(char **)(&Globals.szLockDir) : ""));
5218 char *lp_cachedir(void) {
5219 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5220 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5221 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5222 *(char **)(&Globals.szCacheDir) : ""));
5224 return(lp_string(*(char **)(&Globals.szLockDir) ?
5225 *(char **)(&Globals.szLockDir) : ""));
5227 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5228 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5229 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5230 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5231 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5232 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5233 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5234 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5235 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5236 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5237 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5238 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5239 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5240 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5241 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5242 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5243 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5244 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5245 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5246 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5247 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5248 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5249 FN_GLOBAL_BOOL(lp_force_username_map, &Globals.bForceUsernameMap)
5250 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5251 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5252 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5253 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5254 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5255 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5256 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5257 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5258 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5259 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5260 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5261 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5262 * lp_passdb_backend() should be replace by the this macro again after
5265 const char *lp_passdb_backend(void)
5267 char *delim, *quote;
5269 delim = strchr( Globals.szPassdbBackend, ' ');
5270 /* no space at all */
5271 if (delim == NULL) {
5275 quote = strchr(Globals.szPassdbBackend, '"');
5276 /* no quote char or non in the first part */
5277 if (quote == NULL || quote > delim) {
5282 quote = strchr(quote+1, '"');
5283 if (quote == NULL) {
5284 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5286 } else if (*(quote+1) == '\0') {
5287 /* space, fitting quote char, and one backend only */
5290 /* terminate string after the fitting quote char */
5295 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5296 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5297 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5298 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5301 return Globals.szPassdbBackend;
5303 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5304 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5305 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5306 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5307 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5309 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5310 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5311 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5312 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5313 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5314 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5316 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5318 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5319 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5320 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5322 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5324 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5325 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5326 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5327 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5328 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5329 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5330 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5331 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5332 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5333 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5334 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5335 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5336 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5337 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5338 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5340 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5341 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5342 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5343 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5344 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5345 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5347 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5348 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5349 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5350 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5351 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5352 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5353 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5354 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5355 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5356 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5357 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5358 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5359 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5360 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5361 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5362 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5363 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5364 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5366 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5368 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5369 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5370 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5371 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5372 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5373 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5374 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5375 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5376 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5377 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5378 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5379 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5380 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5381 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5382 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5383 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5384 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5385 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5386 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5387 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5388 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5389 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5390 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5391 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5392 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5393 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5394 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5395 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5396 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5397 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5398 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5399 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5400 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5401 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5402 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5403 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5404 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5405 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5406 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5407 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5408 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5409 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5410 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5411 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5412 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5413 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5414 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5415 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5416 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5417 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5418 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5419 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5420 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5421 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5422 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5423 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5424 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5425 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5426 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5427 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5428 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5429 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5430 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5431 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5432 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5433 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5434 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5435 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5436 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5437 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5438 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5439 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5440 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5441 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5442 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5443 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5444 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5445 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5446 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5447 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5448 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5449 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5450 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5451 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5452 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5453 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5454 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5455 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5456 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5457 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5458 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5459 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5460 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5461 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5462 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5463 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5464 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5465 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5466 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5467 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5469 FN_LOCAL_STRING(lp_preexec, szPreExec)
5470 FN_LOCAL_STRING(lp_postexec, szPostExec)
5471 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5472 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5473 FN_LOCAL_STRING(lp_servicename, szService)
5474 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5475 FN_LOCAL_STRING(lp_pathname, szPath)
5476 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5477 FN_LOCAL_STRING(lp_username, szUsername)
5478 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5479 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5480 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5481 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5482 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5483 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5484 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5485 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5486 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5487 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5488 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5489 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5490 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5491 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5492 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5493 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5494 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5495 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5496 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5497 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5498 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5499 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5500 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5501 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5502 FN_LOCAL_STRING(lp_comment, comment)
5503 FN_LOCAL_STRING(lp_force_user, force_user)
5504 FN_LOCAL_STRING(lp_force_group, force_group)
5505 FN_LOCAL_LIST(lp_readlist, readlist)
5506 FN_LOCAL_LIST(lp_writelist, writelist)
5507 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5508 FN_LOCAL_STRING(lp_fstype, fstype)
5509 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5510 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5511 static FN_LOCAL_STRING(lp_volume, volume)
5512 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5513 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5514 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5515 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5516 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5517 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5518 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5519 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5520 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5521 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5522 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5523 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5524 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5525 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5526 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5527 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5528 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5529 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5530 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5531 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5532 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5533 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5534 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5535 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5536 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5537 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5538 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5539 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5540 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5541 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5542 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5543 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5544 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5545 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5546 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5547 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5548 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5549 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5550 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5551 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5552 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5553 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5554 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5555 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5556 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5557 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5558 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5559 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5560 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5561 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5562 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5563 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5564 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5565 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5566 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5567 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5568 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5569 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5570 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5571 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5572 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5573 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5574 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5575 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5576 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5577 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5578 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5579 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5580 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5581 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5582 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5583 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5584 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5585 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5586 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5587 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5588 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5589 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5590 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5591 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5592 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5593 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5594 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5595 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5596 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5597 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5598 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5599 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5600 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5601 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5602 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5603 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5604 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5605 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5606 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5607 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5608 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5609 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5610 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5612 /* local prototypes */
5614 static int map_parameter(const char *pszParmName);
5615 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5616 static const char *get_boolean(bool bool_value);
5617 static int getservicebyname(const char *pszServiceName,
5618 struct service *pserviceDest);
5619 static void copy_service(struct service *pserviceDest,
5620 struct service *pserviceSource,
5621 struct bitmap *pcopymapDest);
5622 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5624 static bool do_section(const char *pszSectionName, void *userdata);
5625 static void init_copymap(struct service *pservice);
5626 static bool hash_a_service(const char *name, int number);
5627 static void free_service_byindex(int iService);
5628 static void free_param_opts(struct param_opt_struct **popts);
5629 static char * canonicalize_servicename(const char *name);
5630 static void show_parameter(int parmIndex);
5631 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5634 * This is a helper function for parametrical options support. It returns a
5635 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5636 * parametrical functions are quite simple
5638 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5641 bool global_section = False;
5643 struct param_opt_struct *data;
5645 if (snum >= iNumServices) return NULL;
5648 data = Globals.param_opt;
5649 global_section = True;
5651 data = ServicePtrs[snum]->param_opt;
5654 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5655 DEBUG(0,("asprintf failed!\n"));
5660 if (strwicmp(data->key, param_key) == 0) {
5661 string_free(¶m_key);
5667 if (!global_section) {
5668 /* Try to fetch the same option but from globals */
5669 /* but only if we are not already working with Globals */
5670 data = Globals.param_opt;
5672 if (strwicmp(data->key, param_key) == 0) {
5673 string_free(¶m_key);
5680 string_free(¶m_key);
5686 #define MISSING_PARAMETER(name) \
5687 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5689 /*******************************************************************
5690 convenience routine to return int parameters.
5691 ********************************************************************/
5692 static int lp_int(const char *s)
5696 MISSING_PARAMETER(lp_int);
5700 return (int)strtol(s, NULL, 0);
5703 /*******************************************************************
5704 convenience routine to return unsigned long parameters.
5705 ********************************************************************/
5706 static unsigned long lp_ulong(const char *s)
5710 MISSING_PARAMETER(lp_ulong);
5714 return strtoul(s, NULL, 0);
5717 /*******************************************************************
5718 convenience routine to return boolean parameters.
5719 ********************************************************************/
5720 static bool lp_bool(const char *s)
5725 MISSING_PARAMETER(lp_bool);
5729 if (!set_boolean(s, &ret)) {
5730 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5737 /*******************************************************************
5738 convenience routine to return enum parameters.
5739 ********************************************************************/
5740 static int lp_enum(const char *s,const struct enum_list *_enum)
5744 if (!s || !*s || !_enum) {
5745 MISSING_PARAMETER(lp_enum);
5749 for (i=0; _enum[i].name; i++) {
5750 if (strequal(_enum[i].name,s))
5751 return _enum[i].value;
5754 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5758 #undef MISSING_PARAMETER
5760 /* DO NOT USE lp_parm_string ANYMORE!!!!
5761 * use lp_parm_const_string or lp_parm_talloc_string
5763 * lp_parm_string is only used to let old modules find this symbol
5765 #undef lp_parm_string
5766 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5767 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5769 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5772 /* Return parametric option from a given service. Type is a part of option before ':' */
5773 /* Parametric option has following syntax: 'Type: option = value' */
5774 /* the returned value is talloced on the talloc_tos() */
5775 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5777 struct param_opt_struct *data = get_parametrics(snum, type, option);
5779 if (data == NULL||data->value==NULL) {
5781 return lp_string(def);
5787 return lp_string(data->value);
5790 /* Return parametric option from a given service. Type is a part of option before ':' */
5791 /* Parametric option has following syntax: 'Type: option = value' */
5792 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5794 struct param_opt_struct *data = get_parametrics(snum, type, option);
5796 if (data == NULL||data->value==NULL)
5802 /* Return parametric option from a given service. Type is a part of option before ':' */
5803 /* Parametric option has following syntax: 'Type: option = value' */
5805 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5807 struct param_opt_struct *data = get_parametrics(snum, type, option);
5809 if (data == NULL||data->value==NULL)
5810 return (const char **)def;
5812 if (data->list==NULL) {
5813 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5816 return (const char **)data->list;
5819 /* Return parametric option from a given service. Type is a part of option before ':' */
5820 /* Parametric option has following syntax: 'Type: option = value' */
5822 int lp_parm_int(int snum, const char *type, const char *option, int def)
5824 struct param_opt_struct *data = get_parametrics(snum, type, option);
5826 if (data && data->value && *data->value)
5827 return lp_int(data->value);
5832 /* Return parametric option from a given service. Type is a part of option before ':' */
5833 /* Parametric option has following syntax: 'Type: option = value' */
5835 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5837 struct param_opt_struct *data = get_parametrics(snum, type, option);
5839 if (data && data->value && *data->value)
5840 return lp_ulong(data->value);
5845 /* Return parametric option from a given service. Type is a part of option before ':' */
5846 /* Parametric option has following syntax: 'Type: option = value' */
5848 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5850 struct param_opt_struct *data = get_parametrics(snum, type, option);
5852 if (data && data->value && *data->value)
5853 return lp_bool(data->value);
5858 /* Return parametric option from a given service. Type is a part of option before ':' */
5859 /* Parametric option has following syntax: 'Type: option = value' */
5861 int lp_parm_enum(int snum, const char *type, const char *option,
5862 const struct enum_list *_enum, int def)
5864 struct param_opt_struct *data = get_parametrics(snum, type, option);
5866 if (data && data->value && *data->value && _enum)
5867 return lp_enum(data->value, _enum);
5873 /***************************************************************************
5874 Initialise a service to the defaults.
5875 ***************************************************************************/
5877 static void init_service(struct service *pservice)
5879 memset((char *)pservice, '\0', sizeof(struct service));
5880 copy_service(pservice, &sDefault, NULL);
5885 * free a param_opts structure.
5886 * param_opts handling should be moved to talloc;
5887 * then this whole functions reduces to a TALLOC_FREE().
5890 static void free_param_opts(struct param_opt_struct **popts)
5892 struct param_opt_struct *opt, *next_opt;
5894 if (popts == NULL) {
5898 if (*popts != NULL) {
5899 DEBUG(5, ("Freeing parametrics:\n"));
5902 while (opt != NULL) {
5903 string_free(&opt->key);
5904 string_free(&opt->value);
5905 TALLOC_FREE(opt->list);
5906 next_opt = opt->next;
5913 /***************************************************************************
5914 Free the dynamically allocated parts of a service struct.
5915 ***************************************************************************/
5917 static void free_service(struct service *pservice)
5922 if (pservice->szService)
5923 DEBUG(5, ("free_service: Freeing service %s\n",
5924 pservice->szService));
5926 free_parameters(pservice);
5928 string_free(&pservice->szService);
5929 bitmap_free(pservice->copymap);
5931 free_param_opts(&pservice->param_opt);
5933 ZERO_STRUCTP(pservice);
5937 /***************************************************************************
5938 remove a service indexed in the ServicePtrs array from the ServiceHash
5939 and free the dynamically allocated parts
5940 ***************************************************************************/
5942 static void free_service_byindex(int idx)
5944 if ( !LP_SNUM_OK(idx) )
5947 ServicePtrs[idx]->valid = False;
5948 invalid_services[num_invalid_services++] = idx;
5950 /* we have to cleanup the hash record */
5952 if (ServicePtrs[idx]->szService) {
5953 char *canon_name = canonicalize_servicename(
5954 ServicePtrs[idx]->szService );
5956 dbwrap_delete_bystring(ServiceHash, canon_name );
5957 TALLOC_FREE(canon_name);
5960 free_service(ServicePtrs[idx]);
5963 /***************************************************************************
5964 Add a new service to the services array initialising it with the given
5966 ***************************************************************************/
5968 static int add_a_service(const struct service *pservice, const char *name)
5971 struct service tservice;
5972 int num_to_alloc = iNumServices + 1;
5974 tservice = *pservice;
5976 /* it might already exist */
5978 i = getservicebyname(name, NULL);
5980 /* Clean all parametric options for service */
5981 /* They will be added during parsing again */
5982 free_param_opts(&ServicePtrs[i]->param_opt);
5987 /* find an invalid one */
5989 if (num_invalid_services > 0) {
5990 i = invalid_services[--num_invalid_services];
5993 /* if not, then create one */
5994 if (i == iNumServices) {
5995 struct service **tsp;
5998 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6000 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6004 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6005 if (!ServicePtrs[iNumServices]) {
6006 DEBUG(0,("add_a_service: out of memory!\n"));
6011 /* enlarge invalid_services here for now... */
6012 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6014 if (tinvalid == NULL) {
6015 DEBUG(0,("add_a_service: failed to enlarge "
6016 "invalid_services!\n"));
6019 invalid_services = tinvalid;
6021 free_service_byindex(i);
6024 ServicePtrs[i]->valid = True;
6026 init_service(ServicePtrs[i]);
6027 copy_service(ServicePtrs[i], &tservice, NULL);
6029 string_set(&ServicePtrs[i]->szService, name);
6031 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6032 i, ServicePtrs[i]->szService));
6034 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6041 /***************************************************************************
6042 Convert a string to uppercase and remove whitespaces.
6043 ***************************************************************************/
6045 static char *canonicalize_servicename(const char *src)
6050 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6054 result = talloc_strdup(talloc_tos(), src);
6055 SMB_ASSERT(result != NULL);
6061 /***************************************************************************
6062 Add a name/index pair for the services array to the hash table.
6063 ***************************************************************************/
6065 static bool hash_a_service(const char *name, int idx)
6069 if ( !ServiceHash ) {
6070 DEBUG(10,("hash_a_service: creating servicehash\n"));
6071 ServiceHash = db_open_rbt(NULL);
6072 if ( !ServiceHash ) {
6073 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6078 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6081 canon_name = canonicalize_servicename( name );
6083 dbwrap_store_bystring(ServiceHash, canon_name,
6084 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6087 TALLOC_FREE(canon_name);
6092 /***************************************************************************
6093 Add a new home service, with the specified home directory, defaults coming
6095 ***************************************************************************/
6097 bool lp_add_home(const char *pszHomename, int iDefaultService,
6098 const char *user, const char *pszHomedir)
6102 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6107 if (!(*(ServicePtrs[iDefaultService]->szPath))
6108 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6109 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6112 if (!(*(ServicePtrs[i]->comment))) {
6113 char *comment = NULL;
6114 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6117 string_set(&ServicePtrs[i]->comment, comment);
6121 /* set the browseable flag from the global default */
6123 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6124 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6126 ServicePtrs[i]->autoloaded = True;
6128 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6129 user, ServicePtrs[i]->szPath ));
6134 /***************************************************************************
6135 Add a new service, based on an old one.
6136 ***************************************************************************/
6138 int lp_add_service(const char *pszService, int iDefaultService)
6140 if (iDefaultService < 0) {
6141 return add_a_service(&sDefault, pszService);
6144 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6147 /***************************************************************************
6148 Add the IPC service.
6149 ***************************************************************************/
6151 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6153 char *comment = NULL;
6154 int i = add_a_service(&sDefault, ipc_name);
6159 if (asprintf(&comment, "IPC Service (%s)",
6160 Globals.szServerString) < 0) {
6164 string_set(&ServicePtrs[i]->szPath, tmpdir());
6165 string_set(&ServicePtrs[i]->szUsername, "");
6166 string_set(&ServicePtrs[i]->comment, comment);
6167 string_set(&ServicePtrs[i]->fstype, "IPC");
6168 ServicePtrs[i]->iMaxConnections = 0;
6169 ServicePtrs[i]->bAvailable = True;
6170 ServicePtrs[i]->bRead_only = True;
6171 ServicePtrs[i]->bGuest_only = False;
6172 ServicePtrs[i]->bAdministrative_share = True;
6173 ServicePtrs[i]->bGuest_ok = guest_ok;
6174 ServicePtrs[i]->bPrint_ok = False;
6175 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6177 DEBUG(3, ("adding IPC service\n"));
6183 /***************************************************************************
6184 Add a new printer service, with defaults coming from service iFrom.
6185 ***************************************************************************/
6187 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6189 const char *comment = "From Printcap";
6190 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6195 /* note that we do NOT default the availability flag to True - */
6196 /* we take it from the default service passed. This allows all */
6197 /* dynamic printers to be disabled by disabling the [printers] */
6198 /* entry (if/when the 'available' keyword is implemented!). */
6200 /* the printer name is set to the service name. */
6201 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6202 string_set(&ServicePtrs[i]->comment, comment);
6204 /* set the browseable flag from the gloabl default */
6205 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6207 /* Printers cannot be read_only. */
6208 ServicePtrs[i]->bRead_only = False;
6209 /* No share modes on printer services. */
6210 ServicePtrs[i]->bShareModes = False;
6211 /* No oplocks on printer services. */
6212 ServicePtrs[i]->bOpLocks = False;
6213 /* Printer services must be printable. */
6214 ServicePtrs[i]->bPrint_ok = True;
6216 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6222 /***************************************************************************
6223 Check whether the given parameter name is valid.
6224 Parametric options (names containing a colon) are considered valid.
6225 ***************************************************************************/
6227 bool lp_parameter_is_valid(const char *pszParmName)
6229 return ((map_parameter(pszParmName) != -1) ||
6230 (strchr(pszParmName, ':') != NULL));
6233 /***************************************************************************
6234 Check whether the given name is the name of a global parameter.
6235 Returns True for strings belonging to parameters of class
6236 P_GLOBAL, False for all other strings, also for parametric options
6237 and strings not belonging to any option.
6238 ***************************************************************************/
6240 bool lp_parameter_is_global(const char *pszParmName)
6242 int num = map_parameter(pszParmName);
6245 return (parm_table[num].p_class == P_GLOBAL);
6251 /**************************************************************************
6252 Check whether the given name is the canonical name of a parameter.
6253 Returns False if it is not a valid parameter Name.
6254 For parametric options, True is returned.
6255 **************************************************************************/
6257 bool lp_parameter_is_canonical(const char *parm_name)
6259 if (!lp_parameter_is_valid(parm_name)) {
6263 return (map_parameter(parm_name) ==
6264 map_parameter_canonical(parm_name, NULL));
6267 /**************************************************************************
6268 Determine the canonical name for a parameter.
6269 Indicate when it is an inverse (boolean) synonym instead of a
6271 **************************************************************************/
6273 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6278 if (!lp_parameter_is_valid(parm_name)) {
6283 num = map_parameter_canonical(parm_name, inverse);
6285 /* parametric option */
6286 *canon_parm = parm_name;
6288 *canon_parm = parm_table[num].label;
6295 /**************************************************************************
6296 Determine the canonical name for a parameter.
6297 Turn the value given into the inverse boolean expression when
6298 the synonym is an invers boolean synonym.
6300 Return True if parm_name is a valid parameter name and
6301 in case it is an invers boolean synonym, if the val string could
6302 successfully be converted to the reverse bool.
6303 Return false in all other cases.
6304 **************************************************************************/
6306 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6308 const char **canon_parm,
6309 const char **canon_val)
6314 if (!lp_parameter_is_valid(parm_name)) {
6320 num = map_parameter_canonical(parm_name, &inverse);
6322 /* parametric option */
6323 *canon_parm = parm_name;
6326 *canon_parm = parm_table[num].label;
6328 if (!lp_invert_boolean(val, canon_val)) {
6340 /***************************************************************************
6341 Map a parameter's string representation to something we can use.
6342 Returns False if the parameter string is not recognised, else TRUE.
6343 ***************************************************************************/
6345 static int map_parameter(const char *pszParmName)
6349 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6352 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6353 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6356 /* Warn only if it isn't parametric option */
6357 if (strchr(pszParmName, ':') == NULL)
6358 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6359 /* We do return 'fail' for parametric options as well because they are
6360 stored in different storage
6365 /***************************************************************************
6366 Map a parameter's string representation to the index of the canonical
6367 form of the parameter (it might be a synonym).
6368 Returns -1 if the parameter string is not recognised.
6369 ***************************************************************************/
6371 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6373 int parm_num, canon_num;
6374 bool loc_inverse = False;
6376 parm_num = map_parameter(pszParmName);
6377 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6378 /* invalid, parametric or no canidate for synonyms ... */
6382 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6383 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6384 parm_num = canon_num;
6390 if (inverse != NULL) {
6391 *inverse = loc_inverse;
6396 /***************************************************************************
6397 return true if parameter number parm1 is a synonym of parameter
6398 number parm2 (parm2 being the principal name).
6399 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6401 ***************************************************************************/
6403 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6405 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6406 (parm_table[parm1].flags & FLAG_HIDE) &&
6407 !(parm_table[parm2].flags & FLAG_HIDE))
6409 if (inverse != NULL) {
6410 if ((parm_table[parm1].type == P_BOOLREV) &&
6411 (parm_table[parm2].type == P_BOOL))
6423 /***************************************************************************
6424 Show one parameter's name, type, [values,] and flags.
6425 (helper functions for show_parameter_list)
6426 ***************************************************************************/
6428 static void show_parameter(int parmIndex)
6430 int enumIndex, flagIndex;
6435 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6436 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6438 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6439 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6440 FLAG_HIDE, FLAG_DOS_STRING};
6441 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6442 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6443 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6445 printf("%s=%s", parm_table[parmIndex].label,
6446 type[parm_table[parmIndex].type]);
6447 if (parm_table[parmIndex].type == P_ENUM) {
6450 parm_table[parmIndex].enum_list[enumIndex].name;
6454 enumIndex ? "|" : "",
6455 parm_table[parmIndex].enum_list[enumIndex].name);
6460 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6461 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6464 flag_names[flagIndex]);
6469 /* output synonyms */
6471 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6472 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6473 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6474 parm_table[parmIndex2].label);
6475 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6477 printf(" (synonyms: ");
6482 printf("%s%s", parm_table[parmIndex2].label,
6483 inverse ? "[i]" : "");
6493 /***************************************************************************
6494 Show all parameter's name, type, [values,] and flags.
6495 ***************************************************************************/
6497 void show_parameter_list(void)
6499 int classIndex, parmIndex;
6500 const char *section_names[] = { "local", "global", NULL};
6502 for (classIndex=0; section_names[classIndex]; classIndex++) {
6503 printf("[%s]\n", section_names[classIndex]);
6504 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6505 if (parm_table[parmIndex].p_class == classIndex) {
6506 show_parameter(parmIndex);
6512 /***************************************************************************
6513 Check if a given string correctly represents a boolean value.
6514 ***************************************************************************/
6516 bool lp_string_is_valid_boolean(const char *parm_value)
6518 return set_boolean(parm_value, NULL);
6521 /***************************************************************************
6522 Get the standard string representation of a boolean value ("yes" or "no")
6523 ***************************************************************************/
6525 static const char *get_boolean(bool bool_value)
6527 static const char *yes_str = "yes";
6528 static const char *no_str = "no";
6530 return (bool_value ? yes_str : no_str);
6533 /***************************************************************************
6534 Provide the string of the negated boolean value associated to the boolean
6535 given as a string. Returns False if the passed string does not correctly
6536 represent a boolean.
6537 ***************************************************************************/
6539 bool lp_invert_boolean(const char *str, const char **inverse_str)
6543 if (!set_boolean(str, &val)) {
6547 *inverse_str = get_boolean(!val);
6551 /***************************************************************************
6552 Provide the canonical string representation of a boolean value given
6553 as a string. Return True on success, False if the string given does
6554 not correctly represent a boolean.
6555 ***************************************************************************/
6557 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6561 if (!set_boolean(str, &val)) {
6565 *canon_str = get_boolean(val);
6569 /***************************************************************************
6570 Find a service by name. Otherwise works like get_service.
6571 ***************************************************************************/
6573 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6579 if (ServiceHash == NULL) {
6583 canon_name = canonicalize_servicename(pszServiceName);
6585 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6587 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6588 iService = *(int *)data.dptr;
6591 TALLOC_FREE(canon_name);
6593 if ((iService != -1) && (LP_SNUM_OK(iService))
6594 && (pserviceDest != NULL)) {
6595 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6601 /***************************************************************************
6602 Copy a service structure to another.
6603 If pcopymapDest is NULL then copy all fields
6604 ***************************************************************************/
6607 * Add a parametric option to a param_opt_struct,
6608 * replacing old value, if already present.
6610 static void set_param_opt(struct param_opt_struct **opt_list,
6611 const char *opt_name,
6612 const char *opt_value)
6614 struct param_opt_struct *new_opt, *opt;
6617 if (opt_list == NULL) {
6624 /* Traverse destination */
6626 /* If we already have same option, override it */
6627 if (strwicmp(opt->key, opt_name) == 0) {
6628 string_free(&opt->value);
6629 TALLOC_FREE(opt->list);
6630 opt->value = SMB_STRDUP(opt_value);
6637 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6638 new_opt->key = SMB_STRDUP(opt_name);
6639 new_opt->value = SMB_STRDUP(opt_value);
6640 new_opt->list = NULL;
6641 DLIST_ADD(*opt_list, new_opt);
6645 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6646 struct bitmap *pcopymapDest)
6649 bool bcopyall = (pcopymapDest == NULL);
6650 struct param_opt_struct *data;
6652 for (i = 0; parm_table[i].label; i++)
6653 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6654 (bcopyall || bitmap_query(pcopymapDest,i))) {
6655 void *def_ptr = parm_table[i].ptr;
6657 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6660 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6663 switch (parm_table[i].type) {
6666 *(bool *)dest_ptr = *(bool *)src_ptr;
6672 *(int *)dest_ptr = *(int *)src_ptr;
6676 *(char *)dest_ptr = *(char *)src_ptr;
6680 string_set((char **)dest_ptr,
6685 string_set((char **)dest_ptr,
6687 strupper_m(*(char **)dest_ptr);
6690 TALLOC_FREE(*((char ***)dest_ptr));
6691 *((char ***)dest_ptr) = str_list_copy(NULL,
6692 *(const char ***)src_ptr);
6700 init_copymap(pserviceDest);
6701 if (pserviceSource->copymap)
6702 bitmap_copy(pserviceDest->copymap,
6703 pserviceSource->copymap);
6706 data = pserviceSource->param_opt;
6708 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6713 /***************************************************************************
6714 Check a service for consistency. Return False if the service is in any way
6715 incomplete or faulty, else True.
6716 ***************************************************************************/
6718 bool service_ok(int iService)
6723 if (ServicePtrs[iService]->szService[0] == '\0') {
6724 DEBUG(0, ("The following message indicates an internal error:\n"));
6725 DEBUG(0, ("No service name in service entry.\n"));
6729 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6730 /* I can't see why you'd want a non-printable printer service... */
6731 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6732 if (!ServicePtrs[iService]->bPrint_ok) {
6733 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6734 ServicePtrs[iService]->szService));
6735 ServicePtrs[iService]->bPrint_ok = True;
6737 /* [printers] service must also be non-browsable. */
6738 if (ServicePtrs[iService]->bBrowseable)
6739 ServicePtrs[iService]->bBrowseable = False;
6742 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6743 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6744 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6746 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6747 ServicePtrs[iService]->szService));
6748 ServicePtrs[iService]->bAvailable = False;
6751 /* If a service is flagged unavailable, log the fact at level 1. */
6752 if (!ServicePtrs[iService]->bAvailable)
6753 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6754 ServicePtrs[iService]->szService));
6759 static struct smbconf_ctx *lp_smbconf_ctx(void)
6762 static struct smbconf_ctx *conf_ctx = NULL;
6764 if (conf_ctx == NULL) {
6765 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6766 if (!W_ERROR_IS_OK(werr)) {
6767 DEBUG(1, ("error initializing registry configuration: "
6768 "%s\n", win_errstr(werr)));
6776 static bool process_smbconf_service(struct smbconf_service *service)
6781 if (service == NULL) {
6785 ret = do_section(service->name, NULL);
6789 for (count = 0; count < service->num_params; count++) {
6790 ret = do_parameter(service->param_names[count],
6791 service->param_values[count],
6801 * process_registry_globals
6803 static bool process_registry_globals(void)
6806 struct smbconf_service *service = NULL;
6807 TALLOC_CTX *mem_ctx = talloc_stackframe();
6808 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6811 if (conf_ctx == NULL) {
6815 ret = do_parameter("registry shares", "yes", NULL);
6820 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6821 /* nothing to read from the registry yet but make sure lp_load
6822 * doesn't return false */
6827 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6828 if (!W_ERROR_IS_OK(werr)) {
6832 ret = process_smbconf_service(service);
6838 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6841 TALLOC_FREE(mem_ctx);
6845 static bool process_registry_shares(void)
6849 struct smbconf_service **service = NULL;
6850 uint32_t num_shares = 0;
6851 TALLOC_CTX *mem_ctx = talloc_stackframe();
6852 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6855 if (conf_ctx == NULL) {
6859 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6860 if (!W_ERROR_IS_OK(werr)) {
6866 for (count = 0; count < num_shares; count++) {
6867 if (strequal(service[count]->name, GLOBAL_NAME)) {
6870 ret = process_smbconf_service(service[count]);
6877 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6880 TALLOC_FREE(mem_ctx);
6884 static struct file_lists {
6885 struct file_lists *next;
6889 } *file_lists = NULL;
6891 /*******************************************************************
6892 Keep a linked list of all config files so we know when one has changed
6893 it's date and needs to be reloaded.
6894 ********************************************************************/
6896 static void add_to_file_list(const char *fname, const char *subfname)
6898 struct file_lists *f = file_lists;
6901 if (f->name && !strcmp(f->name, fname))
6907 f = SMB_MALLOC_P(struct file_lists);
6910 f->next = file_lists;
6911 f->name = SMB_STRDUP(fname);
6916 f->subfname = SMB_STRDUP(subfname);
6922 f->modtime = file_modtime(subfname);
6924 time_t t = file_modtime(subfname);
6931 * Utility function for outsiders to check if we're running on registry.
6933 bool lp_config_backend_is_registry(void)
6935 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6939 * Utility function to check if the config backend is FILE.
6941 bool lp_config_backend_is_file(void)
6943 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6946 /*******************************************************************
6947 Check if a config file has changed date.
6948 ********************************************************************/
6950 bool lp_file_list_changed(void)
6952 struct file_lists *f = file_lists;
6954 DEBUG(6, ("lp_file_list_changed()\n"));
6956 if (lp_config_backend_is_registry()) {
6957 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6959 if (conf_ctx == NULL) {
6962 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6963 DEBUGADD(6, ("registry config changed\n"));
6972 n2 = alloc_sub_basic(get_current_username(),
6973 current_user_info.domain,
6978 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6979 f->name, n2, ctime(&f->modtime)));
6981 mod_time = file_modtime(n2);
6983 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6985 ("file %s modified: %s\n", n2,
6987 f->modtime = mod_time;
6988 SAFE_FREE(f->subfname);
6989 f->subfname = n2; /* Passing ownership of
6990 return from alloc_sub_basic
7001 /***************************************************************************
7002 Run standard_sub_basic on netbios name... needed because global_myname
7003 is not accessed through any lp_ macro.
7004 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7005 ***************************************************************************/
7007 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7010 char *netbios_name = alloc_sub_basic(get_current_username(),
7011 current_user_info.domain,
7014 ret = set_global_myname(netbios_name);
7015 SAFE_FREE(netbios_name);
7016 string_set(&Globals.szNetbiosName,global_myname());
7018 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7024 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7026 if (strcmp(*ptr, pszParmValue) != 0) {
7027 string_set(ptr, pszParmValue);
7035 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7039 ret = set_global_myworkgroup(pszParmValue);
7040 string_set(&Globals.szWorkgroup,lp_workgroup());
7045 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7049 ret = set_global_scope(pszParmValue);
7050 string_set(&Globals.szNetbiosScope,global_scope());
7055 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7057 TALLOC_FREE(Globals.szNetbiosAliases);
7058 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7059 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7062 /***************************************************************************
7063 Handle the include operation.
7064 ***************************************************************************/
7065 static bool bAllowIncludeRegistry = true;
7067 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7071 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7072 if (!bAllowIncludeRegistry) {
7075 if (bInGlobalSection) {
7076 return process_registry_globals();
7078 DEBUG(1, ("\"include = registry\" only effective "
7079 "in %s section\n", GLOBAL_NAME));
7084 fname = alloc_sub_basic(get_current_username(),
7085 current_user_info.domain,
7088 add_to_file_list(pszParmValue, fname);
7090 string_set(ptr, fname);
7092 if (file_exist(fname)) {
7093 bool ret = pm_process(fname, do_section, do_parameter, NULL);
7098 DEBUG(2, ("Can't find include file %s\n", fname));
7103 /***************************************************************************
7104 Handle the interpretation of the copy parameter.
7105 ***************************************************************************/
7107 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7111 struct service serviceTemp;
7113 string_set(ptr, pszParmValue);
7115 init_service(&serviceTemp);
7119 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7121 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7122 if (iTemp == iServiceIndex) {
7123 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7125 copy_service(ServicePtrs[iServiceIndex],
7127 ServicePtrs[iServiceIndex]->copymap);
7131 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7135 free_service(&serviceTemp);
7139 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7141 Globals.ldap_debug_level = lp_int(pszParmValue);
7142 init_ldap_debugging();
7146 /***************************************************************************
7147 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7152 idmap uid = 1000-1999
7155 We only do simple parsing checks here. The strings are parsed into useful
7156 structures in the idmap daemon code.
7158 ***************************************************************************/
7160 /* Some lp_ routines to return idmap [ug]id information */
7162 static uid_t idmap_uid_low, idmap_uid_high;
7163 static gid_t idmap_gid_low, idmap_gid_high;
7165 bool lp_idmap_uid(uid_t *low, uid_t *high)
7167 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7171 *low = idmap_uid_low;
7174 *high = idmap_uid_high;
7179 bool lp_idmap_gid(gid_t *low, gid_t *high)
7181 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7185 *low = idmap_gid_low;
7188 *high = idmap_gid_high;
7193 /* Do some simple checks on "idmap [ug]id" parameter values */
7195 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7199 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7204 string_set(ptr, pszParmValue);
7206 idmap_uid_low = low;
7207 idmap_uid_high = high;
7212 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7216 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7221 string_set(ptr, pszParmValue);
7223 idmap_gid_low = low;
7224 idmap_gid_high = high;
7229 /***************************************************************************
7230 Handle the DEBUG level list.
7231 ***************************************************************************/
7233 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7235 string_set(ptr, pszParmValueIn);
7236 return debug_parse_levels(pszParmValueIn);
7239 /***************************************************************************
7240 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7241 ***************************************************************************/
7243 static const char *append_ldap_suffix( const char *str )
7245 const char *suffix_string;
7248 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7249 Globals.szLdapSuffix );
7250 if ( !suffix_string ) {
7251 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7255 return suffix_string;
7258 const char *lp_ldap_machine_suffix(void)
7260 if (Globals.szLdapMachineSuffix[0])
7261 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7263 return lp_string(Globals.szLdapSuffix);
7266 const char *lp_ldap_user_suffix(void)
7268 if (Globals.szLdapUserSuffix[0])
7269 return append_ldap_suffix(Globals.szLdapUserSuffix);
7271 return lp_string(Globals.szLdapSuffix);
7274 const char *lp_ldap_group_suffix(void)
7276 if (Globals.szLdapGroupSuffix[0])
7277 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7279 return lp_string(Globals.szLdapSuffix);
7282 const char *lp_ldap_idmap_suffix(void)
7284 if (Globals.szLdapIdmapSuffix[0])
7285 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7287 return lp_string(Globals.szLdapSuffix);
7290 /****************************************************************************
7291 set the value for a P_ENUM
7292 ***************************************************************************/
7294 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7299 for (i = 0; parm->enum_list[i].name; i++) {
7300 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7301 *ptr = parm->enum_list[i].value;
7305 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7306 pszParmValue, parm->label));
7309 /***************************************************************************
7310 ***************************************************************************/
7312 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7314 static int parm_num = -1;
7317 if ( parm_num == -1 )
7318 parm_num = map_parameter( "printing" );
7320 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7325 s = ServicePtrs[snum];
7327 init_printer_values( s );
7333 /***************************************************************************
7334 Initialise a copymap.
7335 ***************************************************************************/
7337 static void init_copymap(struct service *pservice)
7340 if (pservice->copymap) {
7341 bitmap_free(pservice->copymap);
7343 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7344 if (!pservice->copymap)
7346 ("Couldn't allocate copymap!! (size %d)\n",
7347 (int)NUMPARAMETERS));
7349 for (i = 0; i < NUMPARAMETERS; i++)
7350 bitmap_set(pservice->copymap, i);
7353 /***************************************************************************
7354 Return the local pointer to a parameter given a service struct and the
7355 pointer into the default structure.
7356 ***************************************************************************/
7358 static void *lp_local_ptr(struct service *service, void *ptr)
7360 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7363 /***************************************************************************
7364 Return the local pointer to a parameter given the service number and the
7365 pointer into the default structure.
7366 ***************************************************************************/
7368 void *lp_local_ptr_by_snum(int snum, void *ptr)
7370 return lp_local_ptr(ServicePtrs[snum], ptr);
7373 /***************************************************************************
7374 Process a parameter for a particular service number. If snum < 0
7375 then assume we are in the globals.
7376 ***************************************************************************/
7378 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7381 void *parm_ptr = NULL; /* where we are going to store the result */
7382 void *def_ptr = NULL;
7383 struct param_opt_struct **opt_list;
7385 parmnum = map_parameter(pszParmName);
7388 if (strchr(pszParmName, ':') == NULL) {
7389 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7395 * We've got a parametric option
7398 opt_list = (snum < 0)
7399 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7400 set_param_opt(opt_list, pszParmName, pszParmValue);
7405 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7406 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7410 def_ptr = parm_table[parmnum].ptr;
7412 /* we might point at a service, the default service or a global */
7416 if (parm_table[parmnum].p_class == P_GLOBAL) {
7418 ("Global parameter %s found in service section!\n",
7422 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7426 if (!ServicePtrs[snum]->copymap)
7427 init_copymap(ServicePtrs[snum]);
7429 /* this handles the aliases - set the copymap for other entries with
7430 the same data pointer */
7431 for (i = 0; parm_table[i].label; i++)
7432 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7433 bitmap_clear(ServicePtrs[snum]->copymap, i);
7436 /* if it is a special case then go ahead */
7437 if (parm_table[parmnum].special) {
7438 return parm_table[parmnum].special(snum, pszParmValue,
7442 /* now switch on the type of variable it is */
7443 switch (parm_table[parmnum].type)
7446 *(bool *)parm_ptr = lp_bool(pszParmValue);
7450 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7454 *(int *)parm_ptr = lp_int(pszParmValue);
7458 *(char *)parm_ptr = *pszParmValue;
7462 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7464 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7469 TALLOC_FREE(*((char ***)parm_ptr));
7470 *(char ***)parm_ptr = str_list_make_v3(
7471 talloc_autofree_context(), pszParmValue, NULL);
7475 string_set((char **)parm_ptr, pszParmValue);
7479 string_set((char **)parm_ptr, pszParmValue);
7480 strupper_m(*(char **)parm_ptr);
7484 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7493 /***************************************************************************
7494 Process a parameter.
7495 ***************************************************************************/
7497 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7500 if (!bInGlobalSection && bGlobalOnly)
7503 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7505 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7506 pszParmName, pszParmValue));
7509 /***************************************************************************
7510 Print a parameter of the specified type.
7511 ***************************************************************************/
7513 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7519 for (i = 0; p->enum_list[i].name; i++) {
7520 if (*(int *)ptr == p->enum_list[i].value) {
7522 p->enum_list[i].name);
7529 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7533 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7537 fprintf(f, "%d", *(int *)ptr);
7541 fprintf(f, "%c", *(char *)ptr);
7545 char *o = octal_string(*(int *)ptr);
7546 fprintf(f, "%s", o);
7552 if ((char ***)ptr && *(char ***)ptr) {
7553 char **list = *(char ***)ptr;
7554 for (; *list; list++) {
7555 /* surround strings with whitespace in double quotes */
7556 if ( strchr_m( *list, ' ' ) )
7557 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7559 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7566 if (*(char **)ptr) {
7567 fprintf(f, "%s", *(char **)ptr);
7575 /***************************************************************************
7576 Check if two parameters are equal.
7577 ***************************************************************************/
7579 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7584 return (*((bool *)ptr1) == *((bool *)ptr2));
7589 return (*((int *)ptr1) == *((int *)ptr2));
7592 return (*((char *)ptr1) == *((char *)ptr2));
7595 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7600 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7605 return (p1 == p2 || strequal(p1, p2));
7613 /***************************************************************************
7614 Initialize any local varients in the sDefault table.
7615 ***************************************************************************/
7617 void init_locals(void)
7622 /***************************************************************************
7623 Process a new section (service). At this stage all sections are services.
7624 Later we'll have special sections that permit server parameters to be set.
7625 Returns True on success, False on failure.
7626 ***************************************************************************/
7628 static bool do_section(const char *pszSectionName, void *userdata)
7631 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7632 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7635 /* if we were in a global section then do the local inits */
7636 if (bInGlobalSection && !isglobal)
7639 /* if we've just struck a global section, note the fact. */
7640 bInGlobalSection = isglobal;
7642 /* check for multiple global sections */
7643 if (bInGlobalSection) {
7644 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7648 if (!bInGlobalSection && bGlobalOnly)
7651 /* if we have a current service, tidy it up before moving on */
7654 if (iServiceIndex >= 0)
7655 bRetval = service_ok(iServiceIndex);
7657 /* if all is still well, move to the next record in the services array */
7659 /* We put this here to avoid an odd message order if messages are */
7660 /* issued by the post-processing of a previous section. */
7661 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7663 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7665 DEBUG(0, ("Failed to add a new service\n"));
7674 /***************************************************************************
7675 Determine if a partcular base parameter is currentl set to the default value.
7676 ***************************************************************************/
7678 static bool is_default(int i)
7680 if (!defaults_saved)
7682 switch (parm_table[i].type) {
7684 return str_list_equal((const char **)parm_table[i].def.lvalue,
7685 *(const char ***)parm_table[i].ptr);
7688 return strequal(parm_table[i].def.svalue,
7689 *(char **)parm_table[i].ptr);
7692 return parm_table[i].def.bvalue ==
7693 *(bool *)parm_table[i].ptr;
7695 return parm_table[i].def.cvalue ==
7696 *(char *)parm_table[i].ptr;
7700 return parm_table[i].def.ivalue ==
7701 *(int *)parm_table[i].ptr;
7708 /***************************************************************************
7709 Display the contents of the global structure.
7710 ***************************************************************************/
7712 static void dump_globals(FILE *f)
7715 struct param_opt_struct *data;
7717 fprintf(f, "[global]\n");
7719 for (i = 0; parm_table[i].label; i++)
7720 if (parm_table[i].p_class == P_GLOBAL &&
7721 parm_table[i].ptr &&
7722 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7723 if (defaults_saved && is_default(i))
7725 fprintf(f, "\t%s = ", parm_table[i].label);
7726 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7729 if (Globals.param_opt != NULL) {
7730 data = Globals.param_opt;
7732 fprintf(f, "\t%s = %s\n", data->key, data->value);
7739 /***************************************************************************
7740 Return True if a local parameter is currently set to the global default.
7741 ***************************************************************************/
7743 bool lp_is_default(int snum, struct parm_struct *parm)
7745 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7747 return equal_parameter(parm->type,
7748 ((char *)ServicePtrs[snum]) + pdiff,
7749 ((char *)&sDefault) + pdiff);
7752 /***************************************************************************
7753 Display the contents of a single services record.
7754 ***************************************************************************/
7756 static void dump_a_service(struct service *pService, FILE * f)
7759 struct param_opt_struct *data;
7761 if (pService != &sDefault)
7762 fprintf(f, "[%s]\n", pService->szService);
7764 for (i = 0; parm_table[i].label; i++) {
7766 if (parm_table[i].p_class == P_LOCAL &&
7767 parm_table[i].ptr &&
7768 (*parm_table[i].label != '-') &&
7769 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7772 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7774 if (pService == &sDefault) {
7775 if (defaults_saved && is_default(i))
7778 if (equal_parameter(parm_table[i].type,
7779 ((char *)pService) +
7781 ((char *)&sDefault) +
7786 fprintf(f, "\t%s = ", parm_table[i].label);
7787 print_parameter(&parm_table[i],
7788 ((char *)pService) + pdiff, f);
7793 if (pService->param_opt != NULL) {
7794 data = pService->param_opt;
7796 fprintf(f, "\t%s = %s\n", data->key, data->value);
7802 /***************************************************************************
7803 Display the contents of a parameter of a single services record.
7804 ***************************************************************************/
7806 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7809 bool result = False;
7812 fstring local_parm_name;
7814 const char *parm_opt_value;
7816 /* check for parametrical option */
7817 fstrcpy( local_parm_name, parm_name);
7818 parm_opt = strchr( local_parm_name, ':');
7823 if (strlen(parm_opt)) {
7824 parm_opt_value = lp_parm_const_string( snum,
7825 local_parm_name, parm_opt, NULL);
7826 if (parm_opt_value) {
7827 printf( "%s\n", parm_opt_value);
7834 /* check for a key and print the value */
7841 for (i = 0; parm_table[i].label; i++) {
7842 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7843 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7844 parm_table[i].ptr &&
7845 (*parm_table[i].label != '-') &&
7846 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7851 ptr = parm_table[i].ptr;
7853 struct service *pService = ServicePtrs[snum];
7854 ptr = ((char *)pService) +
7855 PTR_DIFF(parm_table[i].ptr, &sDefault);
7858 print_parameter(&parm_table[i],
7869 /***************************************************************************
7870 Return info about the requested parameter (given as a string).
7871 Return NULL when the string is not a valid parameter name.
7872 ***************************************************************************/
7874 struct parm_struct *lp_get_parameter(const char *param_name)
7876 int num = map_parameter(param_name);
7882 return &parm_table[num];
7885 /***************************************************************************
7886 Return info about the next parameter in a service.
7887 snum==GLOBAL_SECTION_SNUM gives the globals.
7888 Return NULL when out of parameters.
7889 ***************************************************************************/
7891 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7894 /* do the globals */
7895 for (; parm_table[*i].label; (*i)++) {
7896 if (parm_table[*i].p_class == P_SEPARATOR)
7897 return &parm_table[(*i)++];
7899 if (!parm_table[*i].ptr
7900 || (*parm_table[*i].label == '-'))
7904 && (parm_table[*i].ptr ==
7905 parm_table[(*i) - 1].ptr))
7908 if (is_default(*i) && !allparameters)
7911 return &parm_table[(*i)++];
7914 struct service *pService = ServicePtrs[snum];
7916 for (; parm_table[*i].label; (*i)++) {
7917 if (parm_table[*i].p_class == P_SEPARATOR)
7918 return &parm_table[(*i)++];
7920 if (parm_table[*i].p_class == P_LOCAL &&
7921 parm_table[*i].ptr &&
7922 (*parm_table[*i].label != '-') &&
7924 (parm_table[*i].ptr !=
7925 parm_table[(*i) - 1].ptr)))
7928 PTR_DIFF(parm_table[*i].ptr,
7931 if (allparameters ||
7932 !equal_parameter(parm_table[*i].type,
7933 ((char *)pService) +
7935 ((char *)&sDefault) +
7938 return &parm_table[(*i)++];
7949 /***************************************************************************
7950 Display the contents of a single copy structure.
7951 ***************************************************************************/
7952 static void dump_copy_map(bool *pcopymap)
7958 printf("\n\tNon-Copied parameters:\n");
7960 for (i = 0; parm_table[i].label; i++)
7961 if (parm_table[i].p_class == P_LOCAL &&
7962 parm_table[i].ptr && !pcopymap[i] &&
7963 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7965 printf("\t\t%s\n", parm_table[i].label);
7970 /***************************************************************************
7971 Return TRUE if the passed service number is within range.
7972 ***************************************************************************/
7974 bool lp_snum_ok(int iService)
7976 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7979 /***************************************************************************
7980 Auto-load some home services.
7981 ***************************************************************************/
7983 static void lp_add_auto_services(char *str)
7993 s = SMB_STRDUP(str);
7997 homes = lp_servicenumber(HOMES_NAME);
7999 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8000 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8003 if (lp_servicenumber(p) >= 0)
8006 home = get_user_home_dir(talloc_tos(), p);
8008 if (home && homes >= 0)
8009 lp_add_home(p, homes, p, home);
8016 /***************************************************************************
8017 Auto-load one printer.
8018 ***************************************************************************/
8020 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8022 int printers = lp_servicenumber(PRINTERS_NAME);
8025 if (lp_servicenumber(name) < 0) {
8026 lp_add_printer(name, printers);
8027 if ((i = lp_servicenumber(name)) >= 0) {
8028 string_set(&ServicePtrs[i]->comment, comment);
8029 ServicePtrs[i]->autoloaded = True;
8034 /***************************************************************************
8035 Have we loaded a services file yet?
8036 ***************************************************************************/
8038 bool lp_loaded(void)
8043 /***************************************************************************
8044 Unload unused services.
8045 ***************************************************************************/
8047 void lp_killunused(bool (*snumused) (int))
8050 for (i = 0; i < iNumServices; i++) {
8054 /* don't kill autoloaded or usershare services */
8055 if ( ServicePtrs[i]->autoloaded ||
8056 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8060 if (!snumused || !snumused(i)) {
8061 free_service_byindex(i);
8067 * Kill all except autoloaded and usershare services - convenience wrapper
8069 void lp_kill_all_services(void)
8071 lp_killunused(NULL);
8074 /***************************************************************************
8076 ***************************************************************************/
8078 void lp_killservice(int iServiceIn)
8080 if (VALID(iServiceIn)) {
8081 free_service_byindex(iServiceIn);
8085 /***************************************************************************
8086 Save the curent values of all global and sDefault parameters into the
8087 defaults union. This allows swat and testparm to show only the
8088 changed (ie. non-default) parameters.
8089 ***************************************************************************/
8091 static void lp_save_defaults(void)
8094 for (i = 0; parm_table[i].label; i++) {
8095 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8097 switch (parm_table[i].type) {
8099 parm_table[i].def.lvalue = str_list_copy(
8100 NULL, *(const char ***)parm_table[i].ptr);
8104 if (parm_table[i].ptr) {
8105 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8107 parm_table[i].def.svalue = NULL;
8112 parm_table[i].def.bvalue =
8113 *(bool *)parm_table[i].ptr;
8116 parm_table[i].def.cvalue =
8117 *(char *)parm_table[i].ptr;
8122 parm_table[i].def.ivalue =
8123 *(int *)parm_table[i].ptr;
8129 defaults_saved = True;
8132 /*******************************************************************
8133 Set the server type we will announce as via nmbd.
8134 ********************************************************************/
8136 static const struct srv_role_tab {
8138 const char *role_str;
8139 } srv_role_tab [] = {
8140 { ROLE_STANDALONE, "ROLE_STANDALONE" },
8141 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8142 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8143 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8147 const char* server_role_str(uint32 role)
8150 for (i=0; srv_role_tab[i].role_str; i++) {
8151 if (role == srv_role_tab[i].role) {
8152 return srv_role_tab[i].role_str;
8158 static void set_server_role(void)
8160 server_role = ROLE_STANDALONE;
8162 switch (lp_security()) {
8164 if (lp_domain_logons())
8165 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8168 if (lp_domain_logons())
8169 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8170 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8171 server_role = ROLE_STANDALONE;
8174 if (lp_domain_logons()) {
8175 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8176 server_role = ROLE_DOMAIN_BDC;
8179 server_role = ROLE_DOMAIN_MEMBER;
8182 if (lp_domain_logons()) {
8183 server_role = ROLE_DOMAIN_PDC;
8186 server_role = ROLE_DOMAIN_MEMBER;
8189 if (lp_domain_logons()) {
8191 if (Globals.iDomainMaster) /* auto or yes */
8192 server_role = ROLE_DOMAIN_PDC;
8194 server_role = ROLE_DOMAIN_BDC;
8198 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8202 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8205 /***********************************************************
8206 If we should send plaintext/LANMAN passwords in the clinet
8207 ************************************************************/
8209 static void set_allowed_client_auth(void)
8211 if (Globals.bClientNTLMv2Auth) {
8212 Globals.bClientLanManAuth = False;
8214 if (!Globals.bClientLanManAuth) {
8215 Globals.bClientPlaintextAuth = False;
8219 /***************************************************************************
8221 The following code allows smbd to read a user defined share file.
8222 Yes, this is my intent. Yes, I'm comfortable with that...
8224 THE FOLLOWING IS SECURITY CRITICAL CODE.
8226 It washes your clothes, it cleans your house, it guards you while you sleep...
8227 Do not f%^k with it....
8228 ***************************************************************************/
8230 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8232 /***************************************************************************
8233 Check allowed stat state of a usershare file.
8234 Ensure we print out who is dicking with us so the admin can
8235 get their sorry ass fired.
8236 ***************************************************************************/
8238 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8240 if (!S_ISREG(psbuf->st_mode)) {
8241 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8242 "not a regular file\n",
8243 fname, (unsigned int)psbuf->st_uid ));
8247 /* Ensure this doesn't have the other write bit set. */
8248 if (psbuf->st_mode & S_IWOTH) {
8249 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8250 "public write. Refusing to allow as a usershare file.\n",
8251 fname, (unsigned int)psbuf->st_uid ));
8255 /* Should be 10k or less. */
8256 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8257 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8258 "too large (%u) to be a user share file.\n",
8259 fname, (unsigned int)psbuf->st_uid,
8260 (unsigned int)psbuf->st_size ));
8267 /***************************************************************************
8268 Parse the contents of a usershare file.
8269 ***************************************************************************/
8271 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8272 SMB_STRUCT_STAT *psbuf,
8273 const char *servicename,
8277 char **pp_sharepath,
8282 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8283 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8286 SMB_STRUCT_STAT sbuf;
8287 char *sharepath = NULL;
8288 char *comment = NULL;
8290 *pp_sharepath = NULL;
8293 *pallow_guest = False;
8296 return USERSHARE_MALFORMED_FILE;
8299 if (strcmp(lines[0], "#VERSION 1") == 0) {
8301 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8304 return USERSHARE_MALFORMED_FILE;
8307 return USERSHARE_BAD_VERSION;
8310 if (strncmp(lines[1], "path=", 5) != 0) {
8311 return USERSHARE_MALFORMED_PATH;
8314 sharepath = talloc_strdup(ctx, &lines[1][5]);
8316 return USERSHARE_POSIX_ERR;
8318 trim_string(sharepath, " ", " ");
8320 if (strncmp(lines[2], "comment=", 8) != 0) {
8321 return USERSHARE_MALFORMED_COMMENT_DEF;
8324 comment = talloc_strdup(ctx, &lines[2][8]);
8326 return USERSHARE_POSIX_ERR;
8328 trim_string(comment, " ", " ");
8329 trim_char(comment, '"', '"');
8331 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8332 return USERSHARE_MALFORMED_ACL_DEF;
8335 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8336 return USERSHARE_ACL_ERR;
8340 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8341 return USERSHARE_MALFORMED_ACL_DEF;
8343 if (lines[4][9] == 'y') {
8344 *pallow_guest = True;
8348 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8349 /* Path didn't change, no checks needed. */
8350 *pp_sharepath = sharepath;
8351 *pp_comment = comment;
8352 return USERSHARE_OK;
8355 /* The path *must* be absolute. */
8356 if (sharepath[0] != '/') {
8357 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8358 servicename, sharepath));
8359 return USERSHARE_PATH_NOT_ABSOLUTE;
8362 /* If there is a usershare prefix deny list ensure one of these paths
8363 doesn't match the start of the user given path. */
8364 if (prefixdenylist) {
8366 for ( i=0; prefixdenylist[i]; i++ ) {
8367 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8368 servicename, i, prefixdenylist[i], sharepath ));
8369 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8370 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8371 "usershare prefix deny list entries.\n",
8372 servicename, sharepath));
8373 return USERSHARE_PATH_IS_DENIED;
8378 /* If there is a usershare prefix allow list ensure one of these paths
8379 does match the start of the user given path. */
8381 if (prefixallowlist) {
8383 for ( i=0; prefixallowlist[i]; i++ ) {
8384 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8385 servicename, i, prefixallowlist[i], sharepath ));
8386 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8390 if (prefixallowlist[i] == NULL) {
8391 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8392 "usershare prefix allow list entries.\n",
8393 servicename, sharepath));
8394 return USERSHARE_PATH_NOT_ALLOWED;
8398 /* Ensure this is pointing to a directory. */
8399 dp = sys_opendir(sharepath);
8402 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8403 servicename, sharepath));
8404 return USERSHARE_PATH_NOT_DIRECTORY;
8407 /* Ensure the owner of the usershare file has permission to share
8410 if (sys_stat(sharepath, &sbuf) == -1) {
8411 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8412 servicename, sharepath, strerror(errno) ));
8414 return USERSHARE_POSIX_ERR;
8419 if (!S_ISDIR(sbuf.st_mode)) {
8420 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8421 servicename, sharepath ));
8422 return USERSHARE_PATH_NOT_DIRECTORY;
8425 /* Check if sharing is restricted to owner-only. */
8426 /* psbuf is the stat of the usershare definition file,
8427 sbuf is the stat of the target directory to be shared. */
8429 if (lp_usershare_owner_only()) {
8430 /* root can share anything. */
8431 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8432 return USERSHARE_PATH_NOT_ALLOWED;
8436 *pp_sharepath = sharepath;
8437 *pp_comment = comment;
8438 return USERSHARE_OK;
8441 /***************************************************************************
8442 Deal with a usershare file.
8445 -1 - Bad name, invalid contents.
8446 - service name already existed and not a usershare, problem
8447 with permissions to share directory etc.
8448 ***************************************************************************/
8450 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8452 SMB_STRUCT_STAT sbuf;
8453 SMB_STRUCT_STAT lsbuf;
8455 char *sharepath = NULL;
8456 char *comment = NULL;
8457 fstring service_name;
8458 char **lines = NULL;
8462 TALLOC_CTX *ctx = NULL;
8463 SEC_DESC *psd = NULL;
8464 bool guest_ok = False;
8466 /* Ensure share name doesn't contain invalid characters. */
8467 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8468 DEBUG(0,("process_usershare_file: share name %s contains "
8469 "invalid characters (any of %s)\n",
8470 file_name, INVALID_SHARENAME_CHARS ));
8474 fstrcpy(service_name, file_name);
8476 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8479 /* Minimize the race condition by doing an lstat before we
8480 open and fstat. Ensure this isn't a symlink link. */
8482 if (sys_lstat(fname, &lsbuf) != 0) {
8483 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8484 fname, strerror(errno) ));
8489 /* This must be a regular file, not a symlink, directory or
8490 other strange filetype. */
8491 if (!check_usershare_stat(fname, &lsbuf)) {
8497 char *canon_name = canonicalize_servicename(service_name);
8498 TDB_DATA data = dbwrap_fetch_bystring(
8499 ServiceHash, canon_name, canon_name);
8503 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8504 iService = *(int *)data.dptr;
8506 TALLOC_FREE(canon_name);
8509 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8510 /* Nothing changed - Mark valid and return. */
8511 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8513 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8518 /* Try and open the file read only - no symlinks allowed. */
8520 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8522 fd = sys_open(fname, O_RDONLY, 0);
8526 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8527 fname, strerror(errno) ));
8532 /* Now fstat to be *SURE* it's a regular file. */
8533 if (sys_fstat(fd, &sbuf) != 0) {
8535 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8536 fname, strerror(errno) ));
8541 /* Is it the same dev/inode as was lstated ? */
8542 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8544 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8545 "Symlink spoofing going on ?\n", fname ));
8550 /* This must be a regular file, not a symlink, directory or
8551 other strange filetype. */
8552 if (!check_usershare_stat(fname, &sbuf)) {
8557 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8560 if (lines == NULL) {
8561 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8562 fname, (unsigned int)sbuf.st_uid ));
8569 /* Should we allow printers to be shared... ? */
8570 ctx = talloc_init("usershare_sd_xctx");
8576 if (parse_usershare_file(ctx, &sbuf, service_name,
8577 iService, lines, numlines, &sharepath,
8578 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8579 talloc_destroy(ctx);
8586 /* Everything ok - add the service possibly using a template. */
8588 const struct service *sp = &sDefault;
8589 if (snum_template != -1) {
8590 sp = ServicePtrs[snum_template];
8593 if ((iService = add_a_service(sp, service_name)) < 0) {
8594 DEBUG(0, ("process_usershare_file: Failed to add "
8595 "new service %s\n", service_name));
8596 talloc_destroy(ctx);
8600 /* Read only is controlled by usershare ACL below. */
8601 ServicePtrs[iService]->bRead_only = False;
8604 /* Write the ACL of the new/modified share. */
8605 if (!set_share_security(service_name, psd)) {
8606 DEBUG(0, ("process_usershare_file: Failed to set share "
8607 "security for user share %s\n",
8609 lp_remove_service(iService);
8610 talloc_destroy(ctx);
8614 /* If from a template it may be marked invalid. */
8615 ServicePtrs[iService]->valid = True;
8617 /* Set the service as a valid usershare. */
8618 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8620 /* Set guest access. */
8621 if (lp_usershare_allow_guests()) {
8622 ServicePtrs[iService]->bGuest_ok = guest_ok;
8625 /* And note when it was loaded. */
8626 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8627 string_set(&ServicePtrs[iService]->szPath, sharepath);
8628 string_set(&ServicePtrs[iService]->comment, comment);
8630 talloc_destroy(ctx);
8635 /***************************************************************************
8636 Checks if a usershare entry has been modified since last load.
8637 ***************************************************************************/
8639 static bool usershare_exists(int iService, time_t *last_mod)
8641 SMB_STRUCT_STAT lsbuf;
8642 const char *usersharepath = Globals.szUsersharePath;
8645 if (asprintf(&fname, "%s/%s",
8647 ServicePtrs[iService]->szService) < 0) {
8651 if (sys_lstat(fname, &lsbuf) != 0) {
8656 if (!S_ISREG(lsbuf.st_mode)) {
8662 *last_mod = lsbuf.st_mtime;
8666 /***************************************************************************
8667 Load a usershare service by name. Returns a valid servicenumber or -1.
8668 ***************************************************************************/
8670 int load_usershare_service(const char *servicename)
8672 SMB_STRUCT_STAT sbuf;
8673 const char *usersharepath = Globals.szUsersharePath;
8674 int max_user_shares = Globals.iUsershareMaxShares;
8675 int snum_template = -1;
8677 if (*usersharepath == 0 || max_user_shares == 0) {
8681 if (sys_stat(usersharepath, &sbuf) != 0) {
8682 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8683 usersharepath, strerror(errno) ));
8687 if (!S_ISDIR(sbuf.st_mode)) {
8688 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8694 * This directory must be owned by root, and have the 't' bit set.
8695 * It also must not be writable by "other".
8699 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8701 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8703 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8704 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8709 /* Ensure the template share exists if it's set. */
8710 if (Globals.szUsershareTemplateShare[0]) {
8711 /* We can't use lp_servicenumber here as we are recommending that
8712 template shares have -valid=False set. */
8713 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8714 if (ServicePtrs[snum_template]->szService &&
8715 strequal(ServicePtrs[snum_template]->szService,
8716 Globals.szUsershareTemplateShare)) {
8721 if (snum_template == -1) {
8722 DEBUG(0,("load_usershare_service: usershare template share %s "
8723 "does not exist.\n",
8724 Globals.szUsershareTemplateShare ));
8729 return process_usershare_file(usersharepath, servicename, snum_template);
8732 /***************************************************************************
8733 Load all user defined shares from the user share directory.
8734 We only do this if we're enumerating the share list.
8735 This is the function that can delete usershares that have
8737 ***************************************************************************/
8739 int load_usershare_shares(void)
8742 SMB_STRUCT_STAT sbuf;
8743 SMB_STRUCT_DIRENT *de;
8744 int num_usershares = 0;
8745 int max_user_shares = Globals.iUsershareMaxShares;
8746 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8747 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8748 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8750 int snum_template = -1;
8751 const char *usersharepath = Globals.szUsersharePath;
8752 int ret = lp_numservices();
8754 if (max_user_shares == 0 || *usersharepath == '\0') {
8755 return lp_numservices();
8758 if (sys_stat(usersharepath, &sbuf) != 0) {
8759 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8760 usersharepath, strerror(errno) ));
8765 * This directory must be owned by root, and have the 't' bit set.
8766 * It also must not be writable by "other".
8770 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8772 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8774 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8775 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8780 /* Ensure the template share exists if it's set. */
8781 if (Globals.szUsershareTemplateShare[0]) {
8782 /* We can't use lp_servicenumber here as we are recommending that
8783 template shares have -valid=False set. */
8784 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8785 if (ServicePtrs[snum_template]->szService &&
8786 strequal(ServicePtrs[snum_template]->szService,
8787 Globals.szUsershareTemplateShare)) {
8792 if (snum_template == -1) {
8793 DEBUG(0,("load_usershare_shares: usershare template share %s "
8794 "does not exist.\n",
8795 Globals.szUsershareTemplateShare ));
8800 /* Mark all existing usershares as pending delete. */
8801 for (iService = iNumServices - 1; iService >= 0; iService--) {
8802 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8803 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8807 dp = sys_opendir(usersharepath);
8809 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8810 usersharepath, strerror(errno) ));
8814 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8815 (de = sys_readdir(dp));
8816 num_dir_entries++ ) {
8818 const char *n = de->d_name;
8820 /* Ignore . and .. */
8822 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8828 /* Temporary file used when creating a share. */
8829 num_tmp_dir_entries++;
8832 /* Allow 20% tmp entries. */
8833 if (num_tmp_dir_entries > allowed_tmp_entries) {
8834 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8835 "in directory %s\n",
8836 num_tmp_dir_entries, usersharepath));
8840 r = process_usershare_file(usersharepath, n, snum_template);
8842 /* Update the services count. */
8844 if (num_usershares >= max_user_shares) {
8845 DEBUG(0,("load_usershare_shares: max user shares reached "
8846 "on file %s in directory %s\n",
8847 n, usersharepath ));
8850 } else if (r == -1) {
8851 num_bad_dir_entries++;
8854 /* Allow 20% bad entries. */
8855 if (num_bad_dir_entries > allowed_bad_entries) {
8856 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8857 "in directory %s\n",
8858 num_bad_dir_entries, usersharepath));
8862 /* Allow 20% bad entries. */
8863 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8864 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8865 "in directory %s\n",
8866 num_dir_entries, usersharepath));
8873 /* Sweep through and delete any non-refreshed usershares that are
8874 not currently in use. */
8875 for (iService = iNumServices - 1; iService >= 0; iService--) {
8876 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8877 if (conn_snum_used(iService)) {
8880 /* Remove from the share ACL db. */
8881 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8882 lp_servicename(iService) ));
8883 delete_share_security(lp_servicename(iService));
8884 free_service_byindex(iService);
8888 return lp_numservices();
8891 /********************************************************
8892 Destroy global resources allocated in this file
8893 ********************************************************/
8895 void gfree_loadparm(void)
8897 struct file_lists *f;
8898 struct file_lists *next;
8901 /* Free the file lists */
8906 SAFE_FREE( f->name );
8907 SAFE_FREE( f->subfname );
8913 /* Free resources allocated to services */
8915 for ( i = 0; i < iNumServices; i++ ) {
8917 free_service_byindex(i);
8921 SAFE_FREE( ServicePtrs );
8924 /* Now release all resources allocated to global
8925 parameters and the default service */
8927 free_global_parameters();
8931 /***************************************************************************
8932 Allow client apps to specify that they are a client
8933 ***************************************************************************/
8934 void lp_set_in_client(bool b)
8940 /***************************************************************************
8941 Determine if we're running in a client app
8942 ***************************************************************************/
8943 bool lp_is_in_client(void)
8948 /***************************************************************************
8949 Load the services array from the services file. Return True on success,
8951 ***************************************************************************/
8953 bool lp_load_ex(const char *pszFname,
8957 bool initialize_globals,
8958 bool allow_include_registry,
8959 bool allow_registry_shares)
8966 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8968 bInGlobalSection = True;
8969 bGlobalOnly = global_only;
8970 bAllowIncludeRegistry = allow_include_registry;
8972 init_globals(! initialize_globals);
8975 if (save_defaults) {
8980 free_param_opts(&Globals.param_opt);
8982 /* We get sections first, so have to start 'behind' to make up */
8985 if (lp_config_backend_is_file()) {
8986 n2 = alloc_sub_basic(get_current_username(),
8987 current_user_info.domain,
8990 smb_panic("lp_load_ex: out of memory");
8993 add_to_file_list(pszFname, n2);
8995 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8998 /* finish up the last section */
8999 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9001 if (iServiceIndex >= 0) {
9002 bRetval = service_ok(iServiceIndex);
9006 if (lp_config_backend_is_registry()) {
9007 /* config backend changed to registry in config file */
9009 * We need to use this extra global variable here to
9010 * survive restart: init_globals uses this as a default
9011 * for ConfigBackend. Otherwise, init_globals would
9012 * send us into an endless loop here.
9014 config_backend = CONFIG_BACKEND_REGISTRY;
9016 DEBUG(1, ("lp_load_ex: changing to config backend "
9018 init_globals(false);
9019 lp_kill_all_services();
9020 return lp_load_ex(pszFname, global_only, save_defaults,
9021 add_ipc, initialize_globals,
9022 allow_include_registry,
9023 allow_registry_shares);
9025 } else if (lp_config_backend_is_registry()) {
9026 bRetval = process_registry_globals();
9028 DEBUG(0, ("Illegal config backend given: %d\n",
9029 lp_config_backend()));
9033 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9034 bRetval = process_registry_shares();
9037 lp_add_auto_services(lp_auto_services());
9040 /* When 'restrict anonymous = 2' guest connections to ipc$
9042 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9043 if ( lp_enable_asu_support() ) {
9044 lp_add_ipc("ADMIN$", false);
9049 set_default_server_announce_type();
9050 set_allowed_client_auth();
9054 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9055 /* if bWINSsupport is true and we are in the client */
9056 if (lp_is_in_client() && Globals.bWINSsupport) {
9057 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9062 bAllowIncludeRegistry = true;
9067 bool lp_load(const char *pszFname,
9071 bool initialize_globals)
9073 return lp_load_ex(pszFname,
9081 bool lp_load_initial_only(const char *pszFname)
9083 return lp_load_ex(pszFname,
9092 bool lp_load_with_registry_shares(const char *pszFname,
9096 bool initialize_globals)
9098 return lp_load_ex(pszFname,
9107 /***************************************************************************
9108 Return the max number of services.
9109 ***************************************************************************/
9111 int lp_numservices(void)
9113 return (iNumServices);
9116 /***************************************************************************
9117 Display the contents of the services array in human-readable form.
9118 ***************************************************************************/
9120 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9125 defaults_saved = False;
9129 dump_a_service(&sDefault, f);
9131 for (iService = 0; iService < maxtoprint; iService++) {
9133 lp_dump_one(f, show_defaults, iService);
9137 /***************************************************************************
9138 Display the contents of one service in human-readable form.
9139 ***************************************************************************/
9141 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9144 if (ServicePtrs[snum]->szService[0] == '\0')
9146 dump_a_service(ServicePtrs[snum], f);
9150 /***************************************************************************
9151 Return the number of the service with the given name, or -1 if it doesn't
9152 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9153 getservicebyname()! This works ONLY if all services have been loaded, and
9154 does not copy the found service.
9155 ***************************************************************************/
9157 int lp_servicenumber(const char *pszServiceName)
9160 fstring serviceName;
9162 if (!pszServiceName) {
9163 return GLOBAL_SECTION_SNUM;
9166 for (iService = iNumServices - 1; iService >= 0; iService--) {
9167 if (VALID(iService) && ServicePtrs[iService]->szService) {
9169 * The substitution here is used to support %U is
9172 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9173 standard_sub_basic(get_current_username(),
9174 current_user_info.domain,
9175 serviceName,sizeof(serviceName));
9176 if (strequal(serviceName, pszServiceName)) {
9182 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9185 if (!usershare_exists(iService, &last_mod)) {
9186 /* Remove the share security tdb entry for it. */
9187 delete_share_security(lp_servicename(iService));
9188 /* Remove it from the array. */
9189 free_service_byindex(iService);
9190 /* Doesn't exist anymore. */
9191 return GLOBAL_SECTION_SNUM;
9194 /* Has it been modified ? If so delete and reload. */
9195 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9196 /* Remove it from the array. */
9197 free_service_byindex(iService);
9198 /* and now reload it. */
9199 iService = load_usershare_service(pszServiceName);
9204 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9205 return GLOBAL_SECTION_SNUM;
9211 bool share_defined(const char *service_name)
9213 return (lp_servicenumber(service_name) != -1);
9216 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9217 const char *sharename)
9219 struct share_params *result;
9223 if (!(sname = SMB_STRDUP(sharename))) {
9227 snum = find_service(sname);
9234 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9235 DEBUG(0, ("talloc failed\n"));
9239 result->service = snum;
9243 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9245 struct share_iterator *result;
9247 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9248 DEBUG(0, ("talloc failed\n"));
9252 result->next_id = 0;
9256 struct share_params *next_share(struct share_iterator *list)
9258 struct share_params *result;
9260 while (!lp_snum_ok(list->next_id) &&
9261 (list->next_id < lp_numservices())) {
9265 if (list->next_id >= lp_numservices()) {
9269 if (!(result = TALLOC_P(list, struct share_params))) {
9270 DEBUG(0, ("talloc failed\n"));
9274 result->service = list->next_id;
9279 struct share_params *next_printer(struct share_iterator *list)
9281 struct share_params *result;
9283 while ((result = next_share(list)) != NULL) {
9284 if (lp_print_ok(result->service)) {
9292 * This is a hack for a transition period until we transformed all code from
9293 * service numbers to struct share_params.
9296 struct share_params *snum2params_static(int snum)
9298 static struct share_params result;
9299 result.service = snum;
9303 /*******************************************************************
9304 A useful volume label function.
9305 ********************************************************************/
9307 const char *volume_label(int snum)
9310 const char *label = lp_volume(snum);
9312 label = lp_servicename(snum);
9315 /* This returns a 33 byte guarenteed null terminated string. */
9316 ret = talloc_strndup(talloc_tos(), label, 32);
9323 /*******************************************************************
9324 Set the server type we will announce as via nmbd.
9325 ********************************************************************/
9327 static void set_default_server_announce_type(void)
9329 default_server_announce = 0;
9330 default_server_announce |= SV_TYPE_WORKSTATION;
9331 default_server_announce |= SV_TYPE_SERVER;
9332 default_server_announce |= SV_TYPE_SERVER_UNIX;
9334 /* note that the flag should be set only if we have a
9335 printer service but nmbd doesn't actually load the
9336 services so we can't tell --jerry */
9338 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9340 switch (lp_announce_as()) {
9341 case ANNOUNCE_AS_NT_SERVER:
9342 default_server_announce |= SV_TYPE_SERVER_NT;
9343 /* fall through... */
9344 case ANNOUNCE_AS_NT_WORKSTATION:
9345 default_server_announce |= SV_TYPE_NT;
9347 case ANNOUNCE_AS_WIN95:
9348 default_server_announce |= SV_TYPE_WIN95_PLUS;
9350 case ANNOUNCE_AS_WFW:
9351 default_server_announce |= SV_TYPE_WFW;
9357 switch (lp_server_role()) {
9358 case ROLE_DOMAIN_MEMBER:
9359 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9361 case ROLE_DOMAIN_PDC:
9362 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9364 case ROLE_DOMAIN_BDC:
9365 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9367 case ROLE_STANDALONE:
9371 if (lp_time_server())
9372 default_server_announce |= SV_TYPE_TIME_SOURCE;
9374 if (lp_host_msdfs())
9375 default_server_announce |= SV_TYPE_DFS_SERVER;
9378 /***********************************************************
9379 returns role of Samba server
9380 ************************************************************/
9382 int lp_server_role(void)
9387 /***********************************************************
9388 If we are PDC then prefer us as DMB
9389 ************************************************************/
9391 bool lp_domain_master(void)
9393 if (Globals.iDomainMaster == Auto)
9394 return (lp_server_role() == ROLE_DOMAIN_PDC);
9396 return (bool)Globals.iDomainMaster;
9399 /***********************************************************
9400 If we are DMB then prefer us as LMB
9401 ************************************************************/
9403 bool lp_preferred_master(void)
9405 if (Globals.iPreferredMaster == Auto)
9406 return (lp_local_master() && lp_domain_master());
9408 return (bool)Globals.iPreferredMaster;
9411 /*******************************************************************
9413 ********************************************************************/
9415 void lp_remove_service(int snum)
9417 ServicePtrs[snum]->valid = False;
9418 invalid_services[num_invalid_services++] = snum;
9421 /*******************************************************************
9423 ********************************************************************/
9425 void lp_copy_service(int snum, const char *new_name)
9427 do_section(new_name, NULL);
9429 snum = lp_servicenumber(new_name);
9431 lp_do_parameter(snum, "copy", lp_servicename(snum));
9436 /*******************************************************************
9437 Get the default server type we will announce as via nmbd.
9438 ********************************************************************/
9440 int lp_default_server_announce(void)
9442 return default_server_announce;
9445 /*******************************************************************
9446 Split the announce version into major and minor numbers.
9447 ********************************************************************/
9449 int lp_major_announce_version(void)
9451 static bool got_major = False;
9452 static int major_version = DEFAULT_MAJOR_VERSION;
9457 return major_version;
9460 if ((vers = lp_announce_version()) == NULL)
9461 return major_version;
9463 if ((p = strchr_m(vers, '.')) == 0)
9464 return major_version;
9467 major_version = atoi(vers);
9468 return major_version;
9471 int lp_minor_announce_version(void)
9473 static bool got_minor = False;
9474 static int minor_version = DEFAULT_MINOR_VERSION;
9479 return minor_version;
9482 if ((vers = lp_announce_version()) == NULL)
9483 return minor_version;
9485 if ((p = strchr_m(vers, '.')) == 0)
9486 return minor_version;
9489 minor_version = atoi(p);
9490 return minor_version;
9493 /***********************************************************
9494 Set the global name resolution order (used in smbclient).
9495 ************************************************************/
9497 void lp_set_name_resolve_order(const char *new_order)
9499 string_set(&Globals.szNameResolveOrder, new_order);
9502 const char *lp_printername(int snum)
9504 const char *ret = _lp_printername(snum);
9505 if (ret == NULL || (ret != NULL && *ret == '\0'))
9506 ret = lp_const_servicename(snum);
9512 /***********************************************************
9513 Allow daemons such as winbindd to fix their logfile name.
9514 ************************************************************/
9516 void lp_set_logfile(const char *name)
9518 string_set(&Globals.szLogFile, name);
9519 debug_set_logfile(name);
9522 /*******************************************************************
9523 Return the max print jobs per queue.
9524 ********************************************************************/
9526 int lp_maxprintjobs(int snum)
9528 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9529 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9530 maxjobs = PRINT_MAX_JOBID - 1;
9535 const char *lp_printcapname(void)
9537 if ((Globals.szPrintcapname != NULL) &&
9538 (Globals.szPrintcapname[0] != '\0'))
9539 return Globals.szPrintcapname;
9541 if (sDefault.iPrinting == PRINT_CUPS) {
9549 if (sDefault.iPrinting == PRINT_BSD)
9550 return "/etc/printcap";
9552 return PRINTCAP_NAME;
9555 /*******************************************************************
9556 Ensure we don't use sendfile if server smb signing is active.
9557 ********************************************************************/
9559 static uint32 spoolss_state;
9561 bool lp_disable_spoolss( void )
9563 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9564 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9566 return spoolss_state == SVCCTL_STOPPED ? True : False;
9569 void lp_set_spoolss_state( uint32 state )
9571 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9573 spoolss_state = state;
9576 uint32 lp_get_spoolss_state( void )
9578 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9581 /*******************************************************************
9582 Ensure we don't use sendfile if server smb signing is active.
9583 ********************************************************************/
9585 bool lp_use_sendfile(int snum)
9587 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9588 if (Protocol < PROTOCOL_NT1) {
9591 return (_lp_use_sendfile(snum) &&
9592 (get_remote_arch() != RA_WIN95) &&
9593 !srv_is_signing_active());
9596 /*******************************************************************
9597 Turn off sendfile if we find the underlying OS doesn't support it.
9598 ********************************************************************/
9600 void set_use_sendfile(int snum, bool val)
9602 if (LP_SNUM_OK(snum))
9603 ServicePtrs[snum]->bUseSendfile = val;
9605 sDefault.bUseSendfile = val;
9608 /*******************************************************************
9609 Turn off storing DOS attributes if this share doesn't support it.
9610 ********************************************************************/
9612 void set_store_dos_attributes(int snum, bool val)
9614 if (!LP_SNUM_OK(snum))
9616 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9619 void lp_set_mangling_method(const char *new_method)
9621 string_set(&Globals.szManglingMethod, new_method);
9624 /*******************************************************************
9625 Global state for POSIX pathname processing.
9626 ********************************************************************/
9628 static bool posix_pathnames;
9630 bool lp_posix_pathnames(void)
9632 return posix_pathnames;
9635 /*******************************************************************
9636 Change everything needed to ensure POSIX pathname processing (currently
9638 ********************************************************************/
9640 void lp_set_posix_pathnames(void)
9642 posix_pathnames = True;
9645 /*******************************************************************
9646 Global state for POSIX lock processing - CIFS unix extensions.
9647 ********************************************************************/
9649 bool posix_default_lock_was_set;
9650 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9652 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9654 if (posix_default_lock_was_set) {
9655 return posix_cifsx_locktype;
9657 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9661 /*******************************************************************
9662 ********************************************************************/
9664 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9666 posix_default_lock_was_set = True;
9667 posix_cifsx_locktype = val;
9670 int lp_min_receive_file_size(void)
9672 if (Globals.iminreceivefile < 0) {
9675 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9678 /*******************************************************************
9679 If socket address is an empty character string, it is necessary to
9680 define it as "0.0.0.0".
9681 ********************************************************************/
9683 const char *lp_socket_address(void)
9685 char *sock_addr = Globals.szSocketAddress;
9687 if (sock_addr[0] == '\0'){
9688 string_set(&Globals.szSocketAddress, "0.0.0.0");
9690 return Globals.szSocketAddress;