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
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 3 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
30 * This module provides suitable callback functions for the params
31 * module. It builds the internal table of service details which is
32 * then used by the rest of the server.
36 * 1) add it to the global or service structure definition
37 * 2) add it to the parm_table
38 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
39 * 4) If it's a global then initialise it in init_globals. If a local
40 * (ie. service) parameter then initialise it in the sDefault structure
44 * The configuration file is processed sequentially for speed. It is NOT
45 * accessed randomly as happens in 'real' Windows. For this reason, there
46 * is a fair bit of sequence-dependent code here - ie., code which assumes
47 * that certain things happen before others. In particular, the code which
48 * happens at the boundary between sections is delicately poised, so be
55 bool in_client = False; /* Not in the client by default */
58 extern enum protocol_types Protocol;
59 extern userdom_struct current_user_info;
62 #define GLOBAL_NAME "global"
66 #define PRINTERS_NAME "printers"
70 #define HOMES_NAME "homes"
73 /* the special value for the include parameter
74 * to be interpreted not as a file name but to
75 * trigger loading of the global smb.conf options
77 #ifndef INCLUDE_REGISTRY_NAME
78 #define INCLUDE_REGISTRY_NAME "registry"
81 static int regdb_last_seqnum = 0;
82 static bool include_registry_globals = False;
84 /* some helpful bits */
85 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
86 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
88 #define USERSHARE_VALID 1
89 #define USERSHARE_PENDING_DELETE 2
91 bool use_getwd_cache = True;
93 extern int extra_time_offset;
95 static bool defaults_saved = False;
97 typedef struct _param_opt_struct param_opt_struct;
98 struct _param_opt_struct {
99 param_opt_struct *prev, *next;
106 * This structure describes global (ie., server-wide) parameters.
112 char *display_charset;
113 char *szPrintcapname;
114 char *szAddPortCommand;
115 char *szEnumPortsCommand;
116 char *szAddPrinterCommand;
117 char *szDeletePrinterCommand;
118 char *szOs2DriverMap;
122 char *szDefaultService;
126 char *szServerString;
127 char *szAutoServices;
128 char *szPasswdProgram;
132 char *szSMBPasswdFile;
134 char *szPassdbBackend;
135 char **szPreloadModules;
136 char *szPasswordServer;
137 char *szSocketOptions;
139 char *szAfsUsernameMap;
140 int iAfsTokenLifetime;
141 char *szLogNtTokenCommand;
147 char **szWINSservers;
149 char *szRemoteAnnounce;
150 char *szRemoteBrowseSync;
151 char *szSocketAddress;
152 char *szNISHomeMapName;
153 char *szAnnounceVersion; /* This is initialised in init_globals */
156 char **szNetbiosAliases;
157 char *szNetbiosScope;
158 char *szNameResolveOrder;
160 char *szAddUserScript;
161 char *szRenameUserScript;
162 char *szDelUserScript;
163 char *szAddGroupScript;
164 char *szDelGroupScript;
165 char *szAddUserToGroupScript;
166 char *szDelUserFromGroupScript;
167 char *szSetPrimaryGroupScript;
168 char *szAddMachineScript;
169 char *szShutdownScript;
170 char *szAbortShutdownScript;
171 char *szUsernameMapScript;
172 char *szCheckPasswordScript;
179 bool bPassdbExpandExplicit;
180 int AlgorithmicRidBase;
181 char *szTemplateHomedir;
182 char *szTemplateShell;
183 char *szWinbindSeparator;
184 bool bWinbindEnumUsers;
185 bool bWinbindEnumGroups;
186 bool bWinbindUseDefaultDomain;
187 bool bWinbindTrustedDomainsOnly;
188 bool bWinbindNestedGroups;
189 int winbind_expand_groups;
190 bool bWinbindRefreshTickets;
191 bool bWinbindOfflineLogon;
192 bool bWinbindNormalizeNames;
193 bool bWinbindRpcOnly;
194 char **szIdmapDomains;
195 char **szIdmapBackend; /* deprecated */
196 char *szIdmapAllocBackend;
197 char *szAddShareCommand;
198 char *szChangeShareCommand;
199 char *szDeleteShareCommand;
201 char *szGuestaccount;
202 char *szManglingMethod;
203 char **szServicesList;
204 char *szUsersharePath;
205 char *szUsershareTemplateShare;
206 char **szUsersharePrefixAllowList;
207 char **szUsersharePrefixDenyList;
214 int open_files_db_hash_size;
222 bool paranoid_server_security;
225 int iMaxSmbdProcesses;
226 bool bDisableSpoolss;
229 bool enhanced_browsing;
235 int announce_as; /* This is initialised in init_globals */
236 int machine_password_timeout;
238 int oplock_break_wait_time;
239 int winbind_cache_time;
240 int winbind_max_idle_children;
241 char **szWinbindNssInfo;
243 char *szLdapMachineSuffix;
244 char *szLdapUserSuffix;
245 char *szLdapIdmapSuffix;
246 char *szLdapGroupSuffix;
252 char *szIPrintServer;
254 char **szClusterAddresses;
256 int ldap_passwd_sync;
257 int ldap_replication_sleep;
258 int ldap_timeout; /* This is initialised in init_globals */
261 bool bMsAddPrinterWizard;
266 int iPreferredMaster;
269 bool bEncryptPasswords;
274 bool bObeyPamRestrictions;
276 int PrintcapCacheTime;
277 bool bLargeReadwrite;
284 bool bBindInterfacesOnly;
285 bool bPamPasswordChange;
286 bool bUnixPasswdSync;
287 bool bPasswdChatDebug;
288 int iPasswdChatTimeout;
292 bool bNTStatusSupport;
294 int iMaxStatCacheSize;
296 bool bAllowTrustedDomains;
300 bool bClientLanManAuth;
301 bool bClientNTLMv2Auth;
302 bool bClientPlaintextAuth;
303 bool bClientUseSpnego;
304 bool bDebugPrefixTimestamp;
305 bool bDebugHiresTimestamp;
309 bool bEnableCoreFiles;
312 bool bHostnameLookups;
313 bool bUnixExtensions;
314 bool bDisableNetbios;
315 bool bUseKerberosKeytab;
316 bool bDeferSharingViolations;
317 bool bEnablePrivileges;
319 bool bUsershareOwnerOnly;
320 bool bUsershareAllowGuests;
321 bool bRegistryShares;
322 int restrict_anonymous;
323 int name_cache_timeout;
326 int client_ldap_sasl_wrapping;
327 int iUsershareMaxShares;
329 int iIdmapNegativeCacheTime;
334 param_opt_struct *param_opt;
337 static global Globals;
340 * This structure describes a single service.
346 time_t usershare_last_mod;
350 char **szInvalidUsers;
358 char *szRootPostExec;
360 char *szPrintcommand;
363 char *szLppausecommand;
364 char *szLpresumecommand;
365 char *szQueuepausecommand;
366 char *szQueueresumecommand;
368 char *szPrintjobUsername;
376 char *szVetoOplockFiles;
382 char **printer_admin;
387 char *szAioWriteBehind;
391 int iMaxReportedPrintJobs;
394 int iCreate_force_mode;
396 int iSecurity_force_mode;
399 int iDir_Security_mask;
400 int iDir_Security_force_mode;
404 int iOplockContentionLimit;
409 bool bRootpreexecClose;
412 bool bShortCasePreserve;
414 bool bHideSpecialFiles;
415 bool bHideUnReadable;
416 bool bHideUnWriteableFiles;
427 bool bStoreDosAttributes;
440 bool bStrictAllocate;
443 struct bitmap *copymap;
444 bool bDeleteReadonly;
446 bool bDeleteVetoFiles;
449 bool bDosFiletimeResolution;
450 bool bFakeDirCreateTimes;
456 bool bUseClientDriver;
457 bool bDefaultDevmode;
458 bool bForcePrintername;
460 bool bForceUnknownAclUser;
463 bool bMap_acl_inherit;
466 bool bAclCheckPermissions;
467 bool bAclMapFullControl;
468 bool bAclGroupControl;
470 bool bKernelChangeNotify;
471 int iallocation_roundup_size;
475 int iDirectoryNameCacheSize;
476 param_opt_struct *param_opt;
478 char dummy[3]; /* for alignment */
482 /* This is a default service used to prime a services structure */
483 static service sDefault = {
485 False, /* not autoloaded */
486 0, /* not a usershare */
487 (time_t)0, /* No last mod time */
488 NULL, /* szService */
490 NULL, /* szUsername */
491 NULL, /* szInvalidUsers */
492 NULL, /* szValidUsers */
493 NULL, /* szAdminUsers */
495 NULL, /* szInclude */
496 NULL, /* szPreExec */
497 NULL, /* szPostExec */
498 NULL, /* szRootPreExec */
499 NULL, /* szRootPostExec */
500 NULL, /* szCupsOptions */
501 NULL, /* szPrintcommand */
502 NULL, /* szLpqcommand */
503 NULL, /* szLprmcommand */
504 NULL, /* szLppausecommand */
505 NULL, /* szLpresumecommand */
506 NULL, /* szQueuepausecommand */
507 NULL, /* szQueueresumecommand */
508 NULL, /* szPrintername */
509 NULL, /* szPrintjobUsername */
510 NULL, /* szDontdescend */
511 NULL, /* szHostsallow */
512 NULL, /* szHostsdeny */
513 NULL, /* szMagicScript */
514 NULL, /* szMagicOutput */
515 NULL, /* szVetoFiles */
516 NULL, /* szHideFiles */
517 NULL, /* szVetoOplockFiles */
519 NULL, /* force user */
520 NULL, /* force group */
522 NULL, /* writelist */
523 NULL, /* printer admin */
526 NULL, /* vfs objects */
527 NULL, /* szMSDfsProxy */
528 NULL, /* szAioWriteBehind */
530 0, /* iMinPrintSpace */
531 1000, /* iMaxPrintJobs */
532 0, /* iMaxReportedPrintJobs */
533 0, /* iWriteCacheSize */
534 0744, /* iCreate_mask */
535 0000, /* iCreate_force_mode */
536 0777, /* iSecurity_mask */
537 0, /* iSecurity_force_mode */
538 0755, /* iDir_mask */
539 0000, /* iDir_force_mode */
540 0777, /* iDir_Security_mask */
541 0, /* iDir_Security_force_mode */
542 0, /* iMaxConnections */
543 CASE_LOWER, /* iDefaultCase */
544 DEFAULT_PRINTING, /* iPrinting */
545 2, /* iOplockContentionLimit */
547 1024, /* iBlock_size */
548 0, /* iDfreeCacheTime */
549 False, /* bPreexecClose */
550 False, /* bRootpreexecClose */
551 Auto, /* case sensitive */
552 True, /* case preserve */
553 True, /* short case preserve */
554 True, /* bHideDotFiles */
555 False, /* bHideSpecialFiles */
556 False, /* bHideUnReadable */
557 False, /* bHideUnWriteableFiles */
558 True, /* bBrowseable */
559 True, /* bAvailable */
560 True, /* bRead_only */
561 True, /* bNo_set_dir */
562 False, /* bGuest_only */
563 False, /* bGuest_ok */
564 False, /* bPrint_ok */
565 False, /* bMap_system */
566 False, /* bMap_hidden */
567 True, /* bMap_archive */
568 False, /* bStoreDosAttributes */
569 False, /* bDmapiSupport */
571 Auto, /* iStrictLocking */
572 True, /* bPosixLocking */
573 True, /* bShareModes */
575 True, /* bLevel2OpLocks */
576 False, /* bOnlyUser */
577 True, /* bMangledNames */
578 True, /* bWidelinks */
579 True, /* bSymlinks */
580 False, /* bSyncAlways */
581 False, /* bStrictAllocate */
582 False, /* bStrictSync */
583 '~', /* magic char */
585 False, /* bDeleteReadonly */
586 False, /* bFakeOplocks */
587 False, /* bDeleteVetoFiles */
588 False, /* bDosFilemode */
589 True, /* bDosFiletimes */
590 False, /* bDosFiletimeResolution */
591 False, /* bFakeDirCreateTimes */
592 True, /* bBlockingLocks */
593 False, /* bInheritPerms */
594 False, /* bInheritACLS */
595 False, /* bInheritOwner */
596 False, /* bMSDfsRoot */
597 False, /* bUseClientDriver */
598 True, /* bDefaultDevmode */
599 False, /* bForcePrintername */
600 True, /* bNTAclSupport */
601 False, /* bForceUnknownAclUser */
602 False, /* bUseSendfile */
603 False, /* bProfileAcls */
604 False, /* bMap_acl_inherit */
605 False, /* bAfs_Share */
606 False, /* bEASupport */
607 True, /* bAclCheckPermissions */
608 True, /* bAclMapFullControl */
609 False, /* bAclGroupControl */
610 True, /* bChangeNotify */
611 True, /* bKernelChangeNotify */
612 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
613 0, /* iAioReadSize */
614 0, /* iAioWriteSize */
615 MAP_READONLY_YES, /* iMap_readonly */
616 #ifdef BROKEN_DIRECTORY_HANDLING
617 0, /* iDirectoryNameCacheSize */
619 100, /* iDirectoryNameCacheSize */
621 NULL, /* Parametric options */
626 /* local variables */
627 static service **ServicePtrs = NULL;
628 static int iNumServices = 0;
629 static int iServiceIndex = 0;
630 static TDB_CONTEXT *ServiceHash;
631 static int *invalid_services = NULL;
632 static int num_invalid_services = 0;
633 static bool bInGlobalSection = True;
634 static bool bGlobalOnly = False;
635 static int server_role;
636 static int default_server_announce;
638 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
640 /* prototypes for the special type handlers */
641 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
642 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
643 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
644 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
645 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
646 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
647 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
648 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
649 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
650 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
651 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
653 static void set_server_role(void);
654 static void set_default_server_announce_type(void);
655 static void set_allowed_client_auth(void);
657 static const struct enum_list enum_protocol[] = {
658 {PROTOCOL_NT1, "NT1"},
659 {PROTOCOL_LANMAN2, "LANMAN2"},
660 {PROTOCOL_LANMAN1, "LANMAN1"},
661 {PROTOCOL_CORE, "CORE"},
662 {PROTOCOL_COREPLUS, "COREPLUS"},
663 {PROTOCOL_COREPLUS, "CORE+"},
667 static const struct enum_list enum_security[] = {
668 {SEC_SHARE, "SHARE"},
670 {SEC_SERVER, "SERVER"},
671 {SEC_DOMAIN, "DOMAIN"},
678 static const struct enum_list enum_printing[] = {
679 {PRINT_SYSV, "sysv"},
681 {PRINT_HPUX, "hpux"},
685 {PRINT_LPRNG, "lprng"},
686 {PRINT_CUPS, "cups"},
687 {PRINT_IPRINT, "iprint"},
689 {PRINT_LPROS2, "os2"},
691 {PRINT_TEST, "test"},
693 #endif /* DEVELOPER */
697 static const struct enum_list enum_ldap_sasl_wrapping[] = {
699 {ADS_AUTH_SASL_SIGN, "sign"},
700 {ADS_AUTH_SASL_SEAL, "seal"},
704 static const struct enum_list enum_ldap_ssl[] = {
705 {LDAP_SSL_OFF, "no"},
706 {LDAP_SSL_OFF, "No"},
707 {LDAP_SSL_OFF, "off"},
708 {LDAP_SSL_OFF, "Off"},
709 {LDAP_SSL_START_TLS, "start tls"},
710 {LDAP_SSL_START_TLS, "Start_tls"},
714 static const struct enum_list enum_ldap_passwd_sync[] = {
715 {LDAP_PASSWD_SYNC_OFF, "no"},
716 {LDAP_PASSWD_SYNC_OFF, "No"},
717 {LDAP_PASSWD_SYNC_OFF, "off"},
718 {LDAP_PASSWD_SYNC_OFF, "Off"},
719 {LDAP_PASSWD_SYNC_ON, "Yes"},
720 {LDAP_PASSWD_SYNC_ON, "yes"},
721 {LDAP_PASSWD_SYNC_ON, "on"},
722 {LDAP_PASSWD_SYNC_ON, "On"},
723 {LDAP_PASSWD_SYNC_ONLY, "Only"},
724 {LDAP_PASSWD_SYNC_ONLY, "only"},
728 /* Types of machine we can announce as. */
729 #define ANNOUNCE_AS_NT_SERVER 1
730 #define ANNOUNCE_AS_WIN95 2
731 #define ANNOUNCE_AS_WFW 3
732 #define ANNOUNCE_AS_NT_WORKSTATION 4
734 static const struct enum_list enum_announce_as[] = {
735 {ANNOUNCE_AS_NT_SERVER, "NT"},
736 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
737 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
738 {ANNOUNCE_AS_WIN95, "win95"},
739 {ANNOUNCE_AS_WFW, "WfW"},
743 static const struct enum_list enum_map_readonly[] = {
744 {MAP_READONLY_NO, "no"},
745 {MAP_READONLY_NO, "false"},
746 {MAP_READONLY_NO, "0"},
747 {MAP_READONLY_YES, "yes"},
748 {MAP_READONLY_YES, "true"},
749 {MAP_READONLY_YES, "1"},
750 {MAP_READONLY_PERMISSIONS, "permissions"},
751 {MAP_READONLY_PERMISSIONS, "perms"},
755 static const struct enum_list enum_case[] = {
756 {CASE_LOWER, "lower"},
757 {CASE_UPPER, "upper"},
761 static const struct enum_list enum_bool_auto[] = {
772 /* Client-side offline caching policy types */
773 #define CSC_POLICY_MANUAL 0
774 #define CSC_POLICY_DOCUMENTS 1
775 #define CSC_POLICY_PROGRAMS 2
776 #define CSC_POLICY_DISABLE 3
778 static const struct enum_list enum_csc_policy[] = {
779 {CSC_POLICY_MANUAL, "manual"},
780 {CSC_POLICY_DOCUMENTS, "documents"},
781 {CSC_POLICY_PROGRAMS, "programs"},
782 {CSC_POLICY_DISABLE, "disable"},
786 /* SMB signing types. */
787 static const struct enum_list enum_smb_signing_vals[] = {
799 {Required, "required"},
800 {Required, "mandatory"},
802 {Required, "forced"},
803 {Required, "enforced"},
807 /* ACL compatibility options. */
808 static const struct enum_list enum_acl_compat_vals[] = {
809 { ACL_COMPAT_AUTO, "auto" },
810 { ACL_COMPAT_WINNT, "winnt" },
811 { ACL_COMPAT_WIN2K, "win2k" },
816 Do you want session setups at user level security with a invalid
817 password to be rejected or allowed in as guest? WinNT rejects them
818 but it can be a pain as it means "net view" needs to use a password
820 You have 3 choices in the setting of map_to_guest:
822 "Never" means session setups with an invalid password
823 are rejected. This is the default.
825 "Bad User" means session setups with an invalid password
826 are rejected, unless the username does not exist, in which case it
827 is treated as a guest login
829 "Bad Password" means session setups with an invalid password
830 are treated as a guest login
832 Note that map_to_guest only has an effect in user or server
836 static const struct enum_list enum_map_to_guest[] = {
837 {NEVER_MAP_TO_GUEST, "Never"},
838 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
839 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
840 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
844 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
846 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
847 * screen in SWAT. This is used to exclude parameters as well as to squash all
848 * parameters that have been duplicated by pseudonyms.
850 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
851 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
852 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
855 * NOTE2: Handling of duplicated (synonym) paramters:
856 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
857 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
858 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
859 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
862 static struct parm_struct parm_table[] = {
863 {N_("Base Options"), P_SEP, P_SEPARATOR},
865 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
866 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
867 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
868 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
869 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
870 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
871 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
873 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
875 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
876 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
877 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
878 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
879 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
880 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
882 {N_("Security Options"), P_SEP, P_SEPARATOR},
884 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
885 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
886 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
887 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
888 {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
889 {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
890 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
891 {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
892 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
893 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
894 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
895 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
896 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
897 {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
898 {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
899 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
900 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
901 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
902 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
903 {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
905 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
906 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
907 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
908 {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
909 {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
910 {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED},
911 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
912 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
913 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
914 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
915 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
916 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
917 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
918 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
919 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
920 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
922 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
923 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
924 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
926 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
927 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
928 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
929 {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
930 {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
931 {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED },
932 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
933 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
934 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
936 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
937 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
938 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
939 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
941 {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
942 {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED },
943 {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
944 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
945 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
946 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
947 {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
948 {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
949 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
950 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
951 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
952 {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
953 {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
954 {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
955 {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
956 {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
957 {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
958 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
959 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
961 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
962 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
964 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
965 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
966 {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
967 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
968 {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
969 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
970 {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED},
972 {N_("Logging Options"), P_SEP, P_SEPARATOR},
974 {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
975 {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
976 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
977 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
978 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
980 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
981 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
982 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
983 {"debug prefix timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugPrefixTimestamp, NULL, NULL, FLAG_ADVANCED},
984 {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
985 {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
986 {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
987 {"debug class", P_BOOL, P_GLOBAL, &Globals.bDebugClass, NULL, NULL, FLAG_ADVANCED},
988 {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
990 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
992 {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED},
993 {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED},
994 {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED},
995 {"aio write behind", P_STRING, P_LOCAL, &sDefault.szAioWriteBehind, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
996 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
997 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
998 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
999 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
1000 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
1001 {"min receivefile size", P_INTEGER, P_GLOBAL, &Globals.iminreceivefile, NULL, NULL, FLAG_ADVANCED},
1002 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
1003 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
1004 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
1005 {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED},
1007 {"acl compatibility", P_ENUM, P_GLOBAL, &Globals.iAclCompat, NULL, enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1008 {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1009 {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1010 {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1011 {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
1012 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
1013 {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1015 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
1016 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED},
1017 {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1018 {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1019 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
1020 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
1022 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1023 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
1024 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
1025 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
1026 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
1027 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
1028 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
1029 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1030 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1031 {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
1032 {"client ldap sasl wrapping", P_ENUM, P_GLOBAL, &Globals.client_ldap_sasl_wrapping, NULL, enum_ldap_sasl_wrapping, FLAG_ADVANCED},
1033 {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED},
1034 {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
1036 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1038 {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1039 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
1040 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
1041 {"keepalive", P_INTEGER, P_GLOBAL, &Globals.iKeepalive, NULL, NULL, FLAG_ADVANCED},
1042 {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1043 {"directory name cache size", P_INTEGER, P_LOCAL, &sDefault.iDirectoryNameCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1044 {"kernel change notify", P_BOOL, P_LOCAL, &sDefault.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1046 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
1047 {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
1048 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1049 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
1050 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
1051 {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
1052 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1054 {"socket options", P_STRING, P_GLOBAL, &Globals.szSocketOptions, NULL, NULL, FLAG_ADVANCED},
1055 {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1056 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1057 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1058 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
1059 {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1060 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
1061 {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
1063 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
1064 {"ctdbd socket", P_STRING, P_GLOBAL, &Globals.ctdbdSocket, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1065 {"cluster addresses", P_LIST, P_GLOBAL, &Globals.szClusterAddresses, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1066 {"clustering", P_BOOL, P_GLOBAL, &Globals.clustering, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1068 {N_("Printing Options"), P_SEP, P_SEPARATOR},
1070 {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1071 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1072 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1073 {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1074 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1075 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
1076 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1077 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
1078 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1079 {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1080 {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1081 {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1082 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1083 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1084 {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE},
1085 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1086 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1087 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1088 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1089 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1090 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1092 {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED},
1093 {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
1094 {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
1095 {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
1096 {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
1097 {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
1099 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1100 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
1101 {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1102 {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1103 {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1104 {"printjob username", P_STRING, P_LOCAL, &sDefault.szPrintjobUsername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1106 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
1107 {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
1108 {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
1110 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
1111 {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1112 {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE},
1113 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1114 {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1115 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1116 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1117 {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1118 {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1119 {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1120 {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1121 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1122 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1123 {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1124 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1125 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1126 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1127 {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1128 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1129 {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
1130 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
1131 {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1132 {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1135 {N_("Domain Options"), P_SEP, P_SEPARATOR},
1137 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1139 {N_("Logon Options"), P_SEP, P_SEPARATOR},
1141 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
1142 {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
1143 {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
1144 {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
1145 {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
1146 {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
1147 {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
1148 {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
1149 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
1150 {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
1151 {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
1152 {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED},
1154 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
1155 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
1156 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
1157 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
1158 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
1160 {N_("Browse Options"), P_SEP, P_SEPARATOR},
1162 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1163 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
1164 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
1165 {"preferred master", P_ENUM, P_GLOBAL, &Globals.iPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1166 {"prefered master", P_ENUM, P_GLOBAL, &Globals.iPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
1167 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1168 {"domain master", P_ENUM, P_GLOBAL, &Globals.iDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1169 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
1170 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1171 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1172 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
1174 {N_("WINS Options"), P_SEP, P_SEPARATOR},
1176 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
1177 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
1179 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1180 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1181 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
1183 {N_("Locking Options"), P_SEP, P_SEPARATOR},
1185 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1186 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1187 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1188 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1189 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1190 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1192 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1193 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1194 {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1195 {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1196 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1197 {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1198 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1200 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
1202 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
1203 {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
1204 {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
1205 {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
1206 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
1207 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
1208 {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE},
1209 {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1210 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
1211 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
1212 {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1213 {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
1214 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
1216 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
1217 {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
1218 {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
1219 {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
1221 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
1222 {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1224 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1225 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1226 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1227 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
1228 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
1229 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
1231 {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
1232 {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
1233 {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
1236 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1237 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1238 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
1239 {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED},
1240 {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED},
1241 {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
1242 {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
1243 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
1244 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
1245 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
1246 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
1247 {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
1248 {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1249 {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1250 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
1251 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
1252 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1254 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1255 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1256 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1257 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
1259 {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1260 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1261 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1262 {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1263 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1264 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1265 {"registry shares", P_BOOL, P_GLOBAL, &Globals.bRegistryShares, NULL, NULL, FLAG_ADVANCED},
1266 {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
1267 {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
1268 {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED},
1269 {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
1270 {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED},
1271 {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED},
1272 {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
1273 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1274 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1275 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1276 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1277 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1278 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1279 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1280 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1281 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1282 {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1283 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1284 {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1286 {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1287 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
1289 {N_("VFS module options"), P_SEP, P_SEPARATOR},
1291 {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1292 {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
1295 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1296 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1297 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
1299 {N_("Winbind options"), P_SEP, P_SEPARATOR},
1301 {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
1302 {"idmap domains", P_LIST, P_GLOBAL, &Globals.szIdmapDomains, NULL, NULL, FLAG_ADVANCED},
1303 {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED },
1304 {"idmap alloc backend", P_STRING, P_GLOBAL, &Globals.szIdmapAllocBackend, NULL, NULL, FLAG_ADVANCED},
1305 {"idmap cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapCacheTime, NULL, NULL, FLAG_ADVANCED},
1306 {"idmap negative cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeCacheTime, NULL, NULL, FLAG_ADVANCED},
1307 {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED },
1308 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE },
1309 {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED },
1310 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE },
1311 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
1312 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
1313 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
1314 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
1315 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
1316 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
1317 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
1318 {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
1319 {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
1320 {"winbind expand groups", P_INTEGER, P_GLOBAL, &Globals.winbind_expand_groups, NULL, NULL, FLAG_ADVANCED},
1321 {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED},
1322 {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED},
1323 {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
1324 {"winbind normalize names", P_BOOL, P_GLOBAL, &Globals.bWinbindNormalizeNames, NULL, NULL, FLAG_ADVANCED},
1325 {"winbind rpc only", P_BOOL, P_GLOBAL, &Globals.bWinbindRpcOnly, NULL, NULL, FLAG_ADVANCED},
1327 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1330 /***************************************************************************
1331 Initialise the sDefault parameter structure for the printer values.
1332 ***************************************************************************/
1334 static void init_printer_values(service *pService)
1336 /* choose defaults depending on the type of printing */
1337 switch (pService->iPrinting) {
1342 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1343 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1344 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1349 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1350 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1351 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1352 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1353 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1354 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1355 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1361 /* set the lpq command to contain the destination printer
1362 name only. This is used by cups_queue_get() */
1363 string_set(&pService->szLpqcommand, "%p");
1364 string_set(&pService->szLprmcommand, "");
1365 string_set(&pService->szPrintcommand, "");
1366 string_set(&pService->szLppausecommand, "");
1367 string_set(&pService->szLpresumecommand, "");
1368 string_set(&pService->szQueuepausecommand, "");
1369 string_set(&pService->szQueueresumecommand, "");
1371 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1372 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1373 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
1374 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1375 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1376 string_set(&pService->szQueuepausecommand, "disable '%p'");
1377 string_set(&pService->szQueueresumecommand, "enable '%p'");
1378 #endif /* HAVE_CUPS */
1383 string_set(&pService->szLpqcommand, "lpstat -o%p");
1384 string_set(&pService->szLprmcommand, "cancel %p-%j");
1385 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1386 string_set(&pService->szQueuepausecommand, "disable %p");
1387 string_set(&pService->szQueueresumecommand, "enable %p");
1389 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1390 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1395 string_set(&pService->szLpqcommand, "lpq -P%p");
1396 string_set(&pService->szLprmcommand, "lprm -P%p %j");
1397 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1403 string_set(&pService->szPrintcommand, "vlp print %p %s");
1404 string_set(&pService->szLpqcommand, "vlp lpq %p");
1405 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1406 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1407 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1408 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1409 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1411 #endif /* DEVELOPER */
1416 /***************************************************************************
1417 Initialise the global parameter structure.
1418 ***************************************************************************/
1420 static void init_globals(bool first_time_only)
1422 static bool done_init = False;
1425 /* If requested to initialize only once and we've already done it... */
1426 if (first_time_only && done_init) {
1427 /* ... then we have nothing more to do */
1434 /* The logfile can be set before this is invoked. Free it if so. */
1435 if (Globals.szLogFile != NULL) {
1436 string_free(&Globals.szLogFile);
1437 Globals.szLogFile = NULL;
1440 memset((void *)&Globals, '\0', sizeof(Globals));
1442 for (i = 0; parm_table[i].label; i++)
1443 if ((parm_table[i].type == P_STRING ||
1444 parm_table[i].type == P_USTRING) &&
1446 string_set((char **)parm_table[i].ptr, "");
1448 string_set(&sDefault.fstype, FSTYPE_STRING);
1449 string_set(&sDefault.szPrintjobUsername, "%U");
1451 init_printer_values(&sDefault);
1457 DEBUG(3, ("Initialising global parameters\n"));
1459 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1460 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1462 /* use the new 'hash2' method by default, with a prefix of 1 */
1463 string_set(&Globals.szManglingMethod, "hash2");
1464 Globals.mangle_prefix = 1;
1466 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1468 /* using UTF8 by default allows us to support all chars */
1469 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1471 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1472 /* If the system supports nl_langinfo(), try to grab the value
1473 from the user's locale */
1474 string_set(&Globals.display_charset, "LOCALE");
1476 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1479 /* Use codepage 850 as a default for the dos character set */
1480 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1483 * Allow the default PASSWD_CHAT to be overridden in local.h.
1485 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1487 set_global_myname(myhostname());
1488 string_set(&Globals.szNetbiosName,global_myname());
1490 set_global_myworkgroup(WORKGROUP);
1491 string_set(&Globals.szWorkgroup, lp_workgroup());
1493 string_set(&Globals.szPasswdProgram, "");
1494 string_set(&Globals.szPidDir, dyn_PIDDIR);
1495 string_set(&Globals.szLockDir, dyn_LOCKDIR);
1496 string_set(&Globals.szSocketAddress, "0.0.0.0");
1498 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
1499 smb_panic("init_globals: ENOMEM");
1501 string_set(&Globals.szServerString, s);
1503 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
1504 DEFAULT_MINOR_VERSION) < 0) {
1505 smb_panic("init_globals: ENOMEM");
1507 string_set(&Globals.szAnnounceVersion, s);
1510 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1513 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
1515 string_set(&Globals.szLogonDrive, "");
1516 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1517 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1518 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1520 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1521 string_set(&Globals.szPasswordServer, "*");
1523 Globals.AlgorithmicRidBase = BASE_RID;
1525 Globals.bLoadPrinters = True;
1526 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
1528 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1529 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1530 Globals.max_xmit = 0x4104;
1531 Globals.max_mux = 50; /* This is *needed* for profile support. */
1532 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
1533 Globals.bDisableSpoolss = False;
1534 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1535 Globals.pwordlevel = 0;
1536 Globals.unamelevel = 0;
1537 Globals.deadtime = 0;
1538 Globals.bLargeReadwrite = True;
1539 Globals.max_log_size = 5000;
1540 Globals.max_open_files = MAX_OPEN_FILES;
1541 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
1542 Globals.maxprotocol = PROTOCOL_NT1;
1543 Globals.minprotocol = PROTOCOL_CORE;
1544 Globals.security = SEC_USER;
1545 Globals.paranoid_server_security = True;
1546 Globals.bEncryptPasswords = True;
1547 Globals.bUpdateEncrypt = False;
1548 Globals.clientSchannel = Auto;
1549 Globals.serverSchannel = Auto;
1550 Globals.bReadRaw = True;
1551 Globals.bWriteRaw = True;
1552 Globals.bNullPasswords = False;
1553 Globals.bObeyPamRestrictions = False;
1555 Globals.bSyslogOnly = False;
1556 Globals.bTimestampLogs = True;
1557 string_set(&Globals.szLogLevel, "0");
1558 Globals.bDebugPrefixTimestamp = False;
1559 Globals.bDebugHiresTimestamp = False;
1560 Globals.bDebugPid = False;
1561 Globals.bDebugUid = False;
1562 Globals.bDebugClass = False;
1563 Globals.bEnableCoreFiles = True;
1564 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1565 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1566 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1567 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1568 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1569 Globals.lm_interval = 60;
1570 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1571 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1572 Globals.bNISHomeMap = False;
1573 #ifdef WITH_NISPLUS_HOME
1574 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1576 string_set(&Globals.szNISHomeMapName, "auto.home");
1579 Globals.bTimeServer = False;
1580 Globals.bBindInterfacesOnly = False;
1581 Globals.bUnixPasswdSync = False;
1582 Globals.bPamPasswordChange = False;
1583 Globals.bPasswdChatDebug = False;
1584 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1585 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
1586 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1587 Globals.bStatCache = True; /* use stat cache by default */
1588 Globals.iMaxStatCacheSize = 1024; /* one Meg by default. */
1589 Globals.restrict_anonymous = 0;
1590 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
1591 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
1592 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
1593 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
1594 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1595 /* Note, that we will use NTLM2 session security (which is different), if it is available */
1597 Globals.map_to_guest = 0; /* By Default, "Never" */
1598 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
1599 Globals.enhanced_browsing = true;
1600 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
1601 #ifdef MMAP_BLACKLIST
1602 Globals.bUseMmap = False;
1604 Globals.bUseMmap = True;
1606 Globals.bUnixExtensions = True;
1607 Globals.bResetOnZeroVC = False;
1609 /* hostname lookups can be very expensive and are broken on
1610 a large number of sites (tridge) */
1611 Globals.bHostnameLookups = False;
1613 string_set(&Globals.szPassdbBackend, "smbpasswd");
1614 string_set(&Globals.szLdapSuffix, "");
1615 string_set(&Globals.szLdapMachineSuffix, "");
1616 string_set(&Globals.szLdapUserSuffix, "");
1617 string_set(&Globals.szLdapGroupSuffix, "");
1618 string_set(&Globals.szLdapIdmapSuffix, "");
1620 string_set(&Globals.szLdapAdminDn, "");
1621 Globals.ldap_ssl = LDAP_SSL_ON;
1622 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1623 Globals.ldap_delete_dn = False;
1624 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1625 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1626 Globals.ldap_page_size = LDAP_PAGE_SIZE;
1628 /* This is what we tell the afs client. in reality we set the token
1629 * to never expire, though, when this runs out the afs client will
1630 * forget the token. Set to 0 to get NEVERDATE.*/
1631 Globals.iAfsTokenLifetime = 604800;
1633 /* these parameters are set to defaults that are more appropriate
1634 for the increasing samba install base:
1636 as a member of the workgroup, that will possibly become a
1637 _local_ master browser (lm = True). this is opposed to a forced
1638 local master browser startup (pm = True).
1640 doesn't provide WINS server service by default (wsupp = False),
1641 and doesn't provide domain master browser services by default, either.
1645 Globals.bMsAddPrinterWizard = True;
1646 Globals.os_level = 20;
1647 Globals.bLocalMaster = True;
1648 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
1649 Globals.bDomainLogons = False;
1650 Globals.bBrowseList = True;
1651 Globals.bWINSsupport = False;
1652 Globals.bWINSproxy = False;
1654 Globals.bDNSproxy = True;
1656 /* this just means to use them if they exist */
1657 Globals.bKernelOplocks = True;
1659 Globals.bAllowTrustedDomains = True;
1661 string_set(&Globals.szTemplateShell, "/bin/false");
1662 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1663 string_set(&Globals.szWinbindSeparator, "\\");
1665 string_set(&Globals.szCupsServer, "");
1666 string_set(&Globals.szIPrintServer, "");
1668 string_set(&Globals.ctdbdSocket, "");
1669 Globals.szClusterAddresses = NULL;
1670 Globals.clustering = False;
1672 Globals.winbind_cache_time = 300; /* 5 minutes */
1673 Globals.bWinbindEnumUsers = False;
1674 Globals.bWinbindEnumGroups = False;
1675 Globals.bWinbindUseDefaultDomain = False;
1676 Globals.bWinbindTrustedDomainsOnly = False;
1677 Globals.bWinbindNestedGroups = True;
1678 Globals.winbind_expand_groups = 1;
1679 Globals.szWinbindNssInfo = str_list_make("template", NULL);
1680 Globals.bWinbindRefreshTickets = False;
1681 Globals.bWinbindOfflineLogon = False;
1683 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
1684 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
1686 Globals.bPassdbExpandExplicit = False;
1688 Globals.name_cache_timeout = 660; /* In seconds */
1690 Globals.bUseSpnego = True;
1691 Globals.bClientUseSpnego = True;
1693 Globals.client_signing = Auto;
1694 Globals.server_signing = False;
1696 Globals.bDeferSharingViolations = True;
1697 string_set(&Globals.smb_ports, SMB_PORTS);
1699 Globals.bEnablePrivileges = True;
1700 Globals.bHostMSDfs = True;
1701 Globals.bASUSupport = False;
1703 /* User defined shares. */
1704 if (asprintf(&s, "%s/usershares", dyn_STATEDIR()) < 0) {
1705 smb_panic("init_globals: ENOMEM");
1707 string_set(&Globals.szUsersharePath, s);
1709 string_set(&Globals.szUsershareTemplateShare, "");
1710 Globals.iUsershareMaxShares = 0;
1711 /* By default disallow sharing of directories not owned by the sharer. */
1712 Globals.bUsershareOwnerOnly = True;
1713 /* By default disallow guest access to usershares. */
1714 Globals.bUsershareAllowGuests = False;
1716 Globals.iKeepalive = DEFAULT_KEEPALIVE;
1718 /* By default no shares out of the registry */
1719 Globals.bRegistryShares = False;
1721 Globals.iminreceivefile = 0;
1724 /*******************************************************************
1725 Convenience routine to grab string parameters into temporary memory
1726 and run standard_sub_basic on them. The buffers can be written to by
1727 callers without affecting the source string.
1728 ********************************************************************/
1730 static char *lp_string(const char *s)
1733 TALLOC_CTX *ctx = talloc_tos();
1735 /* The follow debug is useful for tracking down memory problems
1736 especially if you have an inner loop that is calling a lp_*()
1737 function that returns a string. Perhaps this debug should be
1738 present all the time? */
1741 DEBUG(10, ("lp_string(%s)\n", s));
1744 ret = talloc_sub_basic(ctx,
1745 get_current_username(),
1746 current_user_info.domain,
1748 if (trim_char(ret, '\"', '\"')) {
1749 if (strchr(ret,'\"') != NULL) {
1751 ret = talloc_sub_basic(ctx,
1752 get_current_username(),
1753 current_user_info.domain,
1761 In this section all the functions that are used to access the
1762 parameters from the rest of the program are defined
1765 #define FN_GLOBAL_STRING(fn_name,ptr) \
1766 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1767 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1768 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1769 #define FN_GLOBAL_LIST(fn_name,ptr) \
1770 const char **fn_name(void) {return(*(const char ***)(ptr));}
1771 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1772 bool fn_name(void) {return(*(bool *)(ptr));}
1773 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1774 char fn_name(void) {return(*(char *)(ptr));}
1775 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1776 int fn_name(void) {return(*(int *)(ptr));}
1778 #define FN_LOCAL_STRING(fn_name,val) \
1779 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1780 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1781 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1782 #define FN_LOCAL_LIST(fn_name,val) \
1783 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1784 #define FN_LOCAL_BOOL(fn_name,val) \
1785 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1786 #define FN_LOCAL_INTEGER(fn_name,val) \
1787 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1789 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1790 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1791 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1792 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1793 #define FN_LOCAL_PARM_STRING(fn_name,val) \
1794 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));}
1795 #define FN_LOCAL_CHAR(fn_name,val) \
1796 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1798 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1799 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1800 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1801 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1802 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1803 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1804 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1805 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1806 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1807 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1808 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1809 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1810 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1811 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1812 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1813 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1814 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1815 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1816 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1817 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1818 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1819 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1820 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1821 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1822 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1823 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1824 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1825 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1826 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1827 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1828 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1829 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1830 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1831 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1832 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1833 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1834 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1835 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1836 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1837 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1838 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1839 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1840 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1841 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1842 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1843 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1844 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1845 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1846 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1847 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1848 * lp_passdb_backend() should be replace by the this macro again after
1851 const char *lp_passdb_backend(void)
1853 char *delim, *quote;
1855 delim = strchr( Globals.szPassdbBackend, ' ');
1856 /* no space at all */
1857 if (delim == NULL) {
1861 quote = strchr(Globals.szPassdbBackend, '"');
1862 /* no quote char or non in the first part */
1863 if (quote == NULL || quote > delim) {
1868 quote = strchr(quote+1, '"');
1869 if (quote == NULL) {
1870 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
1872 } else if (*(quote+1) == '\0') {
1873 /* space, fitting quote char, and one backend only */
1876 /* terminate string after the fitting quote char */
1881 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
1882 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
1883 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
1884 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
1887 return Globals.szPassdbBackend;
1889 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1890 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1891 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1892 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1893 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1895 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1896 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1897 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1898 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1899 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1900 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1902 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1904 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1905 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1906 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1908 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1910 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1911 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1912 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1913 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1914 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
1915 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1916 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1917 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1918 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1919 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1920 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
1921 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1922 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1923 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
1924 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
1926 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
1927 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
1928 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
1929 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
1930 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
1931 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
1932 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1934 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1935 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1936 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1937 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1938 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1939 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1940 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1941 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1942 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1943 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1944 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1945 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1946 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1947 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1949 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1951 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
1952 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1953 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1954 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1955 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1956 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1957 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1958 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1959 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1960 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1961 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1962 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1963 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1964 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1965 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1966 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1967 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1968 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1969 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1970 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1971 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1972 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1973 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1974 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1975 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
1976 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1977 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1978 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1979 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
1980 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
1981 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1982 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1983 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1984 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1985 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1986 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1987 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1988 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1989 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1990 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1991 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1992 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1993 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1994 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1995 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1996 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1997 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1998 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1999 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
2000 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
2001 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
2002 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
2003 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
2004 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
2005 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
2006 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
2007 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
2008 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
2009 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
2010 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
2011 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
2012 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
2013 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
2014 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
2015 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
2016 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
2017 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
2018 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
2019 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
2020 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
2021 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
2022 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
2023 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
2024 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
2025 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
2026 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
2027 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
2028 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
2029 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
2030 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
2031 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
2032 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
2033 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
2034 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
2035 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
2036 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
2037 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
2038 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
2039 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
2040 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
2041 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
2042 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
2043 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
2044 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
2046 FN_LOCAL_STRING(lp_preexec, szPreExec)
2047 FN_LOCAL_STRING(lp_postexec, szPostExec)
2048 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
2049 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
2050 FN_LOCAL_STRING(lp_servicename, szService)
2051 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
2052 FN_LOCAL_STRING(lp_pathname, szPath)
2053 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
2054 FN_LOCAL_STRING(lp_username, szUsername)
2055 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
2056 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
2057 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
2058 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
2059 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
2060 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
2061 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
2062 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
2063 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
2064 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering);
2065 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
2066 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
2067 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
2068 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
2069 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
2070 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
2071 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
2072 static FN_LOCAL_STRING(_lp_printername, szPrintername)
2073 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
2074 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
2075 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
2076 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
2077 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
2078 FN_LOCAL_STRING(lp_comment, comment)
2079 FN_LOCAL_STRING(lp_force_user, force_user)
2080 FN_LOCAL_STRING(lp_force_group, force_group)
2081 FN_LOCAL_LIST(lp_readlist, readlist)
2082 FN_LOCAL_LIST(lp_writelist, writelist)
2083 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
2084 FN_LOCAL_STRING(lp_fstype, fstype)
2085 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
2086 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
2087 static FN_LOCAL_STRING(lp_volume, volume)
2088 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
2089 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
2090 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
2091 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
2092 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
2093 FN_LOCAL_STRING(lp_dfree_command, szDfree)
2094 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
2095 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
2096 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
2097 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
2098 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
2099 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
2100 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
2101 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2102 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2103 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2104 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2105 FN_LOCAL_BOOL(lp_readonly, bRead_only)
2106 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2107 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2108 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2109 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2110 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2111 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2112 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2113 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2114 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
2115 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
2116 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
2117 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2118 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2119 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2120 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2121 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
2122 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2123 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2124 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2125 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2126 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2127 FN_LOCAL_BOOL(lp_map_system, bMap_system)
2128 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2129 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2130 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2131 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2132 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2133 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2134 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2135 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2136 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2137 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2138 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2139 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2140 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2141 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2142 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2143 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2144 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2145 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2146 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2147 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2148 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2149 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2150 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2151 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2152 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2153 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2154 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2155 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2156 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2157 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2158 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2159 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2160 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2161 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2162 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2163 FN_LOCAL_INTEGER(lp_printing, iPrinting)
2164 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2165 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2166 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2167 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2168 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2169 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2170 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2171 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2172 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2173 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2174 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
2175 FN_LOCAL_CHAR(lp_magicchar, magic_char)
2176 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2177 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2178 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2179 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2180 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2181 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2182 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
2184 /* local prototypes */
2186 static int map_parameter(const char *pszParmName);
2187 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
2188 static bool set_boolean(bool *pb, const char *pszParmValue);
2189 static const char *get_boolean(bool bool_value);
2190 static int getservicebyname(const char *pszServiceName,
2191 service * pserviceDest);
2192 static void copy_service(service * pserviceDest,
2193 service * pserviceSource,
2194 struct bitmap *pcopymapDest);
2195 static bool do_parameter(const char *pszParmName, const char *pszParmValue);
2196 static bool do_section(const char *pszSectionName);
2197 static void init_copymap(service * pservice);
2198 static bool hash_a_service(const char *name, int number);
2199 static void free_service_byindex(int iService);
2200 static char * canonicalize_servicename(const char *name);
2201 static void show_parameter(int parmIndex);
2202 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
2204 /* This is a helper function for parametrical options support. */
2205 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2206 /* Actual parametrical functions are quite simple */
2207 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2209 bool global_section = False;
2211 param_opt_struct *data;
2213 if (snum >= iNumServices) return NULL;
2216 data = Globals.param_opt;
2217 global_section = True;
2219 data = ServicePtrs[snum]->param_opt;
2222 asprintf(¶m_key, "%s:%s", type, option);
2224 DEBUG(0,("asprintf failed!\n"));
2229 if (strcmp(data->key, param_key) == 0) {
2230 string_free(¶m_key);
2236 if (!global_section) {
2237 /* Try to fetch the same option but from globals */
2238 /* but only if we are not already working with Globals */
2239 data = Globals.param_opt;
2241 if (strcmp(data->key, param_key) == 0) {
2242 string_free(¶m_key);
2249 string_free(¶m_key);
2255 #define MISSING_PARAMETER(name) \
2256 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2258 /*******************************************************************
2259 convenience routine to return int parameters.
2260 ********************************************************************/
2261 static int lp_int(const char *s)
2265 MISSING_PARAMETER(lp_int);
2269 return (int)strtol(s, NULL, 0);
2272 /*******************************************************************
2273 convenience routine to return unsigned long parameters.
2274 ********************************************************************/
2275 static unsigned long lp_ulong(const char *s)
2279 MISSING_PARAMETER(lp_ulong);
2283 return strtoul(s, NULL, 0);
2286 /*******************************************************************
2287 convenience routine to return boolean parameters.
2288 ********************************************************************/
2289 static bool lp_bool(const char *s)
2294 MISSING_PARAMETER(lp_bool);
2298 if (!set_boolean(&ret,s)) {
2299 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2306 /*******************************************************************
2307 convenience routine to return enum parameters.
2308 ********************************************************************/
2309 static int lp_enum(const char *s,const struct enum_list *_enum)
2313 if (!s || !*s || !_enum) {
2314 MISSING_PARAMETER(lp_enum);
2318 for (i=0; _enum[i].name; i++) {
2319 if (strequal(_enum[i].name,s))
2320 return _enum[i].value;
2323 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2327 #undef MISSING_PARAMETER
2329 /* DO NOT USE lp_parm_string ANYMORE!!!!
2330 * use lp_parm_const_string or lp_parm_talloc_string
2332 * lp_parm_string is only used to let old modules find this symbol
2334 #undef lp_parm_string
2335 char *lp_parm_string(const char *servicename, const char *type, const char *option);
2336 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2338 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2341 /* Return parametric option from a given service. Type is a part of option before ':' */
2342 /* Parametric option has following syntax: 'Type: option = value' */
2343 /* the returned value is talloced on the talloc_tos() */
2344 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2346 param_opt_struct *data = get_parametrics(snum, type, option);
2348 if (data == NULL||data->value==NULL) {
2350 return lp_string(def);
2356 return lp_string(data->value);
2359 /* Return parametric option from a given service. Type is a part of option before ':' */
2360 /* Parametric option has following syntax: 'Type: option = value' */
2361 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2363 param_opt_struct *data = get_parametrics(snum, type, option);
2365 if (data == NULL||data->value==NULL)
2371 /* Return parametric option from a given service. Type is a part of option before ':' */
2372 /* Parametric option has following syntax: 'Type: option = value' */
2374 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2376 param_opt_struct *data = get_parametrics(snum, type, option);
2378 if (data == NULL||data->value==NULL)
2379 return (const char **)def;
2381 if (data->list==NULL) {
2382 data->list = str_list_make(data->value, NULL);
2385 return (const char **)data->list;
2388 /* Return parametric option from a given service. Type is a part of option before ':' */
2389 /* Parametric option has following syntax: 'Type: option = value' */
2391 int lp_parm_int(int snum, const char *type, const char *option, int def)
2393 param_opt_struct *data = get_parametrics(snum, type, option);
2395 if (data && data->value && *data->value)
2396 return lp_int(data->value);
2401 /* Return parametric option from a given service. Type is a part of option before ':' */
2402 /* Parametric option has following syntax: 'Type: option = value' */
2404 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2406 param_opt_struct *data = get_parametrics(snum, type, option);
2408 if (data && data->value && *data->value)
2409 return lp_ulong(data->value);
2414 /* Return parametric option from a given service. Type is a part of option before ':' */
2415 /* Parametric option has following syntax: 'Type: option = value' */
2417 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
2419 param_opt_struct *data = get_parametrics(snum, type, option);
2421 if (data && data->value && *data->value)
2422 return lp_bool(data->value);
2427 /* Return parametric option from a given service. Type is a part of option before ':' */
2428 /* Parametric option has following syntax: 'Type: option = value' */
2430 int lp_parm_enum(int snum, const char *type, const char *option,
2431 const struct enum_list *_enum, int def)
2433 param_opt_struct *data = get_parametrics(snum, type, option);
2435 if (data && data->value && *data->value && _enum)
2436 return lp_enum(data->value, _enum);
2442 /***************************************************************************
2443 Initialise a service to the defaults.
2444 ***************************************************************************/
2446 static void init_service(service * pservice)
2448 memset((char *)pservice, '\0', sizeof(service));
2449 copy_service(pservice, &sDefault, NULL);
2452 /***************************************************************************
2453 Free the dynamically allocated parts of a service struct.
2454 ***************************************************************************/
2456 static void free_service(service *pservice)
2459 param_opt_struct *data, *pdata;
2463 if (pservice->szService)
2464 DEBUG(5, ("free_service: Freeing service %s\n",
2465 pservice->szService));
2467 string_free(&pservice->szService);
2468 bitmap_free(pservice->copymap);
2470 for (i = 0; parm_table[i].label; i++) {
2471 if ((parm_table[i].type == P_STRING ||
2472 parm_table[i].type == P_USTRING) &&
2473 parm_table[i].p_class == P_LOCAL)
2474 string_free((char **)
2475 (((char *)pservice) +
2476 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2477 else if (parm_table[i].type == P_LIST &&
2478 parm_table[i].p_class == P_LOCAL)
2479 str_list_free((char ***)
2480 (((char *)pservice) +
2481 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2484 data = pservice->param_opt;
2486 DEBUG(5,("Freeing parametrics:\n"));
2488 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2489 string_free(&data->key);
2490 string_free(&data->value);
2491 str_list_free(&data->list);
2497 ZERO_STRUCTP(pservice);
2501 /***************************************************************************
2502 remove a service indexed in the ServicePtrs array from the ServiceHash
2503 and free the dynamically allocated parts
2504 ***************************************************************************/
2506 static void free_service_byindex(int idx)
2508 if ( !LP_SNUM_OK(idx) )
2511 ServicePtrs[idx]->valid = False;
2512 invalid_services[num_invalid_services++] = idx;
2514 /* we have to cleanup the hash record */
2516 if (ServicePtrs[idx]->szService) {
2517 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2519 tdb_delete_bystring(ServiceHash, canon_name );
2522 free_service(ServicePtrs[idx]);
2525 /***************************************************************************
2526 Add a new service to the services array initialising it with the given
2528 ***************************************************************************/
2530 static int add_a_service(const service *pservice, const char *name)
2534 int num_to_alloc = iNumServices + 1;
2535 param_opt_struct *data, *pdata;
2537 tservice = *pservice;
2539 /* it might already exist */
2541 i = getservicebyname(name, NULL);
2543 /* Clean all parametric options for service */
2544 /* They will be added during parsing again */
2545 data = ServicePtrs[i]->param_opt;
2547 string_free(&data->key);
2548 string_free(&data->value);
2549 str_list_free(&data->list);
2554 ServicePtrs[i]->param_opt = NULL;
2559 /* find an invalid one */
2561 if (num_invalid_services > 0) {
2562 i = invalid_services[--num_invalid_services];
2565 /* if not, then create one */
2566 if (i == iNumServices) {
2570 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2572 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2576 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2577 if (!ServicePtrs[iNumServices]) {
2578 DEBUG(0,("add_a_service: out of memory!\n"));
2583 /* enlarge invalid_services here for now... */
2584 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2586 if (tinvalid == NULL) {
2587 DEBUG(0,("add_a_service: failed to enlarge "
2588 "invalid_services!\n"));
2591 invalid_services = tinvalid;
2593 free_service_byindex(i);
2596 ServicePtrs[i]->valid = True;
2598 init_service(ServicePtrs[i]);
2599 copy_service(ServicePtrs[i], &tservice, NULL);
2601 string_set(&ServicePtrs[i]->szService, name);
2603 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2604 i, ServicePtrs[i]->szService));
2606 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2613 /***************************************************************************
2614 Convert a string to uppercase and remove whitespaces.
2615 ***************************************************************************/
2617 static char *canonicalize_servicename(const char *src)
2619 static fstring canon; /* is fstring large enough? */
2622 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2626 fstrcpy( canon, src );
2627 strlower_m( canon );
2632 /***************************************************************************
2633 Add a name/index pair for the services array to the hash table.
2634 ***************************************************************************/
2636 static bool hash_a_service(const char *name, int idx)
2640 if ( !ServiceHash ) {
2641 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2642 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2643 (O_RDWR|O_CREAT), 0600);
2644 if ( !ServiceHash ) {
2645 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2650 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2653 if ( !(canon_name = canonicalize_servicename( name )) )
2656 tdb_store_int32(ServiceHash, canon_name, idx);
2661 /***************************************************************************
2662 Add a new home service, with the specified home directory, defaults coming
2664 ***************************************************************************/
2666 bool lp_add_home(const char *pszHomename, int iDefaultService,
2667 const char *user, const char *pszHomedir)
2671 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2676 if (!(*(ServicePtrs[iDefaultService]->szPath))
2677 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2678 string_set(&ServicePtrs[i]->szPath, pszHomedir);
2681 if (!(*(ServicePtrs[i]->comment))) {
2682 char *comment = NULL;
2683 if (asprintf(&comment, "Home directory of %s", user) < 0) {
2686 string_set(&ServicePtrs[i]->comment, comment);
2690 /* set the browseable flag from the global default */
2692 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2694 ServicePtrs[i]->autoloaded = True;
2696 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2697 user, ServicePtrs[i]->szPath ));
2702 /***************************************************************************
2703 Add a new service, based on an old one.
2704 ***************************************************************************/
2706 int lp_add_service(const char *pszService, int iDefaultService)
2708 if (iDefaultService < 0) {
2709 return add_a_service(&sDefault, pszService);
2712 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2715 /***************************************************************************
2716 Add the IPC service.
2717 ***************************************************************************/
2719 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
2721 char *comment = NULL;
2722 int i = add_a_service(&sDefault, ipc_name);
2727 if (asprintf(&comment, "IPC Service (%s)",
2728 Globals.szServerString) < 0) {
2732 string_set(&ServicePtrs[i]->szPath, tmpdir());
2733 string_set(&ServicePtrs[i]->szUsername, "");
2734 string_set(&ServicePtrs[i]->comment, comment);
2735 string_set(&ServicePtrs[i]->fstype, "IPC");
2736 ServicePtrs[i]->iMaxConnections = 0;
2737 ServicePtrs[i]->bAvailable = True;
2738 ServicePtrs[i]->bRead_only = True;
2739 ServicePtrs[i]->bGuest_only = False;
2740 ServicePtrs[i]->bGuest_ok = guest_ok;
2741 ServicePtrs[i]->bPrint_ok = False;
2742 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2744 DEBUG(3, ("adding IPC service\n"));
2750 /***************************************************************************
2751 Add a new printer service, with defaults coming from service iFrom.
2752 ***************************************************************************/
2754 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
2756 const char *comment = "From Printcap";
2757 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2762 /* note that we do NOT default the availability flag to True - */
2763 /* we take it from the default service passed. This allows all */
2764 /* dynamic printers to be disabled by disabling the [printers] */
2765 /* entry (if/when the 'available' keyword is implemented!). */
2767 /* the printer name is set to the service name. */
2768 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2769 string_set(&ServicePtrs[i]->comment, comment);
2771 /* set the browseable flag from the gloabl default */
2772 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2774 /* Printers cannot be read_only. */
2775 ServicePtrs[i]->bRead_only = False;
2776 /* No share modes on printer services. */
2777 ServicePtrs[i]->bShareModes = False;
2778 /* No oplocks on printer services. */
2779 ServicePtrs[i]->bOpLocks = False;
2780 /* Printer services must be printable. */
2781 ServicePtrs[i]->bPrint_ok = True;
2783 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2789 /***************************************************************************
2790 Check whether the given parameter name is valid.
2791 Parametric options (names containing a colon) are considered valid.
2792 ***************************************************************************/
2794 bool lp_parameter_is_valid(const char *pszParmName)
2796 return ((map_parameter(pszParmName) != -1) ||
2797 (strchr(pszParmName, ':') != NULL));
2800 /***************************************************************************
2801 Check whether the given name is the name of a global parameter.
2802 Returns True for strings belonging to parameters of class
2803 P_GLOBAL, False for all other strings, also for parametric options
2804 and strings not belonging to any option.
2805 ***************************************************************************/
2807 bool lp_parameter_is_global(const char *pszParmName)
2809 int num = map_parameter(pszParmName);
2812 return (parm_table[num].p_class == P_GLOBAL);
2818 /**************************************************************************
2819 Check whether the given name is the canonical name of a parameter.
2820 Returns False if it is not a valid parameter Name.
2821 For parametric options, True is returned.
2822 **************************************************************************/
2824 bool lp_parameter_is_canonical(const char *parm_name)
2826 if (!lp_parameter_is_valid(parm_name)) {
2830 return (map_parameter(parm_name) ==
2831 map_parameter_canonical(parm_name, NULL));
2834 /**************************************************************************
2835 Determine the canonical name for a parameter.
2836 Indicate when it is an inverse (boolean) synonym instead of a
2838 **************************************************************************/
2840 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
2845 if (!lp_parameter_is_valid(parm_name)) {
2850 num = map_parameter_canonical(parm_name, inverse);
2852 /* parametric option */
2853 *canon_parm = parm_name;
2855 *canon_parm = parm_table[num].label;
2862 /**************************************************************************
2863 Determine the canonical name for a parameter.
2864 Turn the value given into the inverse boolean expression when
2865 the synonym is an invers boolean synonym.
2867 Return True if parm_name is a valid parameter name and
2868 in case it is an invers boolean synonym, if the val string could
2869 successfully be converted to the reverse bool.
2870 Return false in all other cases.
2871 **************************************************************************/
2873 bool lp_canonicalize_parameter_with_value(const char *parm_name,
2875 const char **canon_parm,
2876 const char **canon_val)
2881 if (!lp_parameter_is_valid(parm_name)) {
2887 num = map_parameter_canonical(parm_name, &inverse);
2889 /* parametric option */
2890 *canon_parm = parm_name;
2893 *canon_parm = parm_table[num].label;
2895 if (!lp_invert_boolean(val, canon_val)) {
2907 /***************************************************************************
2908 Map a parameter's string representation to something we can use.
2909 Returns False if the parameter string is not recognised, else TRUE.
2910 ***************************************************************************/
2912 static int map_parameter(const char *pszParmName)
2916 if (*pszParmName == '-')
2919 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2920 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2923 /* Warn only if it isn't parametric option */
2924 if (strchr(pszParmName, ':') == NULL)
2925 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2926 /* We do return 'fail' for parametric options as well because they are
2927 stored in different storage
2932 /***************************************************************************
2933 Map a parameter's string representation to the index of the canonical
2934 form of the parameter (it might be a synonym).
2935 Returns -1 if the parameter string is not recognised.
2936 ***************************************************************************/
2938 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
2940 int parm_num, canon_num;
2941 bool loc_inverse = False;
2943 parm_num = map_parameter(pszParmName);
2944 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
2945 /* invalid, parametric or no canidate for synonyms ... */
2949 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
2950 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
2951 parm_num = canon_num;
2957 if (inverse != NULL) {
2958 *inverse = loc_inverse;
2963 /***************************************************************************
2964 return true if parameter number parm1 is a synonym of parameter
2965 number parm2 (parm2 being the principal name).
2966 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
2968 ***************************************************************************/
2970 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
2972 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
2973 (parm_table[parm1].flags & FLAG_HIDE) &&
2974 !(parm_table[parm2].flags & FLAG_HIDE))
2976 if (inverse != NULL) {
2977 if ((parm_table[parm1].type == P_BOOLREV) &&
2978 (parm_table[parm2].type == P_BOOL))
2990 /***************************************************************************
2991 Show one parameter's name, type, [values,] and flags.
2992 (helper functions for show_parameter_list)
2993 ***************************************************************************/
2995 static void show_parameter(int parmIndex)
2997 int enumIndex, flagIndex;
3002 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
3003 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
3004 "P_UGSTRING", "P_ENUM", "P_SEP"};
3005 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
3006 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
3007 FLAG_HIDE, FLAG_DOS_STRING};
3008 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
3009 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
3010 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
3012 printf("%s=%s", parm_table[parmIndex].label,
3013 type[parm_table[parmIndex].type]);
3014 if (parm_table[parmIndex].type == P_ENUM) {
3017 parm_table[parmIndex].enum_list[enumIndex].name;
3021 enumIndex ? "|" : "",
3022 parm_table[parmIndex].enum_list[enumIndex].name);
3027 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
3028 if (parm_table[parmIndex].flags & flags[flagIndex]) {
3031 flag_names[flagIndex]);
3036 /* output synonyms */
3038 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
3039 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
3040 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
3041 parm_table[parmIndex2].label);
3042 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
3044 printf(" (synonyms: ");
3049 printf("%s%s", parm_table[parmIndex2].label,
3050 inverse ? "[i]" : "");
3060 /***************************************************************************
3061 Show all parameter's name, type, [values,] and flags.
3062 ***************************************************************************/
3064 void show_parameter_list(void)
3066 int classIndex, parmIndex;
3067 const char *section_names[] = { "local", "global", NULL};
3069 for (classIndex=0; section_names[classIndex]; classIndex++) {
3070 printf("[%s]\n", section_names[classIndex]);
3071 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
3072 if (parm_table[parmIndex].p_class == classIndex) {
3073 show_parameter(parmIndex);
3079 /***************************************************************************
3080 Set a boolean variable from the text value stored in the passed string.
3081 Returns True in success, False if the passed string does not correctly
3082 represent a boolean.
3083 ***************************************************************************/
3085 static bool set_boolean(bool *pb, const char *pszParmValue)
3092 if (strwicmp(pszParmValue, "yes") == 0 ||
3093 strwicmp(pszParmValue, "true") == 0 ||
3094 strwicmp(pszParmValue, "1") == 0)
3096 else if (strwicmp(pszParmValue, "no") == 0 ||
3097 strwicmp(pszParmValue, "False") == 0 ||
3098 strwicmp(pszParmValue, "0") == 0)
3102 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
3107 if ((pb != NULL) && (bRetval != False)) {
3115 /***************************************************************************
3116 Check if a given string correctly represents a boolean value.
3117 ***************************************************************************/
3119 bool lp_string_is_valid_boolean(const char *parm_value)
3121 return set_boolean(NULL, parm_value);
3124 /***************************************************************************
3125 Get the standard string representation of a boolean value ("yes" or "no")
3126 ***************************************************************************/
3128 static const char *get_boolean(bool bool_value)
3130 static const char *yes_str = "yes";
3131 static const char *no_str = "no";
3133 return (bool_value ? yes_str : no_str);
3136 /***************************************************************************
3137 Provide the string of the negated boolean value associated to the boolean
3138 given as a string. Returns False if the passed string does not correctly
3139 represent a boolean.
3140 ***************************************************************************/
3142 bool lp_invert_boolean(const char *str, const char **inverse_str)
3146 if (!set_boolean(&val, str)) {
3150 *inverse_str = get_boolean(!val);
3154 /***************************************************************************
3155 Provide the canonical string representation of a boolean value given
3156 as a string. Return True on success, False if the string given does
3157 not correctly represent a boolean.
3158 ***************************************************************************/
3160 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
3164 if (!set_boolean(&val, str)) {
3168 *canon_str = get_boolean(val);
3172 /***************************************************************************
3173 Find a service by name. Otherwise works like get_service.
3174 ***************************************************************************/
3176 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
3181 if (ServiceHash != NULL) {
3182 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
3185 iService = tdb_fetch_int32(ServiceHash, canon_name );
3187 if (LP_SNUM_OK(iService)) {
3188 if (pserviceDest != NULL) {
3189 copy_service(pserviceDest, ServicePtrs[iService], NULL);
3199 /***************************************************************************
3200 Copy a service structure to another.
3201 If pcopymapDest is NULL then copy all fields
3202 ***************************************************************************/
3204 static void copy_service(service * pserviceDest, service * pserviceSource,
3205 struct bitmap *pcopymapDest)
3208 bool bcopyall = (pcopymapDest == NULL);
3209 param_opt_struct *data, *pdata, *paramo;
3212 for (i = 0; parm_table[i].label; i++)
3213 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
3214 (bcopyall || bitmap_query(pcopymapDest,i))) {
3215 void *def_ptr = parm_table[i].ptr;
3217 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
3220 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
3223 switch (parm_table[i].type) {
3226 *(bool *)dest_ptr = *(bool *)src_ptr;
3232 *(int *)dest_ptr = *(int *)src_ptr;
3236 *(char *)dest_ptr = *(char *)src_ptr;
3240 string_set((char **)dest_ptr,
3245 string_set((char **)dest_ptr,
3247 strupper_m(*(char **)dest_ptr);
3250 str_list_free((char ***)dest_ptr);
3251 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
3259 init_copymap(pserviceDest);
3260 if (pserviceSource->copymap)
3261 bitmap_copy(pserviceDest->copymap,
3262 pserviceSource->copymap);
3265 data = pserviceSource->param_opt;
3268 pdata = pserviceDest->param_opt;
3269 /* Traverse destination */
3271 /* If we already have same option, override it */
3272 if (strcmp(pdata->key, data->key) == 0) {
3273 string_free(&pdata->value);
3274 str_list_free(&data->list);
3275 pdata->value = SMB_STRDUP(data->value);
3279 pdata = pdata->next;
3282 paramo = SMB_XMALLOC_P(param_opt_struct);
3283 paramo->key = SMB_STRDUP(data->key);
3284 paramo->value = SMB_STRDUP(data->value);
3285 paramo->list = NULL;
3286 DLIST_ADD(pserviceDest->param_opt, paramo);
3292 /***************************************************************************
3293 Check a service for consistency. Return False if the service is in any way
3294 incomplete or faulty, else True.
3295 ***************************************************************************/
3297 bool service_ok(int iService)
3302 if (ServicePtrs[iService]->szService[0] == '\0') {
3303 DEBUG(0, ("The following message indicates an internal error:\n"));
3304 DEBUG(0, ("No service name in service entry.\n"));
3308 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
3309 /* I can't see why you'd want a non-printable printer service... */
3310 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
3311 if (!ServicePtrs[iService]->bPrint_ok) {
3312 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
3313 ServicePtrs[iService]->szService));
3314 ServicePtrs[iService]->bPrint_ok = True;
3316 /* [printers] service must also be non-browsable. */
3317 if (ServicePtrs[iService]->bBrowseable)
3318 ServicePtrs[iService]->bBrowseable = False;
3321 if (ServicePtrs[iService]->szPath[0] == '\0' &&
3322 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
3323 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
3325 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
3326 ServicePtrs[iService]->szService));
3327 ServicePtrs[iService]->bAvailable = False;
3330 /* If a service is flagged unavailable, log the fact at level 1. */
3331 if (!ServicePtrs[iService]->bAvailable)
3332 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
3333 ServicePtrs[iService]->szService));
3339 * lp_regdb_open - regdb helper function
3341 * this should be considered an interim solution that becomes
3342 * superfluous once the registry code has been rewritten
3343 * do allow use of the tdb portion of the registry alone.
3345 * in the meanwhile this provides a lean access
3346 * to the registry globals.
3349 static struct tdb_wrap *lp_regdb_open(void)
3351 struct tdb_wrap *reg_tdb = NULL;
3352 const char *vstring = "INFO/version";
3356 reg_tdb = tdb_wrap_open(NULL, state_path("registry.tdb"), 0,
3357 REG_TDB_FLAGS, O_RDWR, 0600);
3360 DEBUG(1, ("lp_regdb_open: failed to open %s: %s\n",
3361 state_path("registry.tdb"), strerror(errno)));
3365 DEBUG(10, ("lp_regdb_open: reg tdb opened.\n"));
3368 vers_id = tdb_fetch_int32(reg_tdb->tdb, vstring);
3369 if (vers_id != REGVER_V1) {
3370 DEBUG(10, ("lp_regdb_open: INFO: registry tdb %s has wrong "
3371 "INFO/version (got %d, expected %d)\n",
3372 state_path("registry.tdb"), vers_id, REGVER_V1));
3373 /* this is apparently not implemented in the tdb */
3381 * process_registry_globals
3383 * this is the interim version of process_registry globals
3385 * until we can do it as we would like using the api and only
3386 * using the tdb portion of the registry (see below),
3387 * this just provides the needed functionality of regdb_fetch_values
3388 * and regdb_unpack_values, circumventing any fancy stuff, to
3389 * give us access to the registry globals.
3391 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
3394 struct tdb_wrap *reg_tdb = NULL;
3398 /* vars for the tdb unpack loop */
3405 uint32 num_values = 0;
3408 struct registry_value *value = NULL;
3410 include_registry_globals = True;
3414 reg_tdb = lp_regdb_open();
3416 DEBUG(1, ("Error opening the registry!\n"));
3420 /* reg_tdb is from now on used as talloc ctx.
3421 * freeing it closes the tdb (if refcount is 0) */
3423 keystr = talloc_asprintf(reg_tdb,"%s/%s/%s", REG_VALUE_PREFIX,
3424 KEY_SMBCONF, GLOBAL_NAME);
3425 normalize_dbkey(keystr);
3427 DEBUG(10, ("process_registry_globals: fetching key '%s'\n",
3430 data = tdb_fetch_bystring(reg_tdb->tdb, keystr);
3437 buflen = data.dsize;
3439 /* unpack number of values */
3440 len = tdb_unpack(buf, buflen, "d", &num_values);
3441 DEBUG(10, ("process_registry_globals: got %d values from tdb\n",
3444 /* unpack the values */
3445 for (i=0; i < num_values; i++) {
3450 len += tdb_unpack(buf+len, buflen-len, "fdB",
3455 if (registry_smbconf_valname_forbidden(valname)) {
3456 DEBUG(10, ("process_registry_globals: Ignoring "
3457 "parameter '%s' in registry.\n", valname));
3460 DEBUG(10, ("process_registry_globals: got value '%s'\n",
3462 if (size && data_p) {
3463 err = registry_pull_value(reg_tdb,
3470 if (!W_ERROR_IS_OK(err)) {
3475 valstr = talloc_asprintf(reg_tdb, "%d",
3477 pfunc(valname, valstr);
3480 pfunc(valname, value->v.sz.str);
3483 /* ignore other types */
3489 ret = pfunc("registry shares", "yes");
3490 regdb_last_seqnum = tdb_get_seqnum(reg_tdb->tdb);
3493 TALLOC_FREE(reg_tdb);
3494 SAFE_FREE(data.dptr);
3500 * this is process_registry_globals as it _should_ be (roughly)
3501 * using the reg_api functions...
3504 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
3507 TALLOC_CTX *ctx = NULL;
3508 char *regpath = NULL;
3509 WERROR werr = WERR_OK;
3510 struct registry_key *key = NULL;
3511 struct registry_value *value = NULL;
3512 char *valname = NULL;
3513 char *valstr = NULL;
3515 NT_USER_TOKEN *token;
3517 ctx = talloc_init("process_registry_globals");
3519 smb_panic("Failed to create talloc context!");
3522 include_registry_globals = True;
3524 if (!registry_init_regdb()) {
3525 DEBUG(1, ("Error initializing the registry.\n"));
3529 if (!(token = registry_create_admin_token(ctx))) {
3530 DEBUG(1, ("Error creating admin token\n"));
3534 regpath = talloc_asprintf(ctx,"%s\\%s", KEY_SMBCONF, GLOBAL_NAME);
3535 werr = reg_open_path(ctx, regpath, REG_KEY_READ, token, &key);
3536 if (!W_ERROR_IS_OK(werr)) {
3537 DEBUG(1, ("Registry smbconf global section does not exist.\n"));
3538 DEBUGADD(1, ("Error opening registry path '%s\\%s: %s\n",
3539 KEY_SMBCONF, GLOBAL_NAME, dos_errstr(werr)));
3544 W_ERROR_IS_OK(werr = reg_enumvalue(ctx, key, idx, &valname,
3548 DEBUG(5, ("got global registry parameter '%s'\n", valname));
3549 switch(value->type) {
3551 valstr = talloc_asprintf(ctx, "%d", value->v.dword);
3552 pfunc(valname, valstr);
3553 TALLOC_FREE(valstr);
3556 pfunc(valname, value->v.sz.str);
3559 /* ignore other types */
3563 TALLOC_FREE(valstr);
3566 ret = pfunc("registry shares", "yes");
3568 regdb_last_seqnum = regdb_get_seqnum();
3571 talloc_destroy(ctx);
3576 static struct file_lists {
3577 struct file_lists *next;
3581 } *file_lists = NULL;
3583 /*******************************************************************
3584 Keep a linked list of all config files so we know when one has changed
3585 it's date and needs to be reloaded.
3586 ********************************************************************/
3588 static void add_to_file_list(const char *fname, const char *subfname)
3590 struct file_lists *f = file_lists;
3593 if (f->name && !strcmp(f->name, fname))
3599 f = SMB_MALLOC_P(struct file_lists);
3602 f->next = file_lists;
3603 f->name = SMB_STRDUP(fname);
3608 f->subfname = SMB_STRDUP(subfname);
3614 f->modtime = file_modtime(subfname);
3616 time_t t = file_modtime(subfname);
3622 /*******************************************************************
3623 Check if a config file has changed date.
3624 ********************************************************************/
3626 bool lp_file_list_changed(void)
3628 struct file_lists *f = file_lists;
3629 struct tdb_wrap *reg_tdb = NULL;
3631 DEBUG(6, ("lp_file_list_changed()\n"));
3633 if (include_registry_globals) {
3634 reg_tdb = lp_regdb_open();
3635 if (reg_tdb && (regdb_last_seqnum != tdb_get_seqnum(reg_tdb->tdb)))
3637 DEBUGADD(6, ("regdb seqnum changed: old = %d, new = %d\n",
3638 regdb_last_seqnum, tdb_get_seqnum(reg_tdb->tdb)));
3639 TALLOC_FREE(reg_tdb);
3648 n2 = alloc_sub_basic(get_current_username(),
3649 current_user_info.domain,
3654 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3655 f->name, n2, ctime(&f->modtime)));
3657 mod_time = file_modtime(n2);
3659 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3661 ("file %s modified: %s\n", n2,
3663 f->modtime = mod_time;
3664 SAFE_FREE(f->subfname);
3665 f->subfname = n2; /* Passing ownership of
3666 return from alloc_sub_basic
3676 /***************************************************************************
3677 Run standard_sub_basic on netbios name... needed because global_myname
3678 is not accessed through any lp_ macro.
3679 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3680 ***************************************************************************/
3682 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3685 char *netbios_name = alloc_sub_basic(get_current_username(),
3686 current_user_info.domain,
3689 ret = set_global_myname(netbios_name);
3690 SAFE_FREE(netbios_name);
3691 string_set(&Globals.szNetbiosName,global_myname());
3693 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3699 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
3701 if (strcmp(*ptr, pszParmValue) != 0) {
3702 string_set(ptr, pszParmValue);
3710 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3714 ret = set_global_myworkgroup(pszParmValue);
3715 string_set(&Globals.szWorkgroup,lp_workgroup());
3720 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3724 ret = set_global_scope(pszParmValue);
3725 string_set(&Globals.szNetbiosScope,global_scope());
3730 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3732 str_list_free(&Globals.szNetbiosAliases);
3733 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3734 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3737 /***************************************************************************
3738 Handle the include operation.
3739 ***************************************************************************/
3741 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
3745 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
3746 if (bInGlobalSection) {
3747 return process_registry_globals(do_parameter);
3750 DEBUG(1, ("\"include = registry\" only effective "
3751 "in %s section\n", GLOBAL_NAME));
3756 fname = alloc_sub_basic(get_current_username(),
3757 current_user_info.domain,
3760 add_to_file_list(pszParmValue, fname);
3762 string_set(ptr, fname);
3764 if (file_exist(fname, NULL)) {
3765 bool ret = pm_process(fname, do_section, do_parameter);
3770 DEBUG(2, ("Can't find include file %s\n", fname));
3775 /***************************************************************************
3776 Handle the interpretation of the copy parameter.
3777 ***************************************************************************/
3779 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
3783 service serviceTemp;
3785 string_set(ptr, pszParmValue);
3787 init_service(&serviceTemp);
3791 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3793 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3794 if (iTemp == iServiceIndex) {
3795 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3797 copy_service(ServicePtrs[iServiceIndex],
3799 ServicePtrs[iServiceIndex]->copymap);
3803 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3807 free_service(&serviceTemp);
3811 /***************************************************************************
3812 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3817 idmap uid = 1000-1999
3820 We only do simple parsing checks here. The strings are parsed into useful
3821 structures in the idmap daemon code.
3823 ***************************************************************************/
3825 /* Some lp_ routines to return idmap [ug]id information */
3827 static uid_t idmap_uid_low, idmap_uid_high;
3828 static gid_t idmap_gid_low, idmap_gid_high;
3830 bool lp_idmap_uid(uid_t *low, uid_t *high)
3832 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3836 *low = idmap_uid_low;
3839 *high = idmap_uid_high;
3844 bool lp_idmap_gid(gid_t *low, gid_t *high)
3846 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3850 *low = idmap_gid_low;
3853 *high = idmap_gid_high;
3858 /* Do some simple checks on "idmap [ug]id" parameter values */
3860 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3864 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3869 string_set(ptr, pszParmValue);
3871 idmap_uid_low = low;
3872 idmap_uid_high = high;
3877 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3881 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3886 string_set(ptr, pszParmValue);
3888 idmap_gid_low = low;
3889 idmap_gid_high = high;
3894 /***************************************************************************
3895 Handle the DEBUG level list.
3896 ***************************************************************************/
3898 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3900 string_set(ptr, pszParmValueIn);
3901 return debug_parse_levels(pszParmValueIn);
3904 /***************************************************************************
3905 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3906 ***************************************************************************/
3908 static const char *append_ldap_suffix( const char *str )
3910 const char *suffix_string;
3913 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
3914 Globals.szLdapSuffix );
3915 if ( !suffix_string ) {
3916 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3920 return suffix_string;
3923 const char *lp_ldap_machine_suffix(void)
3925 if (Globals.szLdapMachineSuffix[0])
3926 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3928 return lp_string(Globals.szLdapSuffix);
3931 const char *lp_ldap_user_suffix(void)
3933 if (Globals.szLdapUserSuffix[0])
3934 return append_ldap_suffix(Globals.szLdapUserSuffix);
3936 return lp_string(Globals.szLdapSuffix);
3939 const char *lp_ldap_group_suffix(void)
3941 if (Globals.szLdapGroupSuffix[0])
3942 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3944 return lp_string(Globals.szLdapSuffix);
3947 const char *lp_ldap_idmap_suffix(void)
3949 if (Globals.szLdapIdmapSuffix[0])
3950 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3952 return lp_string(Globals.szLdapSuffix);
3955 /****************************************************************************
3956 set the value for a P_ENUM
3957 ***************************************************************************/
3959 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3964 for (i = 0; parm->enum_list[i].name; i++) {
3965 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3966 *ptr = parm->enum_list[i].value;
3972 /***************************************************************************
3973 ***************************************************************************/
3975 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
3977 static int parm_num = -1;
3980 if ( parm_num == -1 )
3981 parm_num = map_parameter( "printing" );
3983 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3988 s = ServicePtrs[snum];
3990 init_printer_values( s );
3996 /***************************************************************************
3997 Initialise a copymap.
3998 ***************************************************************************/
4000 static void init_copymap(service * pservice)
4003 if (pservice->copymap) {
4004 bitmap_free(pservice->copymap);
4006 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
4007 if (!pservice->copymap)
4009 ("Couldn't allocate copymap!! (size %d)\n",
4010 (int)NUMPARAMETERS));
4012 for (i = 0; i < NUMPARAMETERS; i++)
4013 bitmap_set(pservice->copymap, i);
4016 /***************************************************************************
4017 Return the local pointer to a parameter given the service number and the
4018 pointer into the default structure.
4019 ***************************************************************************/
4021 void *lp_local_ptr(int snum, void *ptr)
4023 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
4026 /***************************************************************************
4027 Process a parameter for a particular service number. If snum < 0
4028 then assume we are in the globals.
4029 ***************************************************************************/
4031 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
4033 int parmnum, i, slen;
4034 void *parm_ptr = NULL; /* where we are going to store the result */
4035 void *def_ptr = NULL;
4036 char *param_key = NULL;
4038 param_opt_struct *paramo, *data;
4041 parmnum = map_parameter(pszParmName);
4044 if ((sep=strchr(pszParmName, ':')) != NULL) {
4045 TALLOC_CTX *frame = talloc_stackframe();
4048 param_key = talloc_asprintf(frame, "%s:", pszParmName);
4053 slen = strlen(param_key);
4054 param_key = talloc_asprintf_append(param_key, sep+1);
4059 trim_char(param_key+slen, ' ', ' ');
4061 data = (snum < 0) ? Globals.param_opt :
4062 ServicePtrs[snum]->param_opt;
4063 /* Traverse destination */
4065 /* If we already have same option, override it */
4066 if (strcmp(data->key, param_key) == 0) {
4067 string_free(&data->value);
4068 str_list_free(&data->list);
4069 data->value = SMB_STRDUP(pszParmValue);
4076 paramo = SMB_XMALLOC_P(param_opt_struct);
4077 paramo->key = SMB_STRDUP(param_key);
4078 paramo->value = SMB_STRDUP(pszParmValue);
4079 paramo->list = NULL;
4081 DLIST_ADD(Globals.param_opt, paramo);
4083 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
4091 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
4095 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
4096 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
4100 def_ptr = parm_table[parmnum].ptr;
4102 /* we might point at a service, the default service or a global */
4106 if (parm_table[parmnum].p_class == P_GLOBAL) {
4108 ("Global parameter %s found in service section!\n",
4113 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
4118 if (!ServicePtrs[snum]->copymap)
4119 init_copymap(ServicePtrs[snum]);
4121 /* this handles the aliases - set the copymap for other entries with
4122 the same data pointer */
4123 for (i = 0; parm_table[i].label; i++)
4124 if (parm_table[i].ptr == parm_table[parmnum].ptr)
4125 bitmap_clear(ServicePtrs[snum]->copymap, i);
4128 /* if it is a special case then go ahead */
4129 if (parm_table[parmnum].special) {
4130 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
4134 /* now switch on the type of variable it is */
4135 switch (parm_table[parmnum].type)
4138 *(bool *)parm_ptr = lp_bool(pszParmValue);
4142 *(bool *)parm_ptr = !lp_bool(pszParmValue);
4146 *(int *)parm_ptr = lp_int(pszParmValue);
4150 *(char *)parm_ptr = *pszParmValue;
4154 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
4156 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
4161 str_list_free((char ***)parm_ptr);
4162 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
4166 string_set((char **)parm_ptr, pszParmValue);
4170 string_set((char **)parm_ptr, pszParmValue);
4171 strupper_m(*(char **)parm_ptr);
4175 pstrcpy((char *)parm_ptr, pszParmValue);
4179 pstrcpy((char *)parm_ptr, pszParmValue);
4180 strupper_m((char *)parm_ptr);
4184 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
4193 /***************************************************************************
4194 Process a parameter.
4195 ***************************************************************************/
4197 static bool do_parameter(const char *pszParmName, const char *pszParmValue)
4199 if (!bInGlobalSection && bGlobalOnly)
4202 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
4204 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
4205 pszParmName, pszParmValue));
4208 /***************************************************************************
4209 Print a parameter of the specified type.
4210 ***************************************************************************/
4212 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
4218 for (i = 0; p->enum_list[i].name; i++) {
4219 if (*(int *)ptr == p->enum_list[i].value) {
4221 p->enum_list[i].name);
4228 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
4232 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
4236 fprintf(f, "%d", *(int *)ptr);
4240 fprintf(f, "%c", *(char *)ptr);
4244 fprintf(f, "%s", octal_string(*(int *)ptr));
4248 if ((char ***)ptr && *(char ***)ptr) {
4249 char **list = *(char ***)ptr;
4251 for (; *list; list++) {
4252 /* surround strings with whitespace in double quotes */
4253 if ( strchr_m( *list, ' ' ) )
4254 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
4256 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
4264 fprintf(f, "%s", (char *)ptr);
4270 if (*(char **)ptr) {
4271 fprintf(f, "%s", *(char **)ptr);
4279 /***************************************************************************
4280 Check if two parameters are equal.
4281 ***************************************************************************/
4283 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
4288 return (*((bool *)ptr1) == *((bool *)ptr2));
4293 return (*((int *)ptr1) == *((int *)ptr2));
4296 return (*((char *)ptr1) == *((char *)ptr2));
4299 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
4304 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
4309 return (p1 == p2 || strequal(p1, p2));
4314 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
4319 return (p1 == p2 || strequal(p1, p2));
4327 /***************************************************************************
4328 Initialize any local varients in the sDefault table.
4329 ***************************************************************************/
4331 void init_locals(void)
4336 /***************************************************************************
4337 Process a new section (service). At this stage all sections are services.
4338 Later we'll have special sections that permit server parameters to be set.
4339 Returns True on success, False on failure.
4340 ***************************************************************************/
4342 static bool do_section(const char *pszSectionName)
4345 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
4346 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
4349 /* if we were in a global section then do the local inits */
4350 if (bInGlobalSection && !isglobal)
4353 /* if we've just struck a global section, note the fact. */
4354 bInGlobalSection = isglobal;
4356 /* check for multiple global sections */
4357 if (bInGlobalSection) {
4358 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
4362 if (!bInGlobalSection && bGlobalOnly)
4365 /* if we have a current service, tidy it up before moving on */
4368 if (iServiceIndex >= 0)
4369 bRetval = service_ok(iServiceIndex);
4371 /* if all is still well, move to the next record in the services array */
4373 /* We put this here to avoid an odd message order if messages are */
4374 /* issued by the post-processing of a previous section. */
4375 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
4377 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
4379 DEBUG(0, ("Failed to add a new service\n"));
4388 /***************************************************************************
4389 Determine if a partcular base parameter is currentl set to the default value.
4390 ***************************************************************************/
4392 static bool is_default(int i)
4394 if (!defaults_saved)
4396 switch (parm_table[i].type) {
4398 return str_list_compare (parm_table[i].def.lvalue,
4399 *(char ***)parm_table[i].ptr);
4402 return strequal(parm_table[i].def.svalue,
4403 *(char **)parm_table[i].ptr);
4406 return strequal(parm_table[i].def.svalue,
4407 (char *)parm_table[i].ptr);
4410 return parm_table[i].def.bvalue ==
4411 *(bool *)parm_table[i].ptr;
4413 return parm_table[i].def.cvalue ==
4414 *(char *)parm_table[i].ptr;
4418 return parm_table[i].def.ivalue ==
4419 *(int *)parm_table[i].ptr;
4426 /***************************************************************************
4427 Display the contents of the global structure.
4428 ***************************************************************************/
4430 static void dump_globals(FILE *f)
4433 param_opt_struct *data;
4435 fprintf(f, "[global]\n");
4437 for (i = 0; parm_table[i].label; i++)
4438 if (parm_table[i].p_class == P_GLOBAL &&
4439 parm_table[i].ptr &&
4440 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
4441 if (defaults_saved && is_default(i))
4443 fprintf(f, "\t%s = ", parm_table[i].label);
4444 print_parameter(&parm_table[i], parm_table[i].ptr, f);
4447 if (Globals.param_opt != NULL) {
4448 data = Globals.param_opt;
4450 fprintf(f, "\t%s = %s\n", data->key, data->value);
4457 /***************************************************************************
4458 Return True if a local parameter is currently set to the global default.
4459 ***************************************************************************/
4461 bool lp_is_default(int snum, struct parm_struct *parm)
4463 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
4465 return equal_parameter(parm->type,
4466 ((char *)ServicePtrs[snum]) + pdiff,
4467 ((char *)&sDefault) + pdiff);
4470 /***************************************************************************
4471 Display the contents of a single services record.
4472 ***************************************************************************/
4474 static void dump_a_service(service * pService, FILE * f)
4477 param_opt_struct *data;
4479 if (pService != &sDefault)
4480 fprintf(f, "[%s]\n", pService->szService);
4482 for (i = 0; parm_table[i].label; i++) {
4484 if (parm_table[i].p_class == P_LOCAL &&
4485 parm_table[i].ptr &&
4486 (*parm_table[i].label != '-') &&
4487 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4490 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
4492 if (pService == &sDefault) {
4493 if (defaults_saved && is_default(i))
4496 if (equal_parameter(parm_table[i].type,
4497 ((char *)pService) +
4499 ((char *)&sDefault) +
4504 fprintf(f, "\t%s = ", parm_table[i].label);
4505 print_parameter(&parm_table[i],
4506 ((char *)pService) + pdiff, f);
4511 if (pService->param_opt != NULL) {
4512 data = pService->param_opt;
4514 fprintf(f, "\t%s = %s\n", data->key, data->value);
4520 /***************************************************************************
4521 Display the contents of a parameter of a single services record.
4522 ***************************************************************************/
4524 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
4527 bool result = False;
4530 fstring local_parm_name;
4532 const char *parm_opt_value;
4534 /* check for parametrical option */
4535 fstrcpy( local_parm_name, parm_name);
4536 parm_opt = strchr( local_parm_name, ':');
4541 if (strlen(parm_opt)) {
4542 parm_opt_value = lp_parm_const_string( snum,
4543 local_parm_name, parm_opt, NULL);
4544 if (parm_opt_value) {
4545 printf( "%s\n", parm_opt_value);
4552 /* check for a key and print the value */
4559 for (i = 0; parm_table[i].label; i++) {
4560 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
4561 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
4562 parm_table[i].ptr &&
4563 (*parm_table[i].label != '-') &&
4564 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4569 ptr = parm_table[i].ptr;
4571 service * pService = ServicePtrs[snum];
4572 ptr = ((char *)pService) +
4573 PTR_DIFF(parm_table[i].ptr, &sDefault);
4576 print_parameter(&parm_table[i],
4587 /***************************************************************************
4588 Return info about the requested parameter (given as a string).
4589 Return NULL when the string is not a valid parameter name.
4590 ***************************************************************************/
4592 struct parm_struct *lp_get_parameter(const char *param_name)
4594 int num = map_parameter(param_name);
4600 return &parm_table[num];
4603 /***************************************************************************
4604 Return info about the next parameter in a service.
4605 snum==GLOBAL_SECTION_SNUM gives the globals.
4606 Return NULL when out of parameters.
4607 ***************************************************************************/
4609 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
4612 /* do the globals */
4613 for (; parm_table[*i].label; (*i)++) {
4614 if (parm_table[*i].p_class == P_SEPARATOR)
4615 return &parm_table[(*i)++];
4617 if (!parm_table[*i].ptr
4618 || (*parm_table[*i].label == '-'))
4622 && (parm_table[*i].ptr ==
4623 parm_table[(*i) - 1].ptr))
4626 if (is_default(*i) && !allparameters)
4629 return &parm_table[(*i)++];
4632 service *pService = ServicePtrs[snum];
4634 for (; parm_table[*i].label; (*i)++) {
4635 if (parm_table[*i].p_class == P_SEPARATOR)
4636 return &parm_table[(*i)++];
4638 if (parm_table[*i].p_class == P_LOCAL &&
4639 parm_table[*i].ptr &&
4640 (*parm_table[*i].label != '-') &&
4642 (parm_table[*i].ptr !=
4643 parm_table[(*i) - 1].ptr)))
4646 PTR_DIFF(parm_table[*i].ptr,
4649 if (allparameters ||
4650 !equal_parameter(parm_table[*i].type,
4651 ((char *)pService) +
4653 ((char *)&sDefault) +
4656 return &parm_table[(*i)++];
4667 /***************************************************************************
4668 Display the contents of a single copy structure.
4669 ***************************************************************************/
4670 static void dump_copy_map(bool *pcopymap)
4676 printf("\n\tNon-Copied parameters:\n");
4678 for (i = 0; parm_table[i].label; i++)
4679 if (parm_table[i].p_class == P_LOCAL &&
4680 parm_table[i].ptr && !pcopymap[i] &&
4681 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4683 printf("\t\t%s\n", parm_table[i].label);
4688 /***************************************************************************
4689 Return TRUE if the passed service number is within range.
4690 ***************************************************************************/
4692 bool lp_snum_ok(int iService)
4694 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4697 /***************************************************************************
4698 Auto-load some home services.
4699 ***************************************************************************/
4701 static void lp_add_auto_services(char *str)
4710 s = SMB_STRDUP(str);
4714 homes = lp_servicenumber(HOMES_NAME);
4716 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4717 char *home = get_user_home_dir(p);
4719 if (lp_servicenumber(p) >= 0)
4722 if (home && homes >= 0)
4723 lp_add_home(p, homes, p, home);
4728 /***************************************************************************
4729 Auto-load one printer.
4730 ***************************************************************************/
4732 void lp_add_one_printer(char *name, char *comment)
4734 int printers = lp_servicenumber(PRINTERS_NAME);
4737 if (lp_servicenumber(name) < 0) {
4738 lp_add_printer(name, printers);
4739 if ((i = lp_servicenumber(name)) >= 0) {
4740 string_set(&ServicePtrs[i]->comment, comment);
4741 ServicePtrs[i]->autoloaded = True;
4746 /***************************************************************************
4747 Have we loaded a services file yet?
4748 ***************************************************************************/
4750 bool lp_loaded(void)
4755 /***************************************************************************
4756 Unload unused services.
4757 ***************************************************************************/
4759 void lp_killunused(bool (*snumused) (int))
4762 for (i = 0; i < iNumServices; i++) {
4766 /* don't kill autoloaded or usershare services */
4767 if ( ServicePtrs[i]->autoloaded ||
4768 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4772 if (!snumused || !snumused(i)) {
4773 free_service_byindex(i);
4778 /***************************************************************************
4780 ***************************************************************************/
4782 void lp_killservice(int iServiceIn)
4784 if (VALID(iServiceIn)) {
4785 free_service_byindex(iServiceIn);
4789 /***************************************************************************
4790 Save the curent values of all global and sDefault parameters into the
4791 defaults union. This allows swat and testparm to show only the
4792 changed (ie. non-default) parameters.
4793 ***************************************************************************/
4795 static void lp_save_defaults(void)
4798 for (i = 0; parm_table[i].label; i++) {
4799 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4801 switch (parm_table[i].type) {
4803 str_list_copy(&(parm_table[i].def.lvalue),
4804 *(const char ***)parm_table[i].ptr);
4808 if (parm_table[i].ptr) {
4809 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4811 parm_table[i].def.svalue = NULL;
4816 if (parm_table[i].ptr) {
4817 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4819 parm_table[i].def.svalue = NULL;
4824 parm_table[i].def.bvalue =
4825 *(bool *)parm_table[i].ptr;
4828 parm_table[i].def.cvalue =
4829 *(char *)parm_table[i].ptr;
4834 parm_table[i].def.ivalue =
4835 *(int *)parm_table[i].ptr;
4841 defaults_saved = True;
4844 /*******************************************************************
4845 Set the server type we will announce as via nmbd.
4846 ********************************************************************/
4848 static const struct srv_role_tab {
4850 const char *role_str;
4851 } srv_role_tab [] = {
4852 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4853 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4854 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4855 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4859 const char* server_role_str(uint32 role)
4862 for (i=0; srv_role_tab[i].role_str; i++) {
4863 if (role == srv_role_tab[i].role) {
4864 return srv_role_tab[i].role_str;
4870 static void set_server_role(void)
4872 server_role = ROLE_STANDALONE;
4874 switch (lp_security()) {
4876 if (lp_domain_logons())
4877 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4880 if (lp_domain_logons())
4881 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4882 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
4883 server_role = ROLE_STANDALONE;
4886 if (lp_domain_logons()) {
4887 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4888 server_role = ROLE_DOMAIN_BDC;
4891 server_role = ROLE_DOMAIN_MEMBER;
4894 if (lp_domain_logons()) {
4895 server_role = ROLE_DOMAIN_PDC;
4898 server_role = ROLE_DOMAIN_MEMBER;
4901 if (lp_domain_logons()) {
4903 if (Globals.iDomainMaster) /* auto or yes */
4904 server_role = ROLE_DOMAIN_PDC;
4906 server_role = ROLE_DOMAIN_BDC;
4910 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4914 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4917 /***********************************************************
4918 If we should send plaintext/LANMAN passwords in the clinet
4919 ************************************************************/
4921 static void set_allowed_client_auth(void)
4923 if (Globals.bClientNTLMv2Auth) {
4924 Globals.bClientLanManAuth = False;
4926 if (!Globals.bClientLanManAuth) {
4927 Globals.bClientPlaintextAuth = False;
4931 /***************************************************************************
4933 The following code allows smbd to read a user defined share file.
4934 Yes, this is my intent. Yes, I'm comfortable with that...
4936 THE FOLLOWING IS SECURITY CRITICAL CODE.
4938 It washes your clothes, it cleans your house, it guards you while you sleep...
4939 Do not f%^k with it....
4940 ***************************************************************************/
4942 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4944 /***************************************************************************
4945 Check allowed stat state of a usershare file.
4946 Ensure we print out who is dicking with us so the admin can
4947 get their sorry ass fired.
4948 ***************************************************************************/
4950 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4952 if (!S_ISREG(psbuf->st_mode)) {
4953 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4954 "not a regular file\n",
4955 fname, (unsigned int)psbuf->st_uid ));
4959 /* Ensure this doesn't have the other write bit set. */
4960 if (psbuf->st_mode & S_IWOTH) {
4961 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4962 "public write. Refusing to allow as a usershare file.\n",
4963 fname, (unsigned int)psbuf->st_uid ));
4967 /* Should be 10k or less. */
4968 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4969 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4970 "too large (%u) to be a user share file.\n",
4971 fname, (unsigned int)psbuf->st_uid,
4972 (unsigned int)psbuf->st_size ));
4979 /***************************************************************************
4980 Parse the contents of a usershare file.
4981 ***************************************************************************/
4983 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4984 SMB_STRUCT_STAT *psbuf,
4985 const char *servicename,
4989 char **pp_sharepath,
4994 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4995 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4998 SMB_STRUCT_STAT sbuf;
4999 char *sharepath = NULL;
5000 char *comment = NULL;
5002 *pp_sharepath = NULL;
5005 *pallow_guest = False;
5008 return USERSHARE_MALFORMED_FILE;
5011 if (strcmp(lines[0], "#VERSION 1") == 0) {
5013 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
5016 return USERSHARE_MALFORMED_FILE;
5019 return USERSHARE_BAD_VERSION;
5022 if (strncmp(lines[1], "path=", 5) != 0) {
5023 return USERSHARE_MALFORMED_PATH;
5026 sharepath = talloc_strdup(ctx, &lines[1][5]);
5028 return USERSHARE_POSIX_ERR;
5030 trim_string(sharepath, " ", " ");
5032 if (strncmp(lines[2], "comment=", 8) != 0) {
5033 return USERSHARE_MALFORMED_COMMENT_DEF;
5036 comment = talloc_strdup(ctx, &lines[2][8]);
5038 return USERSHARE_POSIX_ERR;
5040 trim_string(comment, " ", " ");
5041 trim_char(comment, '"', '"');
5043 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
5044 return USERSHARE_MALFORMED_ACL_DEF;
5047 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
5048 return USERSHARE_ACL_ERR;
5052 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
5053 return USERSHARE_MALFORMED_ACL_DEF;
5055 if (lines[4][9] == 'y') {
5056 *pallow_guest = True;
5060 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
5061 /* Path didn't change, no checks needed. */
5062 *pp_sharepath = sharepath;
5063 *pp_comment = comment;
5064 return USERSHARE_OK;
5067 /* The path *must* be absolute. */
5068 if (sharepath[0] != '/') {
5069 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
5070 servicename, sharepath));
5071 return USERSHARE_PATH_NOT_ABSOLUTE;
5074 /* If there is a usershare prefix deny list ensure one of these paths
5075 doesn't match the start of the user given path. */
5076 if (prefixdenylist) {
5078 for ( i=0; prefixdenylist[i]; i++ ) {
5079 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
5080 servicename, i, prefixdenylist[i], sharepath ));
5081 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
5082 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
5083 "usershare prefix deny list entries.\n",
5084 servicename, sharepath));
5085 return USERSHARE_PATH_IS_DENIED;
5090 /* If there is a usershare prefix allow list ensure one of these paths
5091 does match the start of the user given path. */
5093 if (prefixallowlist) {
5095 for ( i=0; prefixallowlist[i]; i++ ) {
5096 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
5097 servicename, i, prefixallowlist[i], sharepath ));
5098 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
5102 if (prefixallowlist[i] == NULL) {
5103 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
5104 "usershare prefix allow list entries.\n",
5105 servicename, sharepath));
5106 return USERSHARE_PATH_NOT_ALLOWED;
5110 /* Ensure this is pointing to a directory. */
5111 dp = sys_opendir(sharepath);
5114 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
5115 servicename, sharepath));
5116 return USERSHARE_PATH_NOT_DIRECTORY;
5119 /* Ensure the owner of the usershare file has permission to share
5122 if (sys_stat(sharepath, &sbuf) == -1) {
5123 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
5124 servicename, sharepath, strerror(errno) ));
5126 return USERSHARE_POSIX_ERR;
5131 if (!S_ISDIR(sbuf.st_mode)) {
5132 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
5133 servicename, sharepath ));
5134 return USERSHARE_PATH_NOT_DIRECTORY;
5137 /* Check if sharing is restricted to owner-only. */
5138 /* psbuf is the stat of the usershare definition file,
5139 sbuf is the stat of the target directory to be shared. */
5141 if (lp_usershare_owner_only()) {
5142 /* root can share anything. */
5143 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
5144 return USERSHARE_PATH_NOT_ALLOWED;
5148 *pp_sharepath = sharepath;
5149 *pp_comment = comment;
5150 return USERSHARE_OK;
5153 /***************************************************************************
5154 Deal with a usershare file.
5157 -1 - Bad name, invalid contents.
5158 - service name already existed and not a usershare, problem
5159 with permissions to share directory etc.
5160 ***************************************************************************/
5162 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
5164 SMB_STRUCT_STAT sbuf;
5165 SMB_STRUCT_STAT lsbuf;
5167 char *sharepath = NULL;
5168 char *comment = NULL;
5169 fstring service_name;
5170 char **lines = NULL;
5174 TALLOC_CTX *ctx = NULL;
5175 SEC_DESC *psd = NULL;
5176 bool guest_ok = False;
5178 /* Ensure share name doesn't contain invalid characters. */
5179 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
5180 DEBUG(0,("process_usershare_file: share name %s contains "
5181 "invalid characters (any of %s)\n",
5182 file_name, INVALID_SHARENAME_CHARS ));
5186 fstrcpy(service_name, file_name);
5188 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
5191 /* Minimize the race condition by doing an lstat before we
5192 open and fstat. Ensure this isn't a symlink link. */
5194 if (sys_lstat(fname, &lsbuf) != 0) {
5195 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
5196 fname, strerror(errno) ));
5201 /* This must be a regular file, not a symlink, directory or
5202 other strange filetype. */
5203 if (!check_usershare_stat(fname, &lsbuf)) {
5208 /* See if there is already a servicenum for this name. */
5209 /* tdb_fetch_int32 returns -1 if not found. */
5210 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
5212 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
5213 /* Nothing changed - Mark valid and return. */
5214 DEBUG(10,("process_usershare_file: service %s not changed.\n",
5216 ServicePtrs[iService]->usershare = USERSHARE_VALID;
5221 /* Try and open the file read only - no symlinks allowed. */
5223 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
5225 fd = sys_open(fname, O_RDONLY, 0);
5229 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
5230 fname, strerror(errno) ));
5235 /* Now fstat to be *SURE* it's a regular file. */
5236 if (sys_fstat(fd, &sbuf) != 0) {
5238 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
5239 fname, strerror(errno) ));
5244 /* Is it the same dev/inode as was lstated ? */
5245 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
5247 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
5248 "Symlink spoofing going on ?\n", fname ));
5253 /* This must be a regular file, not a symlink, directory or
5254 other strange filetype. */
5255 if (!check_usershare_stat(fname, &sbuf)) {
5260 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
5263 if (lines == NULL) {
5264 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
5265 fname, (unsigned int)sbuf.st_uid ));
5272 /* Should we allow printers to be shared... ? */
5273 ctx = talloc_init("usershare_sd_xctx");
5275 file_lines_free(lines);
5279 if (parse_usershare_file(ctx, &sbuf, service_name,
5280 iService, lines, numlines, &sharepath,
5281 &comment, &psd, &guest_ok) != USERSHARE_OK) {
5282 talloc_destroy(ctx);
5283 file_lines_free(lines);
5287 file_lines_free(lines);
5289 /* Everything ok - add the service possibly using a template. */
5291 const service *sp = &sDefault;
5292 if (snum_template != -1) {
5293 sp = ServicePtrs[snum_template];
5296 if ((iService = add_a_service(sp, service_name)) < 0) {
5297 DEBUG(0, ("process_usershare_file: Failed to add "
5298 "new service %s\n", service_name));
5299 talloc_destroy(ctx);
5303 /* Read only is controlled by usershare ACL below. */
5304 ServicePtrs[iService]->bRead_only = False;
5307 /* Write the ACL of the new/modified share. */
5308 if (!set_share_security(service_name, psd)) {
5309 DEBUG(0, ("process_usershare_file: Failed to set share "
5310 "security for user share %s\n",
5312 lp_remove_service(iService);
5313 talloc_destroy(ctx);
5317 /* If from a template it may be marked invalid. */
5318 ServicePtrs[iService]->valid = True;
5320 /* Set the service as a valid usershare. */
5321 ServicePtrs[iService]->usershare = USERSHARE_VALID;
5323 /* Set guest access. */
5324 if (lp_usershare_allow_guests()) {
5325 ServicePtrs[iService]->bGuest_ok = guest_ok;
5328 /* And note when it was loaded. */
5329 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
5330 string_set(&ServicePtrs[iService]->szPath, sharepath);
5331 string_set(&ServicePtrs[iService]->comment, comment);
5333 talloc_destroy(ctx);
5338 /***************************************************************************
5339 Checks if a usershare entry has been modified since last load.
5340 ***************************************************************************/
5342 static bool usershare_exists(int iService, time_t *last_mod)
5344 SMB_STRUCT_STAT lsbuf;
5345 const char *usersharepath = Globals.szUsersharePath;
5348 if (asprintf(&fname, "%s/%s",
5350 ServicePtrs[iService]->szService) < 0) {
5354 if (sys_lstat(fname, &lsbuf) != 0) {
5359 if (!S_ISREG(lsbuf.st_mode)) {
5365 *last_mod = lsbuf.st_mtime;
5369 /***************************************************************************
5370 Load a usershare service by name. Returns a valid servicenumber or -1.
5371 ***************************************************************************/
5373 int load_usershare_service(const char *servicename)
5375 SMB_STRUCT_STAT sbuf;
5376 const char *usersharepath = Globals.szUsersharePath;
5377 int max_user_shares = Globals.iUsershareMaxShares;
5378 int snum_template = -1;
5380 if (*usersharepath == 0 || max_user_shares == 0) {
5384 if (sys_stat(usersharepath, &sbuf) != 0) {
5385 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
5386 usersharepath, strerror(errno) ));
5390 if (!S_ISDIR(sbuf.st_mode)) {
5391 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
5397 * This directory must be owned by root, and have the 't' bit set.
5398 * It also must not be writable by "other".
5402 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
5404 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
5406 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
5407 "or does not have the sticky bit 't' set or is writable by anyone.\n",
5412 /* Ensure the template share exists if it's set. */
5413 if (Globals.szUsershareTemplateShare[0]) {
5414 /* We can't use lp_servicenumber here as we are recommending that
5415 template shares have -valid=False set. */
5416 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
5417 if (ServicePtrs[snum_template]->szService &&
5418 strequal(ServicePtrs[snum_template]->szService,
5419 Globals.szUsershareTemplateShare)) {
5424 if (snum_template == -1) {
5425 DEBUG(0,("load_usershare_service: usershare template share %s "
5426 "does not exist.\n",
5427 Globals.szUsershareTemplateShare ));
5432 return process_usershare_file(usersharepath, servicename, snum_template);
5435 /***************************************************************************
5436 Load all user defined shares from the user share directory.
5437 We only do this if we're enumerating the share list.
5438 This is the function that can delete usershares that have
5440 ***************************************************************************/
5442 int load_usershare_shares(void)
5445 SMB_STRUCT_STAT sbuf;
5446 SMB_STRUCT_DIRENT *de;
5447 int num_usershares = 0;
5448 int max_user_shares = Globals.iUsershareMaxShares;
5449 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
5450 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
5451 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
5453 int snum_template = -1;
5454 const char *usersharepath = Globals.szUsersharePath;
5455 int ret = lp_numservices();
5457 if (max_user_shares == 0 || *usersharepath == '\0') {
5458 return lp_numservices();
5461 if (sys_stat(usersharepath, &sbuf) != 0) {
5462 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
5463 usersharepath, strerror(errno) ));
5468 * This directory must be owned by root, and have the 't' bit set.
5469 * It also must not be writable by "other".
5473 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
5475 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
5477 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
5478 "or does not have the sticky bit 't' set or is writable by anyone.\n",
5483 /* Ensure the template share exists if it's set. */
5484 if (Globals.szUsershareTemplateShare[0]) {
5485 /* We can't use lp_servicenumber here as we are recommending that
5486 template shares have -valid=False set. */
5487 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
5488 if (ServicePtrs[snum_template]->szService &&
5489 strequal(ServicePtrs[snum_template]->szService,
5490 Globals.szUsershareTemplateShare)) {
5495 if (snum_template == -1) {
5496 DEBUG(0,("load_usershare_shares: usershare template share %s "
5497 "does not exist.\n",
5498 Globals.szUsershareTemplateShare ));
5503 /* Mark all existing usershares as pending delete. */
5504 for (iService = iNumServices - 1; iService >= 0; iService--) {
5505 if (VALID(iService) && ServicePtrs[iService]->usershare) {
5506 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
5510 dp = sys_opendir(usersharepath);
5512 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
5513 usersharepath, strerror(errno) ));
5517 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
5518 (de = sys_readdir(dp));
5519 num_dir_entries++ ) {
5521 const char *n = de->d_name;
5523 /* Ignore . and .. */
5525 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
5531 /* Temporary file used when creating a share. */
5532 num_tmp_dir_entries++;
5535 /* Allow 20% tmp entries. */
5536 if (num_tmp_dir_entries > allowed_tmp_entries) {
5537 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
5538 "in directory %s\n",
5539 num_tmp_dir_entries, usersharepath));
5543 r = process_usershare_file(usersharepath, n, snum_template);
5545 /* Update the services count. */
5547 if (num_usershares >= max_user_shares) {
5548 DEBUG(0,("load_usershare_shares: max user shares reached "
5549 "on file %s in directory %s\n",
5550 n, usersharepath ));
5553 } else if (r == -1) {
5554 num_bad_dir_entries++;
5557 /* Allow 20% bad entries. */
5558 if (num_bad_dir_entries > allowed_bad_entries) {
5559 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
5560 "in directory %s\n",
5561 num_bad_dir_entries, usersharepath));
5565 /* Allow 20% bad entries. */
5566 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
5567 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
5568 "in directory %s\n",
5569 num_dir_entries, usersharepath));
5576 /* Sweep through and delete any non-refreshed usershares that are
5577 not currently in use. */
5578 for (iService = iNumServices - 1; iService >= 0; iService--) {
5579 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
5580 if (conn_snum_used(iService)) {
5583 /* Remove from the share ACL db. */
5584 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
5585 lp_servicename(iService) ));
5586 delete_share_security(lp_servicename(iService));
5587 free_service_byindex(iService);
5591 return lp_numservices();
5594 /********************************************************
5595 Destroy global resources allocated in this file
5596 ********************************************************/
5598 void gfree_loadparm(void)
5600 struct file_lists *f;
5601 struct file_lists *next;
5604 /* Free the file lists */
5609 SAFE_FREE( f->name );
5610 SAFE_FREE( f->subfname );
5615 /* Free resources allocated to services */
5617 for ( i = 0; i < iNumServices; i++ ) {
5619 free_service_byindex(i);
5623 SAFE_FREE( ServicePtrs );
5626 /* Now release all resources allocated to global
5627 parameters and the default service */
5629 for (i = 0; parm_table[i].label; i++)
5631 if ( parm_table[i].type == P_STRING
5632 || parm_table[i].type == P_USTRING )
5634 string_free( (char**)parm_table[i].ptr );
5636 else if (parm_table[i].type == P_LIST) {
5637 str_list_free( (char***)parm_table[i].ptr );
5642 /***************************************************************************
5643 Load the services array from the services file. Return True on success,
5645 ***************************************************************************/
5647 bool lp_load(const char *pszFname,
5651 bool initialize_globals)
5655 param_opt_struct *data, *pdata;
5657 n2 = alloc_sub_basic(get_current_username(),
5658 current_user_info.domain,
5661 smb_panic("lp_load: out of memory");
5664 add_to_file_list(pszFname, n2);
5668 DEBUG(3, ("lp_load: refreshing parameters\n"));
5670 bInGlobalSection = True;
5671 bGlobalOnly = global_only;
5673 init_globals(! initialize_globals);
5676 if (save_defaults) {
5681 if (Globals.param_opt != NULL) {
5682 data = Globals.param_opt;
5684 string_free(&data->key);
5685 string_free(&data->value);
5686 str_list_free(&data->list);
5691 Globals.param_opt = NULL;
5694 /* We get sections first, so have to start 'behind' to make up */
5696 bRetval = pm_process(n2, do_section, do_parameter);
5699 /* finish up the last section */
5700 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
5702 if (iServiceIndex >= 0) {
5703 bRetval = service_ok(iServiceIndex);
5707 lp_add_auto_services(lp_auto_services());
5710 /* When 'restrict anonymous = 2' guest connections to ipc$
5712 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
5713 if ( lp_enable_asu_support() ) {
5714 lp_add_ipc("ADMIN$", false);
5719 set_default_server_announce_type();
5720 set_allowed_client_auth();
5724 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
5725 /* if bWINSsupport is true and we are in the client */
5726 if (in_client && Globals.bWINSsupport) {
5727 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5735 /***************************************************************************
5736 Reset the max number of services.
5737 ***************************************************************************/
5739 void lp_resetnumservices(void)
5744 /***************************************************************************
5745 Return the max number of services.
5746 ***************************************************************************/
5748 int lp_numservices(void)
5750 return (iNumServices);
5753 /***************************************************************************
5754 Display the contents of the services array in human-readable form.
5755 ***************************************************************************/
5757 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
5762 defaults_saved = False;
5766 dump_a_service(&sDefault, f);
5768 for (iService = 0; iService < maxtoprint; iService++) {
5770 lp_dump_one(f, show_defaults, iService);
5774 /***************************************************************************
5775 Display the contents of one service in human-readable form.
5776 ***************************************************************************/
5778 void lp_dump_one(FILE * f, bool show_defaults, int snum)
5781 if (ServicePtrs[snum]->szService[0] == '\0')
5783 dump_a_service(ServicePtrs[snum], f);
5787 /***************************************************************************
5788 Return the number of the service with the given name, or -1 if it doesn't
5789 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5790 getservicebyname()! This works ONLY if all services have been loaded, and
5791 does not copy the found service.
5792 ***************************************************************************/
5794 int lp_servicenumber(const char *pszServiceName)
5797 fstring serviceName;
5799 if (!pszServiceName) {
5800 return GLOBAL_SECTION_SNUM;
5803 for (iService = iNumServices - 1; iService >= 0; iService--) {
5804 if (VALID(iService) && ServicePtrs[iService]->szService) {
5806 * The substitution here is used to support %U is
5809 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5810 standard_sub_basic(get_current_username(),
5811 current_user_info.domain,
5812 serviceName,sizeof(serviceName));
5813 if (strequal(serviceName, pszServiceName)) {
5819 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5822 if (!usershare_exists(iService, &last_mod)) {
5823 /* Remove the share security tdb entry for it. */
5824 delete_share_security(lp_servicename(iService));
5825 /* Remove it from the array. */
5826 free_service_byindex(iService);
5827 /* Doesn't exist anymore. */
5828 return GLOBAL_SECTION_SNUM;
5831 /* Has it been modified ? If so delete and reload. */
5832 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5833 /* Remove it from the array. */
5834 free_service_byindex(iService);
5835 /* and now reload it. */
5836 iService = load_usershare_service(pszServiceName);
5841 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5842 return GLOBAL_SECTION_SNUM;
5848 bool share_defined(const char *service_name)
5850 return (lp_servicenumber(service_name) != -1);
5853 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
5854 const char *sharename)
5856 struct share_params *result;
5860 if (!(sname = SMB_STRDUP(sharename))) {
5864 snum = find_service(sname);
5871 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
5872 DEBUG(0, ("talloc failed\n"));
5876 result->service = snum;
5880 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
5882 struct share_iterator *result;
5884 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
5885 DEBUG(0, ("talloc failed\n"));
5889 result->next_id = 0;
5893 struct share_params *next_share(struct share_iterator *list)
5895 struct share_params *result;
5897 while (!lp_snum_ok(list->next_id) &&
5898 (list->next_id < lp_numservices())) {
5902 if (list->next_id >= lp_numservices()) {
5906 if (!(result = TALLOC_P(list, struct share_params))) {
5907 DEBUG(0, ("talloc failed\n"));
5911 result->service = list->next_id;
5916 struct share_params *next_printer(struct share_iterator *list)
5918 struct share_params *result;
5920 while ((result = next_share(list)) != NULL) {
5921 if (lp_print_ok(result->service)) {
5929 * This is a hack for a transition period until we transformed all code from
5930 * service numbers to struct share_params.
5933 struct share_params *snum2params_static(int snum)
5935 static struct share_params result;
5936 result.service = snum;
5940 /*******************************************************************
5941 A useful volume label function.
5942 ********************************************************************/
5944 const char *volume_label(int snum)
5947 const char *label = lp_volume(snum);
5949 label = lp_servicename(snum);
5952 /* This returns a 33 byte guarenteed null terminated string. */
5953 ret = talloc_strndup(talloc_tos(), label, 32);
5960 /*******************************************************************
5961 Set the server type we will announce as via nmbd.
5962 ********************************************************************/
5964 static void set_default_server_announce_type(void)
5966 default_server_announce = 0;
5967 default_server_announce |= SV_TYPE_WORKSTATION;
5968 default_server_announce |= SV_TYPE_SERVER;
5969 default_server_announce |= SV_TYPE_SERVER_UNIX;
5971 /* note that the flag should be set only if we have a
5972 printer service but nmbd doesn't actually load the
5973 services so we can't tell --jerry */
5975 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5977 switch (lp_announce_as()) {
5978 case ANNOUNCE_AS_NT_SERVER:
5979 default_server_announce |= SV_TYPE_SERVER_NT;
5980 /* fall through... */
5981 case ANNOUNCE_AS_NT_WORKSTATION:
5982 default_server_announce |= SV_TYPE_NT;
5984 case ANNOUNCE_AS_WIN95:
5985 default_server_announce |= SV_TYPE_WIN95_PLUS;
5987 case ANNOUNCE_AS_WFW:
5988 default_server_announce |= SV_TYPE_WFW;
5994 switch (lp_server_role()) {
5995 case ROLE_DOMAIN_MEMBER:
5996 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5998 case ROLE_DOMAIN_PDC:
5999 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
6001 case ROLE_DOMAIN_BDC:
6002 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
6004 case ROLE_STANDALONE:
6008 if (lp_time_server())
6009 default_server_announce |= SV_TYPE_TIME_SOURCE;
6011 if (lp_host_msdfs())
6012 default_server_announce |= SV_TYPE_DFS_SERVER;
6015 /***********************************************************
6016 returns role of Samba server
6017 ************************************************************/
6019 int lp_server_role(void)
6024 /***********************************************************
6025 If we are PDC then prefer us as DMB
6026 ************************************************************/
6028 bool lp_domain_master(void)
6030 if (Globals.iDomainMaster == Auto)
6031 return (lp_server_role() == ROLE_DOMAIN_PDC);
6033 return (bool)Globals.iDomainMaster;
6036 /***********************************************************
6037 If we are DMB then prefer us as LMB
6038 ************************************************************/
6040 bool lp_preferred_master(void)
6042 if (Globals.iPreferredMaster == Auto)
6043 return (lp_local_master() && lp_domain_master());
6045 return (bool)Globals.iPreferredMaster;
6048 /*******************************************************************
6050 ********************************************************************/
6052 void lp_remove_service(int snum)
6054 ServicePtrs[snum]->valid = False;
6055 invalid_services[num_invalid_services++] = snum;
6058 /*******************************************************************
6060 ********************************************************************/
6062 void lp_copy_service(int snum, const char *new_name)
6064 do_section(new_name);
6066 snum = lp_servicenumber(new_name);
6068 lp_do_parameter(snum, "copy", lp_servicename(snum));
6073 /*******************************************************************
6074 Get the default server type we will announce as via nmbd.
6075 ********************************************************************/
6077 int lp_default_server_announce(void)
6079 return default_server_announce;
6082 /*******************************************************************
6083 Split the announce version into major and minor numbers.
6084 ********************************************************************/
6086 int lp_major_announce_version(void)
6088 static bool got_major = False;
6089 static int major_version = DEFAULT_MAJOR_VERSION;
6094 return major_version;
6097 if ((vers = lp_announce_version()) == NULL)
6098 return major_version;
6100 if ((p = strchr_m(vers, '.')) == 0)
6101 return major_version;
6104 major_version = atoi(vers);
6105 return major_version;
6108 int lp_minor_announce_version(void)
6110 static bool got_minor = False;
6111 static int minor_version = DEFAULT_MINOR_VERSION;
6116 return minor_version;
6119 if ((vers = lp_announce_version()) == NULL)
6120 return minor_version;
6122 if ((p = strchr_m(vers, '.')) == 0)
6123 return minor_version;
6126 minor_version = atoi(p);
6127 return minor_version;
6130 /***********************************************************
6131 Set the global name resolution order (used in smbclient).
6132 ************************************************************/
6134 void lp_set_name_resolve_order(const char *new_order)
6136 string_set(&Globals.szNameResolveOrder, new_order);
6139 const char *lp_printername(int snum)
6141 const char *ret = _lp_printername(snum);
6142 if (ret == NULL || (ret != NULL && *ret == '\0'))
6143 ret = lp_const_servicename(snum);
6149 /***********************************************************
6150 Allow daemons such as winbindd to fix their logfile name.
6151 ************************************************************/
6153 void lp_set_logfile(const char *name)
6155 string_set(&Globals.szLogFile, name);
6156 debug_set_logfile(name);
6159 /*******************************************************************
6160 Return the max print jobs per queue.
6161 ********************************************************************/
6163 int lp_maxprintjobs(int snum)
6165 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
6166 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
6167 maxjobs = PRINT_MAX_JOBID - 1;
6172 const char *lp_printcapname(void)
6174 if ((Globals.szPrintcapname != NULL) &&
6175 (Globals.szPrintcapname[0] != '\0'))
6176 return Globals.szPrintcapname;
6178 if (sDefault.iPrinting == PRINT_CUPS) {
6186 if (sDefault.iPrinting == PRINT_BSD)
6187 return "/etc/printcap";
6189 return PRINTCAP_NAME;
6192 /*******************************************************************
6193 Ensure we don't use sendfile if server smb signing is active.
6194 ********************************************************************/
6196 static uint32 spoolss_state;
6198 bool lp_disable_spoolss( void )
6200 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
6201 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
6203 return spoolss_state == SVCCTL_STOPPED ? True : False;
6206 void lp_set_spoolss_state( uint32 state )
6208 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
6210 spoolss_state = state;
6213 uint32 lp_get_spoolss_state( void )
6215 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
6218 /*******************************************************************
6219 Ensure we don't use sendfile if server smb signing is active.
6220 ********************************************************************/
6222 bool lp_use_sendfile(int snum)
6224 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
6225 if (Protocol < PROTOCOL_NT1) {
6228 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
6231 /*******************************************************************
6232 Turn off sendfile if we find the underlying OS doesn't support it.
6233 ********************************************************************/
6235 void set_use_sendfile(int snum, bool val)
6237 if (LP_SNUM_OK(snum))
6238 ServicePtrs[snum]->bUseSendfile = val;
6240 sDefault.bUseSendfile = val;
6243 /*******************************************************************
6244 Turn off storing DOS attributes if this share doesn't support it.
6245 ********************************************************************/
6247 void set_store_dos_attributes(int snum, bool val)
6249 if (!LP_SNUM_OK(snum))
6251 ServicePtrs[(snum)]->bStoreDosAttributes = val;
6254 void lp_set_mangling_method(const char *new_method)
6256 string_set(&Globals.szManglingMethod, new_method);
6259 /*******************************************************************
6260 Global state for POSIX pathname processing.
6261 ********************************************************************/
6263 static bool posix_pathnames;
6265 bool lp_posix_pathnames(void)
6267 return posix_pathnames;
6270 /*******************************************************************
6271 Change everything needed to ensure POSIX pathname processing (currently
6273 ********************************************************************/
6275 void lp_set_posix_pathnames(void)
6277 posix_pathnames = True;
6280 /*******************************************************************
6281 Global state for POSIX lock processing - CIFS unix extensions.
6282 ********************************************************************/
6284 bool posix_default_lock_was_set;
6285 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
6287 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
6289 if (posix_default_lock_was_set) {
6290 return posix_cifsx_locktype;
6292 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
6296 /*******************************************************************
6297 ********************************************************************/
6299 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
6301 posix_default_lock_was_set = True;
6302 posix_cifsx_locktype = val;
6305 int lp_min_receive_file_size(void)
6307 if (Globals.iminreceivefile < 0) {
6310 return MIN(Globals.iminreceivefile, BUFFER_SIZE);