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 struct db_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, get_dyn_SMB_PASSWD_FILE());
1460 string_set(&Globals.szPrivateDir, get_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, get_dyn_PIDDIR());
1495 string_set(&Globals.szLockDir, get_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", get_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(
2518 ServicePtrs[idx]->szService );
2520 dbwrap_delete_bystring(ServiceHash, canon_name );
2521 TALLOC_FREE(canon_name);
2524 free_service(ServicePtrs[idx]);
2527 /***************************************************************************
2528 Add a new service to the services array initialising it with the given
2530 ***************************************************************************/
2532 static int add_a_service(const service *pservice, const char *name)
2536 int num_to_alloc = iNumServices + 1;
2537 param_opt_struct *data, *pdata;
2539 tservice = *pservice;
2541 /* it might already exist */
2543 i = getservicebyname(name, NULL);
2545 /* Clean all parametric options for service */
2546 /* They will be added during parsing again */
2547 data = ServicePtrs[i]->param_opt;
2549 string_free(&data->key);
2550 string_free(&data->value);
2551 str_list_free(&data->list);
2556 ServicePtrs[i]->param_opt = NULL;
2561 /* find an invalid one */
2563 if (num_invalid_services > 0) {
2564 i = invalid_services[--num_invalid_services];
2567 /* if not, then create one */
2568 if (i == iNumServices) {
2572 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2574 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2578 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2579 if (!ServicePtrs[iNumServices]) {
2580 DEBUG(0,("add_a_service: out of memory!\n"));
2585 /* enlarge invalid_services here for now... */
2586 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2588 if (tinvalid == NULL) {
2589 DEBUG(0,("add_a_service: failed to enlarge "
2590 "invalid_services!\n"));
2593 invalid_services = tinvalid;
2595 free_service_byindex(i);
2598 ServicePtrs[i]->valid = True;
2600 init_service(ServicePtrs[i]);
2601 copy_service(ServicePtrs[i], &tservice, NULL);
2603 string_set(&ServicePtrs[i]->szService, name);
2605 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2606 i, ServicePtrs[i]->szService));
2608 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2615 /***************************************************************************
2616 Convert a string to uppercase and remove whitespaces.
2617 ***************************************************************************/
2619 static char *canonicalize_servicename(const char *src)
2624 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2628 result = talloc_strdup(talloc_tos(), src);
2629 SMB_ASSERT(result != NULL);
2635 /***************************************************************************
2636 Add a name/index pair for the services array to the hash table.
2637 ***************************************************************************/
2639 static bool hash_a_service(const char *name, int idx)
2643 if ( !ServiceHash ) {
2644 DEBUG(10,("hash_a_service: creating servicehash\n"));
2645 ServiceHash = db_open_rbt(NULL);
2646 if ( !ServiceHash ) {
2647 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2652 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2655 canon_name = canonicalize_servicename( name );
2657 dbwrap_store_bystring(ServiceHash, canon_name,
2658 make_tdb_data((uint8 *)&idx, sizeof(idx)),
2661 TALLOC_FREE(canon_name);
2666 /***************************************************************************
2667 Add a new home service, with the specified home directory, defaults coming
2669 ***************************************************************************/
2671 bool lp_add_home(const char *pszHomename, int iDefaultService,
2672 const char *user, const char *pszHomedir)
2676 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2681 if (!(*(ServicePtrs[iDefaultService]->szPath))
2682 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2683 string_set(&ServicePtrs[i]->szPath, pszHomedir);
2686 if (!(*(ServicePtrs[i]->comment))) {
2687 char *comment = NULL;
2688 if (asprintf(&comment, "Home directory of %s", user) < 0) {
2691 string_set(&ServicePtrs[i]->comment, comment);
2695 /* set the browseable flag from the global default */
2697 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2699 ServicePtrs[i]->autoloaded = True;
2701 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2702 user, ServicePtrs[i]->szPath ));
2707 /***************************************************************************
2708 Add a new service, based on an old one.
2709 ***************************************************************************/
2711 int lp_add_service(const char *pszService, int iDefaultService)
2713 if (iDefaultService < 0) {
2714 return add_a_service(&sDefault, pszService);
2717 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2720 /***************************************************************************
2721 Add the IPC service.
2722 ***************************************************************************/
2724 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
2726 char *comment = NULL;
2727 int i = add_a_service(&sDefault, ipc_name);
2732 if (asprintf(&comment, "IPC Service (%s)",
2733 Globals.szServerString) < 0) {
2737 string_set(&ServicePtrs[i]->szPath, tmpdir());
2738 string_set(&ServicePtrs[i]->szUsername, "");
2739 string_set(&ServicePtrs[i]->comment, comment);
2740 string_set(&ServicePtrs[i]->fstype, "IPC");
2741 ServicePtrs[i]->iMaxConnections = 0;
2742 ServicePtrs[i]->bAvailable = True;
2743 ServicePtrs[i]->bRead_only = True;
2744 ServicePtrs[i]->bGuest_only = False;
2745 ServicePtrs[i]->bGuest_ok = guest_ok;
2746 ServicePtrs[i]->bPrint_ok = False;
2747 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2749 DEBUG(3, ("adding IPC service\n"));
2755 /***************************************************************************
2756 Add a new printer service, with defaults coming from service iFrom.
2757 ***************************************************************************/
2759 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
2761 const char *comment = "From Printcap";
2762 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2767 /* note that we do NOT default the availability flag to True - */
2768 /* we take it from the default service passed. This allows all */
2769 /* dynamic printers to be disabled by disabling the [printers] */
2770 /* entry (if/when the 'available' keyword is implemented!). */
2772 /* the printer name is set to the service name. */
2773 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2774 string_set(&ServicePtrs[i]->comment, comment);
2776 /* set the browseable flag from the gloabl default */
2777 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2779 /* Printers cannot be read_only. */
2780 ServicePtrs[i]->bRead_only = False;
2781 /* No share modes on printer services. */
2782 ServicePtrs[i]->bShareModes = False;
2783 /* No oplocks on printer services. */
2784 ServicePtrs[i]->bOpLocks = False;
2785 /* Printer services must be printable. */
2786 ServicePtrs[i]->bPrint_ok = True;
2788 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2794 /***************************************************************************
2795 Check whether the given parameter name is valid.
2796 Parametric options (names containing a colon) are considered valid.
2797 ***************************************************************************/
2799 bool lp_parameter_is_valid(const char *pszParmName)
2801 return ((map_parameter(pszParmName) != -1) ||
2802 (strchr(pszParmName, ':') != NULL));
2805 /***************************************************************************
2806 Check whether the given name is the name of a global parameter.
2807 Returns True for strings belonging to parameters of class
2808 P_GLOBAL, False for all other strings, also for parametric options
2809 and strings not belonging to any option.
2810 ***************************************************************************/
2812 bool lp_parameter_is_global(const char *pszParmName)
2814 int num = map_parameter(pszParmName);
2817 return (parm_table[num].p_class == P_GLOBAL);
2823 /**************************************************************************
2824 Check whether the given name is the canonical name of a parameter.
2825 Returns False if it is not a valid parameter Name.
2826 For parametric options, True is returned.
2827 **************************************************************************/
2829 bool lp_parameter_is_canonical(const char *parm_name)
2831 if (!lp_parameter_is_valid(parm_name)) {
2835 return (map_parameter(parm_name) ==
2836 map_parameter_canonical(parm_name, NULL));
2839 /**************************************************************************
2840 Determine the canonical name for a parameter.
2841 Indicate when it is an inverse (boolean) synonym instead of a
2843 **************************************************************************/
2845 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
2850 if (!lp_parameter_is_valid(parm_name)) {
2855 num = map_parameter_canonical(parm_name, inverse);
2857 /* parametric option */
2858 *canon_parm = parm_name;
2860 *canon_parm = parm_table[num].label;
2867 /**************************************************************************
2868 Determine the canonical name for a parameter.
2869 Turn the value given into the inverse boolean expression when
2870 the synonym is an invers boolean synonym.
2872 Return True if parm_name is a valid parameter name and
2873 in case it is an invers boolean synonym, if the val string could
2874 successfully be converted to the reverse bool.
2875 Return false in all other cases.
2876 **************************************************************************/
2878 bool lp_canonicalize_parameter_with_value(const char *parm_name,
2880 const char **canon_parm,
2881 const char **canon_val)
2886 if (!lp_parameter_is_valid(parm_name)) {
2892 num = map_parameter_canonical(parm_name, &inverse);
2894 /* parametric option */
2895 *canon_parm = parm_name;
2898 *canon_parm = parm_table[num].label;
2900 if (!lp_invert_boolean(val, canon_val)) {
2912 /***************************************************************************
2913 Map a parameter's string representation to something we can use.
2914 Returns False if the parameter string is not recognised, else TRUE.
2915 ***************************************************************************/
2917 static int map_parameter(const char *pszParmName)
2921 if (*pszParmName == '-')
2924 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2925 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2928 /* Warn only if it isn't parametric option */
2929 if (strchr(pszParmName, ':') == NULL)
2930 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2931 /* We do return 'fail' for parametric options as well because they are
2932 stored in different storage
2937 /***************************************************************************
2938 Map a parameter's string representation to the index of the canonical
2939 form of the parameter (it might be a synonym).
2940 Returns -1 if the parameter string is not recognised.
2941 ***************************************************************************/
2943 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
2945 int parm_num, canon_num;
2946 bool loc_inverse = False;
2948 parm_num = map_parameter(pszParmName);
2949 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
2950 /* invalid, parametric or no canidate for synonyms ... */
2954 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
2955 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
2956 parm_num = canon_num;
2962 if (inverse != NULL) {
2963 *inverse = loc_inverse;
2968 /***************************************************************************
2969 return true if parameter number parm1 is a synonym of parameter
2970 number parm2 (parm2 being the principal name).
2971 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
2973 ***************************************************************************/
2975 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
2977 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
2978 (parm_table[parm1].flags & FLAG_HIDE) &&
2979 !(parm_table[parm2].flags & FLAG_HIDE))
2981 if (inverse != NULL) {
2982 if ((parm_table[parm1].type == P_BOOLREV) &&
2983 (parm_table[parm2].type == P_BOOL))
2995 /***************************************************************************
2996 Show one parameter's name, type, [values,] and flags.
2997 (helper functions for show_parameter_list)
2998 ***************************************************************************/
3000 static void show_parameter(int parmIndex)
3002 int enumIndex, flagIndex;
3007 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
3008 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
3010 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
3011 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
3012 FLAG_HIDE, FLAG_DOS_STRING};
3013 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
3014 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
3015 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
3017 printf("%s=%s", parm_table[parmIndex].label,
3018 type[parm_table[parmIndex].type]);
3019 if (parm_table[parmIndex].type == P_ENUM) {
3022 parm_table[parmIndex].enum_list[enumIndex].name;
3026 enumIndex ? "|" : "",
3027 parm_table[parmIndex].enum_list[enumIndex].name);
3032 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
3033 if (parm_table[parmIndex].flags & flags[flagIndex]) {
3036 flag_names[flagIndex]);
3041 /* output synonyms */
3043 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
3044 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
3045 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
3046 parm_table[parmIndex2].label);
3047 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
3049 printf(" (synonyms: ");
3054 printf("%s%s", parm_table[parmIndex2].label,
3055 inverse ? "[i]" : "");
3065 /***************************************************************************
3066 Show all parameter's name, type, [values,] and flags.
3067 ***************************************************************************/
3069 void show_parameter_list(void)
3071 int classIndex, parmIndex;
3072 const char *section_names[] = { "local", "global", NULL};
3074 for (classIndex=0; section_names[classIndex]; classIndex++) {
3075 printf("[%s]\n", section_names[classIndex]);
3076 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
3077 if (parm_table[parmIndex].p_class == classIndex) {
3078 show_parameter(parmIndex);
3084 /***************************************************************************
3085 Set a boolean variable from the text value stored in the passed string.
3086 Returns True in success, False if the passed string does not correctly
3087 represent a boolean.
3088 ***************************************************************************/
3090 static bool set_boolean(bool *pb, const char *pszParmValue)
3097 if (strwicmp(pszParmValue, "yes") == 0 ||
3098 strwicmp(pszParmValue, "true") == 0 ||
3099 strwicmp(pszParmValue, "1") == 0)
3101 else if (strwicmp(pszParmValue, "no") == 0 ||
3102 strwicmp(pszParmValue, "False") == 0 ||
3103 strwicmp(pszParmValue, "0") == 0)
3107 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
3112 if ((pb != NULL) && (bRetval != False)) {
3120 /***************************************************************************
3121 Check if a given string correctly represents a boolean value.
3122 ***************************************************************************/
3124 bool lp_string_is_valid_boolean(const char *parm_value)
3126 return set_boolean(NULL, parm_value);
3129 /***************************************************************************
3130 Get the standard string representation of a boolean value ("yes" or "no")
3131 ***************************************************************************/
3133 static const char *get_boolean(bool bool_value)
3135 static const char *yes_str = "yes";
3136 static const char *no_str = "no";
3138 return (bool_value ? yes_str : no_str);
3141 /***************************************************************************
3142 Provide the string of the negated boolean value associated to the boolean
3143 given as a string. Returns False if the passed string does not correctly
3144 represent a boolean.
3145 ***************************************************************************/
3147 bool lp_invert_boolean(const char *str, const char **inverse_str)
3151 if (!set_boolean(&val, str)) {
3155 *inverse_str = get_boolean(!val);
3159 /***************************************************************************
3160 Provide the canonical string representation of a boolean value given
3161 as a string. Return True on success, False if the string given does
3162 not correctly represent a boolean.
3163 ***************************************************************************/
3165 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
3169 if (!set_boolean(&val, str)) {
3173 *canon_str = get_boolean(val);
3177 /***************************************************************************
3178 Find a service by name. Otherwise works like get_service.
3179 ***************************************************************************/
3181 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
3187 if (ServiceHash == NULL) {
3191 canon_name = canonicalize_servicename(pszServiceName);
3193 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
3195 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
3196 iService = *(int *)data.dptr;
3199 TALLOC_FREE(canon_name);
3201 if ((iService != -1) && (LP_SNUM_OK(iService))
3202 && (pserviceDest != NULL)) {
3203 copy_service(pserviceDest, ServicePtrs[iService], NULL);
3209 /***************************************************************************
3210 Copy a service structure to another.
3211 If pcopymapDest is NULL then copy all fields
3212 ***************************************************************************/
3214 static void copy_service(service * pserviceDest, service * pserviceSource,
3215 struct bitmap *pcopymapDest)
3218 bool bcopyall = (pcopymapDest == NULL);
3219 param_opt_struct *data, *pdata, *paramo;
3222 for (i = 0; parm_table[i].label; i++)
3223 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
3224 (bcopyall || bitmap_query(pcopymapDest,i))) {
3225 void *def_ptr = parm_table[i].ptr;
3227 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
3230 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
3233 switch (parm_table[i].type) {
3236 *(bool *)dest_ptr = *(bool *)src_ptr;
3242 *(int *)dest_ptr = *(int *)src_ptr;
3246 *(char *)dest_ptr = *(char *)src_ptr;
3250 string_set((char **)dest_ptr,
3255 string_set((char **)dest_ptr,
3257 strupper_m(*(char **)dest_ptr);
3260 str_list_free((char ***)dest_ptr);
3261 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
3269 init_copymap(pserviceDest);
3270 if (pserviceSource->copymap)
3271 bitmap_copy(pserviceDest->copymap,
3272 pserviceSource->copymap);
3275 data = pserviceSource->param_opt;
3278 pdata = pserviceDest->param_opt;
3279 /* Traverse destination */
3281 /* If we already have same option, override it */
3282 if (strcmp(pdata->key, data->key) == 0) {
3283 string_free(&pdata->value);
3284 str_list_free(&data->list);
3285 pdata->value = SMB_STRDUP(data->value);
3289 pdata = pdata->next;
3292 paramo = SMB_XMALLOC_P(param_opt_struct);
3293 paramo->key = SMB_STRDUP(data->key);
3294 paramo->value = SMB_STRDUP(data->value);
3295 paramo->list = NULL;
3296 DLIST_ADD(pserviceDest->param_opt, paramo);
3302 /***************************************************************************
3303 Check a service for consistency. Return False if the service is in any way
3304 incomplete or faulty, else True.
3305 ***************************************************************************/
3307 bool service_ok(int iService)
3312 if (ServicePtrs[iService]->szService[0] == '\0') {
3313 DEBUG(0, ("The following message indicates an internal error:\n"));
3314 DEBUG(0, ("No service name in service entry.\n"));
3318 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
3319 /* I can't see why you'd want a non-printable printer service... */
3320 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
3321 if (!ServicePtrs[iService]->bPrint_ok) {
3322 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
3323 ServicePtrs[iService]->szService));
3324 ServicePtrs[iService]->bPrint_ok = True;
3326 /* [printers] service must also be non-browsable. */
3327 if (ServicePtrs[iService]->bBrowseable)
3328 ServicePtrs[iService]->bBrowseable = False;
3331 if (ServicePtrs[iService]->szPath[0] == '\0' &&
3332 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
3333 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
3335 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
3336 ServicePtrs[iService]->szService));
3337 ServicePtrs[iService]->bAvailable = False;
3340 /* If a service is flagged unavailable, log the fact at level 1. */
3341 if (!ServicePtrs[iService]->bAvailable)
3342 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
3343 ServicePtrs[iService]->szService));
3349 * lp_regdb_open - regdb helper function
3351 * this should be considered an interim solution that becomes
3352 * superfluous once the registry code has been rewritten
3353 * do allow use of the tdb portion of the registry alone.
3355 * in the meanwhile this provides a lean access
3356 * to the registry globals.
3359 static struct tdb_wrap *lp_regdb_open(void)
3361 struct tdb_wrap *reg_tdb = NULL;
3362 const char *vstring = "INFO/version";
3366 reg_tdb = tdb_wrap_open(NULL, state_path("registry.tdb"), 0,
3367 REG_TDB_FLAGS, O_RDWR, 0600);
3370 DEBUG(1, ("lp_regdb_open: failed to open %s: %s\n",
3371 state_path("registry.tdb"), strerror(errno)));
3375 DEBUG(10, ("lp_regdb_open: reg tdb opened.\n"));
3378 vers_id = tdb_fetch_int32(reg_tdb->tdb, vstring);
3379 if (vers_id != REGVER_V1) {
3380 DEBUG(10, ("lp_regdb_open: INFO: registry tdb %s has wrong "
3381 "INFO/version (got %d, expected %d)\n",
3382 state_path("registry.tdb"), vers_id, REGVER_V1));
3383 /* this is apparently not implemented in the tdb */
3391 * process_registry_globals
3393 * this is the interim version of process_registry globals
3395 * until we can do it as we would like using the api and only
3396 * using the tdb portion of the registry (see below),
3397 * this just provides the needed functionality of regdb_fetch_values
3398 * and regdb_unpack_values, circumventing any fancy stuff, to
3399 * give us access to the registry globals.
3401 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
3404 struct tdb_wrap *reg_tdb = NULL;
3408 /* vars for the tdb unpack loop */
3415 uint32 num_values = 0;
3418 struct registry_value *value = NULL;
3420 include_registry_globals = True;
3424 reg_tdb = lp_regdb_open();
3426 DEBUG(1, ("Error opening the registry!\n"));
3430 /* reg_tdb is from now on used as talloc ctx.
3431 * freeing it closes the tdb (if refcount is 0) */
3433 keystr = talloc_asprintf(reg_tdb,"%s/%s/%s", REG_VALUE_PREFIX,
3434 KEY_SMBCONF, GLOBAL_NAME);
3435 normalize_dbkey(keystr);
3437 DEBUG(10, ("process_registry_globals: fetching key '%s'\n",
3440 data = tdb_fetch_bystring(reg_tdb->tdb, keystr);
3447 buflen = data.dsize;
3449 /* unpack number of values */
3450 len = tdb_unpack(buf, buflen, "d", &num_values);
3451 DEBUG(10, ("process_registry_globals: got %d values from tdb\n",
3454 /* unpack the values */
3455 for (i=0; i < num_values; i++) {
3460 len += tdb_unpack(buf+len, buflen-len, "fdB",
3465 if (registry_smbconf_valname_forbidden(valname)) {
3466 DEBUG(10, ("process_registry_globals: Ignoring "
3467 "parameter '%s' in registry.\n", valname));
3470 DEBUG(10, ("process_registry_globals: got value '%s'\n",
3472 if (size && data_p) {
3473 err = registry_pull_value(reg_tdb,
3480 if (!W_ERROR_IS_OK(err)) {
3485 valstr = talloc_asprintf(reg_tdb, "%d",
3487 pfunc(valname, valstr);
3490 pfunc(valname, value->v.sz.str);
3493 /* ignore other types */
3499 ret = pfunc("registry shares", "yes");
3500 regdb_last_seqnum = tdb_get_seqnum(reg_tdb->tdb);
3503 TALLOC_FREE(reg_tdb);
3504 SAFE_FREE(data.dptr);
3510 * this is process_registry_globals as it _should_ be (roughly)
3511 * using the reg_api functions...
3514 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
3517 TALLOC_CTX *ctx = NULL;
3518 char *regpath = NULL;
3519 WERROR werr = WERR_OK;
3520 struct registry_key *key = NULL;
3521 struct registry_value *value = NULL;
3522 char *valname = NULL;
3523 char *valstr = NULL;
3525 NT_USER_TOKEN *token;
3527 ctx = talloc_init("process_registry_globals");
3529 smb_panic("Failed to create talloc context!");
3532 include_registry_globals = True;
3534 if (!registry_init_regdb()) {
3535 DEBUG(1, ("Error initializing the registry.\n"));
3539 if (!(token = registry_create_admin_token(ctx))) {
3540 DEBUG(1, ("Error creating admin token\n"));
3544 regpath = talloc_asprintf(ctx,"%s\\%s", KEY_SMBCONF, GLOBAL_NAME);
3545 werr = reg_open_path(ctx, regpath, REG_KEY_READ, token, &key);
3546 if (!W_ERROR_IS_OK(werr)) {
3547 DEBUG(1, ("Registry smbconf global section does not exist.\n"));
3548 DEBUGADD(1, ("Error opening registry path '%s\\%s: %s\n",
3549 KEY_SMBCONF, GLOBAL_NAME, dos_errstr(werr)));
3554 W_ERROR_IS_OK(werr = reg_enumvalue(ctx, key, idx, &valname,
3558 DEBUG(5, ("got global registry parameter '%s'\n", valname));
3559 switch(value->type) {
3561 valstr = talloc_asprintf(ctx, "%d", value->v.dword);
3562 pfunc(valname, valstr);
3563 TALLOC_FREE(valstr);
3566 pfunc(valname, value->v.sz.str);
3569 /* ignore other types */
3573 TALLOC_FREE(valstr);
3576 ret = pfunc("registry shares", "yes");
3578 regdb_last_seqnum = regdb_get_seqnum();
3581 talloc_destroy(ctx);
3586 static struct file_lists {
3587 struct file_lists *next;
3591 } *file_lists = NULL;
3593 /*******************************************************************
3594 Keep a linked list of all config files so we know when one has changed
3595 it's date and needs to be reloaded.
3596 ********************************************************************/
3598 static void add_to_file_list(const char *fname, const char *subfname)
3600 struct file_lists *f = file_lists;
3603 if (f->name && !strcmp(f->name, fname))
3609 f = SMB_MALLOC_P(struct file_lists);
3612 f->next = file_lists;
3613 f->name = SMB_STRDUP(fname);
3618 f->subfname = SMB_STRDUP(subfname);
3624 f->modtime = file_modtime(subfname);
3626 time_t t = file_modtime(subfname);
3632 bool lp_include_registry_globals(void)
3634 return include_registry_globals;
3637 /*******************************************************************
3638 Check if a config file has changed date.
3639 ********************************************************************/
3641 bool lp_file_list_changed(void)
3643 struct file_lists *f = file_lists;
3644 struct tdb_wrap *reg_tdb = NULL;
3646 DEBUG(6, ("lp_file_list_changed()\n"));
3648 if (include_registry_globals) {
3649 reg_tdb = lp_regdb_open();
3650 if (reg_tdb && (regdb_last_seqnum != tdb_get_seqnum(reg_tdb->tdb)))
3652 DEBUGADD(6, ("regdb seqnum changed: old = %d, new = %d\n",
3653 regdb_last_seqnum, tdb_get_seqnum(reg_tdb->tdb)));
3654 TALLOC_FREE(reg_tdb);
3663 n2 = alloc_sub_basic(get_current_username(),
3664 current_user_info.domain,
3669 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3670 f->name, n2, ctime(&f->modtime)));
3672 mod_time = file_modtime(n2);
3674 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3676 ("file %s modified: %s\n", n2,
3678 f->modtime = mod_time;
3679 SAFE_FREE(f->subfname);
3680 f->subfname = n2; /* Passing ownership of
3681 return from alloc_sub_basic
3691 /***************************************************************************
3692 Run standard_sub_basic on netbios name... needed because global_myname
3693 is not accessed through any lp_ macro.
3694 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3695 ***************************************************************************/
3697 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3700 char *netbios_name = alloc_sub_basic(get_current_username(),
3701 current_user_info.domain,
3704 ret = set_global_myname(netbios_name);
3705 SAFE_FREE(netbios_name);
3706 string_set(&Globals.szNetbiosName,global_myname());
3708 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3714 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
3716 if (strcmp(*ptr, pszParmValue) != 0) {
3717 string_set(ptr, pszParmValue);
3725 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3729 ret = set_global_myworkgroup(pszParmValue);
3730 string_set(&Globals.szWorkgroup,lp_workgroup());
3735 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3739 ret = set_global_scope(pszParmValue);
3740 string_set(&Globals.szNetbiosScope,global_scope());
3745 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3747 str_list_free(&Globals.szNetbiosAliases);
3748 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3749 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3752 /***************************************************************************
3753 Handle the include operation.
3754 ***************************************************************************/
3756 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
3760 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
3761 if (bInGlobalSection) {
3762 return process_registry_globals(do_parameter);
3765 DEBUG(1, ("\"include = registry\" only effective "
3766 "in %s section\n", GLOBAL_NAME));
3771 fname = alloc_sub_basic(get_current_username(),
3772 current_user_info.domain,
3775 add_to_file_list(pszParmValue, fname);
3777 string_set(ptr, fname);
3779 if (file_exist(fname, NULL)) {
3780 bool ret = pm_process(fname, do_section, do_parameter);
3785 DEBUG(2, ("Can't find include file %s\n", fname));
3790 /***************************************************************************
3791 Handle the interpretation of the copy parameter.
3792 ***************************************************************************/
3794 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
3798 service serviceTemp;
3800 string_set(ptr, pszParmValue);
3802 init_service(&serviceTemp);
3806 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3808 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3809 if (iTemp == iServiceIndex) {
3810 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3812 copy_service(ServicePtrs[iServiceIndex],
3814 ServicePtrs[iServiceIndex]->copymap);
3818 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3822 free_service(&serviceTemp);
3826 /***************************************************************************
3827 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3832 idmap uid = 1000-1999
3835 We only do simple parsing checks here. The strings are parsed into useful
3836 structures in the idmap daemon code.
3838 ***************************************************************************/
3840 /* Some lp_ routines to return idmap [ug]id information */
3842 static uid_t idmap_uid_low, idmap_uid_high;
3843 static gid_t idmap_gid_low, idmap_gid_high;
3845 bool lp_idmap_uid(uid_t *low, uid_t *high)
3847 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3851 *low = idmap_uid_low;
3854 *high = idmap_uid_high;
3859 bool lp_idmap_gid(gid_t *low, gid_t *high)
3861 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3865 *low = idmap_gid_low;
3868 *high = idmap_gid_high;
3873 /* Do some simple checks on "idmap [ug]id" parameter values */
3875 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3879 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3884 string_set(ptr, pszParmValue);
3886 idmap_uid_low = low;
3887 idmap_uid_high = high;
3892 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3896 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3901 string_set(ptr, pszParmValue);
3903 idmap_gid_low = low;
3904 idmap_gid_high = high;
3909 /***************************************************************************
3910 Handle the DEBUG level list.
3911 ***************************************************************************/
3913 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3915 string_set(ptr, pszParmValueIn);
3916 return debug_parse_levels(pszParmValueIn);
3919 /***************************************************************************
3920 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3921 ***************************************************************************/
3923 static const char *append_ldap_suffix( const char *str )
3925 const char *suffix_string;
3928 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
3929 Globals.szLdapSuffix );
3930 if ( !suffix_string ) {
3931 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3935 return suffix_string;
3938 const char *lp_ldap_machine_suffix(void)
3940 if (Globals.szLdapMachineSuffix[0])
3941 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3943 return lp_string(Globals.szLdapSuffix);
3946 const char *lp_ldap_user_suffix(void)
3948 if (Globals.szLdapUserSuffix[0])
3949 return append_ldap_suffix(Globals.szLdapUserSuffix);
3951 return lp_string(Globals.szLdapSuffix);
3954 const char *lp_ldap_group_suffix(void)
3956 if (Globals.szLdapGroupSuffix[0])
3957 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3959 return lp_string(Globals.szLdapSuffix);
3962 const char *lp_ldap_idmap_suffix(void)
3964 if (Globals.szLdapIdmapSuffix[0])
3965 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3967 return lp_string(Globals.szLdapSuffix);
3970 /****************************************************************************
3971 set the value for a P_ENUM
3972 ***************************************************************************/
3974 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3979 for (i = 0; parm->enum_list[i].name; i++) {
3980 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3981 *ptr = parm->enum_list[i].value;
3987 /***************************************************************************
3988 ***************************************************************************/
3990 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
3992 static int parm_num = -1;
3995 if ( parm_num == -1 )
3996 parm_num = map_parameter( "printing" );
3998 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
4003 s = ServicePtrs[snum];
4005 init_printer_values( s );
4011 /***************************************************************************
4012 Initialise a copymap.
4013 ***************************************************************************/
4015 static void init_copymap(service * pservice)
4018 if (pservice->copymap) {
4019 bitmap_free(pservice->copymap);
4021 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
4022 if (!pservice->copymap)
4024 ("Couldn't allocate copymap!! (size %d)\n",
4025 (int)NUMPARAMETERS));
4027 for (i = 0; i < NUMPARAMETERS; i++)
4028 bitmap_set(pservice->copymap, i);
4031 /***************************************************************************
4032 Return the local pointer to a parameter given the service number and the
4033 pointer into the default structure.
4034 ***************************************************************************/
4036 void *lp_local_ptr(int snum, void *ptr)
4038 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
4041 /***************************************************************************
4042 Process a parameter for a particular service number. If snum < 0
4043 then assume we are in the globals.
4044 ***************************************************************************/
4046 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
4048 int parmnum, i, slen;
4049 void *parm_ptr = NULL; /* where we are going to store the result */
4050 void *def_ptr = NULL;
4051 char *param_key = NULL;
4053 param_opt_struct *paramo, *data;
4056 parmnum = map_parameter(pszParmName);
4059 if ((sep=strchr(pszParmName, ':')) != NULL) {
4060 TALLOC_CTX *frame = talloc_stackframe();
4063 param_key = talloc_asprintf(frame, "%s:", pszParmName);
4068 slen = strlen(param_key);
4069 param_key = talloc_asprintf_append(param_key, sep+1);
4074 trim_char(param_key+slen, ' ', ' ');
4076 data = (snum < 0) ? Globals.param_opt :
4077 ServicePtrs[snum]->param_opt;
4078 /* Traverse destination */
4080 /* If we already have same option, override it */
4081 if (strcmp(data->key, param_key) == 0) {
4082 string_free(&data->value);
4083 str_list_free(&data->list);
4084 data->value = SMB_STRDUP(pszParmValue);
4091 paramo = SMB_XMALLOC_P(param_opt_struct);
4092 paramo->key = SMB_STRDUP(param_key);
4093 paramo->value = SMB_STRDUP(pszParmValue);
4094 paramo->list = NULL;
4096 DLIST_ADD(Globals.param_opt, paramo);
4098 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
4106 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
4110 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
4111 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
4115 def_ptr = parm_table[parmnum].ptr;
4117 /* we might point at a service, the default service or a global */
4121 if (parm_table[parmnum].p_class == P_GLOBAL) {
4123 ("Global parameter %s found in service section!\n",
4128 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
4133 if (!ServicePtrs[snum]->copymap)
4134 init_copymap(ServicePtrs[snum]);
4136 /* this handles the aliases - set the copymap for other entries with
4137 the same data pointer */
4138 for (i = 0; parm_table[i].label; i++)
4139 if (parm_table[i].ptr == parm_table[parmnum].ptr)
4140 bitmap_clear(ServicePtrs[snum]->copymap, i);
4143 /* if it is a special case then go ahead */
4144 if (parm_table[parmnum].special) {
4145 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
4149 /* now switch on the type of variable it is */
4150 switch (parm_table[parmnum].type)
4153 *(bool *)parm_ptr = lp_bool(pszParmValue);
4157 *(bool *)parm_ptr = !lp_bool(pszParmValue);
4161 *(int *)parm_ptr = lp_int(pszParmValue);
4165 *(char *)parm_ptr = *pszParmValue;
4169 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
4171 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
4176 str_list_free((char ***)parm_ptr);
4177 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
4181 string_set((char **)parm_ptr, pszParmValue);
4185 string_set((char **)parm_ptr, pszParmValue);
4186 strupper_m(*(char **)parm_ptr);
4190 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
4199 /***************************************************************************
4200 Process a parameter.
4201 ***************************************************************************/
4203 static bool do_parameter(const char *pszParmName, const char *pszParmValue)
4205 if (!bInGlobalSection && bGlobalOnly)
4208 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
4210 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
4211 pszParmName, pszParmValue));
4214 /***************************************************************************
4215 Print a parameter of the specified type.
4216 ***************************************************************************/
4218 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
4224 for (i = 0; p->enum_list[i].name; i++) {
4225 if (*(int *)ptr == p->enum_list[i].value) {
4227 p->enum_list[i].name);
4234 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
4238 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
4242 fprintf(f, "%d", *(int *)ptr);
4246 fprintf(f, "%c", *(char *)ptr);
4250 char *o = octal_string(*(int *)ptr);
4251 fprintf(f, "%s", o);
4257 if ((char ***)ptr && *(char ***)ptr) {
4258 char **list = *(char ***)ptr;
4259 for (; *list; list++) {
4260 /* surround strings with whitespace in double quotes */
4261 if ( strchr_m( *list, ' ' ) )
4262 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
4264 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
4271 if (*(char **)ptr) {
4272 fprintf(f, "%s", *(char **)ptr);
4280 /***************************************************************************
4281 Check if two parameters are equal.
4282 ***************************************************************************/
4284 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
4289 return (*((bool *)ptr1) == *((bool *)ptr2));
4294 return (*((int *)ptr1) == *((int *)ptr2));
4297 return (*((char *)ptr1) == *((char *)ptr2));
4300 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
4305 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
4310 return (p1 == p2 || strequal(p1, p2));
4318 /***************************************************************************
4319 Initialize any local varients in the sDefault table.
4320 ***************************************************************************/
4322 void init_locals(void)
4327 /***************************************************************************
4328 Process a new section (service). At this stage all sections are services.
4329 Later we'll have special sections that permit server parameters to be set.
4330 Returns True on success, False on failure.
4331 ***************************************************************************/
4333 static bool do_section(const char *pszSectionName)
4336 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
4337 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
4340 /* if we were in a global section then do the local inits */
4341 if (bInGlobalSection && !isglobal)
4344 /* if we've just struck a global section, note the fact. */
4345 bInGlobalSection = isglobal;
4347 /* check for multiple global sections */
4348 if (bInGlobalSection) {
4349 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
4353 if (!bInGlobalSection && bGlobalOnly)
4356 /* if we have a current service, tidy it up before moving on */
4359 if (iServiceIndex >= 0)
4360 bRetval = service_ok(iServiceIndex);
4362 /* if all is still well, move to the next record in the services array */
4364 /* We put this here to avoid an odd message order if messages are */
4365 /* issued by the post-processing of a previous section. */
4366 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
4368 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
4370 DEBUG(0, ("Failed to add a new service\n"));
4379 /***************************************************************************
4380 Determine if a partcular base parameter is currentl set to the default value.
4381 ***************************************************************************/
4383 static bool is_default(int i)
4385 if (!defaults_saved)
4387 switch (parm_table[i].type) {
4389 return str_list_compare (parm_table[i].def.lvalue,
4390 *(char ***)parm_table[i].ptr);
4393 return strequal(parm_table[i].def.svalue,
4394 *(char **)parm_table[i].ptr);
4397 return parm_table[i].def.bvalue ==
4398 *(bool *)parm_table[i].ptr;
4400 return parm_table[i].def.cvalue ==
4401 *(char *)parm_table[i].ptr;
4405 return parm_table[i].def.ivalue ==
4406 *(int *)parm_table[i].ptr;
4413 /***************************************************************************
4414 Display the contents of the global structure.
4415 ***************************************************************************/
4417 static void dump_globals(FILE *f)
4420 param_opt_struct *data;
4422 fprintf(f, "[global]\n");
4424 for (i = 0; parm_table[i].label; i++)
4425 if (parm_table[i].p_class == P_GLOBAL &&
4426 parm_table[i].ptr &&
4427 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
4428 if (defaults_saved && is_default(i))
4430 fprintf(f, "\t%s = ", parm_table[i].label);
4431 print_parameter(&parm_table[i], parm_table[i].ptr, f);
4434 if (Globals.param_opt != NULL) {
4435 data = Globals.param_opt;
4437 fprintf(f, "\t%s = %s\n", data->key, data->value);
4444 /***************************************************************************
4445 Return True if a local parameter is currently set to the global default.
4446 ***************************************************************************/
4448 bool lp_is_default(int snum, struct parm_struct *parm)
4450 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
4452 return equal_parameter(parm->type,
4453 ((char *)ServicePtrs[snum]) + pdiff,
4454 ((char *)&sDefault) + pdiff);
4457 /***************************************************************************
4458 Display the contents of a single services record.
4459 ***************************************************************************/
4461 static void dump_a_service(service * pService, FILE * f)
4464 param_opt_struct *data;
4466 if (pService != &sDefault)
4467 fprintf(f, "[%s]\n", pService->szService);
4469 for (i = 0; parm_table[i].label; i++) {
4471 if (parm_table[i].p_class == P_LOCAL &&
4472 parm_table[i].ptr &&
4473 (*parm_table[i].label != '-') &&
4474 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4477 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
4479 if (pService == &sDefault) {
4480 if (defaults_saved && is_default(i))
4483 if (equal_parameter(parm_table[i].type,
4484 ((char *)pService) +
4486 ((char *)&sDefault) +
4491 fprintf(f, "\t%s = ", parm_table[i].label);
4492 print_parameter(&parm_table[i],
4493 ((char *)pService) + pdiff, f);
4498 if (pService->param_opt != NULL) {
4499 data = pService->param_opt;
4501 fprintf(f, "\t%s = %s\n", data->key, data->value);
4507 /***************************************************************************
4508 Display the contents of a parameter of a single services record.
4509 ***************************************************************************/
4511 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
4514 bool result = False;
4517 fstring local_parm_name;
4519 const char *parm_opt_value;
4521 /* check for parametrical option */
4522 fstrcpy( local_parm_name, parm_name);
4523 parm_opt = strchr( local_parm_name, ':');
4528 if (strlen(parm_opt)) {
4529 parm_opt_value = lp_parm_const_string( snum,
4530 local_parm_name, parm_opt, NULL);
4531 if (parm_opt_value) {
4532 printf( "%s\n", parm_opt_value);
4539 /* check for a key and print the value */
4546 for (i = 0; parm_table[i].label; i++) {
4547 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
4548 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
4549 parm_table[i].ptr &&
4550 (*parm_table[i].label != '-') &&
4551 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4556 ptr = parm_table[i].ptr;
4558 service * pService = ServicePtrs[snum];
4559 ptr = ((char *)pService) +
4560 PTR_DIFF(parm_table[i].ptr, &sDefault);
4563 print_parameter(&parm_table[i],
4574 /***************************************************************************
4575 Return info about the requested parameter (given as a string).
4576 Return NULL when the string is not a valid parameter name.
4577 ***************************************************************************/
4579 struct parm_struct *lp_get_parameter(const char *param_name)
4581 int num = map_parameter(param_name);
4587 return &parm_table[num];
4590 /***************************************************************************
4591 Return info about the next parameter in a service.
4592 snum==GLOBAL_SECTION_SNUM gives the globals.
4593 Return NULL when out of parameters.
4594 ***************************************************************************/
4596 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
4599 /* do the globals */
4600 for (; parm_table[*i].label; (*i)++) {
4601 if (parm_table[*i].p_class == P_SEPARATOR)
4602 return &parm_table[(*i)++];
4604 if (!parm_table[*i].ptr
4605 || (*parm_table[*i].label == '-'))
4609 && (parm_table[*i].ptr ==
4610 parm_table[(*i) - 1].ptr))
4613 if (is_default(*i) && !allparameters)
4616 return &parm_table[(*i)++];
4619 service *pService = ServicePtrs[snum];
4621 for (; parm_table[*i].label; (*i)++) {
4622 if (parm_table[*i].p_class == P_SEPARATOR)
4623 return &parm_table[(*i)++];
4625 if (parm_table[*i].p_class == P_LOCAL &&
4626 parm_table[*i].ptr &&
4627 (*parm_table[*i].label != '-') &&
4629 (parm_table[*i].ptr !=
4630 parm_table[(*i) - 1].ptr)))
4633 PTR_DIFF(parm_table[*i].ptr,
4636 if (allparameters ||
4637 !equal_parameter(parm_table[*i].type,
4638 ((char *)pService) +
4640 ((char *)&sDefault) +
4643 return &parm_table[(*i)++];
4654 /***************************************************************************
4655 Display the contents of a single copy structure.
4656 ***************************************************************************/
4657 static void dump_copy_map(bool *pcopymap)
4663 printf("\n\tNon-Copied parameters:\n");
4665 for (i = 0; parm_table[i].label; i++)
4666 if (parm_table[i].p_class == P_LOCAL &&
4667 parm_table[i].ptr && !pcopymap[i] &&
4668 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4670 printf("\t\t%s\n", parm_table[i].label);
4675 /***************************************************************************
4676 Return TRUE if the passed service number is within range.
4677 ***************************************************************************/
4679 bool lp_snum_ok(int iService)
4681 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4684 /***************************************************************************
4685 Auto-load some home services.
4686 ***************************************************************************/
4688 static void lp_add_auto_services(char *str)
4697 s = SMB_STRDUP(str);
4701 homes = lp_servicenumber(HOMES_NAME);
4703 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4704 char *home = get_user_home_dir(p);
4706 if (lp_servicenumber(p) >= 0)
4709 if (home && homes >= 0)
4710 lp_add_home(p, homes, p, home);
4715 /***************************************************************************
4716 Auto-load one printer.
4717 ***************************************************************************/
4719 void lp_add_one_printer(char *name, char *comment)
4721 int printers = lp_servicenumber(PRINTERS_NAME);
4724 if (lp_servicenumber(name) < 0) {
4725 lp_add_printer(name, printers);
4726 if ((i = lp_servicenumber(name)) >= 0) {
4727 string_set(&ServicePtrs[i]->comment, comment);
4728 ServicePtrs[i]->autoloaded = True;
4733 /***************************************************************************
4734 Have we loaded a services file yet?
4735 ***************************************************************************/
4737 bool lp_loaded(void)
4742 /***************************************************************************
4743 Unload unused services.
4744 ***************************************************************************/
4746 void lp_killunused(bool (*snumused) (int))
4749 for (i = 0; i < iNumServices; i++) {
4753 /* don't kill autoloaded or usershare services */
4754 if ( ServicePtrs[i]->autoloaded ||
4755 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4759 if (!snumused || !snumused(i)) {
4760 free_service_byindex(i);
4765 /***************************************************************************
4767 ***************************************************************************/
4769 void lp_killservice(int iServiceIn)
4771 if (VALID(iServiceIn)) {
4772 free_service_byindex(iServiceIn);
4776 /***************************************************************************
4777 Save the curent values of all global and sDefault parameters into the
4778 defaults union. This allows swat and testparm to show only the
4779 changed (ie. non-default) parameters.
4780 ***************************************************************************/
4782 static void lp_save_defaults(void)
4785 for (i = 0; parm_table[i].label; i++) {
4786 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4788 switch (parm_table[i].type) {
4790 str_list_copy(&(parm_table[i].def.lvalue),
4791 *(const char ***)parm_table[i].ptr);
4795 if (parm_table[i].ptr) {
4796 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4798 parm_table[i].def.svalue = NULL;
4803 parm_table[i].def.bvalue =
4804 *(bool *)parm_table[i].ptr;
4807 parm_table[i].def.cvalue =
4808 *(char *)parm_table[i].ptr;
4813 parm_table[i].def.ivalue =
4814 *(int *)parm_table[i].ptr;
4820 defaults_saved = True;
4823 /*******************************************************************
4824 Set the server type we will announce as via nmbd.
4825 ********************************************************************/
4827 static const struct srv_role_tab {
4829 const char *role_str;
4830 } srv_role_tab [] = {
4831 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4832 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4833 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4834 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4838 const char* server_role_str(uint32 role)
4841 for (i=0; srv_role_tab[i].role_str; i++) {
4842 if (role == srv_role_tab[i].role) {
4843 return srv_role_tab[i].role_str;
4849 static void set_server_role(void)
4851 server_role = ROLE_STANDALONE;
4853 switch (lp_security()) {
4855 if (lp_domain_logons())
4856 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4859 if (lp_domain_logons())
4860 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4861 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
4862 server_role = ROLE_STANDALONE;
4865 if (lp_domain_logons()) {
4866 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4867 server_role = ROLE_DOMAIN_BDC;
4870 server_role = ROLE_DOMAIN_MEMBER;
4873 if (lp_domain_logons()) {
4874 server_role = ROLE_DOMAIN_PDC;
4877 server_role = ROLE_DOMAIN_MEMBER;
4880 if (lp_domain_logons()) {
4882 if (Globals.iDomainMaster) /* auto or yes */
4883 server_role = ROLE_DOMAIN_PDC;
4885 server_role = ROLE_DOMAIN_BDC;
4889 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4893 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4896 /***********************************************************
4897 If we should send plaintext/LANMAN passwords in the clinet
4898 ************************************************************/
4900 static void set_allowed_client_auth(void)
4902 if (Globals.bClientNTLMv2Auth) {
4903 Globals.bClientLanManAuth = False;
4905 if (!Globals.bClientLanManAuth) {
4906 Globals.bClientPlaintextAuth = False;
4910 /***************************************************************************
4912 The following code allows smbd to read a user defined share file.
4913 Yes, this is my intent. Yes, I'm comfortable with that...
4915 THE FOLLOWING IS SECURITY CRITICAL CODE.
4917 It washes your clothes, it cleans your house, it guards you while you sleep...
4918 Do not f%^k with it....
4919 ***************************************************************************/
4921 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4923 /***************************************************************************
4924 Check allowed stat state of a usershare file.
4925 Ensure we print out who is dicking with us so the admin can
4926 get their sorry ass fired.
4927 ***************************************************************************/
4929 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4931 if (!S_ISREG(psbuf->st_mode)) {
4932 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4933 "not a regular file\n",
4934 fname, (unsigned int)psbuf->st_uid ));
4938 /* Ensure this doesn't have the other write bit set. */
4939 if (psbuf->st_mode & S_IWOTH) {
4940 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4941 "public write. Refusing to allow as a usershare file.\n",
4942 fname, (unsigned int)psbuf->st_uid ));
4946 /* Should be 10k or less. */
4947 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4948 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4949 "too large (%u) to be a user share file.\n",
4950 fname, (unsigned int)psbuf->st_uid,
4951 (unsigned int)psbuf->st_size ));
4958 /***************************************************************************
4959 Parse the contents of a usershare file.
4960 ***************************************************************************/
4962 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4963 SMB_STRUCT_STAT *psbuf,
4964 const char *servicename,
4968 char **pp_sharepath,
4973 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4974 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4977 SMB_STRUCT_STAT sbuf;
4978 char *sharepath = NULL;
4979 char *comment = NULL;
4981 *pp_sharepath = NULL;
4984 *pallow_guest = False;
4987 return USERSHARE_MALFORMED_FILE;
4990 if (strcmp(lines[0], "#VERSION 1") == 0) {
4992 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4995 return USERSHARE_MALFORMED_FILE;
4998 return USERSHARE_BAD_VERSION;
5001 if (strncmp(lines[1], "path=", 5) != 0) {
5002 return USERSHARE_MALFORMED_PATH;
5005 sharepath = talloc_strdup(ctx, &lines[1][5]);
5007 return USERSHARE_POSIX_ERR;
5009 trim_string(sharepath, " ", " ");
5011 if (strncmp(lines[2], "comment=", 8) != 0) {
5012 return USERSHARE_MALFORMED_COMMENT_DEF;
5015 comment = talloc_strdup(ctx, &lines[2][8]);
5017 return USERSHARE_POSIX_ERR;
5019 trim_string(comment, " ", " ");
5020 trim_char(comment, '"', '"');
5022 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
5023 return USERSHARE_MALFORMED_ACL_DEF;
5026 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
5027 return USERSHARE_ACL_ERR;
5031 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
5032 return USERSHARE_MALFORMED_ACL_DEF;
5034 if (lines[4][9] == 'y') {
5035 *pallow_guest = True;
5039 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
5040 /* Path didn't change, no checks needed. */
5041 *pp_sharepath = sharepath;
5042 *pp_comment = comment;
5043 return USERSHARE_OK;
5046 /* The path *must* be absolute. */
5047 if (sharepath[0] != '/') {
5048 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
5049 servicename, sharepath));
5050 return USERSHARE_PATH_NOT_ABSOLUTE;
5053 /* If there is a usershare prefix deny list ensure one of these paths
5054 doesn't match the start of the user given path. */
5055 if (prefixdenylist) {
5057 for ( i=0; prefixdenylist[i]; i++ ) {
5058 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
5059 servicename, i, prefixdenylist[i], sharepath ));
5060 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
5061 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
5062 "usershare prefix deny list entries.\n",
5063 servicename, sharepath));
5064 return USERSHARE_PATH_IS_DENIED;
5069 /* If there is a usershare prefix allow list ensure one of these paths
5070 does match the start of the user given path. */
5072 if (prefixallowlist) {
5074 for ( i=0; prefixallowlist[i]; i++ ) {
5075 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
5076 servicename, i, prefixallowlist[i], sharepath ));
5077 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
5081 if (prefixallowlist[i] == NULL) {
5082 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
5083 "usershare prefix allow list entries.\n",
5084 servicename, sharepath));
5085 return USERSHARE_PATH_NOT_ALLOWED;
5089 /* Ensure this is pointing to a directory. */
5090 dp = sys_opendir(sharepath);
5093 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
5094 servicename, sharepath));
5095 return USERSHARE_PATH_NOT_DIRECTORY;
5098 /* Ensure the owner of the usershare file has permission to share
5101 if (sys_stat(sharepath, &sbuf) == -1) {
5102 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
5103 servicename, sharepath, strerror(errno) ));
5105 return USERSHARE_POSIX_ERR;
5110 if (!S_ISDIR(sbuf.st_mode)) {
5111 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
5112 servicename, sharepath ));
5113 return USERSHARE_PATH_NOT_DIRECTORY;
5116 /* Check if sharing is restricted to owner-only. */
5117 /* psbuf is the stat of the usershare definition file,
5118 sbuf is the stat of the target directory to be shared. */
5120 if (lp_usershare_owner_only()) {
5121 /* root can share anything. */
5122 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
5123 return USERSHARE_PATH_NOT_ALLOWED;
5127 *pp_sharepath = sharepath;
5128 *pp_comment = comment;
5129 return USERSHARE_OK;
5132 /***************************************************************************
5133 Deal with a usershare file.
5136 -1 - Bad name, invalid contents.
5137 - service name already existed and not a usershare, problem
5138 with permissions to share directory etc.
5139 ***************************************************************************/
5141 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
5143 SMB_STRUCT_STAT sbuf;
5144 SMB_STRUCT_STAT lsbuf;
5146 char *sharepath = NULL;
5147 char *comment = NULL;
5148 fstring service_name;
5149 char **lines = NULL;
5153 TALLOC_CTX *ctx = NULL;
5154 SEC_DESC *psd = NULL;
5155 bool guest_ok = False;
5157 /* Ensure share name doesn't contain invalid characters. */
5158 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
5159 DEBUG(0,("process_usershare_file: share name %s contains "
5160 "invalid characters (any of %s)\n",
5161 file_name, INVALID_SHARENAME_CHARS ));
5165 fstrcpy(service_name, file_name);
5167 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
5170 /* Minimize the race condition by doing an lstat before we
5171 open and fstat. Ensure this isn't a symlink link. */
5173 if (sys_lstat(fname, &lsbuf) != 0) {
5174 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
5175 fname, strerror(errno) ));
5180 /* This must be a regular file, not a symlink, directory or
5181 other strange filetype. */
5182 if (!check_usershare_stat(fname, &lsbuf)) {
5188 char *canon_name = canonicalize_servicename(service_name);
5189 TDB_DATA data = dbwrap_fetch_bystring(
5190 ServiceHash, canon_name, canon_name);
5194 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
5195 iService = *(int *)data.dptr;
5197 TALLOC_FREE(canon_name);
5200 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
5201 /* Nothing changed - Mark valid and return. */
5202 DEBUG(10,("process_usershare_file: service %s not changed.\n",
5204 ServicePtrs[iService]->usershare = USERSHARE_VALID;
5209 /* Try and open the file read only - no symlinks allowed. */
5211 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
5213 fd = sys_open(fname, O_RDONLY, 0);
5217 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
5218 fname, strerror(errno) ));
5223 /* Now fstat to be *SURE* it's a regular file. */
5224 if (sys_fstat(fd, &sbuf) != 0) {
5226 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
5227 fname, strerror(errno) ));
5232 /* Is it the same dev/inode as was lstated ? */
5233 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
5235 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
5236 "Symlink spoofing going on ?\n", fname ));
5241 /* This must be a regular file, not a symlink, directory or
5242 other strange filetype. */
5243 if (!check_usershare_stat(fname, &sbuf)) {
5248 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
5251 if (lines == NULL) {
5252 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
5253 fname, (unsigned int)sbuf.st_uid ));
5260 /* Should we allow printers to be shared... ? */
5261 ctx = talloc_init("usershare_sd_xctx");
5263 file_lines_free(lines);
5267 if (parse_usershare_file(ctx, &sbuf, service_name,
5268 iService, lines, numlines, &sharepath,
5269 &comment, &psd, &guest_ok) != USERSHARE_OK) {
5270 talloc_destroy(ctx);
5271 file_lines_free(lines);
5275 file_lines_free(lines);
5277 /* Everything ok - add the service possibly using a template. */
5279 const service *sp = &sDefault;
5280 if (snum_template != -1) {
5281 sp = ServicePtrs[snum_template];
5284 if ((iService = add_a_service(sp, service_name)) < 0) {
5285 DEBUG(0, ("process_usershare_file: Failed to add "
5286 "new service %s\n", service_name));
5287 talloc_destroy(ctx);
5291 /* Read only is controlled by usershare ACL below. */
5292 ServicePtrs[iService]->bRead_only = False;
5295 /* Write the ACL of the new/modified share. */
5296 if (!set_share_security(service_name, psd)) {
5297 DEBUG(0, ("process_usershare_file: Failed to set share "
5298 "security for user share %s\n",
5300 lp_remove_service(iService);
5301 talloc_destroy(ctx);
5305 /* If from a template it may be marked invalid. */
5306 ServicePtrs[iService]->valid = True;
5308 /* Set the service as a valid usershare. */
5309 ServicePtrs[iService]->usershare = USERSHARE_VALID;
5311 /* Set guest access. */
5312 if (lp_usershare_allow_guests()) {
5313 ServicePtrs[iService]->bGuest_ok = guest_ok;
5316 /* And note when it was loaded. */
5317 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
5318 string_set(&ServicePtrs[iService]->szPath, sharepath);
5319 string_set(&ServicePtrs[iService]->comment, comment);
5321 talloc_destroy(ctx);
5326 /***************************************************************************
5327 Checks if a usershare entry has been modified since last load.
5328 ***************************************************************************/
5330 static bool usershare_exists(int iService, time_t *last_mod)
5332 SMB_STRUCT_STAT lsbuf;
5333 const char *usersharepath = Globals.szUsersharePath;
5336 if (asprintf(&fname, "%s/%s",
5338 ServicePtrs[iService]->szService) < 0) {
5342 if (sys_lstat(fname, &lsbuf) != 0) {
5347 if (!S_ISREG(lsbuf.st_mode)) {
5353 *last_mod = lsbuf.st_mtime;
5357 /***************************************************************************
5358 Load a usershare service by name. Returns a valid servicenumber or -1.
5359 ***************************************************************************/
5361 int load_usershare_service(const char *servicename)
5363 SMB_STRUCT_STAT sbuf;
5364 const char *usersharepath = Globals.szUsersharePath;
5365 int max_user_shares = Globals.iUsershareMaxShares;
5366 int snum_template = -1;
5368 if (*usersharepath == 0 || max_user_shares == 0) {
5372 if (sys_stat(usersharepath, &sbuf) != 0) {
5373 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
5374 usersharepath, strerror(errno) ));
5378 if (!S_ISDIR(sbuf.st_mode)) {
5379 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
5385 * This directory must be owned by root, and have the 't' bit set.
5386 * It also must not be writable by "other".
5390 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
5392 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
5394 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
5395 "or does not have the sticky bit 't' set or is writable by anyone.\n",
5400 /* Ensure the template share exists if it's set. */
5401 if (Globals.szUsershareTemplateShare[0]) {
5402 /* We can't use lp_servicenumber here as we are recommending that
5403 template shares have -valid=False set. */
5404 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
5405 if (ServicePtrs[snum_template]->szService &&
5406 strequal(ServicePtrs[snum_template]->szService,
5407 Globals.szUsershareTemplateShare)) {
5412 if (snum_template == -1) {
5413 DEBUG(0,("load_usershare_service: usershare template share %s "
5414 "does not exist.\n",
5415 Globals.szUsershareTemplateShare ));
5420 return process_usershare_file(usersharepath, servicename, snum_template);
5423 /***************************************************************************
5424 Load all user defined shares from the user share directory.
5425 We only do this if we're enumerating the share list.
5426 This is the function that can delete usershares that have
5428 ***************************************************************************/
5430 int load_usershare_shares(void)
5433 SMB_STRUCT_STAT sbuf;
5434 SMB_STRUCT_DIRENT *de;
5435 int num_usershares = 0;
5436 int max_user_shares = Globals.iUsershareMaxShares;
5437 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
5438 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
5439 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
5441 int snum_template = -1;
5442 const char *usersharepath = Globals.szUsersharePath;
5443 int ret = lp_numservices();
5445 if (max_user_shares == 0 || *usersharepath == '\0') {
5446 return lp_numservices();
5449 if (sys_stat(usersharepath, &sbuf) != 0) {
5450 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
5451 usersharepath, strerror(errno) ));
5456 * This directory must be owned by root, and have the 't' bit set.
5457 * It also must not be writable by "other".
5461 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
5463 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
5465 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
5466 "or does not have the sticky bit 't' set or is writable by anyone.\n",
5471 /* Ensure the template share exists if it's set. */
5472 if (Globals.szUsershareTemplateShare[0]) {
5473 /* We can't use lp_servicenumber here as we are recommending that
5474 template shares have -valid=False set. */
5475 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
5476 if (ServicePtrs[snum_template]->szService &&
5477 strequal(ServicePtrs[snum_template]->szService,
5478 Globals.szUsershareTemplateShare)) {
5483 if (snum_template == -1) {
5484 DEBUG(0,("load_usershare_shares: usershare template share %s "
5485 "does not exist.\n",
5486 Globals.szUsershareTemplateShare ));
5491 /* Mark all existing usershares as pending delete. */
5492 for (iService = iNumServices - 1; iService >= 0; iService--) {
5493 if (VALID(iService) && ServicePtrs[iService]->usershare) {
5494 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
5498 dp = sys_opendir(usersharepath);
5500 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
5501 usersharepath, strerror(errno) ));
5505 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
5506 (de = sys_readdir(dp));
5507 num_dir_entries++ ) {
5509 const char *n = de->d_name;
5511 /* Ignore . and .. */
5513 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
5519 /* Temporary file used when creating a share. */
5520 num_tmp_dir_entries++;
5523 /* Allow 20% tmp entries. */
5524 if (num_tmp_dir_entries > allowed_tmp_entries) {
5525 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
5526 "in directory %s\n",
5527 num_tmp_dir_entries, usersharepath));
5531 r = process_usershare_file(usersharepath, n, snum_template);
5533 /* Update the services count. */
5535 if (num_usershares >= max_user_shares) {
5536 DEBUG(0,("load_usershare_shares: max user shares reached "
5537 "on file %s in directory %s\n",
5538 n, usersharepath ));
5541 } else if (r == -1) {
5542 num_bad_dir_entries++;
5545 /* Allow 20% bad entries. */
5546 if (num_bad_dir_entries > allowed_bad_entries) {
5547 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
5548 "in directory %s\n",
5549 num_bad_dir_entries, usersharepath));
5553 /* Allow 20% bad entries. */
5554 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
5555 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
5556 "in directory %s\n",
5557 num_dir_entries, usersharepath));
5564 /* Sweep through and delete any non-refreshed usershares that are
5565 not currently in use. */
5566 for (iService = iNumServices - 1; iService >= 0; iService--) {
5567 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
5568 if (conn_snum_used(iService)) {
5571 /* Remove from the share ACL db. */
5572 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
5573 lp_servicename(iService) ));
5574 delete_share_security(lp_servicename(iService));
5575 free_service_byindex(iService);
5579 return lp_numservices();
5582 /********************************************************
5583 Destroy global resources allocated in this file
5584 ********************************************************/
5586 void gfree_loadparm(void)
5588 struct file_lists *f;
5589 struct file_lists *next;
5592 /* Free the file lists */
5597 SAFE_FREE( f->name );
5598 SAFE_FREE( f->subfname );
5603 /* Free resources allocated to services */
5605 for ( i = 0; i < iNumServices; i++ ) {
5607 free_service_byindex(i);
5611 SAFE_FREE( ServicePtrs );
5614 /* Now release all resources allocated to global
5615 parameters and the default service */
5617 for (i = 0; parm_table[i].label; i++)
5619 if ( parm_table[i].type == P_STRING
5620 || parm_table[i].type == P_USTRING )
5622 string_free( (char**)parm_table[i].ptr );
5624 else if (parm_table[i].type == P_LIST) {
5625 str_list_free( (char***)parm_table[i].ptr );
5630 /***************************************************************************
5631 Load the services array from the services file. Return True on success,
5633 ***************************************************************************/
5635 bool lp_load(const char *pszFname,
5639 bool initialize_globals)
5643 param_opt_struct *data, *pdata;
5645 n2 = alloc_sub_basic(get_current_username(),
5646 current_user_info.domain,
5649 smb_panic("lp_load: out of memory");
5652 add_to_file_list(pszFname, n2);
5656 DEBUG(3, ("lp_load: refreshing parameters\n"));
5658 bInGlobalSection = True;
5659 bGlobalOnly = global_only;
5661 init_globals(! initialize_globals);
5664 if (save_defaults) {
5669 if (Globals.param_opt != NULL) {
5670 data = Globals.param_opt;
5672 string_free(&data->key);
5673 string_free(&data->value);
5674 str_list_free(&data->list);
5679 Globals.param_opt = NULL;
5682 /* We get sections first, so have to start 'behind' to make up */
5684 bRetval = pm_process(n2, do_section, do_parameter);
5687 /* finish up the last section */
5688 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
5690 if (iServiceIndex >= 0) {
5691 bRetval = service_ok(iServiceIndex);
5695 lp_add_auto_services(lp_auto_services());
5698 /* When 'restrict anonymous = 2' guest connections to ipc$
5700 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
5701 if ( lp_enable_asu_support() ) {
5702 lp_add_ipc("ADMIN$", false);
5707 set_default_server_announce_type();
5708 set_allowed_client_auth();
5712 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
5713 /* if bWINSsupport is true and we are in the client */
5714 if (in_client && Globals.bWINSsupport) {
5715 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5723 /***************************************************************************
5724 Reset the max number of services.
5725 ***************************************************************************/
5727 void lp_resetnumservices(void)
5732 /***************************************************************************
5733 Return the max number of services.
5734 ***************************************************************************/
5736 int lp_numservices(void)
5738 return (iNumServices);
5741 /***************************************************************************
5742 Display the contents of the services array in human-readable form.
5743 ***************************************************************************/
5745 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
5750 defaults_saved = False;
5754 dump_a_service(&sDefault, f);
5756 for (iService = 0; iService < maxtoprint; iService++) {
5758 lp_dump_one(f, show_defaults, iService);
5762 /***************************************************************************
5763 Display the contents of one service in human-readable form.
5764 ***************************************************************************/
5766 void lp_dump_one(FILE * f, bool show_defaults, int snum)
5769 if (ServicePtrs[snum]->szService[0] == '\0')
5771 dump_a_service(ServicePtrs[snum], f);
5775 /***************************************************************************
5776 Return the number of the service with the given name, or -1 if it doesn't
5777 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5778 getservicebyname()! This works ONLY if all services have been loaded, and
5779 does not copy the found service.
5780 ***************************************************************************/
5782 int lp_servicenumber(const char *pszServiceName)
5785 fstring serviceName;
5787 if (!pszServiceName) {
5788 return GLOBAL_SECTION_SNUM;
5791 for (iService = iNumServices - 1; iService >= 0; iService--) {
5792 if (VALID(iService) && ServicePtrs[iService]->szService) {
5794 * The substitution here is used to support %U is
5797 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5798 standard_sub_basic(get_current_username(),
5799 current_user_info.domain,
5800 serviceName,sizeof(serviceName));
5801 if (strequal(serviceName, pszServiceName)) {
5807 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5810 if (!usershare_exists(iService, &last_mod)) {
5811 /* Remove the share security tdb entry for it. */
5812 delete_share_security(lp_servicename(iService));
5813 /* Remove it from the array. */
5814 free_service_byindex(iService);
5815 /* Doesn't exist anymore. */
5816 return GLOBAL_SECTION_SNUM;
5819 /* Has it been modified ? If so delete and reload. */
5820 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5821 /* Remove it from the array. */
5822 free_service_byindex(iService);
5823 /* and now reload it. */
5824 iService = load_usershare_service(pszServiceName);
5829 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5830 return GLOBAL_SECTION_SNUM;
5836 bool share_defined(const char *service_name)
5838 return (lp_servicenumber(service_name) != -1);
5841 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
5842 const char *sharename)
5844 struct share_params *result;
5848 if (!(sname = SMB_STRDUP(sharename))) {
5852 snum = find_service(sname);
5859 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
5860 DEBUG(0, ("talloc failed\n"));
5864 result->service = snum;
5868 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
5870 struct share_iterator *result;
5872 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
5873 DEBUG(0, ("talloc failed\n"));
5877 result->next_id = 0;
5881 struct share_params *next_share(struct share_iterator *list)
5883 struct share_params *result;
5885 while (!lp_snum_ok(list->next_id) &&
5886 (list->next_id < lp_numservices())) {
5890 if (list->next_id >= lp_numservices()) {
5894 if (!(result = TALLOC_P(list, struct share_params))) {
5895 DEBUG(0, ("talloc failed\n"));
5899 result->service = list->next_id;
5904 struct share_params *next_printer(struct share_iterator *list)
5906 struct share_params *result;
5908 while ((result = next_share(list)) != NULL) {
5909 if (lp_print_ok(result->service)) {
5917 * This is a hack for a transition period until we transformed all code from
5918 * service numbers to struct share_params.
5921 struct share_params *snum2params_static(int snum)
5923 static struct share_params result;
5924 result.service = snum;
5928 /*******************************************************************
5929 A useful volume label function.
5930 ********************************************************************/
5932 const char *volume_label(int snum)
5935 const char *label = lp_volume(snum);
5937 label = lp_servicename(snum);
5940 /* This returns a 33 byte guarenteed null terminated string. */
5941 ret = talloc_strndup(talloc_tos(), label, 32);
5948 /*******************************************************************
5949 Set the server type we will announce as via nmbd.
5950 ********************************************************************/
5952 static void set_default_server_announce_type(void)
5954 default_server_announce = 0;
5955 default_server_announce |= SV_TYPE_WORKSTATION;
5956 default_server_announce |= SV_TYPE_SERVER;
5957 default_server_announce |= SV_TYPE_SERVER_UNIX;
5959 /* note that the flag should be set only if we have a
5960 printer service but nmbd doesn't actually load the
5961 services so we can't tell --jerry */
5963 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5965 switch (lp_announce_as()) {
5966 case ANNOUNCE_AS_NT_SERVER:
5967 default_server_announce |= SV_TYPE_SERVER_NT;
5968 /* fall through... */
5969 case ANNOUNCE_AS_NT_WORKSTATION:
5970 default_server_announce |= SV_TYPE_NT;
5972 case ANNOUNCE_AS_WIN95:
5973 default_server_announce |= SV_TYPE_WIN95_PLUS;
5975 case ANNOUNCE_AS_WFW:
5976 default_server_announce |= SV_TYPE_WFW;
5982 switch (lp_server_role()) {
5983 case ROLE_DOMAIN_MEMBER:
5984 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5986 case ROLE_DOMAIN_PDC:
5987 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5989 case ROLE_DOMAIN_BDC:
5990 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5992 case ROLE_STANDALONE:
5996 if (lp_time_server())
5997 default_server_announce |= SV_TYPE_TIME_SOURCE;
5999 if (lp_host_msdfs())
6000 default_server_announce |= SV_TYPE_DFS_SERVER;
6003 /***********************************************************
6004 returns role of Samba server
6005 ************************************************************/
6007 int lp_server_role(void)
6012 /***********************************************************
6013 If we are PDC then prefer us as DMB
6014 ************************************************************/
6016 bool lp_domain_master(void)
6018 if (Globals.iDomainMaster == Auto)
6019 return (lp_server_role() == ROLE_DOMAIN_PDC);
6021 return (bool)Globals.iDomainMaster;
6024 /***********************************************************
6025 If we are DMB then prefer us as LMB
6026 ************************************************************/
6028 bool lp_preferred_master(void)
6030 if (Globals.iPreferredMaster == Auto)
6031 return (lp_local_master() && lp_domain_master());
6033 return (bool)Globals.iPreferredMaster;
6036 /*******************************************************************
6038 ********************************************************************/
6040 void lp_remove_service(int snum)
6042 ServicePtrs[snum]->valid = False;
6043 invalid_services[num_invalid_services++] = snum;
6046 /*******************************************************************
6048 ********************************************************************/
6050 void lp_copy_service(int snum, const char *new_name)
6052 do_section(new_name);
6054 snum = lp_servicenumber(new_name);
6056 lp_do_parameter(snum, "copy", lp_servicename(snum));
6061 /*******************************************************************
6062 Get the default server type we will announce as via nmbd.
6063 ********************************************************************/
6065 int lp_default_server_announce(void)
6067 return default_server_announce;
6070 /*******************************************************************
6071 Split the announce version into major and minor numbers.
6072 ********************************************************************/
6074 int lp_major_announce_version(void)
6076 static bool got_major = False;
6077 static int major_version = DEFAULT_MAJOR_VERSION;
6082 return major_version;
6085 if ((vers = lp_announce_version()) == NULL)
6086 return major_version;
6088 if ((p = strchr_m(vers, '.')) == 0)
6089 return major_version;
6092 major_version = atoi(vers);
6093 return major_version;
6096 int lp_minor_announce_version(void)
6098 static bool got_minor = False;
6099 static int minor_version = DEFAULT_MINOR_VERSION;
6104 return minor_version;
6107 if ((vers = lp_announce_version()) == NULL)
6108 return minor_version;
6110 if ((p = strchr_m(vers, '.')) == 0)
6111 return minor_version;
6114 minor_version = atoi(p);
6115 return minor_version;
6118 /***********************************************************
6119 Set the global name resolution order (used in smbclient).
6120 ************************************************************/
6122 void lp_set_name_resolve_order(const char *new_order)
6124 string_set(&Globals.szNameResolveOrder, new_order);
6127 const char *lp_printername(int snum)
6129 const char *ret = _lp_printername(snum);
6130 if (ret == NULL || (ret != NULL && *ret == '\0'))
6131 ret = lp_const_servicename(snum);
6137 /***********************************************************
6138 Allow daemons such as winbindd to fix their logfile name.
6139 ************************************************************/
6141 void lp_set_logfile(const char *name)
6143 string_set(&Globals.szLogFile, name);
6144 debug_set_logfile(name);
6147 /*******************************************************************
6148 Return the max print jobs per queue.
6149 ********************************************************************/
6151 int lp_maxprintjobs(int snum)
6153 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
6154 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
6155 maxjobs = PRINT_MAX_JOBID - 1;
6160 const char *lp_printcapname(void)
6162 if ((Globals.szPrintcapname != NULL) &&
6163 (Globals.szPrintcapname[0] != '\0'))
6164 return Globals.szPrintcapname;
6166 if (sDefault.iPrinting == PRINT_CUPS) {
6174 if (sDefault.iPrinting == PRINT_BSD)
6175 return "/etc/printcap";
6177 return PRINTCAP_NAME;
6180 /*******************************************************************
6181 Ensure we don't use sendfile if server smb signing is active.
6182 ********************************************************************/
6184 static uint32 spoolss_state;
6186 bool lp_disable_spoolss( void )
6188 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
6189 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
6191 return spoolss_state == SVCCTL_STOPPED ? True : False;
6194 void lp_set_spoolss_state( uint32 state )
6196 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
6198 spoolss_state = state;
6201 uint32 lp_get_spoolss_state( void )
6203 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
6206 /*******************************************************************
6207 Ensure we don't use sendfile if server smb signing is active.
6208 ********************************************************************/
6210 bool lp_use_sendfile(int snum)
6212 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
6213 if (Protocol < PROTOCOL_NT1) {
6216 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
6219 /*******************************************************************
6220 Turn off sendfile if we find the underlying OS doesn't support it.
6221 ********************************************************************/
6223 void set_use_sendfile(int snum, bool val)
6225 if (LP_SNUM_OK(snum))
6226 ServicePtrs[snum]->bUseSendfile = val;
6228 sDefault.bUseSendfile = val;
6231 /*******************************************************************
6232 Turn off storing DOS attributes if this share doesn't support it.
6233 ********************************************************************/
6235 void set_store_dos_attributes(int snum, bool val)
6237 if (!LP_SNUM_OK(snum))
6239 ServicePtrs[(snum)]->bStoreDosAttributes = val;
6242 void lp_set_mangling_method(const char *new_method)
6244 string_set(&Globals.szManglingMethod, new_method);
6247 /*******************************************************************
6248 Global state for POSIX pathname processing.
6249 ********************************************************************/
6251 static bool posix_pathnames;
6253 bool lp_posix_pathnames(void)
6255 return posix_pathnames;
6258 /*******************************************************************
6259 Change everything needed to ensure POSIX pathname processing (currently
6261 ********************************************************************/
6263 void lp_set_posix_pathnames(void)
6265 posix_pathnames = True;
6268 /*******************************************************************
6269 Global state for POSIX lock processing - CIFS unix extensions.
6270 ********************************************************************/
6272 bool posix_default_lock_was_set;
6273 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
6275 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
6277 if (posix_default_lock_was_set) {
6278 return posix_cifsx_locktype;
6280 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
6284 /*******************************************************************
6285 ********************************************************************/
6287 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
6289 posix_default_lock_was_set = True;
6290 posix_cifsx_locktype = val;
6293 int lp_min_receive_file_size(void)
6295 if (Globals.iminreceivefile < 0) {
6298 return MIN(Globals.iminreceivefile, BUFFER_SIZE);