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 extern int extra_time_offset;
99 static bool defaults_saved = False;
101 struct param_opt_struct {
102 struct param_opt_struct *prev, *next;
109 * This structure describes global (ie., server-wide) parameters.
116 char *display_charset;
117 char *szPrintcapname;
118 char *szAddPortCommand;
119 char *szEnumPortsCommand;
120 char *szAddPrinterCommand;
121 char *szDeletePrinterCommand;
122 char *szOs2DriverMap;
126 char *szDefaultService;
130 char *szServerString;
131 char *szAutoServices;
132 char *szPasswdProgram;
136 char *szSMBPasswdFile;
138 char *szPassdbBackend;
139 char **szPreloadModules;
140 char *szPasswordServer;
141 char *szSocketOptions;
143 char *szAfsUsernameMap;
144 int iAfsTokenLifetime;
145 char *szLogNtTokenCommand;
151 char **szWINSservers;
153 char *szRemoteAnnounce;
154 char *szRemoteBrowseSync;
155 char *szSocketAddress;
156 char *szNISHomeMapName;
157 char *szAnnounceVersion; /* This is initialised in init_globals */
160 char **szNetbiosAliases;
161 char *szNetbiosScope;
162 char *szNameResolveOrder;
164 char *szAddUserScript;
165 char *szRenameUserScript;
166 char *szDelUserScript;
167 char *szAddGroupScript;
168 char *szDelGroupScript;
169 char *szAddUserToGroupScript;
170 char *szDelUserFromGroupScript;
171 char *szSetPrimaryGroupScript;
172 char *szAddMachineScript;
173 char *szShutdownScript;
174 char *szAbortShutdownScript;
175 char *szUsernameMapScript;
176 char *szCheckPasswordScript;
183 bool bPassdbExpandExplicit;
184 int AlgorithmicRidBase;
185 char *szTemplateHomedir;
186 char *szTemplateShell;
187 char *szWinbindSeparator;
188 bool bWinbindEnumUsers;
189 bool bWinbindEnumGroups;
190 bool bWinbindUseDefaultDomain;
191 bool bWinbindTrustedDomainsOnly;
192 bool bWinbindNestedGroups;
193 int winbind_expand_groups;
194 bool bWinbindRefreshTickets;
195 bool bWinbindOfflineLogon;
196 bool bWinbindNormalizeNames;
197 bool bWinbindRpcOnly;
198 char *szIdmapBackend;
199 char *szIdmapAllocBackend;
200 char *szAddShareCommand;
201 char *szChangeShareCommand;
202 char *szDeleteShareCommand;
204 char *szGuestaccount;
205 char *szManglingMethod;
206 char **szServicesList;
207 char *szUsersharePath;
208 char *szUsershareTemplateShare;
209 char **szUsersharePrefixAllowList;
210 char **szUsersharePrefixDenyList;
217 int open_files_db_hash_size;
226 bool paranoid_server_security;
229 int iMaxSmbdProcesses;
230 bool bDisableSpoolss;
233 bool enhanced_browsing;
239 int announce_as; /* This is initialised in init_globals */
240 int machine_password_timeout;
242 int oplock_break_wait_time;
243 int winbind_cache_time;
244 int winbind_reconnect_delay;
245 int winbind_max_idle_children;
246 char **szWinbindNssInfo;
248 char *szLdapMachineSuffix;
249 char *szLdapUserSuffix;
250 char *szLdapIdmapSuffix;
251 char *szLdapGroupSuffix;
255 int ldap_debug_level;
256 int ldap_debug_threshold;
259 char *szIPrintServer;
261 char **szClusterAddresses;
263 int ldap_passwd_sync;
264 int ldap_replication_sleep;
265 int ldap_timeout; /* This is initialised in init_globals */
266 int ldap_connection_timeout;
269 bool bMsAddPrinterWizard;
274 int iPreferredMaster;
277 char **szInitLogonDelayedHosts;
279 bool bEncryptPasswords;
284 bool bObeyPamRestrictions;
286 int PrintcapCacheTime;
287 bool bLargeReadwrite;
294 bool bBindInterfacesOnly;
295 bool bPamPasswordChange;
296 bool bUnixPasswdSync;
297 bool bPasswdChatDebug;
298 int iPasswdChatTimeout;
302 bool bNTStatusSupport;
304 int iMaxStatCacheSize;
306 bool bAllowTrustedDomains;
310 bool bClientLanManAuth;
311 bool bClientNTLMv2Auth;
312 bool bClientPlaintextAuth;
313 bool bClientUseSpnego;
314 bool bDebugPrefixTimestamp;
315 bool bDebugHiresTimestamp;
319 bool bEnableCoreFiles;
322 bool bHostnameLookups;
323 bool bUnixExtensions;
324 bool bDisableNetbios;
325 bool bUseKerberosKeytab;
326 bool bDeferSharingViolations;
327 bool bEnablePrivileges;
329 bool bUsershareOwnerOnly;
330 bool bUsershareAllowGuests;
331 bool bRegistryShares;
332 int restrict_anonymous;
333 int name_cache_timeout;
336 int client_ldap_sasl_wrapping;
337 int iUsershareMaxShares;
339 int iIdmapNegativeCacheTime;
343 struct param_opt_struct *param_opt;
344 int cups_connection_timeout;
347 static struct global Globals;
350 * This structure describes a single service.
356 time_t usershare_last_mod;
360 char **szInvalidUsers;
368 char *szRootPostExec;
370 char *szPrintcommand;
373 char *szLppausecommand;
374 char *szLpresumecommand;
375 char *szQueuepausecommand;
376 char *szQueueresumecommand;
378 char *szPrintjobUsername;
386 char *szVetoOplockFiles;
392 char **printer_admin;
397 char *szAioWriteBehind;
401 int iMaxReportedPrintJobs;
404 int iCreate_force_mode;
406 int iSecurity_force_mode;
409 int iDir_Security_mask;
410 int iDir_Security_force_mode;
414 int iOplockContentionLimit;
419 bool bRootpreexecClose;
422 bool bShortCasePreserve;
424 bool bHideSpecialFiles;
425 bool bHideUnReadable;
426 bool bHideUnWriteableFiles;
432 bool bAdministrative_share;
438 bool bStoreDosAttributes;
451 bool bStrictAllocate;
454 struct bitmap *copymap;
455 bool bDeleteReadonly;
457 bool bDeleteVetoFiles;
460 bool bDosFiletimeResolution;
461 bool bFakeDirCreateTimes;
467 bool bUseClientDriver;
468 bool bDefaultDevmode;
469 bool bForcePrintername;
471 bool bForceUnknownAclUser;
474 bool bMap_acl_inherit;
477 bool bAclCheckPermissions;
478 bool bAclMapFullControl;
479 bool bAclGroupControl;
481 bool bKernelChangeNotify;
482 int iallocation_roundup_size;
486 int iDirectoryNameCacheSize;
488 struct param_opt_struct *param_opt;
490 char dummy[3]; /* for alignment */
494 /* This is a default service used to prime a services structure */
495 static struct service sDefault = {
497 False, /* not autoloaded */
498 0, /* not a usershare */
499 (time_t)0, /* No last mod time */
500 NULL, /* szService */
502 NULL, /* szUsername */
503 NULL, /* szInvalidUsers */
504 NULL, /* szValidUsers */
505 NULL, /* szAdminUsers */
507 NULL, /* szInclude */
508 NULL, /* szPreExec */
509 NULL, /* szPostExec */
510 NULL, /* szRootPreExec */
511 NULL, /* szRootPostExec */
512 NULL, /* szCupsOptions */
513 NULL, /* szPrintcommand */
514 NULL, /* szLpqcommand */
515 NULL, /* szLprmcommand */
516 NULL, /* szLppausecommand */
517 NULL, /* szLpresumecommand */
518 NULL, /* szQueuepausecommand */
519 NULL, /* szQueueresumecommand */
520 NULL, /* szPrintername */
521 NULL, /* szPrintjobUsername */
522 NULL, /* szDontdescend */
523 NULL, /* szHostsallow */
524 NULL, /* szHostsdeny */
525 NULL, /* szMagicScript */
526 NULL, /* szMagicOutput */
527 NULL, /* szVetoFiles */
528 NULL, /* szHideFiles */
529 NULL, /* szVetoOplockFiles */
531 NULL, /* force user */
532 NULL, /* force group */
534 NULL, /* writelist */
535 NULL, /* printer admin */
538 NULL, /* vfs objects */
539 NULL, /* szMSDfsProxy */
540 NULL, /* szAioWriteBehind */
542 0, /* iMinPrintSpace */
543 1000, /* iMaxPrintJobs */
544 0, /* iMaxReportedPrintJobs */
545 0, /* iWriteCacheSize */
546 0744, /* iCreate_mask */
547 0000, /* iCreate_force_mode */
548 0777, /* iSecurity_mask */
549 0, /* iSecurity_force_mode */
550 0755, /* iDir_mask */
551 0000, /* iDir_force_mode */
552 0777, /* iDir_Security_mask */
553 0, /* iDir_Security_force_mode */
554 0, /* iMaxConnections */
555 CASE_LOWER, /* iDefaultCase */
556 DEFAULT_PRINTING, /* iPrinting */
557 2, /* iOplockContentionLimit */
559 1024, /* iBlock_size */
560 0, /* iDfreeCacheTime */
561 False, /* bPreexecClose */
562 False, /* bRootpreexecClose */
563 Auto, /* case sensitive */
564 True, /* case preserve */
565 True, /* short case preserve */
566 True, /* bHideDotFiles */
567 False, /* bHideSpecialFiles */
568 False, /* bHideUnReadable */
569 False, /* bHideUnWriteableFiles */
570 True, /* bBrowseable */
571 True, /* bAvailable */
572 True, /* bRead_only */
573 True, /* bNo_set_dir */
574 False, /* bGuest_only */
575 False, /* bAdministrative_share */
576 False, /* bGuest_ok */
577 False, /* bPrint_ok */
578 False, /* bMap_system */
579 False, /* bMap_hidden */
580 True, /* bMap_archive */
581 False, /* bStoreDosAttributes */
582 False, /* bDmapiSupport */
584 Auto, /* iStrictLocking */
585 True, /* bPosixLocking */
586 True, /* bShareModes */
588 True, /* bLevel2OpLocks */
589 False, /* bOnlyUser */
590 True, /* bMangledNames */
591 True, /* bWidelinks */
592 True, /* bSymlinks */
593 False, /* bSyncAlways */
594 False, /* bStrictAllocate */
595 False, /* bStrictSync */
596 '~', /* magic char */
598 False, /* bDeleteReadonly */
599 False, /* bFakeOplocks */
600 False, /* bDeleteVetoFiles */
601 False, /* bDosFilemode */
602 True, /* bDosFiletimes */
603 False, /* bDosFiletimeResolution */
604 False, /* bFakeDirCreateTimes */
605 True, /* bBlockingLocks */
606 False, /* bInheritPerms */
607 False, /* bInheritACLS */
608 False, /* bInheritOwner */
609 False, /* bMSDfsRoot */
610 False, /* bUseClientDriver */
611 True, /* bDefaultDevmode */
612 False, /* bForcePrintername */
613 True, /* bNTAclSupport */
614 False, /* bForceUnknownAclUser */
615 False, /* bUseSendfile */
616 False, /* bProfileAcls */
617 False, /* bMap_acl_inherit */
618 False, /* bAfs_Share */
619 False, /* bEASupport */
620 True, /* bAclCheckPermissions */
621 True, /* bAclMapFullControl */
622 False, /* bAclGroupControl */
623 True, /* bChangeNotify */
624 True, /* bKernelChangeNotify */
625 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
626 0, /* iAioReadSize */
627 0, /* iAioWriteSize */
628 MAP_READONLY_YES, /* iMap_readonly */
629 #ifdef BROKEN_DIRECTORY_HANDLING
630 0, /* iDirectoryNameCacheSize */
632 100, /* iDirectoryNameCacheSize */
634 Auto, /* ismb_encrypt */
635 NULL, /* Parametric options */
640 /* local variables */
641 static struct service **ServicePtrs = NULL;
642 static int iNumServices = 0;
643 static int iServiceIndex = 0;
644 static struct db_context *ServiceHash;
645 static int *invalid_services = NULL;
646 static int num_invalid_services = 0;
647 static bool bInGlobalSection = True;
648 static bool bGlobalOnly = False;
649 static int server_role;
650 static int default_server_announce;
652 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
654 /* prototypes for the special type handlers */
655 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
656 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
657 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
658 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
659 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
660 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
661 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
662 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
663 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
664 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
665 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
666 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
668 static void set_server_role(void);
669 static void set_default_server_announce_type(void);
670 static void set_allowed_client_auth(void);
672 static const struct enum_list enum_protocol[] = {
673 {PROTOCOL_NT1, "NT1"},
674 {PROTOCOL_LANMAN2, "LANMAN2"},
675 {PROTOCOL_LANMAN1, "LANMAN1"},
676 {PROTOCOL_CORE, "CORE"},
677 {PROTOCOL_COREPLUS, "COREPLUS"},
678 {PROTOCOL_COREPLUS, "CORE+"},
682 static const struct enum_list enum_security[] = {
683 {SEC_SHARE, "SHARE"},
685 {SEC_SERVER, "SERVER"},
686 {SEC_DOMAIN, "DOMAIN"},
693 static const struct enum_list enum_printing[] = {
694 {PRINT_SYSV, "sysv"},
696 {PRINT_HPUX, "hpux"},
700 {PRINT_LPRNG, "lprng"},
701 {PRINT_CUPS, "cups"},
702 {PRINT_IPRINT, "iprint"},
704 {PRINT_LPROS2, "os2"},
706 {PRINT_TEST, "test"},
708 #endif /* DEVELOPER */
712 static const struct enum_list enum_ldap_sasl_wrapping[] = {
714 {ADS_AUTH_SASL_SIGN, "sign"},
715 {ADS_AUTH_SASL_SEAL, "seal"},
719 static const struct enum_list enum_ldap_ssl[] = {
720 {LDAP_SSL_OFF, "no"},
721 {LDAP_SSL_OFF, "No"},
722 {LDAP_SSL_OFF, "off"},
723 {LDAP_SSL_OFF, "Off"},
724 {LDAP_SSL_START_TLS, "start tls"},
725 {LDAP_SSL_START_TLS, "Start_tls"},
729 static const struct enum_list enum_ldap_passwd_sync[] = {
730 {LDAP_PASSWD_SYNC_OFF, "no"},
731 {LDAP_PASSWD_SYNC_OFF, "No"},
732 {LDAP_PASSWD_SYNC_OFF, "off"},
733 {LDAP_PASSWD_SYNC_OFF, "Off"},
734 {LDAP_PASSWD_SYNC_ON, "Yes"},
735 {LDAP_PASSWD_SYNC_ON, "yes"},
736 {LDAP_PASSWD_SYNC_ON, "on"},
737 {LDAP_PASSWD_SYNC_ON, "On"},
738 {LDAP_PASSWD_SYNC_ONLY, "Only"},
739 {LDAP_PASSWD_SYNC_ONLY, "only"},
743 /* Types of machine we can announce as. */
744 #define ANNOUNCE_AS_NT_SERVER 1
745 #define ANNOUNCE_AS_WIN95 2
746 #define ANNOUNCE_AS_WFW 3
747 #define ANNOUNCE_AS_NT_WORKSTATION 4
749 static const struct enum_list enum_announce_as[] = {
750 {ANNOUNCE_AS_NT_SERVER, "NT"},
751 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
752 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
753 {ANNOUNCE_AS_WIN95, "win95"},
754 {ANNOUNCE_AS_WFW, "WfW"},
758 static const struct enum_list enum_map_readonly[] = {
759 {MAP_READONLY_NO, "no"},
760 {MAP_READONLY_NO, "false"},
761 {MAP_READONLY_NO, "0"},
762 {MAP_READONLY_YES, "yes"},
763 {MAP_READONLY_YES, "true"},
764 {MAP_READONLY_YES, "1"},
765 {MAP_READONLY_PERMISSIONS, "permissions"},
766 {MAP_READONLY_PERMISSIONS, "perms"},
770 static const struct enum_list enum_case[] = {
771 {CASE_LOWER, "lower"},
772 {CASE_UPPER, "upper"},
776 static const struct enum_list enum_bool_auto[] = {
787 /* Client-side offline caching policy types */
788 #define CSC_POLICY_MANUAL 0
789 #define CSC_POLICY_DOCUMENTS 1
790 #define CSC_POLICY_PROGRAMS 2
791 #define CSC_POLICY_DISABLE 3
793 static const struct enum_list enum_csc_policy[] = {
794 {CSC_POLICY_MANUAL, "manual"},
795 {CSC_POLICY_DOCUMENTS, "documents"},
796 {CSC_POLICY_PROGRAMS, "programs"},
797 {CSC_POLICY_DISABLE, "disable"},
801 /* SMB signing types. */
802 static const struct enum_list enum_smb_signing_vals[] = {
814 {Required, "required"},
815 {Required, "mandatory"},
817 {Required, "forced"},
818 {Required, "enforced"},
822 /* ACL compatibility options. */
823 static const struct enum_list enum_acl_compat_vals[] = {
824 { ACL_COMPAT_AUTO, "auto" },
825 { ACL_COMPAT_WINNT, "winnt" },
826 { ACL_COMPAT_WIN2K, "win2k" },
831 Do you want session setups at user level security with a invalid
832 password to be rejected or allowed in as guest? WinNT rejects them
833 but it can be a pain as it means "net view" needs to use a password
835 You have 3 choices in the setting of map_to_guest:
837 "Never" means session setups with an invalid password
838 are rejected. This is the default.
840 "Bad User" means session setups with an invalid password
841 are rejected, unless the username does not exist, in which case it
842 is treated as a guest login
844 "Bad Password" means session setups with an invalid password
845 are treated as a guest login
847 Note that map_to_guest only has an effect in user or server
851 static const struct enum_list enum_map_to_guest[] = {
852 {NEVER_MAP_TO_GUEST, "Never"},
853 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
854 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
855 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
859 /* Config backend options */
861 static const struct enum_list enum_config_backend[] = {
862 {CONFIG_BACKEND_FILE, "file"},
863 {CONFIG_BACKEND_REGISTRY, "registry"},
867 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
869 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
870 * screen in SWAT. This is used to exclude parameters as well as to squash all
871 * parameters that have been duplicated by pseudonyms.
873 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
874 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
875 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
878 * NOTE2: Handling of duplicated (synonym) paramters:
879 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
880 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
881 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
882 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
885 static struct parm_struct parm_table[] = {
886 {N_("Base Options"), P_SEP, P_SEPARATOR},
889 .label = "dos charset",
892 .ptr = &Globals.dos_charset,
893 .special = handle_charset,
895 .flags = FLAG_ADVANCED
898 .label = "unix charset",
901 .ptr = &Globals.unix_charset,
902 .special = handle_charset,
904 .flags = FLAG_ADVANCED
907 .label = "display charset",
910 .ptr = &Globals.display_charset,
911 .special = handle_charset,
913 .flags = FLAG_ADVANCED
919 .ptr = &sDefault.comment,
922 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
928 .ptr = &sDefault.szPath,
931 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
934 .label = "directory",
937 .ptr = &sDefault.szPath,
943 .label = "workgroup",
946 .ptr = &Globals.szWorkgroup,
947 .special = handle_workgroup,
949 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
956 .ptr = &Globals.szRealm,
959 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
963 .label = "netbios name",
966 .ptr = &Globals.szNetbiosName,
967 .special = handle_netbios_name,
969 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
972 .label = "netbios aliases",
975 .ptr = &Globals.szNetbiosAliases,
976 .special = handle_netbios_aliases,
978 .flags = FLAG_ADVANCED,
981 .label = "netbios scope",
984 .ptr = &Globals.szNetbiosScope,
985 .special = handle_netbios_scope,
987 .flags = FLAG_ADVANCED,
990 .label = "server string",
993 .ptr = &Globals.szServerString,
996 .flags = FLAG_BASIC | FLAG_ADVANCED,
999 .label = "interfaces",
1001 .p_class = P_GLOBAL,
1002 .ptr = &Globals.szInterfaces,
1005 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1008 .label = "bind interfaces only",
1010 .p_class = P_GLOBAL,
1011 .ptr = &Globals.bBindInterfacesOnly,
1014 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1017 .label = "config backend",
1019 .p_class = P_GLOBAL,
1020 .ptr = &Globals.ConfigBackend,
1022 .enum_list = enum_config_backend,
1023 .flags = FLAG_ADVANCED,
1026 {N_("Security Options"), P_SEP, P_SEPARATOR},
1029 .label = "security",
1031 .p_class = P_GLOBAL,
1032 .ptr = &Globals.security,
1034 .enum_list = enum_security,
1035 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1038 .label = "auth methods",
1040 .p_class = P_GLOBAL,
1041 .ptr = &Globals.AuthMethods,
1044 .flags = FLAG_ADVANCED,
1047 .label = "encrypt passwords",
1049 .p_class = P_GLOBAL,
1050 .ptr = &Globals.bEncryptPasswords,
1053 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1056 .label = "update encrypted",
1058 .p_class = P_GLOBAL,
1059 .ptr = &Globals.bUpdateEncrypt,
1062 .flags = FLAG_ADVANCED,
1065 .label = "client schannel",
1067 .p_class = P_GLOBAL,
1068 .ptr = &Globals.clientSchannel,
1070 .enum_list = enum_bool_auto,
1071 .flags = FLAG_BASIC | FLAG_ADVANCED,
1074 .label = "server schannel",
1076 .p_class = P_GLOBAL,
1077 .ptr = &Globals.serverSchannel,
1079 .enum_list = enum_bool_auto,
1080 .flags = FLAG_BASIC | FLAG_ADVANCED,
1083 .label = "allow trusted domains",
1085 .p_class = P_GLOBAL,
1086 .ptr = &Globals.bAllowTrustedDomains,
1089 .flags = FLAG_ADVANCED,
1092 .label = "map to guest",
1094 .p_class = P_GLOBAL,
1095 .ptr = &Globals.map_to_guest,
1097 .enum_list = enum_map_to_guest,
1098 .flags = FLAG_ADVANCED,
1101 .label = "null passwords",
1103 .p_class = P_GLOBAL,
1104 .ptr = &Globals.bNullPasswords,
1107 .flags = FLAG_ADVANCED,
1110 .label = "obey pam restrictions",
1112 .p_class = P_GLOBAL,
1113 .ptr = &Globals.bObeyPamRestrictions,
1116 .flags = FLAG_ADVANCED,
1119 .label = "password server",
1121 .p_class = P_GLOBAL,
1122 .ptr = &Globals.szPasswordServer,
1125 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1128 .label = "smb passwd file",
1130 .p_class = P_GLOBAL,
1131 .ptr = &Globals.szSMBPasswdFile,
1134 .flags = FLAG_ADVANCED,
1137 .label = "private dir",
1139 .p_class = P_GLOBAL,
1140 .ptr = &Globals.szPrivateDir,
1143 .flags = FLAG_ADVANCED,
1146 .label = "passdb backend",
1148 .p_class = P_GLOBAL,
1149 .ptr = &Globals.szPassdbBackend,
1152 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1155 .label = "algorithmic rid base",
1157 .p_class = P_GLOBAL,
1158 .ptr = &Globals.AlgorithmicRidBase,
1161 .flags = FLAG_ADVANCED,
1164 .label = "root directory",
1166 .p_class = P_GLOBAL,
1167 .ptr = &Globals.szRootdir,
1170 .flags = FLAG_ADVANCED,
1173 .label = "root dir",
1175 .p_class = P_GLOBAL,
1176 .ptr = &Globals.szRootdir,
1184 .p_class = P_GLOBAL,
1185 .ptr = &Globals.szRootdir,
1191 .label = "guest account",
1193 .p_class = P_GLOBAL,
1194 .ptr = &Globals.szGuestaccount,
1197 .flags = FLAG_BASIC | FLAG_ADVANCED,
1200 .label = "enable privileges",
1202 .p_class = P_GLOBAL,
1203 .ptr = &Globals.bEnablePrivileges,
1206 .flags = FLAG_ADVANCED,
1210 .label = "pam password change",
1212 .p_class = P_GLOBAL,
1213 .ptr = &Globals.bPamPasswordChange,
1216 .flags = FLAG_ADVANCED,
1219 .label = "passwd program",
1221 .p_class = P_GLOBAL,
1222 .ptr = &Globals.szPasswdProgram,
1225 .flags = FLAG_ADVANCED,
1228 .label = "passwd chat",
1230 .p_class = P_GLOBAL,
1231 .ptr = &Globals.szPasswdChat,
1234 .flags = FLAG_ADVANCED,
1237 .label = "passwd chat debug",
1239 .p_class = P_GLOBAL,
1240 .ptr = &Globals.bPasswdChatDebug,
1243 .flags = FLAG_ADVANCED,
1246 .label = "passwd chat timeout",
1248 .p_class = P_GLOBAL,
1249 .ptr = &Globals.iPasswdChatTimeout,
1252 .flags = FLAG_ADVANCED,
1255 .label = "check password script",
1257 .p_class = P_GLOBAL,
1258 .ptr = &Globals.szCheckPasswordScript,
1261 .flags = FLAG_ADVANCED,
1264 .label = "username map",
1266 .p_class = P_GLOBAL,
1267 .ptr = &Globals.szUsernameMap,
1270 .flags = FLAG_ADVANCED,
1273 .label = "password level",
1275 .p_class = P_GLOBAL,
1276 .ptr = &Globals.pwordlevel,
1279 .flags = FLAG_ADVANCED,
1282 .label = "username level",
1284 .p_class = P_GLOBAL,
1285 .ptr = &Globals.unamelevel,
1288 .flags = FLAG_ADVANCED,
1291 .label = "unix password sync",
1293 .p_class = P_GLOBAL,
1294 .ptr = &Globals.bUnixPasswdSync,
1297 .flags = FLAG_ADVANCED,
1300 .label = "restrict anonymous",
1302 .p_class = P_GLOBAL,
1303 .ptr = &Globals.restrict_anonymous,
1306 .flags = FLAG_ADVANCED,
1309 .label = "lanman auth",
1311 .p_class = P_GLOBAL,
1312 .ptr = &Globals.bLanmanAuth,
1315 .flags = FLAG_ADVANCED,
1318 .label = "ntlm auth",
1320 .p_class = P_GLOBAL,
1321 .ptr = &Globals.bNTLMAuth,
1324 .flags = FLAG_ADVANCED,
1327 .label = "client NTLMv2 auth",
1329 .p_class = P_GLOBAL,
1330 .ptr = &Globals.bClientNTLMv2Auth,
1333 .flags = FLAG_ADVANCED,
1336 .label = "client lanman auth",
1338 .p_class = P_GLOBAL,
1339 .ptr = &Globals.bClientLanManAuth,
1342 .flags = FLAG_ADVANCED,
1345 .label = "client plaintext auth",
1347 .p_class = P_GLOBAL,
1348 .ptr = &Globals.bClientPlaintextAuth,
1351 .flags = FLAG_ADVANCED,
1354 .label = "username",
1357 .ptr = &sDefault.szUsername,
1360 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1366 .ptr = &sDefault.szUsername,
1375 .ptr = &sDefault.szUsername,
1381 .label = "invalid users",
1384 .ptr = &sDefault.szInvalidUsers,
1387 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1390 .label = "valid users",
1393 .ptr = &sDefault.szValidUsers,
1396 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1399 .label = "admin users",
1402 .ptr = &sDefault.szAdminUsers,
1405 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1408 .label = "read list",
1411 .ptr = &sDefault.readlist,
1414 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1417 .label = "write list",
1420 .ptr = &sDefault.writelist,
1423 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1426 .label = "printer admin",
1429 .ptr = &sDefault.printer_admin,
1432 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1435 .label = "force user",
1438 .ptr = &sDefault.force_user,
1441 .flags = FLAG_ADVANCED | FLAG_SHARE,
1444 .label = "force group",
1447 .ptr = &sDefault.force_group,
1450 .flags = FLAG_ADVANCED | FLAG_SHARE,
1456 .ptr = &sDefault.force_group,
1459 .flags = FLAG_ADVANCED,
1462 .label = "read only",
1465 .ptr = &sDefault.bRead_only,
1468 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1471 .label = "write ok",
1474 .ptr = &sDefault.bRead_only,
1480 .label = "writeable",
1483 .ptr = &sDefault.bRead_only,
1489 .label = "writable",
1492 .ptr = &sDefault.bRead_only,
1498 .label = "acl check permissions",
1501 .ptr = &sDefault.bAclCheckPermissions,
1504 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1507 .label = "acl group control",
1510 .ptr = &sDefault.bAclGroupControl,
1513 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1516 .label = "acl map full control",
1519 .ptr = &sDefault.bAclMapFullControl,
1522 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1525 .label = "create mask",
1528 .ptr = &sDefault.iCreate_mask,
1531 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1534 .label = "create mode",
1537 .ptr = &sDefault.iCreate_mask,
1543 .label = "force create mode",
1546 .ptr = &sDefault.iCreate_force_mode,
1549 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1552 .label = "security mask",
1555 .ptr = &sDefault.iSecurity_mask,
1558 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1561 .label = "force security mode",
1564 .ptr = &sDefault.iSecurity_force_mode,
1567 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1570 .label = "directory mask",
1573 .ptr = &sDefault.iDir_mask,
1576 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1579 .label = "directory mode",
1582 .ptr = &sDefault.iDir_mask,
1585 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1588 .label = "force directory mode",
1591 .ptr = &sDefault.iDir_force_mode,
1594 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1597 .label = "directory security mask",
1600 .ptr = &sDefault.iDir_Security_mask,
1603 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1606 .label = "force directory security mode",
1609 .ptr = &sDefault.iDir_Security_force_mode,
1612 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1615 .label = "force unknown acl user",
1618 .ptr = &sDefault.bForceUnknownAclUser,
1621 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1624 .label = "inherit permissions",
1627 .ptr = &sDefault.bInheritPerms,
1630 .flags = FLAG_ADVANCED | FLAG_SHARE,
1633 .label = "inherit acls",
1636 .ptr = &sDefault.bInheritACLS,
1639 .flags = FLAG_ADVANCED | FLAG_SHARE,
1642 .label = "inherit owner",
1645 .ptr = &sDefault.bInheritOwner,
1648 .flags = FLAG_ADVANCED | FLAG_SHARE,
1651 .label = "guest only",
1654 .ptr = &sDefault.bGuest_only,
1657 .flags = FLAG_ADVANCED | FLAG_SHARE,
1660 .label = "only guest",
1663 .ptr = &sDefault.bGuest_only,
1669 .label = "administrative share",
1672 .ptr = &sDefault.bAdministrative_share,
1675 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1679 .label = "guest ok",
1682 .ptr = &sDefault.bGuest_ok,
1685 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1691 .ptr = &sDefault.bGuest_ok,
1697 .label = "only user",
1700 .ptr = &sDefault.bOnlyUser,
1703 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1706 .label = "hosts allow",
1709 .ptr = &sDefault.szHostsallow,
1712 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1715 .label = "allow hosts",
1718 .ptr = &sDefault.szHostsallow,
1724 .label = "hosts deny",
1727 .ptr = &sDefault.szHostsdeny,
1730 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1733 .label = "deny hosts",
1736 .ptr = &sDefault.szHostsdeny,
1742 .label = "preload modules",
1744 .p_class = P_GLOBAL,
1745 .ptr = &Globals.szPreloadModules,
1748 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1751 .label = "use kerberos keytab",
1753 .p_class = P_GLOBAL,
1754 .ptr = &Globals.bUseKerberosKeytab,
1757 .flags = FLAG_ADVANCED,
1760 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1763 .label = "log level",
1765 .p_class = P_GLOBAL,
1766 .ptr = &Globals.szLogLevel,
1767 .special = handle_debug_list,
1769 .flags = FLAG_ADVANCED,
1772 .label = "debuglevel",
1774 .p_class = P_GLOBAL,
1775 .ptr = &Globals.szLogLevel,
1776 .special = handle_debug_list,
1783 .p_class = P_GLOBAL,
1784 .ptr = &Globals.syslog,
1787 .flags = FLAG_ADVANCED,
1790 .label = "syslog only",
1792 .p_class = P_GLOBAL,
1793 .ptr = &Globals.bSyslogOnly,
1796 .flags = FLAG_ADVANCED,
1799 .label = "log file",
1801 .p_class = P_GLOBAL,
1802 .ptr = &Globals.szLogFile,
1805 .flags = FLAG_ADVANCED,
1808 .label = "max log size",
1810 .p_class = P_GLOBAL,
1811 .ptr = &Globals.max_log_size,
1814 .flags = FLAG_ADVANCED,
1817 .label = "debug timestamp",
1819 .p_class = P_GLOBAL,
1820 .ptr = &Globals.bTimestampLogs,
1823 .flags = FLAG_ADVANCED,
1826 .label = "timestamp logs",
1828 .p_class = P_GLOBAL,
1829 .ptr = &Globals.bTimestampLogs,
1832 .flags = FLAG_ADVANCED,
1835 .label = "debug prefix timestamp",
1837 .p_class = P_GLOBAL,
1838 .ptr = &Globals.bDebugPrefixTimestamp,
1841 .flags = FLAG_ADVANCED,
1844 .label = "debug hires timestamp",
1846 .p_class = P_GLOBAL,
1847 .ptr = &Globals.bDebugHiresTimestamp,
1850 .flags = FLAG_ADVANCED,
1853 .label = "debug pid",
1855 .p_class = P_GLOBAL,
1856 .ptr = &Globals.bDebugPid,
1859 .flags = FLAG_ADVANCED,
1862 .label = "debug uid",
1864 .p_class = P_GLOBAL,
1865 .ptr = &Globals.bDebugUid,
1868 .flags = FLAG_ADVANCED,
1871 .label = "debug class",
1873 .p_class = P_GLOBAL,
1874 .ptr = &Globals.bDebugClass,
1877 .flags = FLAG_ADVANCED,
1880 .label = "enable core files",
1882 .p_class = P_GLOBAL,
1883 .ptr = &Globals.bEnableCoreFiles,
1886 .flags = FLAG_ADVANCED,
1889 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1892 .label = "allocation roundup size",
1895 .ptr = &sDefault.iallocation_roundup_size,
1898 .flags = FLAG_ADVANCED,
1901 .label = "aio read size",
1904 .ptr = &sDefault.iAioReadSize,
1907 .flags = FLAG_ADVANCED,
1910 .label = "aio write size",
1913 .ptr = &sDefault.iAioWriteSize,
1916 .flags = FLAG_ADVANCED,
1919 .label = "aio write behind",
1922 .ptr = &sDefault.szAioWriteBehind,
1925 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1928 .label = "smb ports",
1930 .p_class = P_GLOBAL,
1931 .ptr = &Globals.smb_ports,
1934 .flags = FLAG_ADVANCED,
1937 .label = "large readwrite",
1939 .p_class = P_GLOBAL,
1940 .ptr = &Globals.bLargeReadwrite,
1943 .flags = FLAG_ADVANCED,
1946 .label = "max protocol",
1948 .p_class = P_GLOBAL,
1949 .ptr = &Globals.maxprotocol,
1951 .enum_list = enum_protocol,
1952 .flags = FLAG_ADVANCED,
1955 .label = "protocol",
1957 .p_class = P_GLOBAL,
1958 .ptr = &Globals.maxprotocol,
1960 .enum_list = enum_protocol,
1961 .flags = FLAG_ADVANCED,
1964 .label = "min protocol",
1966 .p_class = P_GLOBAL,
1967 .ptr = &Globals.minprotocol,
1969 .enum_list = enum_protocol,
1970 .flags = FLAG_ADVANCED,
1973 .label = "min receivefile size",
1975 .p_class = P_GLOBAL,
1976 .ptr = &Globals.iminreceivefile,
1979 .flags = FLAG_ADVANCED,
1982 .label = "read raw",
1984 .p_class = P_GLOBAL,
1985 .ptr = &Globals.bReadRaw,
1988 .flags = FLAG_ADVANCED,
1991 .label = "write raw",
1993 .p_class = P_GLOBAL,
1994 .ptr = &Globals.bWriteRaw,
1997 .flags = FLAG_ADVANCED,
2000 .label = "disable netbios",
2002 .p_class = P_GLOBAL,
2003 .ptr = &Globals.bDisableNetbios,
2006 .flags = FLAG_ADVANCED,
2009 .label = "reset on zero vc",
2011 .p_class = P_GLOBAL,
2012 .ptr = &Globals.bResetOnZeroVC,
2015 .flags = FLAG_ADVANCED,
2018 .label = "acl compatibility",
2020 .p_class = P_GLOBAL,
2021 .ptr = &Globals.iAclCompat,
2023 .enum_list = enum_acl_compat_vals,
2024 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2027 .label = "defer sharing violations",
2029 .p_class = P_GLOBAL,
2030 .ptr = &Globals.bDeferSharingViolations,
2033 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2036 .label = "ea support",
2039 .ptr = &sDefault.bEASupport,
2042 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2045 .label = "nt acl support",
2048 .ptr = &sDefault.bNTAclSupport,
2051 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2054 .label = "nt pipe support",
2056 .p_class = P_GLOBAL,
2057 .ptr = &Globals.bNTPipeSupport,
2060 .flags = FLAG_ADVANCED,
2063 .label = "nt status support",
2065 .p_class = P_GLOBAL,
2066 .ptr = &Globals.bNTStatusSupport,
2069 .flags = FLAG_ADVANCED,
2072 .label = "profile acls",
2075 .ptr = &sDefault.bProfileAcls,
2078 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2081 .label = "announce version",
2083 .p_class = P_GLOBAL,
2084 .ptr = &Globals.szAnnounceVersion,
2087 .flags = FLAG_ADVANCED,
2090 .label = "announce as",
2092 .p_class = P_GLOBAL,
2093 .ptr = &Globals.announce_as,
2095 .enum_list = enum_announce_as,
2096 .flags = FLAG_ADVANCED,
2099 .label = "map acl inherit",
2102 .ptr = &sDefault.bMap_acl_inherit,
2105 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2108 .label = "afs share",
2111 .ptr = &sDefault.bAfs_Share,
2114 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2119 .p_class = P_GLOBAL,
2120 .ptr = &Globals.max_mux,
2123 .flags = FLAG_ADVANCED,
2126 .label = "max xmit",
2128 .p_class = P_GLOBAL,
2129 .ptr = &Globals.max_xmit,
2132 .flags = FLAG_ADVANCED,
2135 .label = "name resolve order",
2137 .p_class = P_GLOBAL,
2138 .ptr = &Globals.szNameResolveOrder,
2141 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2146 .p_class = P_GLOBAL,
2147 .ptr = &Globals.max_ttl,
2150 .flags = FLAG_ADVANCED,
2153 .label = "max wins ttl",
2155 .p_class = P_GLOBAL,
2156 .ptr = &Globals.max_wins_ttl,
2159 .flags = FLAG_ADVANCED,
2162 .label = "min wins ttl",
2164 .p_class = P_GLOBAL,
2165 .ptr = &Globals.min_wins_ttl,
2168 .flags = FLAG_ADVANCED,
2171 .label = "time server",
2173 .p_class = P_GLOBAL,
2174 .ptr = &Globals.bTimeServer,
2177 .flags = FLAG_ADVANCED,
2180 .label = "unix extensions",
2182 .p_class = P_GLOBAL,
2183 .ptr = &Globals.bUnixExtensions,
2186 .flags = FLAG_ADVANCED,
2189 .label = "use spnego",
2191 .p_class = P_GLOBAL,
2192 .ptr = &Globals.bUseSpnego,
2195 .flags = FLAG_ADVANCED,
2198 .label = "client signing",
2200 .p_class = P_GLOBAL,
2201 .ptr = &Globals.client_signing,
2203 .enum_list = enum_smb_signing_vals,
2204 .flags = FLAG_ADVANCED,
2207 .label = "server signing",
2209 .p_class = P_GLOBAL,
2210 .ptr = &Globals.server_signing,
2212 .enum_list = enum_smb_signing_vals,
2213 .flags = FLAG_ADVANCED,
2216 .label = "smb encrypt",
2219 .ptr = &sDefault.ismb_encrypt,
2221 .enum_list = enum_smb_signing_vals,
2222 .flags = FLAG_ADVANCED,
2225 .label = "client use spnego",
2227 .p_class = P_GLOBAL,
2228 .ptr = &Globals.bClientUseSpnego,
2231 .flags = FLAG_ADVANCED,
2234 .label = "client ldap sasl wrapping",
2236 .p_class = P_GLOBAL,
2237 .ptr = &Globals.client_ldap_sasl_wrapping,
2239 .enum_list = enum_ldap_sasl_wrapping,
2240 .flags = FLAG_ADVANCED,
2243 .label = "enable asu support",
2245 .p_class = P_GLOBAL,
2246 .ptr = &Globals.bASUSupport,
2249 .flags = FLAG_ADVANCED,
2252 .label = "svcctl list",
2254 .p_class = P_GLOBAL,
2255 .ptr = &Globals.szServicesList,
2258 .flags = FLAG_ADVANCED,
2261 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2264 .label = "block size",
2267 .ptr = &sDefault.iBlock_size,
2270 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2273 .label = "deadtime",
2275 .p_class = P_GLOBAL,
2276 .ptr = &Globals.deadtime,
2279 .flags = FLAG_ADVANCED,
2282 .label = "getwd cache",
2284 .p_class = P_GLOBAL,
2285 .ptr = &Globals.getwd_cache,
2288 .flags = FLAG_ADVANCED,
2291 .label = "keepalive",
2293 .p_class = P_GLOBAL,
2294 .ptr = &Globals.iKeepalive,
2297 .flags = FLAG_ADVANCED,
2300 .label = "change notify",
2303 .ptr = &sDefault.bChangeNotify,
2306 .flags = FLAG_ADVANCED | FLAG_SHARE,
2309 .label = "directory name cache size",
2312 .ptr = &sDefault.iDirectoryNameCacheSize,
2315 .flags = FLAG_ADVANCED | FLAG_SHARE,
2318 .label = "kernel change notify",
2321 .ptr = &sDefault.bKernelChangeNotify,
2324 .flags = FLAG_ADVANCED | FLAG_SHARE,
2327 .label = "lpq cache time",
2329 .p_class = P_GLOBAL,
2330 .ptr = &Globals.lpqcachetime,
2333 .flags = FLAG_ADVANCED,
2336 .label = "max smbd processes",
2338 .p_class = P_GLOBAL,
2339 .ptr = &Globals.iMaxSmbdProcesses,
2342 .flags = FLAG_ADVANCED,
2345 .label = "max connections",
2348 .ptr = &sDefault.iMaxConnections,
2351 .flags = FLAG_ADVANCED | FLAG_SHARE,
2354 .label = "paranoid server security",
2356 .p_class = P_GLOBAL,
2357 .ptr = &Globals.paranoid_server_security,
2360 .flags = FLAG_ADVANCED,
2363 .label = "max disk size",
2365 .p_class = P_GLOBAL,
2366 .ptr = &Globals.maxdisksize,
2369 .flags = FLAG_ADVANCED,
2372 .label = "max open files",
2374 .p_class = P_GLOBAL,
2375 .ptr = &Globals.max_open_files,
2378 .flags = FLAG_ADVANCED,
2381 .label = "min print space",
2384 .ptr = &sDefault.iMinPrintSpace,
2387 .flags = FLAG_ADVANCED | FLAG_PRINT,
2390 .label = "socket options",
2392 .p_class = P_GLOBAL,
2393 .ptr = &Globals.szSocketOptions,
2396 .flags = FLAG_ADVANCED,
2399 .label = "strict allocate",
2402 .ptr = &sDefault.bStrictAllocate,
2405 .flags = FLAG_ADVANCED | FLAG_SHARE,
2408 .label = "strict sync",
2411 .ptr = &sDefault.bStrictSync,
2414 .flags = FLAG_ADVANCED | FLAG_SHARE,
2417 .label = "sync always",
2420 .ptr = &sDefault.bSyncAlways,
2423 .flags = FLAG_ADVANCED | FLAG_SHARE,
2426 .label = "use mmap",
2428 .p_class = P_GLOBAL,
2429 .ptr = &Globals.bUseMmap,
2432 .flags = FLAG_ADVANCED,
2435 .label = "use sendfile",
2438 .ptr = &sDefault.bUseSendfile,
2441 .flags = FLAG_ADVANCED | FLAG_SHARE,
2444 .label = "hostname lookups",
2446 .p_class = P_GLOBAL,
2447 .ptr = &Globals.bHostnameLookups,
2450 .flags = FLAG_ADVANCED,
2453 .label = "write cache size",
2456 .ptr = &sDefault.iWriteCacheSize,
2459 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2462 .label = "name cache timeout",
2464 .p_class = P_GLOBAL,
2465 .ptr = &Globals.name_cache_timeout,
2468 .flags = FLAG_ADVANCED,
2471 .label = "ctdbd socket",
2473 .p_class = P_GLOBAL,
2474 .ptr = &Globals.ctdbdSocket,
2477 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2480 .label = "cluster addresses",
2482 .p_class = P_GLOBAL,
2483 .ptr = &Globals.szClusterAddresses,
2486 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2489 .label = "clustering",
2491 .p_class = P_GLOBAL,
2492 .ptr = &Globals.clustering,
2495 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2498 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2501 .label = "max reported print jobs",
2504 .ptr = &sDefault.iMaxReportedPrintJobs,
2507 .flags = FLAG_ADVANCED | FLAG_PRINT,
2510 .label = "max print jobs",
2513 .ptr = &sDefault.iMaxPrintJobs,
2516 .flags = FLAG_ADVANCED | FLAG_PRINT,
2519 .label = "load printers",
2521 .p_class = P_GLOBAL,
2522 .ptr = &Globals.bLoadPrinters,
2525 .flags = FLAG_ADVANCED | FLAG_PRINT,
2528 .label = "printcap cache time",
2530 .p_class = P_GLOBAL,
2531 .ptr = &Globals.PrintcapCacheTime,
2534 .flags = FLAG_ADVANCED | FLAG_PRINT,
2537 .label = "printcap name",
2539 .p_class = P_GLOBAL,
2540 .ptr = &Globals.szPrintcapname,
2543 .flags = FLAG_ADVANCED | FLAG_PRINT,
2546 .label = "printcap",
2548 .p_class = P_GLOBAL,
2549 .ptr = &Globals.szPrintcapname,
2555 .label = "printable",
2558 .ptr = &sDefault.bPrint_ok,
2561 .flags = FLAG_ADVANCED | FLAG_PRINT,
2564 .label = "print ok",
2567 .ptr = &sDefault.bPrint_ok,
2573 .label = "printing",
2576 .ptr = &sDefault.iPrinting,
2577 .special = handle_printing,
2578 .enum_list = enum_printing,
2579 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2582 .label = "cups options",
2585 .ptr = &sDefault.szCupsOptions,
2588 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2591 .label = "cups server",
2593 .p_class = P_GLOBAL,
2594 .ptr = &Globals.szCupsServer,
2597 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2600 .label = "cups connection timeout",
2602 .p_class = P_GLOBAL,
2603 .ptr = &Globals.cups_connection_timeout,
2606 .flags = FLAG_ADVANCED,
2609 .label = "iprint server",
2611 .p_class = P_GLOBAL,
2612 .ptr = &Globals.szIPrintServer,
2615 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2618 .label = "print command",
2621 .ptr = &sDefault.szPrintcommand,
2624 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2627 .label = "disable spoolss",
2629 .p_class = P_GLOBAL,
2630 .ptr = &Globals.bDisableSpoolss,
2633 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2636 .label = "enable spoolss",
2638 .p_class = P_GLOBAL,
2639 .ptr = &Globals.bDisableSpoolss,
2645 .label = "lpq command",
2648 .ptr = &sDefault.szLpqcommand,
2651 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2654 .label = "lprm command",
2657 .ptr = &sDefault.szLprmcommand,
2660 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2663 .label = "lppause command",
2666 .ptr = &sDefault.szLppausecommand,
2669 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2672 .label = "lpresume command",
2675 .ptr = &sDefault.szLpresumecommand,
2678 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2681 .label = "queuepause command",
2684 .ptr = &sDefault.szQueuepausecommand,
2687 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2690 .label = "queueresume command",
2693 .ptr = &sDefault.szQueueresumecommand,
2696 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2699 .label = "addport command",
2701 .p_class = P_GLOBAL,
2702 .ptr = &Globals.szAddPortCommand,
2705 .flags = FLAG_ADVANCED,
2708 .label = "enumports command",
2710 .p_class = P_GLOBAL,
2711 .ptr = &Globals.szEnumPortsCommand,
2714 .flags = FLAG_ADVANCED,
2717 .label = "addprinter command",
2719 .p_class = P_GLOBAL,
2720 .ptr = &Globals.szAddPrinterCommand,
2723 .flags = FLAG_ADVANCED,
2726 .label = "deleteprinter command",
2728 .p_class = P_GLOBAL,
2729 .ptr = &Globals.szDeletePrinterCommand,
2732 .flags = FLAG_ADVANCED,
2735 .label = "show add printer wizard",
2737 .p_class = P_GLOBAL,
2738 .ptr = &Globals.bMsAddPrinterWizard,
2741 .flags = FLAG_ADVANCED,
2744 .label = "os2 driver map",
2746 .p_class = P_GLOBAL,
2747 .ptr = &Globals.szOs2DriverMap,
2750 .flags = FLAG_ADVANCED,
2754 .label = "printer name",
2757 .ptr = &sDefault.szPrintername,
2760 .flags = FLAG_ADVANCED | FLAG_PRINT,
2766 .ptr = &sDefault.szPrintername,
2772 .label = "use client driver",
2775 .ptr = &sDefault.bUseClientDriver,
2778 .flags = FLAG_ADVANCED | FLAG_PRINT,
2781 .label = "default devmode",
2784 .ptr = &sDefault.bDefaultDevmode,
2787 .flags = FLAG_ADVANCED | FLAG_PRINT,
2790 .label = "force printername",
2793 .ptr = &sDefault.bForcePrintername,
2796 .flags = FLAG_ADVANCED | FLAG_PRINT,
2799 .label = "printjob username",
2802 .ptr = &sDefault.szPrintjobUsername,
2805 .flags = FLAG_ADVANCED | FLAG_PRINT,
2808 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2811 .label = "mangling method",
2813 .p_class = P_GLOBAL,
2814 .ptr = &Globals.szManglingMethod,
2817 .flags = FLAG_ADVANCED,
2820 .label = "mangle prefix",
2822 .p_class = P_GLOBAL,
2823 .ptr = &Globals.mangle_prefix,
2826 .flags = FLAG_ADVANCED,
2830 .label = "default case",
2833 .ptr = &sDefault.iDefaultCase,
2835 .enum_list = enum_case,
2836 .flags = FLAG_ADVANCED | FLAG_SHARE,
2839 .label = "case sensitive",
2842 .ptr = &sDefault.iCaseSensitive,
2844 .enum_list = enum_bool_auto,
2845 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2848 .label = "casesignames",
2851 .ptr = &sDefault.iCaseSensitive,
2853 .enum_list = enum_bool_auto,
2854 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2857 .label = "preserve case",
2860 .ptr = &sDefault.bCasePreserve,
2863 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2866 .label = "short preserve case",
2869 .ptr = &sDefault.bShortCasePreserve,
2872 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2875 .label = "mangling char",
2878 .ptr = &sDefault.magic_char,
2881 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2884 .label = "hide dot files",
2887 .ptr = &sDefault.bHideDotFiles,
2890 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2893 .label = "hide special files",
2896 .ptr = &sDefault.bHideSpecialFiles,
2899 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2902 .label = "hide unreadable",
2905 .ptr = &sDefault.bHideUnReadable,
2908 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2911 .label = "hide unwriteable files",
2914 .ptr = &sDefault.bHideUnWriteableFiles,
2917 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2920 .label = "delete veto files",
2923 .ptr = &sDefault.bDeleteVetoFiles,
2926 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2929 .label = "veto files",
2932 .ptr = &sDefault.szVetoFiles,
2935 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2938 .label = "hide files",
2941 .ptr = &sDefault.szHideFiles,
2944 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2947 .label = "veto oplock files",
2950 .ptr = &sDefault.szVetoOplockFiles,
2953 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2956 .label = "map archive",
2959 .ptr = &sDefault.bMap_archive,
2962 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2965 .label = "map hidden",
2968 .ptr = &sDefault.bMap_hidden,
2971 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2974 .label = "map system",
2977 .ptr = &sDefault.bMap_system,
2980 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2983 .label = "map readonly",
2986 .ptr = &sDefault.iMap_readonly,
2988 .enum_list = enum_map_readonly,
2989 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2992 .label = "mangled names",
2995 .ptr = &sDefault.bMangledNames,
2998 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3001 .label = "max stat cache size",
3003 .p_class = P_GLOBAL,
3004 .ptr = &Globals.iMaxStatCacheSize,
3007 .flags = FLAG_ADVANCED,
3010 .label = "stat cache",
3012 .p_class = P_GLOBAL,
3013 .ptr = &Globals.bStatCache,
3016 .flags = FLAG_ADVANCED,
3019 .label = "store dos attributes",
3022 .ptr = &sDefault.bStoreDosAttributes,
3025 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3028 .label = "dmapi support",
3031 .ptr = &sDefault.bDmapiSupport,
3034 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3038 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3041 .label = "machine password timeout",
3043 .p_class = P_GLOBAL,
3044 .ptr = &Globals.machine_password_timeout,
3047 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3050 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3053 .label = "add user script",
3055 .p_class = P_GLOBAL,
3056 .ptr = &Globals.szAddUserScript,
3059 .flags = FLAG_ADVANCED,
3062 .label = "rename user script",
3064 .p_class = P_GLOBAL,
3065 .ptr = &Globals.szRenameUserScript,
3068 .flags = FLAG_ADVANCED,
3071 .label = "delete user script",
3073 .p_class = P_GLOBAL,
3074 .ptr = &Globals.szDelUserScript,
3077 .flags = FLAG_ADVANCED,
3080 .label = "add group script",
3082 .p_class = P_GLOBAL,
3083 .ptr = &Globals.szAddGroupScript,
3086 .flags = FLAG_ADVANCED,
3089 .label = "delete group script",
3091 .p_class = P_GLOBAL,
3092 .ptr = &Globals.szDelGroupScript,
3095 .flags = FLAG_ADVANCED,
3098 .label = "add user to group script",
3100 .p_class = P_GLOBAL,
3101 .ptr = &Globals.szAddUserToGroupScript,
3104 .flags = FLAG_ADVANCED,
3107 .label = "delete user from group script",
3109 .p_class = P_GLOBAL,
3110 .ptr = &Globals.szDelUserFromGroupScript,
3113 .flags = FLAG_ADVANCED,
3116 .label = "set primary group script",
3118 .p_class = P_GLOBAL,
3119 .ptr = &Globals.szSetPrimaryGroupScript,
3122 .flags = FLAG_ADVANCED,
3125 .label = "add machine script",
3127 .p_class = P_GLOBAL,
3128 .ptr = &Globals.szAddMachineScript,
3131 .flags = FLAG_ADVANCED,
3134 .label = "shutdown script",
3136 .p_class = P_GLOBAL,
3137 .ptr = &Globals.szShutdownScript,
3140 .flags = FLAG_ADVANCED,
3143 .label = "abort shutdown script",
3145 .p_class = P_GLOBAL,
3146 .ptr = &Globals.szAbortShutdownScript,
3149 .flags = FLAG_ADVANCED,
3152 .label = "username map script",
3154 .p_class = P_GLOBAL,
3155 .ptr = &Globals.szUsernameMapScript,
3158 .flags = FLAG_ADVANCED,
3161 .label = "logon script",
3163 .p_class = P_GLOBAL,
3164 .ptr = &Globals.szLogonScript,
3167 .flags = FLAG_ADVANCED,
3170 .label = "logon path",
3172 .p_class = P_GLOBAL,
3173 .ptr = &Globals.szLogonPath,
3176 .flags = FLAG_ADVANCED,
3179 .label = "logon drive",
3181 .p_class = P_GLOBAL,
3182 .ptr = &Globals.szLogonDrive,
3185 .flags = FLAG_ADVANCED,
3188 .label = "logon home",
3190 .p_class = P_GLOBAL,
3191 .ptr = &Globals.szLogonHome,
3194 .flags = FLAG_ADVANCED,
3197 .label = "domain logons",
3199 .p_class = P_GLOBAL,
3200 .ptr = &Globals.bDomainLogons,
3203 .flags = FLAG_ADVANCED,
3207 .label = "init logon delayed hosts",
3209 .p_class = P_GLOBAL,
3210 .ptr = &Globals.szInitLogonDelayedHosts,
3211 .flags = FLAG_ADVANCED,
3215 .label = "init logon delay",
3217 .p_class = P_GLOBAL,
3218 .ptr = &Globals.InitLogonDelay,
3219 .flags = FLAG_ADVANCED,
3223 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3226 .label = "os level",
3228 .p_class = P_GLOBAL,
3229 .ptr = &Globals.os_level,
3232 .flags = FLAG_BASIC | FLAG_ADVANCED,
3235 .label = "lm announce",
3237 .p_class = P_GLOBAL,
3238 .ptr = &Globals.lm_announce,
3240 .enum_list = enum_bool_auto,
3241 .flags = FLAG_ADVANCED,
3244 .label = "lm interval",
3246 .p_class = P_GLOBAL,
3247 .ptr = &Globals.lm_interval,
3250 .flags = FLAG_ADVANCED,
3253 .label = "preferred master",
3255 .p_class = P_GLOBAL,
3256 .ptr = &Globals.iPreferredMaster,
3258 .enum_list = enum_bool_auto,
3259 .flags = FLAG_BASIC | FLAG_ADVANCED,
3262 .label = "prefered master",
3264 .p_class = P_GLOBAL,
3265 .ptr = &Globals.iPreferredMaster,
3267 .enum_list = enum_bool_auto,
3271 .label = "local master",
3273 .p_class = P_GLOBAL,
3274 .ptr = &Globals.bLocalMaster,
3277 .flags = FLAG_BASIC | FLAG_ADVANCED,
3280 .label = "domain master",
3282 .p_class = P_GLOBAL,
3283 .ptr = &Globals.iDomainMaster,
3285 .enum_list = enum_bool_auto,
3286 .flags = FLAG_BASIC | FLAG_ADVANCED,
3289 .label = "browse list",
3291 .p_class = P_GLOBAL,
3292 .ptr = &Globals.bBrowseList,
3295 .flags = FLAG_ADVANCED,
3298 .label = "browseable",
3301 .ptr = &sDefault.bBrowseable,
3304 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3307 .label = "browsable",
3310 .ptr = &sDefault.bBrowseable,
3316 .label = "enhanced browsing",
3318 .p_class = P_GLOBAL,
3319 .ptr = &Globals.enhanced_browsing,
3322 .flags = FLAG_ADVANCED,
3325 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3328 .label = "dns proxy",
3330 .p_class = P_GLOBAL,
3331 .ptr = &Globals.bDNSproxy,
3334 .flags = FLAG_ADVANCED,
3337 .label = "wins proxy",
3339 .p_class = P_GLOBAL,
3340 .ptr = &Globals.bWINSproxy,
3343 .flags = FLAG_ADVANCED,
3346 .label = "wins server",
3348 .p_class = P_GLOBAL,
3349 .ptr = &Globals.szWINSservers,
3352 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3355 .label = "wins support",
3357 .p_class = P_GLOBAL,
3358 .ptr = &Globals.bWINSsupport,
3361 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3364 .label = "wins hook",
3366 .p_class = P_GLOBAL,
3367 .ptr = &Globals.szWINSHook,
3370 .flags = FLAG_ADVANCED,
3373 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3376 .label = "blocking locks",
3379 .ptr = &sDefault.bBlockingLocks,
3382 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3385 .label = "csc policy",
3388 .ptr = &sDefault.iCSCPolicy,
3390 .enum_list = enum_csc_policy,
3391 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3394 .label = "fake oplocks",
3397 .ptr = &sDefault.bFakeOplocks,
3400 .flags = FLAG_ADVANCED | FLAG_SHARE,
3403 .label = "kernel oplocks",
3405 .p_class = P_GLOBAL,
3406 .ptr = &Globals.bKernelOplocks,
3409 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3415 .ptr = &sDefault.bLocking,
3418 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3421 .label = "lock spin time",
3423 .p_class = P_GLOBAL,
3424 .ptr = &Globals.iLockSpinTime,
3427 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3433 .ptr = &sDefault.bOpLocks,
3436 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3439 .label = "level2 oplocks",
3442 .ptr = &sDefault.bLevel2OpLocks,
3445 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3448 .label = "oplock break wait time",
3450 .p_class = P_GLOBAL,
3451 .ptr = &Globals.oplock_break_wait_time,
3454 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3457 .label = "oplock contention limit",
3460 .ptr = &sDefault.iOplockContentionLimit,
3463 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3466 .label = "posix locking",
3469 .ptr = &sDefault.bPosixLocking,
3472 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3475 .label = "strict locking",
3478 .ptr = &sDefault.iStrictLocking,
3480 .enum_list = enum_bool_auto,
3481 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3484 .label = "share modes",
3487 .ptr = &sDefault.bShareModes,
3490 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3493 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3496 .label = "ldap admin dn",
3498 .p_class = P_GLOBAL,
3499 .ptr = &Globals.szLdapAdminDn,
3502 .flags = FLAG_ADVANCED,
3505 .label = "ldap delete dn",
3507 .p_class = P_GLOBAL,
3508 .ptr = &Globals.ldap_delete_dn,
3511 .flags = FLAG_ADVANCED,
3514 .label = "ldap group suffix",
3516 .p_class = P_GLOBAL,
3517 .ptr = &Globals.szLdapGroupSuffix,
3520 .flags = FLAG_ADVANCED,
3523 .label = "ldap idmap suffix",
3525 .p_class = P_GLOBAL,
3526 .ptr = &Globals.szLdapIdmapSuffix,
3529 .flags = FLAG_ADVANCED,
3532 .label = "ldap machine suffix",
3534 .p_class = P_GLOBAL,
3535 .ptr = &Globals.szLdapMachineSuffix,
3538 .flags = FLAG_ADVANCED,
3541 .label = "ldap passwd sync",
3543 .p_class = P_GLOBAL,
3544 .ptr = &Globals.ldap_passwd_sync,
3546 .enum_list = enum_ldap_passwd_sync,
3547 .flags = FLAG_ADVANCED,
3550 .label = "ldap password sync",
3552 .p_class = P_GLOBAL,
3553 .ptr = &Globals.ldap_passwd_sync,
3555 .enum_list = enum_ldap_passwd_sync,
3559 .label = "ldap replication sleep",
3561 .p_class = P_GLOBAL,
3562 .ptr = &Globals.ldap_replication_sleep,
3565 .flags = FLAG_ADVANCED,
3568 .label = "ldap suffix",
3570 .p_class = P_GLOBAL,
3571 .ptr = &Globals.szLdapSuffix,
3574 .flags = FLAG_ADVANCED,
3577 .label = "ldap ssl",
3579 .p_class = P_GLOBAL,
3580 .ptr = &Globals.ldap_ssl,
3582 .enum_list = enum_ldap_ssl,
3583 .flags = FLAG_ADVANCED,
3586 .label = "ldap timeout",
3588 .p_class = P_GLOBAL,
3589 .ptr = &Globals.ldap_timeout,
3592 .flags = FLAG_ADVANCED,
3595 .label = "ldap connection timeout",
3597 .p_class = P_GLOBAL,
3598 .ptr = &Globals.ldap_connection_timeout,
3601 .flags = FLAG_ADVANCED,
3604 .label = "ldap page size",
3606 .p_class = P_GLOBAL,
3607 .ptr = &Globals.ldap_page_size,
3610 .flags = FLAG_ADVANCED,
3613 .label = "ldap user suffix",
3615 .p_class = P_GLOBAL,
3616 .ptr = &Globals.szLdapUserSuffix,
3619 .flags = FLAG_ADVANCED,
3622 .label = "ldap debug level",
3624 .p_class = P_GLOBAL,
3625 .ptr = &Globals.ldap_debug_level,
3626 .special = handle_ldap_debug_level,
3628 .flags = FLAG_ADVANCED,
3631 .label = "ldap debug threshold",
3633 .p_class = P_GLOBAL,
3634 .ptr = &Globals.ldap_debug_threshold,
3637 .flags = FLAG_ADVANCED,
3640 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3643 .label = "eventlog list",
3645 .p_class = P_GLOBAL,
3646 .ptr = &Globals.szEventLogs,
3649 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3652 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3655 .label = "add share command",
3657 .p_class = P_GLOBAL,
3658 .ptr = &Globals.szAddShareCommand,
3661 .flags = FLAG_ADVANCED,
3664 .label = "change share command",
3666 .p_class = P_GLOBAL,
3667 .ptr = &Globals.szChangeShareCommand,
3670 .flags = FLAG_ADVANCED,
3673 .label = "delete share command",
3675 .p_class = P_GLOBAL,
3676 .ptr = &Globals.szDeleteShareCommand,
3679 .flags = FLAG_ADVANCED,
3682 .label = "config file",
3684 .p_class = P_GLOBAL,
3685 .ptr = &Globals.szConfigFile,
3693 .p_class = P_GLOBAL,
3694 .ptr = &Globals.szAutoServices,
3697 .flags = FLAG_ADVANCED,
3700 .label = "auto services",
3702 .p_class = P_GLOBAL,
3703 .ptr = &Globals.szAutoServices,
3706 .flags = FLAG_ADVANCED,
3709 .label = "lock directory",
3711 .p_class = P_GLOBAL,
3712 .ptr = &Globals.szLockDir,
3715 .flags = FLAG_ADVANCED,
3718 .label = "lock dir",
3720 .p_class = P_GLOBAL,
3721 .ptr = &Globals.szLockDir,
3727 .label = "pid directory",
3729 .p_class = P_GLOBAL,
3730 .ptr = &Globals.szPidDir,
3733 .flags = FLAG_ADVANCED,
3737 .label = "utmp directory",
3739 .p_class = P_GLOBAL,
3740 .ptr = &Globals.szUtmpDir,
3743 .flags = FLAG_ADVANCED,
3746 .label = "wtmp directory",
3748 .p_class = P_GLOBAL,
3749 .ptr = &Globals.szWtmpDir,
3752 .flags = FLAG_ADVANCED,
3757 .p_class = P_GLOBAL,
3758 .ptr = &Globals.bUtmp,
3761 .flags = FLAG_ADVANCED,
3765 .label = "default service",
3767 .p_class = P_GLOBAL,
3768 .ptr = &Globals.szDefaultService,
3771 .flags = FLAG_ADVANCED,
3776 .p_class = P_GLOBAL,
3777 .ptr = &Globals.szDefaultService,
3780 .flags = FLAG_ADVANCED,
3783 .label = "message command",
3785 .p_class = P_GLOBAL,
3786 .ptr = &Globals.szMsgCommand,
3789 .flags = FLAG_ADVANCED,
3792 .label = "dfree cache time",
3795 .ptr = &sDefault.iDfreeCacheTime,
3798 .flags = FLAG_ADVANCED,
3801 .label = "dfree command",
3804 .ptr = &sDefault.szDfree,
3807 .flags = FLAG_ADVANCED,
3810 .label = "get quota command",
3812 .p_class = P_GLOBAL,
3813 .ptr = &Globals.szGetQuota,
3816 .flags = FLAG_ADVANCED,
3819 .label = "set quota command",
3821 .p_class = P_GLOBAL,
3822 .ptr = &Globals.szSetQuota,
3825 .flags = FLAG_ADVANCED,
3828 .label = "remote announce",
3830 .p_class = P_GLOBAL,
3831 .ptr = &Globals.szRemoteAnnounce,
3834 .flags = FLAG_ADVANCED,
3837 .label = "remote browse sync",
3839 .p_class = P_GLOBAL,
3840 .ptr = &Globals.szRemoteBrowseSync,
3843 .flags = FLAG_ADVANCED,
3846 .label = "socket address",
3848 .p_class = P_GLOBAL,
3849 .ptr = &Globals.szSocketAddress,
3852 .flags = FLAG_ADVANCED,
3855 .label = "homedir map",
3857 .p_class = P_GLOBAL,
3858 .ptr = &Globals.szNISHomeMapName,
3861 .flags = FLAG_ADVANCED,
3864 .label = "afs username map",
3866 .p_class = P_GLOBAL,
3867 .ptr = &Globals.szAfsUsernameMap,
3870 .flags = FLAG_ADVANCED,
3873 .label = "afs token lifetime",
3875 .p_class = P_GLOBAL,
3876 .ptr = &Globals.iAfsTokenLifetime,
3879 .flags = FLAG_ADVANCED,
3882 .label = "log nt token command",
3884 .p_class = P_GLOBAL,
3885 .ptr = &Globals.szLogNtTokenCommand,
3888 .flags = FLAG_ADVANCED,
3891 .label = "time offset",
3893 .p_class = P_GLOBAL,
3894 .ptr = &extra_time_offset,
3897 .flags = FLAG_ADVANCED,
3900 .label = "NIS homedir",
3902 .p_class = P_GLOBAL,
3903 .ptr = &Globals.bNISHomeMap,
3906 .flags = FLAG_ADVANCED,
3912 .ptr = &sDefault.valid,
3921 .ptr = &sDefault.szCopy,
3922 .special = handle_copy,
3930 .ptr = &sDefault.szInclude,
3931 .special = handle_include,
3939 .ptr = &sDefault.szPreExec,
3942 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3948 .ptr = &sDefault.szPreExec,
3951 .flags = FLAG_ADVANCED,
3954 .label = "preexec close",
3957 .ptr = &sDefault.bPreexecClose,
3960 .flags = FLAG_ADVANCED | FLAG_SHARE,
3963 .label = "postexec",
3966 .ptr = &sDefault.szPostExec,
3969 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3972 .label = "root preexec",
3975 .ptr = &sDefault.szRootPreExec,
3978 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3981 .label = "root preexec close",
3984 .ptr = &sDefault.bRootpreexecClose,
3987 .flags = FLAG_ADVANCED | FLAG_SHARE,
3990 .label = "root postexec",
3993 .ptr = &sDefault.szRootPostExec,
3996 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3999 .label = "available",
4002 .ptr = &sDefault.bAvailable,
4005 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4008 .label = "registry shares",
4010 .p_class = P_GLOBAL,
4011 .ptr = &Globals.bRegistryShares,
4014 .flags = FLAG_ADVANCED,
4017 .label = "usershare allow guests",
4019 .p_class = P_GLOBAL,
4020 .ptr = &Globals.bUsershareAllowGuests,
4023 .flags = FLAG_ADVANCED,
4026 .label = "usershare max shares",
4028 .p_class = P_GLOBAL,
4029 .ptr = &Globals.iUsershareMaxShares,
4032 .flags = FLAG_ADVANCED,
4035 .label = "usershare owner only",
4037 .p_class = P_GLOBAL,
4038 .ptr = &Globals.bUsershareOwnerOnly,
4041 .flags = FLAG_ADVANCED,
4044 .label = "usershare path",
4046 .p_class = P_GLOBAL,
4047 .ptr = &Globals.szUsersharePath,
4050 .flags = FLAG_ADVANCED,
4053 .label = "usershare prefix allow list",
4055 .p_class = P_GLOBAL,
4056 .ptr = &Globals.szUsersharePrefixAllowList,
4059 .flags = FLAG_ADVANCED,
4062 .label = "usershare prefix deny list",
4064 .p_class = P_GLOBAL,
4065 .ptr = &Globals.szUsersharePrefixDenyList,
4068 .flags = FLAG_ADVANCED,
4071 .label = "usershare template share",
4073 .p_class = P_GLOBAL,
4074 .ptr = &Globals.szUsershareTemplateShare,
4077 .flags = FLAG_ADVANCED,
4083 .ptr = &sDefault.volume,
4086 .flags = FLAG_ADVANCED | FLAG_SHARE,
4092 .ptr = &sDefault.fstype,
4095 .flags = FLAG_ADVANCED | FLAG_SHARE,
4098 .label = "set directory",
4101 .ptr = &sDefault.bNo_set_dir,
4104 .flags = FLAG_ADVANCED | FLAG_SHARE,
4107 .label = "wide links",
4110 .ptr = &sDefault.bWidelinks,
4113 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4116 .label = "follow symlinks",
4119 .ptr = &sDefault.bSymlinks,
4122 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4125 .label = "dont descend",
4128 .ptr = &sDefault.szDontdescend,
4131 .flags = FLAG_ADVANCED | FLAG_SHARE,
4134 .label = "magic script",
4137 .ptr = &sDefault.szMagicScript,
4140 .flags = FLAG_ADVANCED | FLAG_SHARE,
4143 .label = "magic output",
4146 .ptr = &sDefault.szMagicOutput,
4149 .flags = FLAG_ADVANCED | FLAG_SHARE,
4152 .label = "delete readonly",
4155 .ptr = &sDefault.bDeleteReadonly,
4158 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4161 .label = "dos filemode",
4164 .ptr = &sDefault.bDosFilemode,
4167 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4170 .label = "dos filetimes",
4173 .ptr = &sDefault.bDosFiletimes,
4176 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4179 .label = "dos filetime resolution",
4182 .ptr = &sDefault.bDosFiletimeResolution,
4185 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4188 .label = "fake directory create times",
4191 .ptr = &sDefault.bFakeDirCreateTimes,
4194 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4197 .label = "panic action",
4199 .p_class = P_GLOBAL,
4200 .ptr = &Globals.szPanicAction,
4203 .flags = FLAG_ADVANCED,
4206 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4209 .label = "vfs objects",
4212 .ptr = &sDefault.szVfsObjects,
4215 .flags = FLAG_ADVANCED | FLAG_SHARE,
4218 .label = "vfs object",
4221 .ptr = &sDefault.szVfsObjects,
4228 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4231 .label = "msdfs root",
4234 .ptr = &sDefault.bMSDfsRoot,
4237 .flags = FLAG_ADVANCED | FLAG_SHARE,
4240 .label = "msdfs proxy",
4243 .ptr = &sDefault.szMSDfsProxy,
4246 .flags = FLAG_ADVANCED | FLAG_SHARE,
4249 .label = "host msdfs",
4251 .p_class = P_GLOBAL,
4252 .ptr = &Globals.bHostMSDfs,
4255 .flags = FLAG_ADVANCED,
4258 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4261 .label = "passdb expand explicit",
4263 .p_class = P_GLOBAL,
4264 .ptr = &Globals.bPassdbExpandExplicit,
4267 .flags = FLAG_ADVANCED,
4270 .label = "idmap backend",
4272 .p_class = P_GLOBAL,
4273 .ptr = &Globals.szIdmapBackend,
4276 .flags = FLAG_ADVANCED,
4279 .label = "idmap alloc backend",
4281 .p_class = P_GLOBAL,
4282 .ptr = &Globals.szIdmapAllocBackend,
4285 .flags = FLAG_ADVANCED,
4288 .label = "idmap cache time",
4290 .p_class = P_GLOBAL,
4291 .ptr = &Globals.iIdmapCacheTime,
4294 .flags = FLAG_ADVANCED,
4297 .label = "idmap negative cache time",
4299 .p_class = P_GLOBAL,
4300 .ptr = &Globals.iIdmapNegativeCacheTime,
4303 .flags = FLAG_ADVANCED,
4306 .label = "idmap uid",
4308 .p_class = P_GLOBAL,
4309 .ptr = &Globals.szIdmapUID,
4310 .special = handle_idmap_uid,
4312 .flags = FLAG_ADVANCED,
4315 .label = "winbind uid",
4317 .p_class = P_GLOBAL,
4318 .ptr = &Globals.szIdmapUID,
4319 .special = handle_idmap_uid,
4324 .label = "idmap gid",
4326 .p_class = P_GLOBAL,
4327 .ptr = &Globals.szIdmapGID,
4328 .special = handle_idmap_gid,
4330 .flags = FLAG_ADVANCED,
4333 .label = "winbind gid",
4335 .p_class = P_GLOBAL,
4336 .ptr = &Globals.szIdmapGID,
4337 .special = handle_idmap_gid,
4342 .label = "template homedir",
4344 .p_class = P_GLOBAL,
4345 .ptr = &Globals.szTemplateHomedir,
4348 .flags = FLAG_ADVANCED,
4351 .label = "template shell",
4353 .p_class = P_GLOBAL,
4354 .ptr = &Globals.szTemplateShell,
4357 .flags = FLAG_ADVANCED,
4360 .label = "winbind separator",
4362 .p_class = P_GLOBAL,
4363 .ptr = &Globals.szWinbindSeparator,
4366 .flags = FLAG_ADVANCED,
4369 .label = "winbind cache time",
4371 .p_class = P_GLOBAL,
4372 .ptr = &Globals.winbind_cache_time,
4375 .flags = FLAG_ADVANCED,
4378 .label = "winbind reconnect delay",
4380 .p_class = P_GLOBAL,
4381 .ptr = &Globals.winbind_reconnect_delay,
4384 .flags = FLAG_ADVANCED,
4387 .label = "winbind enum users",
4389 .p_class = P_GLOBAL,
4390 .ptr = &Globals.bWinbindEnumUsers,
4393 .flags = FLAG_ADVANCED,
4396 .label = "winbind enum groups",
4398 .p_class = P_GLOBAL,
4399 .ptr = &Globals.bWinbindEnumGroups,
4402 .flags = FLAG_ADVANCED,
4405 .label = "winbind use default domain",
4407 .p_class = P_GLOBAL,
4408 .ptr = &Globals.bWinbindUseDefaultDomain,
4411 .flags = FLAG_ADVANCED,
4414 .label = "winbind trusted domains only",
4416 .p_class = P_GLOBAL,
4417 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4420 .flags = FLAG_ADVANCED,
4423 .label = "winbind nested groups",
4425 .p_class = P_GLOBAL,
4426 .ptr = &Globals.bWinbindNestedGroups,
4429 .flags = FLAG_ADVANCED,
4432 .label = "winbind expand groups",
4434 .p_class = P_GLOBAL,
4435 .ptr = &Globals.winbind_expand_groups,
4438 .flags = FLAG_ADVANCED,
4441 .label = "winbind nss info",
4443 .p_class = P_GLOBAL,
4444 .ptr = &Globals.szWinbindNssInfo,
4447 .flags = FLAG_ADVANCED,
4450 .label = "winbind refresh tickets",
4452 .p_class = P_GLOBAL,
4453 .ptr = &Globals.bWinbindRefreshTickets,
4456 .flags = FLAG_ADVANCED,
4459 .label = "winbind offline logon",
4461 .p_class = P_GLOBAL,
4462 .ptr = &Globals.bWinbindOfflineLogon,
4465 .flags = FLAG_ADVANCED,
4468 .label = "winbind normalize names",
4470 .p_class = P_GLOBAL,
4471 .ptr = &Globals.bWinbindNormalizeNames,
4474 .flags = FLAG_ADVANCED,
4477 .label = "winbind rpc only",
4479 .p_class = P_GLOBAL,
4480 .ptr = &Globals.bWinbindRpcOnly,
4483 .flags = FLAG_ADVANCED,
4486 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4489 /***************************************************************************
4490 Initialise the sDefault parameter structure for the printer values.
4491 ***************************************************************************/
4493 static void init_printer_values(struct service *pService)
4495 /* choose defaults depending on the type of printing */
4496 switch (pService->iPrinting) {
4501 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4502 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4503 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4508 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4509 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4510 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4511 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4512 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4513 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4514 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4520 /* set the lpq command to contain the destination printer
4521 name only. This is used by cups_queue_get() */
4522 string_set(&pService->szLpqcommand, "%p");
4523 string_set(&pService->szLprmcommand, "");
4524 string_set(&pService->szPrintcommand, "");
4525 string_set(&pService->szLppausecommand, "");
4526 string_set(&pService->szLpresumecommand, "");
4527 string_set(&pService->szQueuepausecommand, "");
4528 string_set(&pService->szQueueresumecommand, "");
4530 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4531 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4532 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4533 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4534 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4535 string_set(&pService->szQueuepausecommand, "disable '%p'");
4536 string_set(&pService->szQueueresumecommand, "enable '%p'");
4537 #endif /* HAVE_CUPS */
4542 string_set(&pService->szLpqcommand, "lpstat -o%p");
4543 string_set(&pService->szLprmcommand, "cancel %p-%j");
4544 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4545 string_set(&pService->szQueuepausecommand, "disable %p");
4546 string_set(&pService->szQueueresumecommand, "enable %p");
4548 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4549 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4554 string_set(&pService->szLpqcommand, "lpq -P%p");
4555 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4556 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4562 string_set(&pService->szPrintcommand, "vlp print %p %s");
4563 string_set(&pService->szLpqcommand, "vlp lpq %p");
4564 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4565 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4566 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4567 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4568 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4570 #endif /* DEVELOPER */
4576 * Free the allocated data for one parameter for a given share.
4578 static void free_parameter(int snum, struct parm_struct parm)
4582 if (parm.ptr == NULL); {
4587 parm_ptr = parm.ptr;
4588 } else if (parm.p_class != P_LOCAL) {
4591 parm_ptr = lp_local_ptr(snum, parm.ptr);
4594 if ((parm.type == P_STRING) ||
4595 (parm.type == P_USTRING))
4597 string_free((char**)parm_ptr);
4598 } else if (parm.type == P_LIST) {
4599 TALLOC_FREE(*((char***)parm_ptr));
4604 * Free the allocated parameter data for a share.
4606 static void free_parameters(int snum)
4610 for (i=0; parm_table[i].label; i++) {
4611 free_parameter(snum, parm_table[i]);
4616 * Free the allocated global parameters.
4618 static void free_global_parameters(void)
4620 free_parameters(GLOBAL_SECTION_SNUM);
4623 /***************************************************************************
4624 Initialise the global parameter structure.
4625 ***************************************************************************/
4627 static void init_globals(bool first_time_only)
4629 static bool done_init = False;
4633 /* If requested to initialize only once and we've already done it... */
4634 if (first_time_only && done_init) {
4635 /* ... then we have nothing more to do */
4640 /* The logfile can be set before this is invoked. Free it if so. */
4641 if (Globals.szLogFile != NULL) {
4642 string_free(&Globals.szLogFile);
4643 Globals.szLogFile = NULL;
4647 free_global_parameters();
4650 memset((void *)&Globals, '\0', sizeof(Globals));
4652 for (i = 0; parm_table[i].label; i++) {
4653 if ((parm_table[i].type == P_STRING ||
4654 parm_table[i].type == P_USTRING) &&
4657 string_set((char **)parm_table[i].ptr, "");
4661 string_set(&sDefault.fstype, FSTYPE_STRING);
4662 string_set(&sDefault.szPrintjobUsername, "%U");
4664 init_printer_values(&sDefault);
4667 DEBUG(3, ("Initialising global parameters\n"));
4669 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4670 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4672 /* use the new 'hash2' method by default, with a prefix of 1 */
4673 string_set(&Globals.szManglingMethod, "hash2");
4674 Globals.mangle_prefix = 1;
4676 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4678 /* using UTF8 by default allows us to support all chars */
4679 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4681 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4682 /* If the system supports nl_langinfo(), try to grab the value
4683 from the user's locale */
4684 string_set(&Globals.display_charset, "LOCALE");
4686 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4689 /* Use codepage 850 as a default for the dos character set */
4690 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4693 * Allow the default PASSWD_CHAT to be overridden in local.h.
4695 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4697 set_global_myname(myhostname());
4698 string_set(&Globals.szNetbiosName,global_myname());
4700 set_global_myworkgroup(WORKGROUP);
4701 string_set(&Globals.szWorkgroup, lp_workgroup());
4703 string_set(&Globals.szPasswdProgram, "");
4704 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4705 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4706 string_set(&Globals.szSocketAddress, "0.0.0.0");
4708 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4709 smb_panic("init_globals: ENOMEM");
4711 string_set(&Globals.szServerString, s);
4713 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4714 DEFAULT_MINOR_VERSION) < 0) {
4715 smb_panic("init_globals: ENOMEM");
4717 string_set(&Globals.szAnnounceVersion, s);
4720 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4723 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4725 string_set(&Globals.szLogonDrive, "");
4726 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4727 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4728 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4730 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4731 string_set(&Globals.szPasswordServer, "*");
4733 Globals.AlgorithmicRidBase = BASE_RID;
4735 Globals.bLoadPrinters = True;
4736 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4738 Globals.ConfigBackend = config_backend;
4740 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4741 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4742 Globals.max_xmit = 0x4104;
4743 Globals.max_mux = 50; /* This is *needed* for profile support. */
4744 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4745 Globals.bDisableSpoolss = False;
4746 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4747 Globals.pwordlevel = 0;
4748 Globals.unamelevel = 0;
4749 Globals.deadtime = 0;
4750 Globals.getwd_cache = true;
4751 Globals.bLargeReadwrite = True;
4752 Globals.max_log_size = 5000;
4753 Globals.max_open_files = MAX_OPEN_FILES;
4754 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4755 Globals.maxprotocol = PROTOCOL_NT1;
4756 Globals.minprotocol = PROTOCOL_CORE;
4757 Globals.security = SEC_USER;
4758 Globals.paranoid_server_security = True;
4759 Globals.bEncryptPasswords = True;
4760 Globals.bUpdateEncrypt = False;
4761 Globals.clientSchannel = Auto;
4762 Globals.serverSchannel = Auto;
4763 Globals.bReadRaw = True;
4764 Globals.bWriteRaw = True;
4765 Globals.bNullPasswords = False;
4766 Globals.bObeyPamRestrictions = False;
4768 Globals.bSyslogOnly = False;
4769 Globals.bTimestampLogs = True;
4770 string_set(&Globals.szLogLevel, "0");
4771 Globals.bDebugPrefixTimestamp = False;
4772 Globals.bDebugHiresTimestamp = False;
4773 Globals.bDebugPid = False;
4774 Globals.bDebugUid = False;
4775 Globals.bDebugClass = False;
4776 Globals.bEnableCoreFiles = True;
4777 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4778 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4779 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4780 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4781 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4782 Globals.lm_interval = 60;
4783 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4784 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4785 Globals.bNISHomeMap = False;
4786 #ifdef WITH_NISPLUS_HOME
4787 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4789 string_set(&Globals.szNISHomeMapName, "auto.home");
4792 Globals.bTimeServer = False;
4793 Globals.bBindInterfacesOnly = False;
4794 Globals.bUnixPasswdSync = False;
4795 Globals.bPamPasswordChange = False;
4796 Globals.bPasswdChatDebug = False;
4797 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4798 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4799 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4800 Globals.bStatCache = True; /* use stat cache by default */
4801 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4802 Globals.restrict_anonymous = 0;
4803 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4804 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4805 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4806 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4807 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4808 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4810 Globals.map_to_guest = 0; /* By Default, "Never" */
4811 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4812 Globals.enhanced_browsing = true;
4813 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4814 #ifdef MMAP_BLACKLIST
4815 Globals.bUseMmap = False;
4817 Globals.bUseMmap = True;
4819 Globals.bUnixExtensions = True;
4820 Globals.bResetOnZeroVC = False;
4822 /* hostname lookups can be very expensive and are broken on
4823 a large number of sites (tridge) */
4824 Globals.bHostnameLookups = False;
4826 string_set(&Globals.szPassdbBackend, "smbpasswd");
4827 string_set(&Globals.szLdapSuffix, "");
4828 string_set(&Globals.szLdapMachineSuffix, "");
4829 string_set(&Globals.szLdapUserSuffix, "");
4830 string_set(&Globals.szLdapGroupSuffix, "");
4831 string_set(&Globals.szLdapIdmapSuffix, "");
4833 string_set(&Globals.szLdapAdminDn, "");
4834 Globals.ldap_ssl = LDAP_SSL_ON;
4835 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4836 Globals.ldap_delete_dn = False;
4837 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4838 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4839 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4840 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4842 Globals.ldap_debug_level = 0;
4843 Globals.ldap_debug_threshold = 10;
4845 /* This is what we tell the afs client. in reality we set the token
4846 * to never expire, though, when this runs out the afs client will
4847 * forget the token. Set to 0 to get NEVERDATE.*/
4848 Globals.iAfsTokenLifetime = 604800;
4849 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
4851 /* these parameters are set to defaults that are more appropriate
4852 for the increasing samba install base:
4854 as a member of the workgroup, that will possibly become a
4855 _local_ master browser (lm = True). this is opposed to a forced
4856 local master browser startup (pm = True).
4858 doesn't provide WINS server service by default (wsupp = False),
4859 and doesn't provide domain master browser services by default, either.
4863 Globals.bMsAddPrinterWizard = True;
4864 Globals.os_level = 20;
4865 Globals.bLocalMaster = True;
4866 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4867 Globals.bDomainLogons = False;
4868 Globals.bBrowseList = True;
4869 Globals.bWINSsupport = False;
4870 Globals.bWINSproxy = False;
4872 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
4873 Globals.InitLogonDelay = 100; /* 100 ms default delay */
4875 Globals.bDNSproxy = True;
4877 /* this just means to use them if they exist */
4878 Globals.bKernelOplocks = True;
4880 Globals.bAllowTrustedDomains = True;
4881 string_set(&Globals.szIdmapBackend, "tdb");
4883 string_set(&Globals.szTemplateShell, "/bin/false");
4884 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4885 string_set(&Globals.szWinbindSeparator, "\\");
4887 string_set(&Globals.szCupsServer, "");
4888 string_set(&Globals.szIPrintServer, "");
4890 string_set(&Globals.ctdbdSocket, "");
4891 Globals.szClusterAddresses = NULL;
4892 Globals.clustering = False;
4894 Globals.winbind_cache_time = 300; /* 5 minutes */
4895 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
4896 Globals.bWinbindEnumUsers = False;
4897 Globals.bWinbindEnumGroups = False;
4898 Globals.bWinbindUseDefaultDomain = False;
4899 Globals.bWinbindTrustedDomainsOnly = False;
4900 Globals.bWinbindNestedGroups = True;
4901 Globals.winbind_expand_groups = 1;
4902 Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4903 Globals.bWinbindRefreshTickets = False;
4904 Globals.bWinbindOfflineLogon = False;
4906 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
4907 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4909 Globals.bPassdbExpandExplicit = False;
4911 Globals.name_cache_timeout = 660; /* In seconds */
4913 Globals.bUseSpnego = True;
4914 Globals.bClientUseSpnego = True;
4916 Globals.client_signing = Auto;
4917 Globals.server_signing = False;
4919 Globals.bDeferSharingViolations = True;
4920 string_set(&Globals.smb_ports, SMB_PORTS);
4922 Globals.bEnablePrivileges = True;
4923 Globals.bHostMSDfs = True;
4924 Globals.bASUSupport = False;
4926 /* User defined shares. */
4927 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4928 smb_panic("init_globals: ENOMEM");
4930 string_set(&Globals.szUsersharePath, s);
4932 string_set(&Globals.szUsershareTemplateShare, "");
4933 Globals.iUsershareMaxShares = 0;
4934 /* By default disallow sharing of directories not owned by the sharer. */
4935 Globals.bUsershareOwnerOnly = True;
4936 /* By default disallow guest access to usershares. */
4937 Globals.bUsershareAllowGuests = False;
4939 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4941 /* By default no shares out of the registry */
4942 Globals.bRegistryShares = False;
4944 Globals.iminreceivefile = 0;
4947 /*******************************************************************
4948 Convenience routine to grab string parameters into temporary memory
4949 and run standard_sub_basic on them. The buffers can be written to by
4950 callers without affecting the source string.
4951 ********************************************************************/
4953 static char *lp_string(const char *s)
4956 TALLOC_CTX *ctx = talloc_tos();
4958 /* The follow debug is useful for tracking down memory problems
4959 especially if you have an inner loop that is calling a lp_*()
4960 function that returns a string. Perhaps this debug should be
4961 present all the time? */
4964 DEBUG(10, ("lp_string(%s)\n", s));
4967 ret = talloc_sub_basic(ctx,
4968 get_current_username(),
4969 current_user_info.domain,
4971 if (trim_char(ret, '\"', '\"')) {
4972 if (strchr(ret,'\"') != NULL) {
4974 ret = talloc_sub_basic(ctx,
4975 get_current_username(),
4976 current_user_info.domain,
4984 In this section all the functions that are used to access the
4985 parameters from the rest of the program are defined
4988 #define FN_GLOBAL_STRING(fn_name,ptr) \
4989 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4990 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4991 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4992 #define FN_GLOBAL_LIST(fn_name,ptr) \
4993 const char **fn_name(void) {return(*(const char ***)(ptr));}
4994 #define FN_GLOBAL_BOOL(fn_name,ptr) \
4995 bool fn_name(void) {return(*(bool *)(ptr));}
4996 #define FN_GLOBAL_CHAR(fn_name,ptr) \
4997 char fn_name(void) {return(*(char *)(ptr));}
4998 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
4999 int fn_name(void) {return(*(int *)(ptr));}
5001 #define FN_LOCAL_STRING(fn_name,val) \
5002 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5003 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5004 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5005 #define FN_LOCAL_LIST(fn_name,val) \
5006 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5007 #define FN_LOCAL_BOOL(fn_name,val) \
5008 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5009 #define FN_LOCAL_INTEGER(fn_name,val) \
5010 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5012 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5013 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5014 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5015 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5016 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5017 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));}
5018 #define FN_LOCAL_CHAR(fn_name,val) \
5019 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5021 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5022 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5023 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5024 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5025 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5026 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5027 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5028 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5029 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5030 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5031 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5032 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5033 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5034 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5035 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5036 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5037 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5038 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5039 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5040 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5041 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5042 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5043 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5044 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5045 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5046 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5047 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5048 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5049 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5050 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5051 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5052 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5053 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5054 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5055 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5056 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5057 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5058 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5059 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5060 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5061 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5062 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5063 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5064 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5065 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5066 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
5067 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5068 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5069 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5070 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5071 * lp_passdb_backend() should be replace by the this macro again after
5074 const char *lp_passdb_backend(void)
5076 char *delim, *quote;
5078 delim = strchr( Globals.szPassdbBackend, ' ');
5079 /* no space at all */
5080 if (delim == NULL) {
5084 quote = strchr(Globals.szPassdbBackend, '"');
5085 /* no quote char or non in the first part */
5086 if (quote == NULL || quote > delim) {
5091 quote = strchr(quote+1, '"');
5092 if (quote == NULL) {
5093 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5095 } else if (*(quote+1) == '\0') {
5096 /* space, fitting quote char, and one backend only */
5099 /* terminate string after the fitting quote char */
5104 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5105 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5106 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5107 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5110 return Globals.szPassdbBackend;
5112 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5113 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5114 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5115 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5116 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5118 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5119 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5120 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5121 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5122 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5123 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5125 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5127 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5128 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5129 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5131 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5133 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5134 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5135 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5136 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5137 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5138 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5139 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5140 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5141 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5142 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5143 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5144 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5145 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5146 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5147 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5149 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5150 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5151 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5152 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5153 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5154 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5156 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5157 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5158 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5159 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5160 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5161 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5162 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5163 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5164 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5165 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5166 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5167 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5168 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5169 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5170 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5171 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5172 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5174 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5176 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5177 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5178 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5179 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5180 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5181 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5182 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5183 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5184 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5185 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5186 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5187 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5188 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5189 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5190 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5191 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5192 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5193 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5194 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5195 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5196 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5197 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5198 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5199 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5200 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5201 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5202 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5203 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5204 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5205 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5206 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5207 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5208 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5209 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5210 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5211 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5212 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5213 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5214 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5215 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5216 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5217 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5218 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5219 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5220 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5221 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5222 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5223 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5224 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5225 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5226 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5227 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5228 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5229 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5230 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5231 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5232 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5233 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5234 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5235 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5236 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5237 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5238 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5239 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5240 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5241 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5242 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5243 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5244 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5245 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5246 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5247 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5248 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5249 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5250 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5251 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5252 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5253 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5254 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5255 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5256 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5257 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5258 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5259 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5260 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5261 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5262 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5263 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5264 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5265 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5266 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5267 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5268 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5269 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5270 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5271 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5272 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5273 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5275 FN_LOCAL_STRING(lp_preexec, szPreExec)
5276 FN_LOCAL_STRING(lp_postexec, szPostExec)
5277 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5278 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5279 FN_LOCAL_STRING(lp_servicename, szService)
5280 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5281 FN_LOCAL_STRING(lp_pathname, szPath)
5282 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5283 FN_LOCAL_STRING(lp_username, szUsername)
5284 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5285 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5286 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5287 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5288 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5289 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5290 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5291 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5292 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5293 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5294 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5295 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5296 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5297 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5298 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5299 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5300 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5301 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5302 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5303 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5304 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5305 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5306 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5307 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5308 FN_LOCAL_STRING(lp_comment, comment)
5309 FN_LOCAL_STRING(lp_force_user, force_user)
5310 FN_LOCAL_STRING(lp_force_group, force_group)
5311 FN_LOCAL_LIST(lp_readlist, readlist)
5312 FN_LOCAL_LIST(lp_writelist, writelist)
5313 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5314 FN_LOCAL_STRING(lp_fstype, fstype)
5315 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5316 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5317 static FN_LOCAL_STRING(lp_volume, volume)
5318 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5319 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5320 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5321 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5322 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5323 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5324 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5325 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5326 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5327 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5328 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5329 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5330 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5331 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5332 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5333 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5334 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5335 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5336 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5337 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5338 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5339 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5340 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5341 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5342 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5343 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5344 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5345 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5346 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5347 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5348 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5349 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5350 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5351 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5352 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5353 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5354 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5355 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5356 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5357 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5358 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5359 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5360 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5361 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5362 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5363 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5364 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5365 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5366 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5367 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5368 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5369 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5370 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5371 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5372 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5373 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5374 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5375 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5376 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5377 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5378 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5379 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5380 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5381 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5382 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5383 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5384 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5385 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5386 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5387 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5388 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5389 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5390 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5391 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5392 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5393 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5394 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5395 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5396 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5397 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5398 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5399 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5400 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5401 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5402 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5403 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5404 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5405 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5406 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5407 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5408 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5409 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5410 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5411 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5412 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5413 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5414 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5415 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5417 /* local prototypes */
5419 static int map_parameter(const char *pszParmName);
5420 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5421 static const char *get_boolean(bool bool_value);
5422 static int getservicebyname(const char *pszServiceName,
5423 struct service *pserviceDest);
5424 static void copy_service(struct service *pserviceDest,
5425 struct service *pserviceSource,
5426 struct bitmap *pcopymapDest);
5427 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5429 static bool do_section(const char *pszSectionName, void *userdata);
5430 static void init_copymap(struct service *pservice);
5431 static bool hash_a_service(const char *name, int number);
5432 static void free_service_byindex(int iService);
5433 static void free_param_opts(struct param_opt_struct **popts);
5434 static char * canonicalize_servicename(const char *name);
5435 static void show_parameter(int parmIndex);
5436 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5439 * This is a helper function for parametrical options support. It returns a
5440 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5441 * parametrical functions are quite simple
5443 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5446 bool global_section = False;
5448 struct param_opt_struct *data;
5450 if (snum >= iNumServices) return NULL;
5453 data = Globals.param_opt;
5454 global_section = True;
5456 data = ServicePtrs[snum]->param_opt;
5459 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5460 DEBUG(0,("asprintf failed!\n"));
5465 if (strwicmp(data->key, param_key) == 0) {
5466 string_free(¶m_key);
5472 if (!global_section) {
5473 /* Try to fetch the same option but from globals */
5474 /* but only if we are not already working with Globals */
5475 data = Globals.param_opt;
5477 if (strwicmp(data->key, param_key) == 0) {
5478 string_free(¶m_key);
5485 string_free(¶m_key);
5491 #define MISSING_PARAMETER(name) \
5492 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5494 /*******************************************************************
5495 convenience routine to return int parameters.
5496 ********************************************************************/
5497 static int lp_int(const char *s)
5501 MISSING_PARAMETER(lp_int);
5505 return (int)strtol(s, NULL, 0);
5508 /*******************************************************************
5509 convenience routine to return unsigned long parameters.
5510 ********************************************************************/
5511 static unsigned long lp_ulong(const char *s)
5515 MISSING_PARAMETER(lp_ulong);
5519 return strtoul(s, NULL, 0);
5522 /*******************************************************************
5523 convenience routine to return boolean parameters.
5524 ********************************************************************/
5525 static bool lp_bool(const char *s)
5530 MISSING_PARAMETER(lp_bool);
5534 if (!set_boolean(s, &ret)) {
5535 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5542 /*******************************************************************
5543 convenience routine to return enum parameters.
5544 ********************************************************************/
5545 static int lp_enum(const char *s,const struct enum_list *_enum)
5549 if (!s || !*s || !_enum) {
5550 MISSING_PARAMETER(lp_enum);
5554 for (i=0; _enum[i].name; i++) {
5555 if (strequal(_enum[i].name,s))
5556 return _enum[i].value;
5559 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5563 #undef MISSING_PARAMETER
5565 /* DO NOT USE lp_parm_string ANYMORE!!!!
5566 * use lp_parm_const_string or lp_parm_talloc_string
5568 * lp_parm_string is only used to let old modules find this symbol
5570 #undef lp_parm_string
5571 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5572 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5574 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5577 /* Return parametric option from a given service. Type is a part of option before ':' */
5578 /* Parametric option has following syntax: 'Type: option = value' */
5579 /* the returned value is talloced on the talloc_tos() */
5580 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5582 struct param_opt_struct *data = get_parametrics(snum, type, option);
5584 if (data == NULL||data->value==NULL) {
5586 return lp_string(def);
5592 return lp_string(data->value);
5595 /* Return parametric option from a given service. Type is a part of option before ':' */
5596 /* Parametric option has following syntax: 'Type: option = value' */
5597 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5599 struct param_opt_struct *data = get_parametrics(snum, type, option);
5601 if (data == NULL||data->value==NULL)
5607 /* Return parametric option from a given service. Type is a part of option before ':' */
5608 /* Parametric option has following syntax: 'Type: option = value' */
5610 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5612 struct param_opt_struct *data = get_parametrics(snum, type, option);
5614 if (data == NULL||data->value==NULL)
5615 return (const char **)def;
5617 if (data->list==NULL) {
5618 data->list = str_list_make(NULL, data->value, NULL);
5621 return (const char **)data->list;
5624 /* Return parametric option from a given service. Type is a part of option before ':' */
5625 /* Parametric option has following syntax: 'Type: option = value' */
5627 int lp_parm_int(int snum, const char *type, const char *option, int def)
5629 struct param_opt_struct *data = get_parametrics(snum, type, option);
5631 if (data && data->value && *data->value)
5632 return lp_int(data->value);
5637 /* Return parametric option from a given service. Type is a part of option before ':' */
5638 /* Parametric option has following syntax: 'Type: option = value' */
5640 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5642 struct param_opt_struct *data = get_parametrics(snum, type, option);
5644 if (data && data->value && *data->value)
5645 return lp_ulong(data->value);
5650 /* Return parametric option from a given service. Type is a part of option before ':' */
5651 /* Parametric option has following syntax: 'Type: option = value' */
5653 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5655 struct param_opt_struct *data = get_parametrics(snum, type, option);
5657 if (data && data->value && *data->value)
5658 return lp_bool(data->value);
5663 /* Return parametric option from a given service. Type is a part of option before ':' */
5664 /* Parametric option has following syntax: 'Type: option = value' */
5666 int lp_parm_enum(int snum, const char *type, const char *option,
5667 const struct enum_list *_enum, int def)
5669 struct param_opt_struct *data = get_parametrics(snum, type, option);
5671 if (data && data->value && *data->value && _enum)
5672 return lp_enum(data->value, _enum);
5678 /***************************************************************************
5679 Initialise a service to the defaults.
5680 ***************************************************************************/
5682 static void init_service(struct service *pservice)
5684 memset((char *)pservice, '\0', sizeof(struct service));
5685 copy_service(pservice, &sDefault, NULL);
5690 * free a param_opts structure.
5691 * param_opts handling should be moved to talloc;
5692 * then this whole functions reduces to a TALLOC_FREE().
5695 static void free_param_opts(struct param_opt_struct **popts)
5697 struct param_opt_struct *opt, *next_opt;
5699 if (popts == NULL) {
5703 if (*popts != NULL) {
5704 DEBUG(5, ("Freeing parametrics:\n"));
5707 while (opt != NULL) {
5708 string_free(&opt->key);
5709 string_free(&opt->value);
5710 TALLOC_FREE(opt->list);
5711 next_opt = opt->next;
5718 /***************************************************************************
5719 Free the dynamically allocated parts of a service struct.
5720 ***************************************************************************/
5722 static void free_service(struct service *pservice)
5727 if (pservice->szService)
5728 DEBUG(5, ("free_service: Freeing service %s\n",
5729 pservice->szService));
5731 free_parameters(getservicebyname(pservice->szService, NULL));
5733 string_free(&pservice->szService);
5734 bitmap_free(pservice->copymap);
5736 free_param_opts(&pservice->param_opt);
5738 ZERO_STRUCTP(pservice);
5742 /***************************************************************************
5743 remove a service indexed in the ServicePtrs array from the ServiceHash
5744 and free the dynamically allocated parts
5745 ***************************************************************************/
5747 static void free_service_byindex(int idx)
5749 if ( !LP_SNUM_OK(idx) )
5752 ServicePtrs[idx]->valid = False;
5753 invalid_services[num_invalid_services++] = idx;
5755 /* we have to cleanup the hash record */
5757 if (ServicePtrs[idx]->szService) {
5758 char *canon_name = canonicalize_servicename(
5759 ServicePtrs[idx]->szService );
5761 dbwrap_delete_bystring(ServiceHash, canon_name );
5762 TALLOC_FREE(canon_name);
5765 free_service(ServicePtrs[idx]);
5768 /***************************************************************************
5769 Add a new service to the services array initialising it with the given
5771 ***************************************************************************/
5773 static int add_a_service(const struct service *pservice, const char *name)
5776 struct service tservice;
5777 int num_to_alloc = iNumServices + 1;
5779 tservice = *pservice;
5781 /* it might already exist */
5783 i = getservicebyname(name, NULL);
5785 /* Clean all parametric options for service */
5786 /* They will be added during parsing again */
5787 free_param_opts(&ServicePtrs[i]->param_opt);
5792 /* find an invalid one */
5794 if (num_invalid_services > 0) {
5795 i = invalid_services[--num_invalid_services];
5798 /* if not, then create one */
5799 if (i == iNumServices) {
5800 struct service **tsp;
5803 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5805 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5809 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5810 if (!ServicePtrs[iNumServices]) {
5811 DEBUG(0,("add_a_service: out of memory!\n"));
5816 /* enlarge invalid_services here for now... */
5817 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5819 if (tinvalid == NULL) {
5820 DEBUG(0,("add_a_service: failed to enlarge "
5821 "invalid_services!\n"));
5824 invalid_services = tinvalid;
5826 free_service_byindex(i);
5829 ServicePtrs[i]->valid = True;
5831 init_service(ServicePtrs[i]);
5832 copy_service(ServicePtrs[i], &tservice, NULL);
5834 string_set(&ServicePtrs[i]->szService, name);
5836 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5837 i, ServicePtrs[i]->szService));
5839 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5846 /***************************************************************************
5847 Convert a string to uppercase and remove whitespaces.
5848 ***************************************************************************/
5850 static char *canonicalize_servicename(const char *src)
5855 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5859 result = talloc_strdup(talloc_tos(), src);
5860 SMB_ASSERT(result != NULL);
5866 /***************************************************************************
5867 Add a name/index pair for the services array to the hash table.
5868 ***************************************************************************/
5870 static bool hash_a_service(const char *name, int idx)
5874 if ( !ServiceHash ) {
5875 DEBUG(10,("hash_a_service: creating servicehash\n"));
5876 ServiceHash = db_open_rbt(NULL);
5877 if ( !ServiceHash ) {
5878 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5883 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5886 canon_name = canonicalize_servicename( name );
5888 dbwrap_store_bystring(ServiceHash, canon_name,
5889 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5892 TALLOC_FREE(canon_name);
5897 /***************************************************************************
5898 Add a new home service, with the specified home directory, defaults coming
5900 ***************************************************************************/
5902 bool lp_add_home(const char *pszHomename, int iDefaultService,
5903 const char *user, const char *pszHomedir)
5907 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5912 if (!(*(ServicePtrs[iDefaultService]->szPath))
5913 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5914 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5917 if (!(*(ServicePtrs[i]->comment))) {
5918 char *comment = NULL;
5919 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5922 string_set(&ServicePtrs[i]->comment, comment);
5926 /* set the browseable flag from the global default */
5928 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5930 ServicePtrs[i]->autoloaded = True;
5932 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5933 user, ServicePtrs[i]->szPath ));
5938 /***************************************************************************
5939 Add a new service, based on an old one.
5940 ***************************************************************************/
5942 int lp_add_service(const char *pszService, int iDefaultService)
5944 if (iDefaultService < 0) {
5945 return add_a_service(&sDefault, pszService);
5948 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5951 /***************************************************************************
5952 Add the IPC service.
5953 ***************************************************************************/
5955 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5957 char *comment = NULL;
5958 int i = add_a_service(&sDefault, ipc_name);
5963 if (asprintf(&comment, "IPC Service (%s)",
5964 Globals.szServerString) < 0) {
5968 string_set(&ServicePtrs[i]->szPath, tmpdir());
5969 string_set(&ServicePtrs[i]->szUsername, "");
5970 string_set(&ServicePtrs[i]->comment, comment);
5971 string_set(&ServicePtrs[i]->fstype, "IPC");
5972 ServicePtrs[i]->iMaxConnections = 0;
5973 ServicePtrs[i]->bAvailable = True;
5974 ServicePtrs[i]->bRead_only = True;
5975 ServicePtrs[i]->bGuest_only = False;
5976 ServicePtrs[i]->bAdministrative_share = True;
5977 ServicePtrs[i]->bGuest_ok = guest_ok;
5978 ServicePtrs[i]->bPrint_ok = False;
5979 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5981 DEBUG(3, ("adding IPC service\n"));
5987 /***************************************************************************
5988 Add a new printer service, with defaults coming from service iFrom.
5989 ***************************************************************************/
5991 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5993 const char *comment = "From Printcap";
5994 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5999 /* note that we do NOT default the availability flag to True - */
6000 /* we take it from the default service passed. This allows all */
6001 /* dynamic printers to be disabled by disabling the [printers] */
6002 /* entry (if/when the 'available' keyword is implemented!). */
6004 /* the printer name is set to the service name. */
6005 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6006 string_set(&ServicePtrs[i]->comment, comment);
6008 /* set the browseable flag from the gloabl default */
6009 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6011 /* Printers cannot be read_only. */
6012 ServicePtrs[i]->bRead_only = False;
6013 /* No share modes on printer services. */
6014 ServicePtrs[i]->bShareModes = False;
6015 /* No oplocks on printer services. */
6016 ServicePtrs[i]->bOpLocks = False;
6017 /* Printer services must be printable. */
6018 ServicePtrs[i]->bPrint_ok = True;
6020 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6026 /***************************************************************************
6027 Check whether the given parameter name is valid.
6028 Parametric options (names containing a colon) are considered valid.
6029 ***************************************************************************/
6031 bool lp_parameter_is_valid(const char *pszParmName)
6033 return ((map_parameter(pszParmName) != -1) ||
6034 (strchr(pszParmName, ':') != NULL));
6037 /***************************************************************************
6038 Check whether the given name is the name of a global parameter.
6039 Returns True for strings belonging to parameters of class
6040 P_GLOBAL, False for all other strings, also for parametric options
6041 and strings not belonging to any option.
6042 ***************************************************************************/
6044 bool lp_parameter_is_global(const char *pszParmName)
6046 int num = map_parameter(pszParmName);
6049 return (parm_table[num].p_class == P_GLOBAL);
6055 /**************************************************************************
6056 Check whether the given name is the canonical name of a parameter.
6057 Returns False if it is not a valid parameter Name.
6058 For parametric options, True is returned.
6059 **************************************************************************/
6061 bool lp_parameter_is_canonical(const char *parm_name)
6063 if (!lp_parameter_is_valid(parm_name)) {
6067 return (map_parameter(parm_name) ==
6068 map_parameter_canonical(parm_name, NULL));
6071 /**************************************************************************
6072 Determine the canonical name for a parameter.
6073 Indicate when it is an inverse (boolean) synonym instead of a
6075 **************************************************************************/
6077 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6082 if (!lp_parameter_is_valid(parm_name)) {
6087 num = map_parameter_canonical(parm_name, inverse);
6089 /* parametric option */
6090 *canon_parm = parm_name;
6092 *canon_parm = parm_table[num].label;
6099 /**************************************************************************
6100 Determine the canonical name for a parameter.
6101 Turn the value given into the inverse boolean expression when
6102 the synonym is an invers boolean synonym.
6104 Return True if parm_name is a valid parameter name and
6105 in case it is an invers boolean synonym, if the val string could
6106 successfully be converted to the reverse bool.
6107 Return false in all other cases.
6108 **************************************************************************/
6110 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6112 const char **canon_parm,
6113 const char **canon_val)
6118 if (!lp_parameter_is_valid(parm_name)) {
6124 num = map_parameter_canonical(parm_name, &inverse);
6126 /* parametric option */
6127 *canon_parm = parm_name;
6130 *canon_parm = parm_table[num].label;
6132 if (!lp_invert_boolean(val, canon_val)) {
6144 /***************************************************************************
6145 Map a parameter's string representation to something we can use.
6146 Returns False if the parameter string is not recognised, else TRUE.
6147 ***************************************************************************/
6149 static int map_parameter(const char *pszParmName)
6153 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6156 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6157 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6160 /* Warn only if it isn't parametric option */
6161 if (strchr(pszParmName, ':') == NULL)
6162 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6163 /* We do return 'fail' for parametric options as well because they are
6164 stored in different storage
6169 /***************************************************************************
6170 Map a parameter's string representation to the index of the canonical
6171 form of the parameter (it might be a synonym).
6172 Returns -1 if the parameter string is not recognised.
6173 ***************************************************************************/
6175 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6177 int parm_num, canon_num;
6178 bool loc_inverse = False;
6180 parm_num = map_parameter(pszParmName);
6181 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6182 /* invalid, parametric or no canidate for synonyms ... */
6186 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6187 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6188 parm_num = canon_num;
6194 if (inverse != NULL) {
6195 *inverse = loc_inverse;
6200 /***************************************************************************
6201 return true if parameter number parm1 is a synonym of parameter
6202 number parm2 (parm2 being the principal name).
6203 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6205 ***************************************************************************/
6207 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6209 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6210 (parm_table[parm1].flags & FLAG_HIDE) &&
6211 !(parm_table[parm2].flags & FLAG_HIDE))
6213 if (inverse != NULL) {
6214 if ((parm_table[parm1].type == P_BOOLREV) &&
6215 (parm_table[parm2].type == P_BOOL))
6227 /***************************************************************************
6228 Show one parameter's name, type, [values,] and flags.
6229 (helper functions for show_parameter_list)
6230 ***************************************************************************/
6232 static void show_parameter(int parmIndex)
6234 int enumIndex, flagIndex;
6239 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6240 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6242 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6243 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6244 FLAG_HIDE, FLAG_DOS_STRING};
6245 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6246 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6247 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6249 printf("%s=%s", parm_table[parmIndex].label,
6250 type[parm_table[parmIndex].type]);
6251 if (parm_table[parmIndex].type == P_ENUM) {
6254 parm_table[parmIndex].enum_list[enumIndex].name;
6258 enumIndex ? "|" : "",
6259 parm_table[parmIndex].enum_list[enumIndex].name);
6264 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6265 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6268 flag_names[flagIndex]);
6273 /* output synonyms */
6275 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6276 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6277 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6278 parm_table[parmIndex2].label);
6279 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6281 printf(" (synonyms: ");
6286 printf("%s%s", parm_table[parmIndex2].label,
6287 inverse ? "[i]" : "");
6297 /***************************************************************************
6298 Show all parameter's name, type, [values,] and flags.
6299 ***************************************************************************/
6301 void show_parameter_list(void)
6303 int classIndex, parmIndex;
6304 const char *section_names[] = { "local", "global", NULL};
6306 for (classIndex=0; section_names[classIndex]; classIndex++) {
6307 printf("[%s]\n", section_names[classIndex]);
6308 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6309 if (parm_table[parmIndex].p_class == classIndex) {
6310 show_parameter(parmIndex);
6316 /***************************************************************************
6317 Check if a given string correctly represents a boolean value.
6318 ***************************************************************************/
6320 bool lp_string_is_valid_boolean(const char *parm_value)
6322 return set_boolean(parm_value, NULL);
6325 /***************************************************************************
6326 Get the standard string representation of a boolean value ("yes" or "no")
6327 ***************************************************************************/
6329 static const char *get_boolean(bool bool_value)
6331 static const char *yes_str = "yes";
6332 static const char *no_str = "no";
6334 return (bool_value ? yes_str : no_str);
6337 /***************************************************************************
6338 Provide the string of the negated boolean value associated to the boolean
6339 given as a string. Returns False if the passed string does not correctly
6340 represent a boolean.
6341 ***************************************************************************/
6343 bool lp_invert_boolean(const char *str, const char **inverse_str)
6347 if (!set_boolean(str, &val)) {
6351 *inverse_str = get_boolean(!val);
6355 /***************************************************************************
6356 Provide the canonical string representation of a boolean value given
6357 as a string. Return True on success, False if the string given does
6358 not correctly represent a boolean.
6359 ***************************************************************************/
6361 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6365 if (!set_boolean(str, &val)) {
6369 *canon_str = get_boolean(val);
6373 /***************************************************************************
6374 Find a service by name. Otherwise works like get_service.
6375 ***************************************************************************/
6377 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6383 if (ServiceHash == NULL) {
6387 canon_name = canonicalize_servicename(pszServiceName);
6389 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6391 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6392 iService = *(int *)data.dptr;
6395 TALLOC_FREE(canon_name);
6397 if ((iService != -1) && (LP_SNUM_OK(iService))
6398 && (pserviceDest != NULL)) {
6399 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6405 /***************************************************************************
6406 Copy a service structure to another.
6407 If pcopymapDest is NULL then copy all fields
6408 ***************************************************************************/
6411 * Add a parametric option to a param_opt_struct,
6412 * replacing old value, if already present.
6414 static void set_param_opt(struct param_opt_struct **opt_list,
6415 const char *opt_name,
6416 const char *opt_value)
6418 struct param_opt_struct *new_opt, *opt;
6421 if (opt_list == NULL) {
6428 /* Traverse destination */
6430 /* If we already have same option, override it */
6431 if (strwicmp(opt->key, opt_name) == 0) {
6432 string_free(&opt->value);
6433 TALLOC_FREE(opt->list);
6434 opt->value = SMB_STRDUP(opt_value);
6441 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6442 new_opt->key = SMB_STRDUP(opt_name);
6443 new_opt->value = SMB_STRDUP(opt_value);
6444 new_opt->list = NULL;
6445 DLIST_ADD(*opt_list, new_opt);
6449 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6450 struct bitmap *pcopymapDest)
6453 bool bcopyall = (pcopymapDest == NULL);
6454 struct param_opt_struct *data;
6456 for (i = 0; parm_table[i].label; i++)
6457 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6458 (bcopyall || bitmap_query(pcopymapDest,i))) {
6459 void *def_ptr = parm_table[i].ptr;
6461 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6464 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6467 switch (parm_table[i].type) {
6470 *(bool *)dest_ptr = *(bool *)src_ptr;
6476 *(int *)dest_ptr = *(int *)src_ptr;
6480 *(char *)dest_ptr = *(char *)src_ptr;
6484 string_set((char **)dest_ptr,
6489 string_set((char **)dest_ptr,
6491 strupper_m(*(char **)dest_ptr);
6494 TALLOC_FREE(*((char ***)dest_ptr));
6495 *((char ***)dest_ptr) = str_list_copy(NULL,
6496 *(const char ***)src_ptr);
6504 init_copymap(pserviceDest);
6505 if (pserviceSource->copymap)
6506 bitmap_copy(pserviceDest->copymap,
6507 pserviceSource->copymap);
6510 data = pserviceSource->param_opt;
6512 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6517 /***************************************************************************
6518 Check a service for consistency. Return False if the service is in any way
6519 incomplete or faulty, else True.
6520 ***************************************************************************/
6522 bool service_ok(int iService)
6527 if (ServicePtrs[iService]->szService[0] == '\0') {
6528 DEBUG(0, ("The following message indicates an internal error:\n"));
6529 DEBUG(0, ("No service name in service entry.\n"));
6533 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6534 /* I can't see why you'd want a non-printable printer service... */
6535 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6536 if (!ServicePtrs[iService]->bPrint_ok) {
6537 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6538 ServicePtrs[iService]->szService));
6539 ServicePtrs[iService]->bPrint_ok = True;
6541 /* [printers] service must also be non-browsable. */
6542 if (ServicePtrs[iService]->bBrowseable)
6543 ServicePtrs[iService]->bBrowseable = False;
6546 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6547 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6548 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6550 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6551 ServicePtrs[iService]->szService));
6552 ServicePtrs[iService]->bAvailable = False;
6555 /* If a service is flagged unavailable, log the fact at level 1. */
6556 if (!ServicePtrs[iService]->bAvailable)
6557 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6558 ServicePtrs[iService]->szService));
6563 static struct smbconf_ctx *lp_smbconf_ctx(void)
6566 static struct smbconf_ctx *conf_ctx = NULL;
6568 if (conf_ctx == NULL) {
6569 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6570 if (!W_ERROR_IS_OK(werr)) {
6571 DEBUG(1, ("error initializing registry configuration: "
6572 "%s\n", win_errstr(werr)));
6580 static bool process_smbconf_service(struct smbconf_service *service)
6585 if (service == NULL) {
6589 ret = do_section(service->name, NULL);
6593 for (count = 0; count < service->num_params; count++) {
6594 ret = do_parameter(service->param_names[count],
6595 service->param_values[count],
6605 * process_registry_globals
6607 static bool process_registry_globals(void)
6610 struct smbconf_service *service = NULL;
6611 TALLOC_CTX *mem_ctx = talloc_stackframe();
6612 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6615 if (conf_ctx == NULL) {
6619 ret = do_parameter("registry shares", "yes", NULL);
6624 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6625 /* nothing to read from the registry yet but make sure lp_load
6626 * doesn't return false */
6631 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6632 if (!W_ERROR_IS_OK(werr)) {
6636 ret = process_smbconf_service(service);
6642 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6645 TALLOC_FREE(mem_ctx);
6649 static bool process_registry_shares(void)
6653 struct smbconf_service **service = NULL;
6654 uint32_t num_shares = 0;
6655 TALLOC_CTX *mem_ctx = talloc_stackframe();
6656 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6659 if (conf_ctx == NULL) {
6663 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6664 if (!W_ERROR_IS_OK(werr)) {
6670 for (count = 0; count < num_shares; count++) {
6671 if (strequal(service[count]->name, GLOBAL_NAME)) {
6674 ret = process_smbconf_service(service[count]);
6681 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6684 TALLOC_FREE(mem_ctx);
6688 static struct file_lists {
6689 struct file_lists *next;
6693 } *file_lists = NULL;
6695 /*******************************************************************
6696 Keep a linked list of all config files so we know when one has changed
6697 it's date and needs to be reloaded.
6698 ********************************************************************/
6700 static void add_to_file_list(const char *fname, const char *subfname)
6702 struct file_lists *f = file_lists;
6705 if (f->name && !strcmp(f->name, fname))
6711 f = SMB_MALLOC_P(struct file_lists);
6714 f->next = file_lists;
6715 f->name = SMB_STRDUP(fname);
6720 f->subfname = SMB_STRDUP(subfname);
6726 f->modtime = file_modtime(subfname);
6728 time_t t = file_modtime(subfname);
6735 * Utility function for outsiders to check if we're running on registry.
6737 bool lp_config_backend_is_registry(void)
6739 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6743 * Utility function to check if the config backend is FILE.
6745 bool lp_config_backend_is_file(void)
6747 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6750 /*******************************************************************
6751 Check if a config file has changed date.
6752 ********************************************************************/
6754 bool lp_file_list_changed(void)
6756 struct file_lists *f = file_lists;
6758 DEBUG(6, ("lp_file_list_changed()\n"));
6760 if (lp_config_backend_is_registry()) {
6761 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6763 if (conf_ctx == NULL) {
6766 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6767 DEBUGADD(6, ("registry config changed\n"));
6776 n2 = alloc_sub_basic(get_current_username(),
6777 current_user_info.domain,
6782 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6783 f->name, n2, ctime(&f->modtime)));
6785 mod_time = file_modtime(n2);
6787 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6789 ("file %s modified: %s\n", n2,
6791 f->modtime = mod_time;
6792 SAFE_FREE(f->subfname);
6793 f->subfname = n2; /* Passing ownership of
6794 return from alloc_sub_basic
6805 /***************************************************************************
6806 Run standard_sub_basic on netbios name... needed because global_myname
6807 is not accessed through any lp_ macro.
6808 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6809 ***************************************************************************/
6811 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6814 char *netbios_name = alloc_sub_basic(get_current_username(),
6815 current_user_info.domain,
6818 ret = set_global_myname(netbios_name);
6819 SAFE_FREE(netbios_name);
6820 string_set(&Globals.szNetbiosName,global_myname());
6822 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6828 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6830 if (strcmp(*ptr, pszParmValue) != 0) {
6831 string_set(ptr, pszParmValue);
6839 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6843 ret = set_global_myworkgroup(pszParmValue);
6844 string_set(&Globals.szWorkgroup,lp_workgroup());
6849 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6853 ret = set_global_scope(pszParmValue);
6854 string_set(&Globals.szNetbiosScope,global_scope());
6859 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6861 TALLOC_FREE(Globals.szNetbiosAliases);
6862 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6863 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6866 /***************************************************************************
6867 Handle the include operation.
6868 ***************************************************************************/
6869 static bool bAllowIncludeRegistry = true;
6871 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6875 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6876 if (!bAllowIncludeRegistry) {
6879 if (bInGlobalSection) {
6880 return process_registry_globals();
6882 DEBUG(1, ("\"include = registry\" only effective "
6883 "in %s section\n", GLOBAL_NAME));
6888 fname = alloc_sub_basic(get_current_username(),
6889 current_user_info.domain,
6892 add_to_file_list(pszParmValue, fname);
6894 string_set(ptr, fname);
6896 if (file_exist(fname)) {
6897 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6902 DEBUG(2, ("Can't find include file %s\n", fname));
6907 /***************************************************************************
6908 Handle the interpretation of the copy parameter.
6909 ***************************************************************************/
6911 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6915 struct service serviceTemp;
6917 string_set(ptr, pszParmValue);
6919 init_service(&serviceTemp);
6923 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6925 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6926 if (iTemp == iServiceIndex) {
6927 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6929 copy_service(ServicePtrs[iServiceIndex],
6931 ServicePtrs[iServiceIndex]->copymap);
6935 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6939 free_service(&serviceTemp);
6943 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6945 Globals.ldap_debug_level = lp_int(pszParmValue);
6946 init_ldap_debugging();
6950 /***************************************************************************
6951 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6956 idmap uid = 1000-1999
6959 We only do simple parsing checks here. The strings are parsed into useful
6960 structures in the idmap daemon code.
6962 ***************************************************************************/
6964 /* Some lp_ routines to return idmap [ug]id information */
6966 static uid_t idmap_uid_low, idmap_uid_high;
6967 static gid_t idmap_gid_low, idmap_gid_high;
6969 bool lp_idmap_uid(uid_t *low, uid_t *high)
6971 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6975 *low = idmap_uid_low;
6978 *high = idmap_uid_high;
6983 bool lp_idmap_gid(gid_t *low, gid_t *high)
6985 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6989 *low = idmap_gid_low;
6992 *high = idmap_gid_high;
6997 /* Do some simple checks on "idmap [ug]id" parameter values */
6999 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7003 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7008 string_set(ptr, pszParmValue);
7010 idmap_uid_low = low;
7011 idmap_uid_high = high;
7016 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7020 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7025 string_set(ptr, pszParmValue);
7027 idmap_gid_low = low;
7028 idmap_gid_high = high;
7033 /***************************************************************************
7034 Handle the DEBUG level list.
7035 ***************************************************************************/
7037 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7039 string_set(ptr, pszParmValueIn);
7040 return debug_parse_levels(pszParmValueIn);
7043 /***************************************************************************
7044 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7045 ***************************************************************************/
7047 static const char *append_ldap_suffix( const char *str )
7049 const char *suffix_string;
7052 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7053 Globals.szLdapSuffix );
7054 if ( !suffix_string ) {
7055 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7059 return suffix_string;
7062 const char *lp_ldap_machine_suffix(void)
7064 if (Globals.szLdapMachineSuffix[0])
7065 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7067 return lp_string(Globals.szLdapSuffix);
7070 const char *lp_ldap_user_suffix(void)
7072 if (Globals.szLdapUserSuffix[0])
7073 return append_ldap_suffix(Globals.szLdapUserSuffix);
7075 return lp_string(Globals.szLdapSuffix);
7078 const char *lp_ldap_group_suffix(void)
7080 if (Globals.szLdapGroupSuffix[0])
7081 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7083 return lp_string(Globals.szLdapSuffix);
7086 const char *lp_ldap_idmap_suffix(void)
7088 if (Globals.szLdapIdmapSuffix[0])
7089 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7091 return lp_string(Globals.szLdapSuffix);
7094 /****************************************************************************
7095 set the value for a P_ENUM
7096 ***************************************************************************/
7098 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7103 for (i = 0; parm->enum_list[i].name; i++) {
7104 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7105 *ptr = parm->enum_list[i].value;
7109 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7110 pszParmValue, parm->label));
7113 /***************************************************************************
7114 ***************************************************************************/
7116 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7118 static int parm_num = -1;
7121 if ( parm_num == -1 )
7122 parm_num = map_parameter( "printing" );
7124 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7129 s = ServicePtrs[snum];
7131 init_printer_values( s );
7137 /***************************************************************************
7138 Initialise a copymap.
7139 ***************************************************************************/
7141 static void init_copymap(struct service *pservice)
7144 if (pservice->copymap) {
7145 bitmap_free(pservice->copymap);
7147 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7148 if (!pservice->copymap)
7150 ("Couldn't allocate copymap!! (size %d)\n",
7151 (int)NUMPARAMETERS));
7153 for (i = 0; i < NUMPARAMETERS; i++)
7154 bitmap_set(pservice->copymap, i);
7157 /***************************************************************************
7158 Return the local pointer to a parameter given the service number and the
7159 pointer into the default structure.
7160 ***************************************************************************/
7162 void *lp_local_ptr(int snum, void *ptr)
7164 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7167 /***************************************************************************
7168 Process a parameter for a particular service number. If snum < 0
7169 then assume we are in the globals.
7170 ***************************************************************************/
7172 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7175 void *parm_ptr = NULL; /* where we are going to store the result */
7176 void *def_ptr = NULL;
7177 struct param_opt_struct **opt_list;
7179 parmnum = map_parameter(pszParmName);
7182 if (strchr(pszParmName, ':') == NULL) {
7183 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7189 * We've got a parametric option
7192 opt_list = (snum < 0)
7193 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7194 set_param_opt(opt_list, pszParmName, pszParmValue);
7199 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7200 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7204 def_ptr = parm_table[parmnum].ptr;
7206 /* we might point at a service, the default service or a global */
7210 if (parm_table[parmnum].p_class == P_GLOBAL) {
7212 ("Global parameter %s found in service section!\n",
7216 parm_ptr = lp_local_ptr(snum, def_ptr);
7220 if (!ServicePtrs[snum]->copymap)
7221 init_copymap(ServicePtrs[snum]);
7223 /* this handles the aliases - set the copymap for other entries with
7224 the same data pointer */
7225 for (i = 0; parm_table[i].label; i++)
7226 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7227 bitmap_clear(ServicePtrs[snum]->copymap, i);
7230 /* if it is a special case then go ahead */
7231 if (parm_table[parmnum].special) {
7232 return parm_table[parmnum].special(snum, pszParmValue,
7236 /* now switch on the type of variable it is */
7237 switch (parm_table[parmnum].type)
7240 *(bool *)parm_ptr = lp_bool(pszParmValue);
7244 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7248 *(int *)parm_ptr = lp_int(pszParmValue);
7252 *(char *)parm_ptr = *pszParmValue;
7256 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7258 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7263 TALLOC_FREE(*((char ***)parm_ptr));
7264 *(char ***)parm_ptr = str_list_make(
7265 NULL, pszParmValue, NULL);
7269 string_set((char **)parm_ptr, pszParmValue);
7273 string_set((char **)parm_ptr, pszParmValue);
7274 strupper_m(*(char **)parm_ptr);
7278 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7287 /***************************************************************************
7288 Process a parameter.
7289 ***************************************************************************/
7291 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7294 if (!bInGlobalSection && bGlobalOnly)
7297 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7299 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7300 pszParmName, pszParmValue));
7303 /***************************************************************************
7304 Print a parameter of the specified type.
7305 ***************************************************************************/
7307 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7313 for (i = 0; p->enum_list[i].name; i++) {
7314 if (*(int *)ptr == p->enum_list[i].value) {
7316 p->enum_list[i].name);
7323 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7327 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7331 fprintf(f, "%d", *(int *)ptr);
7335 fprintf(f, "%c", *(char *)ptr);
7339 char *o = octal_string(*(int *)ptr);
7340 fprintf(f, "%s", o);
7346 if ((char ***)ptr && *(char ***)ptr) {
7347 char **list = *(char ***)ptr;
7348 for (; *list; list++) {
7349 /* surround strings with whitespace in double quotes */
7350 if ( strchr_m( *list, ' ' ) )
7351 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7353 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7360 if (*(char **)ptr) {
7361 fprintf(f, "%s", *(char **)ptr);
7369 /***************************************************************************
7370 Check if two parameters are equal.
7371 ***************************************************************************/
7373 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7378 return (*((bool *)ptr1) == *((bool *)ptr2));
7383 return (*((int *)ptr1) == *((int *)ptr2));
7386 return (*((char *)ptr1) == *((char *)ptr2));
7389 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7394 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7399 return (p1 == p2 || strequal(p1, p2));
7407 /***************************************************************************
7408 Initialize any local varients in the sDefault table.
7409 ***************************************************************************/
7411 void init_locals(void)
7416 /***************************************************************************
7417 Process a new section (service). At this stage all sections are services.
7418 Later we'll have special sections that permit server parameters to be set.
7419 Returns True on success, False on failure.
7420 ***************************************************************************/
7422 static bool do_section(const char *pszSectionName, void *userdata)
7425 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7426 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7429 /* if we were in a global section then do the local inits */
7430 if (bInGlobalSection && !isglobal)
7433 /* if we've just struck a global section, note the fact. */
7434 bInGlobalSection = isglobal;
7436 /* check for multiple global sections */
7437 if (bInGlobalSection) {
7438 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7442 if (!bInGlobalSection && bGlobalOnly)
7445 /* if we have a current service, tidy it up before moving on */
7448 if (iServiceIndex >= 0)
7449 bRetval = service_ok(iServiceIndex);
7451 /* if all is still well, move to the next record in the services array */
7453 /* We put this here to avoid an odd message order if messages are */
7454 /* issued by the post-processing of a previous section. */
7455 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7457 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7459 DEBUG(0, ("Failed to add a new service\n"));
7468 /***************************************************************************
7469 Determine if a partcular base parameter is currentl set to the default value.
7470 ***************************************************************************/
7472 static bool is_default(int i)
7474 if (!defaults_saved)
7476 switch (parm_table[i].type) {
7478 return str_list_equal((const char **)parm_table[i].def.lvalue,
7479 *(const char ***)parm_table[i].ptr);
7482 return strequal(parm_table[i].def.svalue,
7483 *(char **)parm_table[i].ptr);
7486 return parm_table[i].def.bvalue ==
7487 *(bool *)parm_table[i].ptr;
7489 return parm_table[i].def.cvalue ==
7490 *(char *)parm_table[i].ptr;
7494 return parm_table[i].def.ivalue ==
7495 *(int *)parm_table[i].ptr;
7502 /***************************************************************************
7503 Display the contents of the global structure.
7504 ***************************************************************************/
7506 static void dump_globals(FILE *f)
7509 struct param_opt_struct *data;
7511 fprintf(f, "[global]\n");
7513 for (i = 0; parm_table[i].label; i++)
7514 if (parm_table[i].p_class == P_GLOBAL &&
7515 parm_table[i].ptr &&
7516 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7517 if (defaults_saved && is_default(i))
7519 fprintf(f, "\t%s = ", parm_table[i].label);
7520 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7523 if (Globals.param_opt != NULL) {
7524 data = Globals.param_opt;
7526 fprintf(f, "\t%s = %s\n", data->key, data->value);
7533 /***************************************************************************
7534 Return True if a local parameter is currently set to the global default.
7535 ***************************************************************************/
7537 bool lp_is_default(int snum, struct parm_struct *parm)
7539 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7541 return equal_parameter(parm->type,
7542 ((char *)ServicePtrs[snum]) + pdiff,
7543 ((char *)&sDefault) + pdiff);
7546 /***************************************************************************
7547 Display the contents of a single services record.
7548 ***************************************************************************/
7550 static void dump_a_service(struct service *pService, FILE * f)
7553 struct param_opt_struct *data;
7555 if (pService != &sDefault)
7556 fprintf(f, "[%s]\n", pService->szService);
7558 for (i = 0; parm_table[i].label; i++) {
7560 if (parm_table[i].p_class == P_LOCAL &&
7561 parm_table[i].ptr &&
7562 (*parm_table[i].label != '-') &&
7563 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7566 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7568 if (pService == &sDefault) {
7569 if (defaults_saved && is_default(i))
7572 if (equal_parameter(parm_table[i].type,
7573 ((char *)pService) +
7575 ((char *)&sDefault) +
7580 fprintf(f, "\t%s = ", parm_table[i].label);
7581 print_parameter(&parm_table[i],
7582 ((char *)pService) + pdiff, f);
7587 if (pService->param_opt != NULL) {
7588 data = pService->param_opt;
7590 fprintf(f, "\t%s = %s\n", data->key, data->value);
7596 /***************************************************************************
7597 Display the contents of a parameter of a single services record.
7598 ***************************************************************************/
7600 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7603 bool result = False;
7606 fstring local_parm_name;
7608 const char *parm_opt_value;
7610 /* check for parametrical option */
7611 fstrcpy( local_parm_name, parm_name);
7612 parm_opt = strchr( local_parm_name, ':');
7617 if (strlen(parm_opt)) {
7618 parm_opt_value = lp_parm_const_string( snum,
7619 local_parm_name, parm_opt, NULL);
7620 if (parm_opt_value) {
7621 printf( "%s\n", parm_opt_value);
7628 /* check for a key and print the value */
7635 for (i = 0; parm_table[i].label; i++) {
7636 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7637 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7638 parm_table[i].ptr &&
7639 (*parm_table[i].label != '-') &&
7640 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7645 ptr = parm_table[i].ptr;
7647 struct service *pService = ServicePtrs[snum];
7648 ptr = ((char *)pService) +
7649 PTR_DIFF(parm_table[i].ptr, &sDefault);
7652 print_parameter(&parm_table[i],
7663 /***************************************************************************
7664 Return info about the requested parameter (given as a string).
7665 Return NULL when the string is not a valid parameter name.
7666 ***************************************************************************/
7668 struct parm_struct *lp_get_parameter(const char *param_name)
7670 int num = map_parameter(param_name);
7676 return &parm_table[num];
7679 /***************************************************************************
7680 Return info about the next parameter in a service.
7681 snum==GLOBAL_SECTION_SNUM gives the globals.
7682 Return NULL when out of parameters.
7683 ***************************************************************************/
7685 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7688 /* do the globals */
7689 for (; parm_table[*i].label; (*i)++) {
7690 if (parm_table[*i].p_class == P_SEPARATOR)
7691 return &parm_table[(*i)++];
7693 if (!parm_table[*i].ptr
7694 || (*parm_table[*i].label == '-'))
7698 && (parm_table[*i].ptr ==
7699 parm_table[(*i) - 1].ptr))
7702 if (is_default(*i) && !allparameters)
7705 return &parm_table[(*i)++];
7708 struct service *pService = ServicePtrs[snum];
7710 for (; parm_table[*i].label; (*i)++) {
7711 if (parm_table[*i].p_class == P_SEPARATOR)
7712 return &parm_table[(*i)++];
7714 if (parm_table[*i].p_class == P_LOCAL &&
7715 parm_table[*i].ptr &&
7716 (*parm_table[*i].label != '-') &&
7718 (parm_table[*i].ptr !=
7719 parm_table[(*i) - 1].ptr)))
7722 PTR_DIFF(parm_table[*i].ptr,
7725 if (allparameters ||
7726 !equal_parameter(parm_table[*i].type,
7727 ((char *)pService) +
7729 ((char *)&sDefault) +
7732 return &parm_table[(*i)++];
7743 /***************************************************************************
7744 Display the contents of a single copy structure.
7745 ***************************************************************************/
7746 static void dump_copy_map(bool *pcopymap)
7752 printf("\n\tNon-Copied parameters:\n");
7754 for (i = 0; parm_table[i].label; i++)
7755 if (parm_table[i].p_class == P_LOCAL &&
7756 parm_table[i].ptr && !pcopymap[i] &&
7757 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7759 printf("\t\t%s\n", parm_table[i].label);
7764 /***************************************************************************
7765 Return TRUE if the passed service number is within range.
7766 ***************************************************************************/
7768 bool lp_snum_ok(int iService)
7770 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7773 /***************************************************************************
7774 Auto-load some home services.
7775 ***************************************************************************/
7777 static void lp_add_auto_services(char *str)
7787 s = SMB_STRDUP(str);
7791 homes = lp_servicenumber(HOMES_NAME);
7793 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7794 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7797 if (lp_servicenumber(p) >= 0)
7800 home = get_user_home_dir(talloc_tos(), p);
7802 if (home && homes >= 0)
7803 lp_add_home(p, homes, p, home);
7810 /***************************************************************************
7811 Auto-load one printer.
7812 ***************************************************************************/
7814 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7816 int printers = lp_servicenumber(PRINTERS_NAME);
7819 if (lp_servicenumber(name) < 0) {
7820 lp_add_printer(name, printers);
7821 if ((i = lp_servicenumber(name)) >= 0) {
7822 string_set(&ServicePtrs[i]->comment, comment);
7823 ServicePtrs[i]->autoloaded = True;
7828 /***************************************************************************
7829 Have we loaded a services file yet?
7830 ***************************************************************************/
7832 bool lp_loaded(void)
7837 /***************************************************************************
7838 Unload unused services.
7839 ***************************************************************************/
7841 void lp_killunused(bool (*snumused) (int))
7844 for (i = 0; i < iNumServices; i++) {
7848 /* don't kill autoloaded or usershare services */
7849 if ( ServicePtrs[i]->autoloaded ||
7850 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7854 if (!snumused || !snumused(i)) {
7855 free_service_byindex(i);
7861 * Kill all except autoloaded and usershare services - convenience wrapper
7863 void lp_kill_all_services(void)
7865 lp_killunused(NULL);
7868 /***************************************************************************
7870 ***************************************************************************/
7872 void lp_killservice(int iServiceIn)
7874 if (VALID(iServiceIn)) {
7875 free_service_byindex(iServiceIn);
7879 /***************************************************************************
7880 Save the curent values of all global and sDefault parameters into the
7881 defaults union. This allows swat and testparm to show only the
7882 changed (ie. non-default) parameters.
7883 ***************************************************************************/
7885 static void lp_save_defaults(void)
7888 for (i = 0; parm_table[i].label; i++) {
7889 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7891 switch (parm_table[i].type) {
7893 parm_table[i].def.lvalue = str_list_copy(
7894 NULL, *(const char ***)parm_table[i].ptr);
7898 if (parm_table[i].ptr) {
7899 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7901 parm_table[i].def.svalue = NULL;
7906 parm_table[i].def.bvalue =
7907 *(bool *)parm_table[i].ptr;
7910 parm_table[i].def.cvalue =
7911 *(char *)parm_table[i].ptr;
7916 parm_table[i].def.ivalue =
7917 *(int *)parm_table[i].ptr;
7923 defaults_saved = True;
7926 /*******************************************************************
7927 Set the server type we will announce as via nmbd.
7928 ********************************************************************/
7930 static const struct srv_role_tab {
7932 const char *role_str;
7933 } srv_role_tab [] = {
7934 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7935 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7936 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7937 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7941 const char* server_role_str(uint32 role)
7944 for (i=0; srv_role_tab[i].role_str; i++) {
7945 if (role == srv_role_tab[i].role) {
7946 return srv_role_tab[i].role_str;
7952 static void set_server_role(void)
7954 server_role = ROLE_STANDALONE;
7956 switch (lp_security()) {
7958 if (lp_domain_logons())
7959 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7962 if (lp_domain_logons())
7963 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7964 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7965 server_role = ROLE_STANDALONE;
7968 if (lp_domain_logons()) {
7969 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7970 server_role = ROLE_DOMAIN_BDC;
7973 server_role = ROLE_DOMAIN_MEMBER;
7976 if (lp_domain_logons()) {
7977 server_role = ROLE_DOMAIN_PDC;
7980 server_role = ROLE_DOMAIN_MEMBER;
7983 if (lp_domain_logons()) {
7985 if (Globals.iDomainMaster) /* auto or yes */
7986 server_role = ROLE_DOMAIN_PDC;
7988 server_role = ROLE_DOMAIN_BDC;
7992 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7996 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7999 /***********************************************************
8000 If we should send plaintext/LANMAN passwords in the clinet
8001 ************************************************************/
8003 static void set_allowed_client_auth(void)
8005 if (Globals.bClientNTLMv2Auth) {
8006 Globals.bClientLanManAuth = False;
8008 if (!Globals.bClientLanManAuth) {
8009 Globals.bClientPlaintextAuth = False;
8013 /***************************************************************************
8015 The following code allows smbd to read a user defined share file.
8016 Yes, this is my intent. Yes, I'm comfortable with that...
8018 THE FOLLOWING IS SECURITY CRITICAL CODE.
8020 It washes your clothes, it cleans your house, it guards you while you sleep...
8021 Do not f%^k with it....
8022 ***************************************************************************/
8024 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8026 /***************************************************************************
8027 Check allowed stat state of a usershare file.
8028 Ensure we print out who is dicking with us so the admin can
8029 get their sorry ass fired.
8030 ***************************************************************************/
8032 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8034 if (!S_ISREG(psbuf->st_mode)) {
8035 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8036 "not a regular file\n",
8037 fname, (unsigned int)psbuf->st_uid ));
8041 /* Ensure this doesn't have the other write bit set. */
8042 if (psbuf->st_mode & S_IWOTH) {
8043 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8044 "public write. Refusing to allow as a usershare file.\n",
8045 fname, (unsigned int)psbuf->st_uid ));
8049 /* Should be 10k or less. */
8050 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8051 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8052 "too large (%u) to be a user share file.\n",
8053 fname, (unsigned int)psbuf->st_uid,
8054 (unsigned int)psbuf->st_size ));
8061 /***************************************************************************
8062 Parse the contents of a usershare file.
8063 ***************************************************************************/
8065 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8066 SMB_STRUCT_STAT *psbuf,
8067 const char *servicename,
8071 char **pp_sharepath,
8076 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8077 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8080 SMB_STRUCT_STAT sbuf;
8081 char *sharepath = NULL;
8082 char *comment = NULL;
8084 *pp_sharepath = NULL;
8087 *pallow_guest = False;
8090 return USERSHARE_MALFORMED_FILE;
8093 if (strcmp(lines[0], "#VERSION 1") == 0) {
8095 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8098 return USERSHARE_MALFORMED_FILE;
8101 return USERSHARE_BAD_VERSION;
8104 if (strncmp(lines[1], "path=", 5) != 0) {
8105 return USERSHARE_MALFORMED_PATH;
8108 sharepath = talloc_strdup(ctx, &lines[1][5]);
8110 return USERSHARE_POSIX_ERR;
8112 trim_string(sharepath, " ", " ");
8114 if (strncmp(lines[2], "comment=", 8) != 0) {
8115 return USERSHARE_MALFORMED_COMMENT_DEF;
8118 comment = talloc_strdup(ctx, &lines[2][8]);
8120 return USERSHARE_POSIX_ERR;
8122 trim_string(comment, " ", " ");
8123 trim_char(comment, '"', '"');
8125 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8126 return USERSHARE_MALFORMED_ACL_DEF;
8129 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8130 return USERSHARE_ACL_ERR;
8134 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8135 return USERSHARE_MALFORMED_ACL_DEF;
8137 if (lines[4][9] == 'y') {
8138 *pallow_guest = True;
8142 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8143 /* Path didn't change, no checks needed. */
8144 *pp_sharepath = sharepath;
8145 *pp_comment = comment;
8146 return USERSHARE_OK;
8149 /* The path *must* be absolute. */
8150 if (sharepath[0] != '/') {
8151 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8152 servicename, sharepath));
8153 return USERSHARE_PATH_NOT_ABSOLUTE;
8156 /* If there is a usershare prefix deny list ensure one of these paths
8157 doesn't match the start of the user given path. */
8158 if (prefixdenylist) {
8160 for ( i=0; prefixdenylist[i]; i++ ) {
8161 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8162 servicename, i, prefixdenylist[i], sharepath ));
8163 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8164 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8165 "usershare prefix deny list entries.\n",
8166 servicename, sharepath));
8167 return USERSHARE_PATH_IS_DENIED;
8172 /* If there is a usershare prefix allow list ensure one of these paths
8173 does match the start of the user given path. */
8175 if (prefixallowlist) {
8177 for ( i=0; prefixallowlist[i]; i++ ) {
8178 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8179 servicename, i, prefixallowlist[i], sharepath ));
8180 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8184 if (prefixallowlist[i] == NULL) {
8185 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8186 "usershare prefix allow list entries.\n",
8187 servicename, sharepath));
8188 return USERSHARE_PATH_NOT_ALLOWED;
8192 /* Ensure this is pointing to a directory. */
8193 dp = sys_opendir(sharepath);
8196 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8197 servicename, sharepath));
8198 return USERSHARE_PATH_NOT_DIRECTORY;
8201 /* Ensure the owner of the usershare file has permission to share
8204 if (sys_stat(sharepath, &sbuf) == -1) {
8205 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8206 servicename, sharepath, strerror(errno) ));
8208 return USERSHARE_POSIX_ERR;
8213 if (!S_ISDIR(sbuf.st_mode)) {
8214 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8215 servicename, sharepath ));
8216 return USERSHARE_PATH_NOT_DIRECTORY;
8219 /* Check if sharing is restricted to owner-only. */
8220 /* psbuf is the stat of the usershare definition file,
8221 sbuf is the stat of the target directory to be shared. */
8223 if (lp_usershare_owner_only()) {
8224 /* root can share anything. */
8225 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8226 return USERSHARE_PATH_NOT_ALLOWED;
8230 *pp_sharepath = sharepath;
8231 *pp_comment = comment;
8232 return USERSHARE_OK;
8235 /***************************************************************************
8236 Deal with a usershare file.
8239 -1 - Bad name, invalid contents.
8240 - service name already existed and not a usershare, problem
8241 with permissions to share directory etc.
8242 ***************************************************************************/
8244 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8246 SMB_STRUCT_STAT sbuf;
8247 SMB_STRUCT_STAT lsbuf;
8249 char *sharepath = NULL;
8250 char *comment = NULL;
8251 fstring service_name;
8252 char **lines = NULL;
8256 TALLOC_CTX *ctx = NULL;
8257 SEC_DESC *psd = NULL;
8258 bool guest_ok = False;
8260 /* Ensure share name doesn't contain invalid characters. */
8261 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8262 DEBUG(0,("process_usershare_file: share name %s contains "
8263 "invalid characters (any of %s)\n",
8264 file_name, INVALID_SHARENAME_CHARS ));
8268 fstrcpy(service_name, file_name);
8270 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8273 /* Minimize the race condition by doing an lstat before we
8274 open and fstat. Ensure this isn't a symlink link. */
8276 if (sys_lstat(fname, &lsbuf) != 0) {
8277 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8278 fname, strerror(errno) ));
8283 /* This must be a regular file, not a symlink, directory or
8284 other strange filetype. */
8285 if (!check_usershare_stat(fname, &lsbuf)) {
8291 char *canon_name = canonicalize_servicename(service_name);
8292 TDB_DATA data = dbwrap_fetch_bystring(
8293 ServiceHash, canon_name, canon_name);
8297 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8298 iService = *(int *)data.dptr;
8300 TALLOC_FREE(canon_name);
8303 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8304 /* Nothing changed - Mark valid and return. */
8305 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8307 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8312 /* Try and open the file read only - no symlinks allowed. */
8314 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8316 fd = sys_open(fname, O_RDONLY, 0);
8320 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8321 fname, strerror(errno) ));
8326 /* Now fstat to be *SURE* it's a regular file. */
8327 if (sys_fstat(fd, &sbuf) != 0) {
8329 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8330 fname, strerror(errno) ));
8335 /* Is it the same dev/inode as was lstated ? */
8336 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8338 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8339 "Symlink spoofing going on ?\n", fname ));
8344 /* This must be a regular file, not a symlink, directory or
8345 other strange filetype. */
8346 if (!check_usershare_stat(fname, &sbuf)) {
8351 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8354 if (lines == NULL) {
8355 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8356 fname, (unsigned int)sbuf.st_uid ));
8363 /* Should we allow printers to be shared... ? */
8364 ctx = talloc_init("usershare_sd_xctx");
8370 if (parse_usershare_file(ctx, &sbuf, service_name,
8371 iService, lines, numlines, &sharepath,
8372 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8373 talloc_destroy(ctx);
8380 /* Everything ok - add the service possibly using a template. */
8382 const struct service *sp = &sDefault;
8383 if (snum_template != -1) {
8384 sp = ServicePtrs[snum_template];
8387 if ((iService = add_a_service(sp, service_name)) < 0) {
8388 DEBUG(0, ("process_usershare_file: Failed to add "
8389 "new service %s\n", service_name));
8390 talloc_destroy(ctx);
8394 /* Read only is controlled by usershare ACL below. */
8395 ServicePtrs[iService]->bRead_only = False;
8398 /* Write the ACL of the new/modified share. */
8399 if (!set_share_security(service_name, psd)) {
8400 DEBUG(0, ("process_usershare_file: Failed to set share "
8401 "security for user share %s\n",
8403 lp_remove_service(iService);
8404 talloc_destroy(ctx);
8408 /* If from a template it may be marked invalid. */
8409 ServicePtrs[iService]->valid = True;
8411 /* Set the service as a valid usershare. */
8412 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8414 /* Set guest access. */
8415 if (lp_usershare_allow_guests()) {
8416 ServicePtrs[iService]->bGuest_ok = guest_ok;
8419 /* And note when it was loaded. */
8420 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8421 string_set(&ServicePtrs[iService]->szPath, sharepath);
8422 string_set(&ServicePtrs[iService]->comment, comment);
8424 talloc_destroy(ctx);
8429 /***************************************************************************
8430 Checks if a usershare entry has been modified since last load.
8431 ***************************************************************************/
8433 static bool usershare_exists(int iService, time_t *last_mod)
8435 SMB_STRUCT_STAT lsbuf;
8436 const char *usersharepath = Globals.szUsersharePath;
8439 if (asprintf(&fname, "%s/%s",
8441 ServicePtrs[iService]->szService) < 0) {
8445 if (sys_lstat(fname, &lsbuf) != 0) {
8450 if (!S_ISREG(lsbuf.st_mode)) {
8456 *last_mod = lsbuf.st_mtime;
8460 /***************************************************************************
8461 Load a usershare service by name. Returns a valid servicenumber or -1.
8462 ***************************************************************************/
8464 int load_usershare_service(const char *servicename)
8466 SMB_STRUCT_STAT sbuf;
8467 const char *usersharepath = Globals.szUsersharePath;
8468 int max_user_shares = Globals.iUsershareMaxShares;
8469 int snum_template = -1;
8471 if (*usersharepath == 0 || max_user_shares == 0) {
8475 if (sys_stat(usersharepath, &sbuf) != 0) {
8476 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8477 usersharepath, strerror(errno) ));
8481 if (!S_ISDIR(sbuf.st_mode)) {
8482 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8488 * This directory must be owned by root, and have the 't' bit set.
8489 * It also must not be writable by "other".
8493 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8495 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8497 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8498 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8503 /* Ensure the template share exists if it's set. */
8504 if (Globals.szUsershareTemplateShare[0]) {
8505 /* We can't use lp_servicenumber here as we are recommending that
8506 template shares have -valid=False set. */
8507 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8508 if (ServicePtrs[snum_template]->szService &&
8509 strequal(ServicePtrs[snum_template]->szService,
8510 Globals.szUsershareTemplateShare)) {
8515 if (snum_template == -1) {
8516 DEBUG(0,("load_usershare_service: usershare template share %s "
8517 "does not exist.\n",
8518 Globals.szUsershareTemplateShare ));
8523 return process_usershare_file(usersharepath, servicename, snum_template);
8526 /***************************************************************************
8527 Load all user defined shares from the user share directory.
8528 We only do this if we're enumerating the share list.
8529 This is the function that can delete usershares that have
8531 ***************************************************************************/
8533 int load_usershare_shares(void)
8536 SMB_STRUCT_STAT sbuf;
8537 SMB_STRUCT_DIRENT *de;
8538 int num_usershares = 0;
8539 int max_user_shares = Globals.iUsershareMaxShares;
8540 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8541 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8542 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8544 int snum_template = -1;
8545 const char *usersharepath = Globals.szUsersharePath;
8546 int ret = lp_numservices();
8548 if (max_user_shares == 0 || *usersharepath == '\0') {
8549 return lp_numservices();
8552 if (sys_stat(usersharepath, &sbuf) != 0) {
8553 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8554 usersharepath, strerror(errno) ));
8559 * This directory must be owned by root, and have the 't' bit set.
8560 * It also must not be writable by "other".
8564 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8566 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8568 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8569 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8574 /* Ensure the template share exists if it's set. */
8575 if (Globals.szUsershareTemplateShare[0]) {
8576 /* We can't use lp_servicenumber here as we are recommending that
8577 template shares have -valid=False set. */
8578 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8579 if (ServicePtrs[snum_template]->szService &&
8580 strequal(ServicePtrs[snum_template]->szService,
8581 Globals.szUsershareTemplateShare)) {
8586 if (snum_template == -1) {
8587 DEBUG(0,("load_usershare_shares: usershare template share %s "
8588 "does not exist.\n",
8589 Globals.szUsershareTemplateShare ));
8594 /* Mark all existing usershares as pending delete. */
8595 for (iService = iNumServices - 1; iService >= 0; iService--) {
8596 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8597 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8601 dp = sys_opendir(usersharepath);
8603 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8604 usersharepath, strerror(errno) ));
8608 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8609 (de = sys_readdir(dp));
8610 num_dir_entries++ ) {
8612 const char *n = de->d_name;
8614 /* Ignore . and .. */
8616 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8622 /* Temporary file used when creating a share. */
8623 num_tmp_dir_entries++;
8626 /* Allow 20% tmp entries. */
8627 if (num_tmp_dir_entries > allowed_tmp_entries) {
8628 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8629 "in directory %s\n",
8630 num_tmp_dir_entries, usersharepath));
8634 r = process_usershare_file(usersharepath, n, snum_template);
8636 /* Update the services count. */
8638 if (num_usershares >= max_user_shares) {
8639 DEBUG(0,("load_usershare_shares: max user shares reached "
8640 "on file %s in directory %s\n",
8641 n, usersharepath ));
8644 } else if (r == -1) {
8645 num_bad_dir_entries++;
8648 /* Allow 20% bad entries. */
8649 if (num_bad_dir_entries > allowed_bad_entries) {
8650 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8651 "in directory %s\n",
8652 num_bad_dir_entries, usersharepath));
8656 /* Allow 20% bad entries. */
8657 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8658 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8659 "in directory %s\n",
8660 num_dir_entries, usersharepath));
8667 /* Sweep through and delete any non-refreshed usershares that are
8668 not currently in use. */
8669 for (iService = iNumServices - 1; iService >= 0; iService--) {
8670 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8671 if (conn_snum_used(iService)) {
8674 /* Remove from the share ACL db. */
8675 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8676 lp_servicename(iService) ));
8677 delete_share_security(lp_servicename(iService));
8678 free_service_byindex(iService);
8682 return lp_numservices();
8685 /********************************************************
8686 Destroy global resources allocated in this file
8687 ********************************************************/
8689 void gfree_loadparm(void)
8691 struct file_lists *f;
8692 struct file_lists *next;
8695 /* Free the file lists */
8700 SAFE_FREE( f->name );
8701 SAFE_FREE( f->subfname );
8707 /* Free resources allocated to services */
8709 for ( i = 0; i < iNumServices; i++ ) {
8711 free_service_byindex(i);
8715 SAFE_FREE( ServicePtrs );
8718 /* Now release all resources allocated to global
8719 parameters and the default service */
8721 free_global_parameters();
8725 /***************************************************************************
8726 Allow client apps to specify that they are a client
8727 ***************************************************************************/
8728 void lp_set_in_client(bool b)
8734 /***************************************************************************
8735 Determine if we're running in a client app
8736 ***************************************************************************/
8737 bool lp_is_in_client(void)
8742 /***************************************************************************
8743 Load the services array from the services file. Return True on success,
8745 ***************************************************************************/
8747 bool lp_load_ex(const char *pszFname,
8751 bool initialize_globals,
8752 bool allow_include_registry,
8753 bool allow_registry_shares)
8760 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8762 bInGlobalSection = True;
8763 bGlobalOnly = global_only;
8764 bAllowIncludeRegistry = allow_include_registry;
8766 init_globals(! initialize_globals);
8769 if (save_defaults) {
8774 free_param_opts(&Globals.param_opt);
8776 /* We get sections first, so have to start 'behind' to make up */
8779 if (lp_config_backend_is_file()) {
8780 n2 = alloc_sub_basic(get_current_username(),
8781 current_user_info.domain,
8784 smb_panic("lp_load_ex: out of memory");
8787 add_to_file_list(pszFname, n2);
8789 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8792 /* finish up the last section */
8793 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8795 if (iServiceIndex >= 0) {
8796 bRetval = service_ok(iServiceIndex);
8800 if (lp_config_backend_is_registry()) {
8801 /* config backend changed to registry in config file */
8803 * We need to use this extra global variable here to
8804 * survive restart: init_globals uses this as a default
8805 * for ConfigBackend. Otherwise, init_globals would
8806 * send us into an endless loop here.
8808 config_backend = CONFIG_BACKEND_REGISTRY;
8810 DEBUG(1, ("lp_load_ex: changing to config backend "
8812 init_globals(false);
8813 lp_kill_all_services();
8814 return lp_load_ex(pszFname, global_only, save_defaults,
8815 add_ipc, initialize_globals,
8816 allow_include_registry,
8817 allow_registry_shares);
8819 } else if (lp_config_backend_is_registry()) {
8820 bRetval = process_registry_globals();
8822 DEBUG(0, ("Illegal config backend given: %d\n",
8823 lp_config_backend()));
8827 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8828 bRetval = process_registry_shares();
8831 lp_add_auto_services(lp_auto_services());
8834 /* When 'restrict anonymous = 2' guest connections to ipc$
8836 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8837 if ( lp_enable_asu_support() ) {
8838 lp_add_ipc("ADMIN$", false);
8843 set_default_server_announce_type();
8844 set_allowed_client_auth();
8848 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8849 /* if bWINSsupport is true and we are in the client */
8850 if (lp_is_in_client() && Globals.bWINSsupport) {
8851 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8856 bAllowIncludeRegistry = true;
8861 bool lp_load(const char *pszFname,
8865 bool initialize_globals)
8867 return lp_load_ex(pszFname,
8875 bool lp_load_initial_only(const char *pszFname)
8877 return lp_load_ex(pszFname,
8886 bool lp_load_with_registry_shares(const char *pszFname,
8890 bool initialize_globals)
8892 return lp_load_ex(pszFname,
8901 /***************************************************************************
8902 Return the max number of services.
8903 ***************************************************************************/
8905 int lp_numservices(void)
8907 return (iNumServices);
8910 /***************************************************************************
8911 Display the contents of the services array in human-readable form.
8912 ***************************************************************************/
8914 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8919 defaults_saved = False;
8923 dump_a_service(&sDefault, f);
8925 for (iService = 0; iService < maxtoprint; iService++) {
8927 lp_dump_one(f, show_defaults, iService);
8931 /***************************************************************************
8932 Display the contents of one service in human-readable form.
8933 ***************************************************************************/
8935 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8938 if (ServicePtrs[snum]->szService[0] == '\0')
8940 dump_a_service(ServicePtrs[snum], f);
8944 /***************************************************************************
8945 Return the number of the service with the given name, or -1 if it doesn't
8946 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8947 getservicebyname()! This works ONLY if all services have been loaded, and
8948 does not copy the found service.
8949 ***************************************************************************/
8951 int lp_servicenumber(const char *pszServiceName)
8954 fstring serviceName;
8956 if (!pszServiceName) {
8957 return GLOBAL_SECTION_SNUM;
8960 for (iService = iNumServices - 1; iService >= 0; iService--) {
8961 if (VALID(iService) && ServicePtrs[iService]->szService) {
8963 * The substitution here is used to support %U is
8966 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8967 standard_sub_basic(get_current_username(),
8968 current_user_info.domain,
8969 serviceName,sizeof(serviceName));
8970 if (strequal(serviceName, pszServiceName)) {
8976 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8979 if (!usershare_exists(iService, &last_mod)) {
8980 /* Remove the share security tdb entry for it. */
8981 delete_share_security(lp_servicename(iService));
8982 /* Remove it from the array. */
8983 free_service_byindex(iService);
8984 /* Doesn't exist anymore. */
8985 return GLOBAL_SECTION_SNUM;
8988 /* Has it been modified ? If so delete and reload. */
8989 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
8990 /* Remove it from the array. */
8991 free_service_byindex(iService);
8992 /* and now reload it. */
8993 iService = load_usershare_service(pszServiceName);
8998 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
8999 return GLOBAL_SECTION_SNUM;
9005 bool share_defined(const char *service_name)
9007 return (lp_servicenumber(service_name) != -1);
9010 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9011 const char *sharename)
9013 struct share_params *result;
9017 if (!(sname = SMB_STRDUP(sharename))) {
9021 snum = find_service(sname);
9028 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9029 DEBUG(0, ("talloc failed\n"));
9033 result->service = snum;
9037 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9039 struct share_iterator *result;
9041 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9042 DEBUG(0, ("talloc failed\n"));
9046 result->next_id = 0;
9050 struct share_params *next_share(struct share_iterator *list)
9052 struct share_params *result;
9054 while (!lp_snum_ok(list->next_id) &&
9055 (list->next_id < lp_numservices())) {
9059 if (list->next_id >= lp_numservices()) {
9063 if (!(result = TALLOC_P(list, struct share_params))) {
9064 DEBUG(0, ("talloc failed\n"));
9068 result->service = list->next_id;
9073 struct share_params *next_printer(struct share_iterator *list)
9075 struct share_params *result;
9077 while ((result = next_share(list)) != NULL) {
9078 if (lp_print_ok(result->service)) {
9086 * This is a hack for a transition period until we transformed all code from
9087 * service numbers to struct share_params.
9090 struct share_params *snum2params_static(int snum)
9092 static struct share_params result;
9093 result.service = snum;
9097 /*******************************************************************
9098 A useful volume label function.
9099 ********************************************************************/
9101 const char *volume_label(int snum)
9104 const char *label = lp_volume(snum);
9106 label = lp_servicename(snum);
9109 /* This returns a 33 byte guarenteed null terminated string. */
9110 ret = talloc_strndup(talloc_tos(), label, 32);
9117 /*******************************************************************
9118 Set the server type we will announce as via nmbd.
9119 ********************************************************************/
9121 static void set_default_server_announce_type(void)
9123 default_server_announce = 0;
9124 default_server_announce |= SV_TYPE_WORKSTATION;
9125 default_server_announce |= SV_TYPE_SERVER;
9126 default_server_announce |= SV_TYPE_SERVER_UNIX;
9128 /* note that the flag should be set only if we have a
9129 printer service but nmbd doesn't actually load the
9130 services so we can't tell --jerry */
9132 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9134 switch (lp_announce_as()) {
9135 case ANNOUNCE_AS_NT_SERVER:
9136 default_server_announce |= SV_TYPE_SERVER_NT;
9137 /* fall through... */
9138 case ANNOUNCE_AS_NT_WORKSTATION:
9139 default_server_announce |= SV_TYPE_NT;
9141 case ANNOUNCE_AS_WIN95:
9142 default_server_announce |= SV_TYPE_WIN95_PLUS;
9144 case ANNOUNCE_AS_WFW:
9145 default_server_announce |= SV_TYPE_WFW;
9151 switch (lp_server_role()) {
9152 case ROLE_DOMAIN_MEMBER:
9153 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9155 case ROLE_DOMAIN_PDC:
9156 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9158 case ROLE_DOMAIN_BDC:
9159 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9161 case ROLE_STANDALONE:
9165 if (lp_time_server())
9166 default_server_announce |= SV_TYPE_TIME_SOURCE;
9168 if (lp_host_msdfs())
9169 default_server_announce |= SV_TYPE_DFS_SERVER;
9172 /***********************************************************
9173 returns role of Samba server
9174 ************************************************************/
9176 int lp_server_role(void)
9181 /***********************************************************
9182 If we are PDC then prefer us as DMB
9183 ************************************************************/
9185 bool lp_domain_master(void)
9187 if (Globals.iDomainMaster == Auto)
9188 return (lp_server_role() == ROLE_DOMAIN_PDC);
9190 return (bool)Globals.iDomainMaster;
9193 /***********************************************************
9194 If we are DMB then prefer us as LMB
9195 ************************************************************/
9197 bool lp_preferred_master(void)
9199 if (Globals.iPreferredMaster == Auto)
9200 return (lp_local_master() && lp_domain_master());
9202 return (bool)Globals.iPreferredMaster;
9205 /*******************************************************************
9207 ********************************************************************/
9209 void lp_remove_service(int snum)
9211 ServicePtrs[snum]->valid = False;
9212 invalid_services[num_invalid_services++] = snum;
9215 /*******************************************************************
9217 ********************************************************************/
9219 void lp_copy_service(int snum, const char *new_name)
9221 do_section(new_name, NULL);
9223 snum = lp_servicenumber(new_name);
9225 lp_do_parameter(snum, "copy", lp_servicename(snum));
9230 /*******************************************************************
9231 Get the default server type we will announce as via nmbd.
9232 ********************************************************************/
9234 int lp_default_server_announce(void)
9236 return default_server_announce;
9239 /*******************************************************************
9240 Split the announce version into major and minor numbers.
9241 ********************************************************************/
9243 int lp_major_announce_version(void)
9245 static bool got_major = False;
9246 static int major_version = DEFAULT_MAJOR_VERSION;
9251 return major_version;
9254 if ((vers = lp_announce_version()) == NULL)
9255 return major_version;
9257 if ((p = strchr_m(vers, '.')) == 0)
9258 return major_version;
9261 major_version = atoi(vers);
9262 return major_version;
9265 int lp_minor_announce_version(void)
9267 static bool got_minor = False;
9268 static int minor_version = DEFAULT_MINOR_VERSION;
9273 return minor_version;
9276 if ((vers = lp_announce_version()) == NULL)
9277 return minor_version;
9279 if ((p = strchr_m(vers, '.')) == 0)
9280 return minor_version;
9283 minor_version = atoi(p);
9284 return minor_version;
9287 /***********************************************************
9288 Set the global name resolution order (used in smbclient).
9289 ************************************************************/
9291 void lp_set_name_resolve_order(const char *new_order)
9293 string_set(&Globals.szNameResolveOrder, new_order);
9296 const char *lp_printername(int snum)
9298 const char *ret = _lp_printername(snum);
9299 if (ret == NULL || (ret != NULL && *ret == '\0'))
9300 ret = lp_const_servicename(snum);
9306 /***********************************************************
9307 Allow daemons such as winbindd to fix their logfile name.
9308 ************************************************************/
9310 void lp_set_logfile(const char *name)
9312 string_set(&Globals.szLogFile, name);
9313 debug_set_logfile(name);
9316 /*******************************************************************
9317 Return the max print jobs per queue.
9318 ********************************************************************/
9320 int lp_maxprintjobs(int snum)
9322 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9323 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9324 maxjobs = PRINT_MAX_JOBID - 1;
9329 const char *lp_printcapname(void)
9331 if ((Globals.szPrintcapname != NULL) &&
9332 (Globals.szPrintcapname[0] != '\0'))
9333 return Globals.szPrintcapname;
9335 if (sDefault.iPrinting == PRINT_CUPS) {
9343 if (sDefault.iPrinting == PRINT_BSD)
9344 return "/etc/printcap";
9346 return PRINTCAP_NAME;
9349 /*******************************************************************
9350 Ensure we don't use sendfile if server smb signing is active.
9351 ********************************************************************/
9353 static uint32 spoolss_state;
9355 bool lp_disable_spoolss( void )
9357 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9358 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9360 return spoolss_state == SVCCTL_STOPPED ? True : False;
9363 void lp_set_spoolss_state( uint32 state )
9365 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9367 spoolss_state = state;
9370 uint32 lp_get_spoolss_state( void )
9372 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9375 /*******************************************************************
9376 Ensure we don't use sendfile if server smb signing is active.
9377 ********************************************************************/
9379 bool lp_use_sendfile(int snum)
9381 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9382 if (Protocol < PROTOCOL_NT1) {
9385 return (_lp_use_sendfile(snum) &&
9386 (get_remote_arch() != RA_WIN95) &&
9387 !srv_is_signing_active());
9390 /*******************************************************************
9391 Turn off sendfile if we find the underlying OS doesn't support it.
9392 ********************************************************************/
9394 void set_use_sendfile(int snum, bool val)
9396 if (LP_SNUM_OK(snum))
9397 ServicePtrs[snum]->bUseSendfile = val;
9399 sDefault.bUseSendfile = val;
9402 /*******************************************************************
9403 Turn off storing DOS attributes if this share doesn't support it.
9404 ********************************************************************/
9406 void set_store_dos_attributes(int snum, bool val)
9408 if (!LP_SNUM_OK(snum))
9410 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9413 void lp_set_mangling_method(const char *new_method)
9415 string_set(&Globals.szManglingMethod, new_method);
9418 /*******************************************************************
9419 Global state for POSIX pathname processing.
9420 ********************************************************************/
9422 static bool posix_pathnames;
9424 bool lp_posix_pathnames(void)
9426 return posix_pathnames;
9429 /*******************************************************************
9430 Change everything needed to ensure POSIX pathname processing (currently
9432 ********************************************************************/
9434 void lp_set_posix_pathnames(void)
9436 posix_pathnames = True;
9439 /*******************************************************************
9440 Global state for POSIX lock processing - CIFS unix extensions.
9441 ********************************************************************/
9443 bool posix_default_lock_was_set;
9444 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9446 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9448 if (posix_default_lock_was_set) {
9449 return posix_cifsx_locktype;
9451 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9455 /*******************************************************************
9456 ********************************************************************/
9458 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9460 posix_default_lock_was_set = True;
9461 posix_cifsx_locktype = val;
9464 int lp_min_receive_file_size(void)
9466 if (Globals.iminreceivefile < 0) {
9469 return MIN(Globals.iminreceivefile, BUFFER_SIZE);