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 pstring user_socket_options;
59 extern enum protocol_types Protocol;
60 extern userdom_struct current_user_info;
63 #define GLOBAL_NAME "global"
67 #define PRINTERS_NAME "printers"
71 #define HOMES_NAME "homes"
74 /* the special value for the include parameter
75 * to be interpreted not as a file name but to
76 * trigger loading of the global smb.conf options
78 #ifndef INCLUDE_REGISTRY_NAME
79 #define INCLUDE_REGISTRY_NAME "registry"
82 static int regdb_last_seqnum = 0;
83 static bool include_registry_globals = False;
85 /* some helpful bits */
86 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
87 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
89 #define USERSHARE_VALID 1
90 #define USERSHARE_PENDING_DELETE 2
92 bool use_getwd_cache = True;
94 extern int extra_time_offset;
96 static bool defaults_saved = False;
98 typedef struct _param_opt_struct param_opt_struct;
99 struct _param_opt_struct {
100 param_opt_struct *prev, *next;
107 * This structure describes global (ie., server-wide) parameters.
113 char *display_charset;
114 char *szPrintcapname;
115 char *szAddPortCommand;
116 char *szEnumPortsCommand;
117 char *szAddPrinterCommand;
118 char *szDeletePrinterCommand;
119 char *szOs2DriverMap;
123 char *szDefaultService;
127 char *szServerString;
128 char *szAutoServices;
129 char *szPasswdProgram;
133 char *szSMBPasswdFile;
135 char *szPassdbBackend;
136 char **szPreloadModules;
137 char *szPasswordServer;
138 char *szSocketOptions;
140 char *szAfsUsernameMap;
141 int iAfsTokenLifetime;
142 char *szLogNtTokenCommand;
148 char **szWINSservers;
150 char *szRemoteAnnounce;
151 char *szRemoteBrowseSync;
152 char *szSocketAddress;
153 char *szNISHomeMapName;
154 char *szAnnounceVersion; /* This is initialised in init_globals */
157 char **szNetbiosAliases;
158 char *szNetbiosScope;
159 char *szNameResolveOrder;
161 char *szAddUserScript;
162 char *szRenameUserScript;
163 char *szDelUserScript;
164 char *szAddGroupScript;
165 char *szDelGroupScript;
166 char *szAddUserToGroupScript;
167 char *szDelUserFromGroupScript;
168 char *szSetPrimaryGroupScript;
169 char *szAddMachineScript;
170 char *szShutdownScript;
171 char *szAbortShutdownScript;
172 char *szUsernameMapScript;
173 char *szCheckPasswordScript;
180 bool bPassdbExpandExplicit;
181 int AlgorithmicRidBase;
182 char *szTemplateHomedir;
183 char *szTemplateShell;
184 char *szWinbindSeparator;
185 bool bWinbindEnumUsers;
186 bool bWinbindEnumGroups;
187 bool bWinbindUseDefaultDomain;
188 bool bWinbindTrustedDomainsOnly;
189 bool bWinbindNestedGroups;
190 int winbind_expand_groups;
191 bool bWinbindRefreshTickets;
192 bool bWinbindOfflineLogon;
193 bool bWinbindNormalizeNames;
194 bool bWinbindRpcOnly;
195 char **szIdmapDomains;
196 char **szIdmapBackend; /* deprecated */
197 char *szIdmapAllocBackend;
198 char *szAddShareCommand;
199 char *szChangeShareCommand;
200 char *szDeleteShareCommand;
202 char *szGuestaccount;
203 char *szManglingMethod;
204 char **szServicesList;
205 char *szUsersharePath;
206 char *szUsershareTemplateShare;
207 char **szUsersharePrefixAllowList;
208 char **szUsersharePrefixDenyList;
215 int open_files_db_hash_size;
223 bool paranoid_server_security;
226 int iMaxSmbdProcesses;
227 bool bDisableSpoolss;
230 bool enhanced_browsing;
236 int announce_as; /* This is initialised in init_globals */
237 int machine_password_timeout;
239 int oplock_break_wait_time;
240 int winbind_cache_time;
241 int winbind_max_idle_children;
242 char **szWinbindNssInfo;
244 char *szLdapMachineSuffix;
245 char *szLdapUserSuffix;
246 char *szLdapIdmapSuffix;
247 char *szLdapGroupSuffix;
253 char *szIPrintServer;
255 char **szClusterAddresses;
257 int ldap_passwd_sync;
258 int ldap_replication_sleep;
259 int ldap_timeout; /* This is initialised in init_globals */
262 bool bMsAddPrinterWizard;
267 int iPreferredMaster;
270 bool bEncryptPasswords;
275 bool bObeyPamRestrictions;
277 int PrintcapCacheTime;
278 bool bLargeReadwrite;
285 bool bBindInterfacesOnly;
286 bool bPamPasswordChange;
287 bool bUnixPasswdSync;
288 bool bPasswdChatDebug;
289 int iPasswdChatTimeout;
293 bool bNTStatusSupport;
295 int iMaxStatCacheSize;
297 bool bAllowTrustedDomains;
301 bool bClientLanManAuth;
302 bool bClientNTLMv2Auth;
303 bool bClientPlaintextAuth;
304 bool bClientUseSpnego;
305 bool bDebugPrefixTimestamp;
306 bool bDebugHiresTimestamp;
310 bool bEnableCoreFiles;
313 bool bHostnameLookups;
314 bool bUnixExtensions;
315 bool bDisableNetbios;
316 bool bUseKerberosKeytab;
317 bool bDeferSharingViolations;
318 bool bEnablePrivileges;
320 bool bUsershareOwnerOnly;
321 bool bUsershareAllowGuests;
322 bool bRegistryShares;
323 int restrict_anonymous;
324 int name_cache_timeout;
327 int client_ldap_sasl_wrapping;
328 int iUsershareMaxShares;
330 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;
444 bool bDeleteReadonly;
446 bool bDeleteVetoFiles;
449 bool bDosFiletimeResolution;
450 bool bFakeDirCreateTimes;
456 bool bUseClientDriver;
457 bool bDefaultDevmode;
458 bool bForcePrintername;
460 bool bForceUnknownAclUser;
463 bool bMap_acl_inherit;
466 bool bAclCheckPermissions;
467 bool bAclMapFullControl;
468 bool bAclGroupControl;
470 bool bKernelChangeNotify;
471 int iallocation_roundup_size;
475 int iDirectoryNameCacheSize;
476 param_opt_struct *param_opt;
478 char dummy[3]; /* for alignment */
482 /* This is a default service used to prime a services structure */
483 static service sDefault = {
485 False, /* not autoloaded */
486 0, /* not a usershare */
487 (time_t)0, /* No last mod time */
488 NULL, /* szService */
490 NULL, /* szUsername */
491 NULL, /* szInvalidUsers */
492 NULL, /* szValidUsers */
493 NULL, /* szAdminUsers */
495 NULL, /* szInclude */
496 NULL, /* szPreExec */
497 NULL, /* szPostExec */
498 NULL, /* szRootPreExec */
499 NULL, /* szRootPostExec */
500 NULL, /* szCupsOptions */
501 NULL, /* szPrintcommand */
502 NULL, /* szLpqcommand */
503 NULL, /* szLprmcommand */
504 NULL, /* szLppausecommand */
505 NULL, /* szLpresumecommand */
506 NULL, /* szQueuepausecommand */
507 NULL, /* szQueueresumecommand */
508 NULL, /* szPrintername */
509 NULL, /* szPrintjobUsername */
510 NULL, /* szDontdescend */
511 NULL, /* szHostsallow */
512 NULL, /* szHostsdeny */
513 NULL, /* szMagicScript */
514 NULL, /* szMagicOutput */
515 NULL, /* szVetoFiles */
516 NULL, /* szHideFiles */
517 NULL, /* szVetoOplockFiles */
519 NULL, /* force user */
520 NULL, /* force group */
522 NULL, /* writelist */
523 NULL, /* printer admin */
526 NULL, /* vfs objects */
527 NULL, /* szMSDfsProxy */
528 NULL, /* szAioWriteBehind */
530 0, /* iMinPrintSpace */
531 1000, /* iMaxPrintJobs */
532 0, /* iMaxReportedPrintJobs */
533 0, /* iWriteCacheSize */
534 0744, /* iCreate_mask */
535 0000, /* iCreate_force_mode */
536 0777, /* iSecurity_mask */
537 0, /* iSecurity_force_mode */
538 0755, /* iDir_mask */
539 0000, /* iDir_force_mode */
540 0777, /* iDir_Security_mask */
541 0, /* iDir_Security_force_mode */
542 0, /* iMaxConnections */
543 CASE_LOWER, /* iDefaultCase */
544 DEFAULT_PRINTING, /* iPrinting */
545 2, /* iOplockContentionLimit */
547 1024, /* iBlock_size */
548 0, /* iDfreeCacheTime */
549 False, /* bPreexecClose */
550 False, /* bRootpreexecClose */
551 Auto, /* case sensitive */
552 True, /* case preserve */
553 True, /* short case preserve */
554 True, /* bHideDotFiles */
555 False, /* bHideSpecialFiles */
556 False, /* bHideUnReadable */
557 False, /* bHideUnWriteableFiles */
558 True, /* bBrowseable */
559 True, /* bAvailable */
560 True, /* bRead_only */
561 True, /* bNo_set_dir */
562 False, /* bGuest_only */
563 False, /* bGuest_ok */
564 False, /* bPrint_ok */
565 False, /* bMap_system */
566 False, /* bMap_hidden */
567 True, /* bMap_archive */
568 False, /* bStoreDosAttributes */
569 False, /* bDmapiSupport */
571 Auto, /* iStrictLocking */
572 True, /* bPosixLocking */
573 True, /* bShareModes */
575 True, /* bLevel2OpLocks */
576 False, /* bOnlyUser */
577 True, /* bMangledNames */
578 True, /* bWidelinks */
579 True, /* bSymlinks */
580 False, /* bSyncAlways */
581 False, /* bStrictAllocate */
582 False, /* bStrictSync */
583 '~', /* magic char */
585 False, /* bDeleteReadonly */
586 False, /* bFakeOplocks */
587 False, /* bDeleteVetoFiles */
588 False, /* bDosFilemode */
589 True, /* bDosFiletimes */
590 False, /* bDosFiletimeResolution */
591 False, /* bFakeDirCreateTimes */
592 True, /* bBlockingLocks */
593 False, /* bInheritPerms */
594 False, /* bInheritACLS */
595 False, /* bInheritOwner */
596 False, /* bMSDfsRoot */
597 False, /* bUseClientDriver */
598 True, /* bDefaultDevmode */
599 False, /* bForcePrintername */
600 True, /* bNTAclSupport */
601 False, /* bForceUnknownAclUser */
602 False, /* bUseSendfile */
603 False, /* bProfileAcls */
604 False, /* bMap_acl_inherit */
605 False, /* bAfs_Share */
606 False, /* bEASupport */
607 True, /* bAclCheckPermissions */
608 True, /* bAclMapFullControl */
609 False, /* bAclGroupControl */
610 True, /* bChangeNotify */
611 True, /* bKernelChangeNotify */
612 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
613 0, /* iAioReadSize */
614 0, /* iAioWriteSize */
615 MAP_READONLY_YES, /* iMap_readonly */
616 #ifdef BROKEN_DIRECTORY_HANDLING
617 0, /* iDirectoryNameCacheSize */
619 100, /* iDirectoryNameCacheSize */
621 NULL, /* Parametric options */
626 /* local variables */
627 static service **ServicePtrs = NULL;
628 static int iNumServices = 0;
629 static int iServiceIndex = 0;
630 static TDB_CONTEXT *ServiceHash;
631 static int *invalid_services = NULL;
632 static int num_invalid_services = 0;
633 static bool bInGlobalSection = True;
634 static bool bGlobalOnly = False;
635 static int server_role;
636 static int default_server_announce;
638 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
640 /* prototypes for the special type handlers */
641 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
642 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
643 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
644 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
645 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
646 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
647 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
648 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
649 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
650 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
651 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
653 static void set_server_role(void);
654 static void set_default_server_announce_type(void);
655 static void set_allowed_client_auth(void);
657 static const struct enum_list enum_protocol[] = {
658 {PROTOCOL_NT1, "NT1"},
659 {PROTOCOL_LANMAN2, "LANMAN2"},
660 {PROTOCOL_LANMAN1, "LANMAN1"},
661 {PROTOCOL_CORE, "CORE"},
662 {PROTOCOL_COREPLUS, "COREPLUS"},
663 {PROTOCOL_COREPLUS, "CORE+"},
667 static const struct enum_list enum_security[] = {
668 {SEC_SHARE, "SHARE"},
670 {SEC_SERVER, "SERVER"},
671 {SEC_DOMAIN, "DOMAIN"},
678 static const struct enum_list enum_printing[] = {
679 {PRINT_SYSV, "sysv"},
681 {PRINT_HPUX, "hpux"},
685 {PRINT_LPRNG, "lprng"},
686 {PRINT_CUPS, "cups"},
687 {PRINT_IPRINT, "iprint"},
689 {PRINT_LPROS2, "os2"},
691 {PRINT_TEST, "test"},
693 #endif /* DEVELOPER */
697 static const struct enum_list enum_ldap_sasl_wrapping[] = {
699 {ADS_AUTH_SASL_SIGN, "sign"},
700 {ADS_AUTH_SASL_SEAL, "seal"},
704 static const struct enum_list enum_ldap_ssl[] = {
705 {LDAP_SSL_OFF, "no"},
706 {LDAP_SSL_OFF, "No"},
707 {LDAP_SSL_OFF, "off"},
708 {LDAP_SSL_OFF, "Off"},
709 {LDAP_SSL_START_TLS, "start tls"},
710 {LDAP_SSL_START_TLS, "Start_tls"},
714 static const struct enum_list enum_ldap_passwd_sync[] = {
715 {LDAP_PASSWD_SYNC_OFF, "no"},
716 {LDAP_PASSWD_SYNC_OFF, "No"},
717 {LDAP_PASSWD_SYNC_OFF, "off"},
718 {LDAP_PASSWD_SYNC_OFF, "Off"},
719 {LDAP_PASSWD_SYNC_ON, "Yes"},
720 {LDAP_PASSWD_SYNC_ON, "yes"},
721 {LDAP_PASSWD_SYNC_ON, "on"},
722 {LDAP_PASSWD_SYNC_ON, "On"},
723 {LDAP_PASSWD_SYNC_ONLY, "Only"},
724 {LDAP_PASSWD_SYNC_ONLY, "only"},
728 /* Types of machine we can announce as. */
729 #define ANNOUNCE_AS_NT_SERVER 1
730 #define ANNOUNCE_AS_WIN95 2
731 #define ANNOUNCE_AS_WFW 3
732 #define ANNOUNCE_AS_NT_WORKSTATION 4
734 static const struct enum_list enum_announce_as[] = {
735 {ANNOUNCE_AS_NT_SERVER, "NT"},
736 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
737 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
738 {ANNOUNCE_AS_WIN95, "win95"},
739 {ANNOUNCE_AS_WFW, "WfW"},
743 static const struct enum_list enum_map_readonly[] = {
744 {MAP_READONLY_NO, "no"},
745 {MAP_READONLY_NO, "false"},
746 {MAP_READONLY_NO, "0"},
747 {MAP_READONLY_YES, "yes"},
748 {MAP_READONLY_YES, "true"},
749 {MAP_READONLY_YES, "1"},
750 {MAP_READONLY_PERMISSIONS, "permissions"},
751 {MAP_READONLY_PERMISSIONS, "perms"},
755 static const struct enum_list enum_case[] = {
756 {CASE_LOWER, "lower"},
757 {CASE_UPPER, "upper"},
761 static const struct enum_list enum_bool_auto[] = {
772 /* Client-side offline caching policy types */
773 #define CSC_POLICY_MANUAL 0
774 #define CSC_POLICY_DOCUMENTS 1
775 #define CSC_POLICY_PROGRAMS 2
776 #define CSC_POLICY_DISABLE 3
778 static const struct enum_list enum_csc_policy[] = {
779 {CSC_POLICY_MANUAL, "manual"},
780 {CSC_POLICY_DOCUMENTS, "documents"},
781 {CSC_POLICY_PROGRAMS, "programs"},
782 {CSC_POLICY_DISABLE, "disable"},
786 /* SMB signing types. */
787 static const struct enum_list enum_smb_signing_vals[] = {
799 {Required, "required"},
800 {Required, "mandatory"},
802 {Required, "forced"},
803 {Required, "enforced"},
807 /* ACL compatibility options. */
808 static const struct enum_list enum_acl_compat_vals[] = {
809 { ACL_COMPAT_AUTO, "auto" },
810 { ACL_COMPAT_WINNT, "winnt" },
811 { ACL_COMPAT_WIN2K, "win2k" },
816 Do you want session setups at user level security with a invalid
817 password to be rejected or allowed in as guest? WinNT rejects them
818 but it can be a pain as it means "net view" needs to use a password
820 You have 3 choices in the setting of map_to_guest:
822 "Never" means session setups with an invalid password
823 are rejected. This is the default.
825 "Bad User" means session setups with an invalid password
826 are rejected, unless the username does not exist, in which case it
827 is treated as a guest login
829 "Bad Password" means session setups with an invalid password
830 are treated as a guest login
832 Note that map_to_guest only has an effect in user or server
836 static const struct enum_list enum_map_to_guest[] = {
837 {NEVER_MAP_TO_GUEST, "Never"},
838 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
839 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
840 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
844 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
846 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
847 * screen in SWAT. This is used to exclude parameters as well as to squash all
848 * parameters that have been duplicated by pseudonyms.
850 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
851 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
852 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
855 * NOTE2: Handling of duplicated (synonym) paramters:
856 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
857 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
858 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
859 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
862 static struct parm_struct parm_table[] = {
863 {N_("Base Options"), P_SEP, P_SEPARATOR},
865 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
866 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
867 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
868 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
869 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
870 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
871 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
873 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
875 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
876 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
877 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
878 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
879 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
880 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
882 {N_("Security Options"), P_SEP, P_SEPARATOR},
884 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
885 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
886 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
887 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
888 {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
889 {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
890 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
891 {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
892 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
893 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
894 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
895 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
896 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
897 {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
898 {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
899 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
900 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
901 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
902 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
903 {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
905 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
906 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
907 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
908 {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
909 {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
910 {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED},
911 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
912 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
913 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
914 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
915 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
916 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
917 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
918 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
919 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
920 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
922 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
923 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
924 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
926 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
927 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
928 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
929 {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
930 {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
931 {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED },
932 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
933 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
934 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
936 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
937 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
938 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
939 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
941 {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
942 {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED },
943 {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
944 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
945 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
946 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
947 {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
948 {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
949 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
950 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
951 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
952 {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
953 {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
954 {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
955 {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
956 {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
957 {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
958 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
959 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
961 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
962 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
964 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
965 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
966 {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
967 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
968 {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
969 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
970 {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED},
972 {N_("Logging Options"), P_SEP, P_SEPARATOR},
974 {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
975 {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
976 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
977 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
978 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
980 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
981 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
982 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
983 {"debug prefix timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugPrefixTimestamp, NULL, NULL, FLAG_ADVANCED},
984 {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
985 {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
986 {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
987 {"debug class", P_BOOL, P_GLOBAL, &Globals.bDebugClass, NULL, NULL, FLAG_ADVANCED},
988 {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
990 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
992 {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED},
993 {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED},
994 {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED},
995 {"aio write behind", P_STRING, P_LOCAL, &sDefault.szAioWriteBehind, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
996 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
997 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
998 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
999 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
1000 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
1001 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
1002 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
1003 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
1004 {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED},
1006 {"acl compatibility", P_ENUM, P_GLOBAL, &Globals.iAclCompat, NULL, enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1007 {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1008 {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1009 {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1010 {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
1011 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
1012 {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1014 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
1015 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED},
1016 {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1017 {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1018 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
1019 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
1021 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1022 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
1023 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
1024 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
1025 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
1026 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
1027 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
1028 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1029 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1030 {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
1031 {"client ldap sasl wrapping", P_ENUM, P_GLOBAL, &Globals.client_ldap_sasl_wrapping, NULL, enum_ldap_sasl_wrapping, FLAG_ADVANCED},
1032 {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED},
1033 {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
1035 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1037 {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1038 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
1039 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
1040 {"keepalive", P_INTEGER, P_GLOBAL, &Globals.iKeepalive, NULL, NULL, FLAG_ADVANCED},
1041 {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1042 {"directory name cache size", P_INTEGER, P_LOCAL, &sDefault.iDirectoryNameCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1043 {"kernel change notify", P_BOOL, P_LOCAL, &sDefault.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1045 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
1046 {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
1047 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1048 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
1049 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
1050 {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
1051 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1053 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
1054 {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1055 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1056 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1057 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
1058 {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1059 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
1060 {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
1062 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
1063 {"ctdbd socket", P_STRING, P_GLOBAL, &Globals.ctdbdSocket, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1064 {"cluster addresses", P_LIST, P_GLOBAL, &Globals.szClusterAddresses, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1065 {"clustering", P_BOOL, P_GLOBAL, &Globals.clustering, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1067 {N_("Printing Options"), P_SEP, P_SEPARATOR},
1069 {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1070 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1071 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1072 {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1073 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1074 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
1075 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1076 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
1077 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1078 {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1079 {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1080 {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1081 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1082 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1083 {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE},
1084 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1085 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1086 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1087 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1088 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1089 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1091 {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED},
1092 {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
1093 {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
1094 {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
1095 {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
1096 {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
1098 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1099 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
1100 {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1101 {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1102 {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1103 {"printjob username", P_STRING, P_LOCAL, &sDefault.szPrintjobUsername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1105 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
1106 {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
1107 {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
1109 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
1110 {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1111 {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE},
1112 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1113 {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1114 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1115 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1116 {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1117 {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1118 {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1119 {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1120 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1121 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1122 {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1123 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1124 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1125 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1126 {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1127 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1128 {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
1129 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
1130 {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1131 {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1134 {N_("Domain Options"), P_SEP, P_SEPARATOR},
1136 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1138 {N_("Logon Options"), P_SEP, P_SEPARATOR},
1140 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
1141 {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
1142 {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
1143 {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
1144 {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
1145 {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
1146 {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
1147 {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
1148 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
1149 {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
1150 {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
1151 {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED},
1153 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
1154 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
1155 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
1156 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
1157 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
1159 {N_("Browse Options"), P_SEP, P_SEPARATOR},
1161 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1162 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
1163 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
1164 {"preferred master", P_ENUM, P_GLOBAL, &Globals.iPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1165 {"prefered master", P_ENUM, P_GLOBAL, &Globals.iPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
1166 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1167 {"domain master", P_ENUM, P_GLOBAL, &Globals.iDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1168 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
1169 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1170 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1171 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
1173 {N_("WINS Options"), P_SEP, P_SEPARATOR},
1175 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
1176 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
1178 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1179 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1180 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
1182 {N_("Locking Options"), P_SEP, P_SEPARATOR},
1184 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1185 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1186 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1187 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1188 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1189 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1191 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1192 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1193 {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1194 {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1195 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1196 {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1197 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1199 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
1201 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
1202 {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
1203 {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
1204 {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
1205 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
1206 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
1207 {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE},
1208 {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1209 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
1210 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
1211 {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1212 {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
1213 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
1215 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
1216 {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
1217 {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
1218 {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
1220 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
1221 {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1223 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1224 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1225 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1226 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
1227 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
1228 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
1230 {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
1231 {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
1232 {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
1235 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1236 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1237 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
1238 {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED},
1239 {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED},
1240 {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
1241 {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
1242 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
1243 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
1244 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
1245 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
1246 {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
1247 {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1248 {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1249 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
1250 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
1251 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1253 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1254 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1255 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1256 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
1258 {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1259 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1260 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1261 {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1262 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1263 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1264 {"registry shares", P_BOOL, P_GLOBAL, &Globals.bRegistryShares, NULL, NULL, FLAG_ADVANCED},
1265 {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
1266 {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
1267 {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED},
1268 {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
1269 {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED},
1270 {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED},
1271 {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
1272 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1273 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1274 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1275 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1276 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1277 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1278 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1279 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1280 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1281 {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1282 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1283 {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1285 {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1286 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
1288 {N_("VFS module options"), P_SEP, P_SEPARATOR},
1290 {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1291 {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
1294 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1295 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1296 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
1298 {N_("Winbind options"), P_SEP, P_SEPARATOR},
1300 {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
1301 {"idmap domains", P_LIST, P_GLOBAL, &Globals.szIdmapDomains, NULL, NULL, FLAG_ADVANCED},
1302 {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED },
1303 {"idmap alloc backend", P_STRING, P_GLOBAL, &Globals.szIdmapAllocBackend, NULL, NULL, FLAG_ADVANCED},
1304 {"idmap cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapCacheTime, NULL, NULL, FLAG_ADVANCED},
1305 {"idmap negative cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeCacheTime, NULL, NULL, FLAG_ADVANCED},
1306 {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED },
1307 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE },
1308 {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED },
1309 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE },
1310 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
1311 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
1312 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
1313 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
1314 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
1315 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
1316 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
1317 {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
1318 {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
1319 {"winbind expand groups", P_INTEGER, P_GLOBAL, &Globals.winbind_expand_groups, NULL, NULL, FLAG_ADVANCED},
1320 {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED},
1321 {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED},
1322 {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
1323 {"winbind normalize names", P_BOOL, P_GLOBAL, &Globals.bWinbindNormalizeNames, NULL, NULL, FLAG_ADVANCED},
1324 {"winbind rpc only", P_BOOL, P_GLOBAL, &Globals.bWinbindRpcOnly, NULL, NULL, FLAG_ADVANCED},
1326 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1329 /***************************************************************************
1330 Initialise the sDefault parameter structure for the printer values.
1331 ***************************************************************************/
1333 static void init_printer_values(service *pService)
1335 /* choose defaults depending on the type of printing */
1336 switch (pService->iPrinting) {
1341 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1342 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1343 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1348 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1349 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1350 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1351 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1352 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1353 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1354 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1360 /* set the lpq command to contain the destination printer
1361 name only. This is used by cups_queue_get() */
1362 string_set(&pService->szLpqcommand, "%p");
1363 string_set(&pService->szLprmcommand, "");
1364 string_set(&pService->szPrintcommand, "");
1365 string_set(&pService->szLppausecommand, "");
1366 string_set(&pService->szLpresumecommand, "");
1367 string_set(&pService->szQueuepausecommand, "");
1368 string_set(&pService->szQueueresumecommand, "");
1370 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1371 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1372 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
1373 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1374 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1375 string_set(&pService->szQueuepausecommand, "disable '%p'");
1376 string_set(&pService->szQueueresumecommand, "enable '%p'");
1377 #endif /* HAVE_CUPS */
1382 string_set(&pService->szLpqcommand, "lpstat -o%p");
1383 string_set(&pService->szLprmcommand, "cancel %p-%j");
1384 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1385 string_set(&pService->szQueuepausecommand, "disable %p");
1386 string_set(&pService->szQueueresumecommand, "enable %p");
1388 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1389 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1394 string_set(&pService->szLpqcommand, "lpq -P%p");
1395 string_set(&pService->szLprmcommand, "lprm -P%p %j");
1396 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1402 string_set(&pService->szPrintcommand, "vlp print %p %s");
1403 string_set(&pService->szLpqcommand, "vlp lpq %p");
1404 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1405 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1406 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1407 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1408 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1410 #endif /* DEVELOPER */
1415 /***************************************************************************
1416 Initialise the global parameter structure.
1417 ***************************************************************************/
1419 static void init_globals(bool first_time_only)
1421 static bool done_init = False;
1424 /* If requested to initialize only once and we've already done it... */
1425 if (first_time_only && done_init) {
1426 /* ... then we have nothing more to do */
1433 /* The logfile can be set before this is invoked. Free it if so. */
1434 if (Globals.szLogFile != NULL) {
1435 string_free(&Globals.szLogFile);
1436 Globals.szLogFile = NULL;
1439 memset((void *)&Globals, '\0', sizeof(Globals));
1441 for (i = 0; parm_table[i].label; i++)
1442 if ((parm_table[i].type == P_STRING ||
1443 parm_table[i].type == P_USTRING) &&
1445 string_set((char **)parm_table[i].ptr, "");
1447 string_set(&sDefault.fstype, FSTYPE_STRING);
1448 string_set(&sDefault.szPrintjobUsername, "%U");
1450 init_printer_values(&sDefault);
1456 DEBUG(3, ("Initialising global parameters\n"));
1458 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1459 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1461 /* use the new 'hash2' method by default, with a prefix of 1 */
1462 string_set(&Globals.szManglingMethod, "hash2");
1463 Globals.mangle_prefix = 1;
1465 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1467 /* using UTF8 by default allows us to support all chars */
1468 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1470 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1471 /* If the system supports nl_langinfo(), try to grab the value
1472 from the user's locale */
1473 string_set(&Globals.display_charset, "LOCALE");
1475 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1478 /* Use codepage 850 as a default for the dos character set */
1479 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1482 * Allow the default PASSWD_CHAT to be overridden in local.h.
1484 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1486 set_global_myname(myhostname());
1487 string_set(&Globals.szNetbiosName,global_myname());
1489 set_global_myworkgroup(WORKGROUP);
1490 string_set(&Globals.szWorkgroup, lp_workgroup());
1492 string_set(&Globals.szPasswdProgram, "");
1493 string_set(&Globals.szPidDir, dyn_PIDDIR);
1494 string_set(&Globals.szLockDir, dyn_LOCKDIR);
1495 string_set(&Globals.szSocketAddress, "0.0.0.0");
1496 pstrcpy(s, "Samba ");
1497 pstrcat(s, SAMBA_VERSION_STRING);
1498 string_set(&Globals.szServerString, s);
1499 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1500 DEFAULT_MINOR_VERSION);
1501 string_set(&Globals.szAnnounceVersion, s);
1503 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1506 pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1508 string_set(&Globals.szLogonDrive, "");
1509 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1510 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1511 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1513 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1514 string_set(&Globals.szPasswordServer, "*");
1516 Globals.AlgorithmicRidBase = BASE_RID;
1518 Globals.bLoadPrinters = True;
1519 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
1521 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1522 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1523 Globals.max_xmit = 0x4104;
1524 Globals.max_mux = 50; /* This is *needed* for profile support. */
1525 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
1526 Globals.bDisableSpoolss = False;
1527 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1528 Globals.pwordlevel = 0;
1529 Globals.unamelevel = 0;
1530 Globals.deadtime = 0;
1531 Globals.bLargeReadwrite = True;
1532 Globals.max_log_size = 5000;
1533 Globals.max_open_files = MAX_OPEN_FILES;
1534 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
1535 Globals.maxprotocol = PROTOCOL_NT1;
1536 Globals.minprotocol = PROTOCOL_CORE;
1537 Globals.security = SEC_USER;
1538 Globals.paranoid_server_security = True;
1539 Globals.bEncryptPasswords = True;
1540 Globals.bUpdateEncrypt = False;
1541 Globals.clientSchannel = Auto;
1542 Globals.serverSchannel = Auto;
1543 Globals.bReadRaw = True;
1544 Globals.bWriteRaw = True;
1545 Globals.bNullPasswords = False;
1546 Globals.bObeyPamRestrictions = False;
1548 Globals.bSyslogOnly = False;
1549 Globals.bTimestampLogs = True;
1550 string_set(&Globals.szLogLevel, "0");
1551 Globals.bDebugPrefixTimestamp = False;
1552 Globals.bDebugHiresTimestamp = False;
1553 Globals.bDebugPid = False;
1554 Globals.bDebugUid = False;
1555 Globals.bDebugClass = False;
1556 Globals.bEnableCoreFiles = True;
1557 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1558 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1559 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1560 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1561 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1562 Globals.lm_interval = 60;
1563 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1564 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1565 Globals.bNISHomeMap = False;
1566 #ifdef WITH_NISPLUS_HOME
1567 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1569 string_set(&Globals.szNISHomeMapName, "auto.home");
1572 Globals.bTimeServer = False;
1573 Globals.bBindInterfacesOnly = False;
1574 Globals.bUnixPasswdSync = False;
1575 Globals.bPamPasswordChange = False;
1576 Globals.bPasswdChatDebug = False;
1577 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1578 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
1579 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1580 Globals.bStatCache = True; /* use stat cache by default */
1581 Globals.iMaxStatCacheSize = 1024; /* one Meg by default. */
1582 Globals.restrict_anonymous = 0;
1583 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
1584 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
1585 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
1586 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
1587 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1588 /* Note, that we will use NTLM2 session security (which is different), if it is available */
1590 Globals.map_to_guest = 0; /* By Default, "Never" */
1591 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
1592 Globals.enhanced_browsing = true;
1593 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
1594 #ifdef MMAP_BLACKLIST
1595 Globals.bUseMmap = False;
1597 Globals.bUseMmap = True;
1599 Globals.bUnixExtensions = True;
1600 Globals.bResetOnZeroVC = False;
1602 /* hostname lookups can be very expensive and are broken on
1603 a large number of sites (tridge) */
1604 Globals.bHostnameLookups = False;
1606 string_set(&Globals.szPassdbBackend, "smbpasswd");
1607 string_set(&Globals.szLdapSuffix, "");
1608 string_set(&Globals.szLdapMachineSuffix, "");
1609 string_set(&Globals.szLdapUserSuffix, "");
1610 string_set(&Globals.szLdapGroupSuffix, "");
1611 string_set(&Globals.szLdapIdmapSuffix, "");
1613 string_set(&Globals.szLdapAdminDn, "");
1614 Globals.ldap_ssl = LDAP_SSL_ON;
1615 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1616 Globals.ldap_delete_dn = False;
1617 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1618 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1619 Globals.ldap_page_size = LDAP_PAGE_SIZE;
1621 /* This is what we tell the afs client. in reality we set the token
1622 * to never expire, though, when this runs out the afs client will
1623 * forget the token. Set to 0 to get NEVERDATE.*/
1624 Globals.iAfsTokenLifetime = 604800;
1626 /* these parameters are set to defaults that are more appropriate
1627 for the increasing samba install base:
1629 as a member of the workgroup, that will possibly become a
1630 _local_ master browser (lm = True). this is opposed to a forced
1631 local master browser startup (pm = True).
1633 doesn't provide WINS server service by default (wsupp = False),
1634 and doesn't provide domain master browser services by default, either.
1638 Globals.bMsAddPrinterWizard = True;
1639 Globals.os_level = 20;
1640 Globals.bLocalMaster = True;
1641 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
1642 Globals.bDomainLogons = False;
1643 Globals.bBrowseList = True;
1644 Globals.bWINSsupport = False;
1645 Globals.bWINSproxy = False;
1647 Globals.bDNSproxy = True;
1649 /* this just means to use them if they exist */
1650 Globals.bKernelOplocks = True;
1652 Globals.bAllowTrustedDomains = True;
1654 string_set(&Globals.szTemplateShell, "/bin/false");
1655 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1656 string_set(&Globals.szWinbindSeparator, "\\");
1658 string_set(&Globals.szCupsServer, "");
1659 string_set(&Globals.szIPrintServer, "");
1661 string_set(&Globals.ctdbdSocket, "");
1662 Globals.szClusterAddresses = NULL;
1663 Globals.clustering = False;
1665 Globals.winbind_cache_time = 300; /* 5 minutes */
1666 Globals.bWinbindEnumUsers = False;
1667 Globals.bWinbindEnumGroups = False;
1668 Globals.bWinbindUseDefaultDomain = False;
1669 Globals.bWinbindTrustedDomainsOnly = False;
1670 Globals.bWinbindNestedGroups = True;
1671 Globals.winbind_expand_groups = 1;
1672 Globals.szWinbindNssInfo = str_list_make("template", NULL);
1673 Globals.bWinbindRefreshTickets = False;
1674 Globals.bWinbindOfflineLogon = False;
1676 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
1677 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
1679 Globals.bPassdbExpandExplicit = False;
1681 Globals.name_cache_timeout = 660; /* In seconds */
1683 Globals.bUseSpnego = True;
1684 Globals.bClientUseSpnego = True;
1686 Globals.client_signing = Auto;
1687 Globals.server_signing = False;
1689 Globals.bDeferSharingViolations = True;
1690 string_set(&Globals.smb_ports, SMB_PORTS);
1692 Globals.bEnablePrivileges = True;
1693 Globals.bHostMSDfs = True;
1694 Globals.bASUSupport = False;
1696 /* User defined shares. */
1697 pstrcpy(s, dyn_LOCKDIR);
1698 pstrcat(s, "/usershares");
1699 string_set(&Globals.szUsersharePath, s);
1700 string_set(&Globals.szUsershareTemplateShare, "");
1701 Globals.iUsershareMaxShares = 0;
1702 /* By default disallow sharing of directories not owned by the sharer. */
1703 Globals.bUsershareOwnerOnly = True;
1704 /* By default disallow guest access to usershares. */
1705 Globals.bUsershareAllowGuests = False;
1707 Globals.iKeepalive = DEFAULT_KEEPALIVE;
1709 /* By default no shares out of the registry */
1710 Globals.bRegistryShares = False;
1713 /*******************************************************************
1714 Convenience routine to grab string parameters into temporary memory
1715 and run standard_sub_basic on them. The buffers can be written to by
1716 callers without affecting the source string.
1717 ********************************************************************/
1719 static char *lp_string(const char *s)
1723 /* The follow debug is useful for tracking down memory problems
1724 especially if you have an inner loop that is calling a lp_*()
1725 function that returns a string. Perhaps this debug should be
1726 present all the time? */
1729 DEBUG(10, ("lp_string(%s)\n", s));
1732 tmpstr = alloc_sub_basic(get_current_username(),
1733 current_user_info.domain, s);
1734 if (trim_char(tmpstr, '\"', '\"')) {
1735 if (strchr(tmpstr,'\"') != NULL) {
1737 tmpstr = alloc_sub_basic(get_current_username(),
1738 current_user_info.domain, s);
1741 ret = talloc_strdup(talloc_tos(), tmpstr);
1748 In this section all the functions that are used to access the
1749 parameters from the rest of the program are defined
1752 #define FN_GLOBAL_STRING(fn_name,ptr) \
1753 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1754 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1755 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1756 #define FN_GLOBAL_LIST(fn_name,ptr) \
1757 const char **fn_name(void) {return(*(const char ***)(ptr));}
1758 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1759 bool fn_name(void) {return(*(bool *)(ptr));}
1760 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1761 char fn_name(void) {return(*(char *)(ptr));}
1762 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1763 int fn_name(void) {return(*(int *)(ptr));}
1765 #define FN_LOCAL_STRING(fn_name,val) \
1766 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1767 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1768 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1769 #define FN_LOCAL_LIST(fn_name,val) \
1770 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1771 #define FN_LOCAL_BOOL(fn_name,val) \
1772 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1773 #define FN_LOCAL_INTEGER(fn_name,val) \
1774 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1776 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1777 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1778 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1779 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1780 #define FN_LOCAL_PARM_STRING(fn_name,val) \
1781 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));}
1782 #define FN_LOCAL_CHAR(fn_name,val) \
1783 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1785 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1786 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1787 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1788 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1789 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1790 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1791 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1792 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1793 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1794 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1795 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1796 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1797 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1798 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1799 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1800 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1801 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1802 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1803 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1804 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1805 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1806 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1807 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1808 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1809 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1810 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1811 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1812 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1813 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1814 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1815 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1816 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1817 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1818 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1819 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1820 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1821 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1822 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1823 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1824 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1825 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1826 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1827 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1828 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1829 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1830 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1831 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1832 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1833 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1834 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1835 * lp_passdb_backend() should be replace by the this macro again after
1838 const char *lp_passdb_backend(void)
1840 char *delim, *quote;
1842 delim = strchr( Globals.szPassdbBackend, ' ');
1843 /* no space at all */
1844 if (delim == NULL) {
1848 quote = strchr(Globals.szPassdbBackend, '"');
1849 /* no quote char or non in the first part */
1850 if (quote == NULL || quote > delim) {
1855 quote = strchr(quote+1, '"');
1856 if (quote == NULL) {
1857 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
1859 } else if (*(quote+1) == '\0') {
1860 /* space, fitting quote char, and one backend only */
1863 /* terminate string after the fitting quote char */
1868 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
1869 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
1870 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
1871 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
1874 return Globals.szPassdbBackend;
1876 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1877 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1878 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1879 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1880 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1882 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1883 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1884 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1885 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1886 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1887 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1889 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1891 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1892 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1893 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1895 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1897 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1898 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1899 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1900 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1901 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
1902 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1903 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1904 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1905 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1906 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1907 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
1908 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1909 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1910 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
1911 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
1913 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
1914 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
1915 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
1916 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
1917 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
1918 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
1919 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1921 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1922 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1923 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1924 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1925 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1926 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1927 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1928 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1929 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1930 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1931 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1932 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1933 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1934 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1936 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1938 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
1939 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1940 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1941 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1942 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1943 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1944 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1945 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1946 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1947 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1948 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1949 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1950 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1951 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1952 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1953 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1954 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1955 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1956 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1957 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1958 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1959 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1960 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1961 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1962 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
1963 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1964 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1965 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1966 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
1967 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
1968 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1969 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1970 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1971 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1972 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1973 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1974 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1975 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1976 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1977 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1978 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1979 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1980 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1981 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1982 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1983 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1984 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1985 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1986 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1987 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1988 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1989 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1990 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1991 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1992 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1993 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1994 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1995 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
1996 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
1997 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
1998 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
1999 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
2000 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
2001 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
2002 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
2003 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
2004 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
2005 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
2006 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
2007 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
2008 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
2009 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
2010 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
2011 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
2012 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
2013 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
2014 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
2015 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
2016 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
2017 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
2018 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
2019 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
2020 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
2021 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
2022 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
2023 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
2024 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
2025 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
2026 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
2027 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
2028 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
2029 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
2030 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
2032 FN_LOCAL_STRING(lp_preexec, szPreExec)
2033 FN_LOCAL_STRING(lp_postexec, szPostExec)
2034 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
2035 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
2036 FN_LOCAL_STRING(lp_servicename, szService)
2037 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
2038 FN_LOCAL_STRING(lp_pathname, szPath)
2039 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
2040 FN_LOCAL_STRING(lp_username, szUsername)
2041 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
2042 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
2043 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
2044 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
2045 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
2046 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
2047 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
2048 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
2049 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
2050 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering);
2051 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
2052 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
2053 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
2054 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
2055 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
2056 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
2057 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
2058 static FN_LOCAL_STRING(_lp_printername, szPrintername)
2059 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
2060 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
2061 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
2062 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
2063 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
2064 FN_LOCAL_STRING(lp_comment, comment)
2065 FN_LOCAL_STRING(lp_force_user, force_user)
2066 FN_LOCAL_STRING(lp_force_group, force_group)
2067 FN_LOCAL_LIST(lp_readlist, readlist)
2068 FN_LOCAL_LIST(lp_writelist, writelist)
2069 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
2070 FN_LOCAL_STRING(lp_fstype, fstype)
2071 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
2072 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
2073 static FN_LOCAL_STRING(lp_volume, volume)
2074 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
2075 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
2076 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
2077 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
2078 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
2079 FN_LOCAL_STRING(lp_dfree_command, szDfree)
2080 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
2081 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
2082 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
2083 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
2084 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
2085 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
2086 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
2087 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2088 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2089 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2090 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2091 FN_LOCAL_BOOL(lp_readonly, bRead_only)
2092 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2093 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2094 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2095 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2096 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2097 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2098 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2099 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2100 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
2101 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
2102 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
2103 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2104 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2105 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2106 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2107 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
2108 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2109 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2110 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2111 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2112 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2113 FN_LOCAL_BOOL(lp_map_system, bMap_system)
2114 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2115 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2116 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2117 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2118 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2119 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2120 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2121 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2122 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2123 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2124 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2125 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2126 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2127 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2128 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2129 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2130 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2131 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2132 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2133 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2134 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2135 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2136 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2137 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2138 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2139 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2140 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2141 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2142 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2143 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2144 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2145 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2146 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2147 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2148 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2149 FN_LOCAL_INTEGER(lp_printing, iPrinting)
2150 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2151 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2152 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2153 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2154 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2155 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2156 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2157 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2158 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2159 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2160 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
2161 FN_LOCAL_CHAR(lp_magicchar, magic_char)
2162 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2163 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2164 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2165 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2166 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2167 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2168 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
2170 /* local prototypes */
2172 static int map_parameter(const char *pszParmName);
2173 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
2174 static bool set_boolean(bool *pb, const char *pszParmValue);
2175 static const char *get_boolean(bool bool_value);
2176 static int getservicebyname(const char *pszServiceName,
2177 service * pserviceDest);
2178 static void copy_service(service * pserviceDest,
2179 service * pserviceSource, bool *pcopymapDest);
2180 static bool do_parameter(const char *pszParmName, const char *pszParmValue);
2181 static bool do_section(const char *pszSectionName);
2182 static void init_copymap(service * pservice);
2183 static bool hash_a_service(const char *name, int number);
2184 static void free_service_byindex(int iService);
2185 static char * canonicalize_servicename(const char *name);
2186 static void show_parameter(int parmIndex);
2187 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
2189 /* This is a helper function for parametrical options support. */
2190 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2191 /* Actual parametrical functions are quite simple */
2192 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2194 bool global_section = False;
2196 param_opt_struct *data;
2198 if (snum >= iNumServices) return NULL;
2201 data = Globals.param_opt;
2202 global_section = True;
2204 data = ServicePtrs[snum]->param_opt;
2207 asprintf(¶m_key, "%s:%s", type, option);
2209 DEBUG(0,("asprintf failed!\n"));
2214 if (strcmp(data->key, param_key) == 0) {
2215 string_free(¶m_key);
2221 if (!global_section) {
2222 /* Try to fetch the same option but from globals */
2223 /* but only if we are not already working with Globals */
2224 data = Globals.param_opt;
2226 if (strcmp(data->key, param_key) == 0) {
2227 string_free(¶m_key);
2234 string_free(¶m_key);
2240 #define MISSING_PARAMETER(name) \
2241 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2243 /*******************************************************************
2244 convenience routine to return int parameters.
2245 ********************************************************************/
2246 static int lp_int(const char *s)
2250 MISSING_PARAMETER(lp_int);
2254 return (int)strtol(s, NULL, 0);
2257 /*******************************************************************
2258 convenience routine to return unsigned long parameters.
2259 ********************************************************************/
2260 static unsigned long lp_ulong(const char *s)
2264 MISSING_PARAMETER(lp_ulong);
2268 return strtoul(s, NULL, 0);
2271 /*******************************************************************
2272 convenience routine to return boolean parameters.
2273 ********************************************************************/
2274 static bool lp_bool(const char *s)
2279 MISSING_PARAMETER(lp_bool);
2283 if (!set_boolean(&ret,s)) {
2284 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2291 /*******************************************************************
2292 convenience routine to return enum parameters.
2293 ********************************************************************/
2294 static int lp_enum(const char *s,const struct enum_list *_enum)
2298 if (!s || !*s || !_enum) {
2299 MISSING_PARAMETER(lp_enum);
2303 for (i=0; _enum[i].name; i++) {
2304 if (strequal(_enum[i].name,s))
2305 return _enum[i].value;
2308 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2312 #undef MISSING_PARAMETER
2314 /* DO NOT USE lp_parm_string ANYMORE!!!!
2315 * use lp_parm_const_string or lp_parm_talloc_string
2317 * lp_parm_string is only used to let old modules find this symbol
2319 #undef lp_parm_string
2320 char *lp_parm_string(const char *servicename, const char *type, const char *option);
2321 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2323 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2326 /* Return parametric option from a given service. Type is a part of option before ':' */
2327 /* Parametric option has following syntax: 'Type: option = value' */
2328 /* the returned value is talloced on the talloc_tos() */
2329 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2331 param_opt_struct *data = get_parametrics(snum, type, option);
2333 if (data == NULL||data->value==NULL) {
2335 return lp_string(def);
2341 return lp_string(data->value);
2344 /* Return parametric option from a given service. Type is a part of option before ':' */
2345 /* Parametric option has following syntax: 'Type: option = value' */
2346 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2348 param_opt_struct *data = get_parametrics(snum, type, option);
2350 if (data == NULL||data->value==NULL)
2356 /* Return parametric option from a given service. Type is a part of option before ':' */
2357 /* Parametric option has following syntax: 'Type: option = value' */
2359 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2361 param_opt_struct *data = get_parametrics(snum, type, option);
2363 if (data == NULL||data->value==NULL)
2364 return (const char **)def;
2366 if (data->list==NULL) {
2367 data->list = str_list_make(data->value, NULL);
2370 return (const char **)data->list;
2373 /* Return parametric option from a given service. Type is a part of option before ':' */
2374 /* Parametric option has following syntax: 'Type: option = value' */
2376 int lp_parm_int(int snum, const char *type, const char *option, int def)
2378 param_opt_struct *data = get_parametrics(snum, type, option);
2380 if (data && data->value && *data->value)
2381 return lp_int(data->value);
2386 /* Return parametric option from a given service. Type is a part of option before ':' */
2387 /* Parametric option has following syntax: 'Type: option = value' */
2389 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2391 param_opt_struct *data = get_parametrics(snum, type, option);
2393 if (data && data->value && *data->value)
2394 return lp_ulong(data->value);
2399 /* Return parametric option from a given service. Type is a part of option before ':' */
2400 /* Parametric option has following syntax: 'Type: option = value' */
2402 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
2404 param_opt_struct *data = get_parametrics(snum, type, option);
2406 if (data && data->value && *data->value)
2407 return lp_bool(data->value);
2412 /* Return parametric option from a given service. Type is a part of option before ':' */
2413 /* Parametric option has following syntax: 'Type: option = value' */
2415 int lp_parm_enum(int snum, const char *type, const char *option,
2416 const struct enum_list *_enum, int def)
2418 param_opt_struct *data = get_parametrics(snum, type, option);
2420 if (data && data->value && *data->value && _enum)
2421 return lp_enum(data->value, _enum);
2427 /***************************************************************************
2428 Initialise a service to the defaults.
2429 ***************************************************************************/
2431 static void init_service(service * pservice)
2433 memset((char *)pservice, '\0', sizeof(service));
2434 copy_service(pservice, &sDefault, NULL);
2437 /***************************************************************************
2438 Free the dynamically allocated parts of a service struct.
2439 ***************************************************************************/
2441 static void free_service(service *pservice)
2444 param_opt_struct *data, *pdata;
2448 if (pservice->szService)
2449 DEBUG(5, ("free_service: Freeing service %s\n",
2450 pservice->szService));
2452 string_free(&pservice->szService);
2453 SAFE_FREE(pservice->copymap);
2455 for (i = 0; parm_table[i].label; i++) {
2456 if ((parm_table[i].type == P_STRING ||
2457 parm_table[i].type == P_USTRING) &&
2458 parm_table[i].p_class == P_LOCAL)
2459 string_free((char **)
2460 (((char *)pservice) +
2461 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2462 else if (parm_table[i].type == P_LIST &&
2463 parm_table[i].p_class == P_LOCAL)
2464 str_list_free((char ***)
2465 (((char *)pservice) +
2466 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2469 data = pservice->param_opt;
2471 DEBUG(5,("Freeing parametrics:\n"));
2473 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2474 string_free(&data->key);
2475 string_free(&data->value);
2476 str_list_free(&data->list);
2482 ZERO_STRUCTP(pservice);
2486 /***************************************************************************
2487 remove a service indexed in the ServicePtrs array from the ServiceHash
2488 and free the dynamically allocated parts
2489 ***************************************************************************/
2491 static void free_service_byindex(int idx)
2493 if ( !LP_SNUM_OK(idx) )
2496 ServicePtrs[idx]->valid = False;
2497 invalid_services[num_invalid_services++] = idx;
2499 /* we have to cleanup the hash record */
2501 if (ServicePtrs[idx]->szService) {
2502 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2504 tdb_delete_bystring(ServiceHash, canon_name );
2507 free_service(ServicePtrs[idx]);
2510 /***************************************************************************
2511 Add a new service to the services array initialising it with the given
2513 ***************************************************************************/
2515 static int add_a_service(const service *pservice, const char *name)
2519 int num_to_alloc = iNumServices + 1;
2520 param_opt_struct *data, *pdata;
2522 tservice = *pservice;
2524 /* it might already exist */
2526 i = getservicebyname(name, NULL);
2528 /* Clean all parametric options for service */
2529 /* They will be added during parsing again */
2530 data = ServicePtrs[i]->param_opt;
2532 string_free(&data->key);
2533 string_free(&data->value);
2534 str_list_free(&data->list);
2539 ServicePtrs[i]->param_opt = NULL;
2544 /* find an invalid one */
2546 if (num_invalid_services > 0) {
2547 i = invalid_services[--num_invalid_services];
2550 /* if not, then create one */
2551 if (i == iNumServices) {
2555 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2557 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2561 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2562 if (!ServicePtrs[iNumServices]) {
2563 DEBUG(0,("add_a_service: out of memory!\n"));
2568 /* enlarge invalid_services here for now... */
2569 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2571 if (tinvalid == NULL) {
2572 DEBUG(0,("add_a_service: failed to enlarge "
2573 "invalid_services!\n"));
2576 invalid_services = tinvalid;
2578 free_service_byindex(i);
2581 ServicePtrs[i]->valid = True;
2583 init_service(ServicePtrs[i]);
2584 copy_service(ServicePtrs[i], &tservice, NULL);
2586 string_set(&ServicePtrs[i]->szService, name);
2588 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2589 i, ServicePtrs[i]->szService));
2591 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2598 /***************************************************************************
2599 Convert a string to uppercase and remove whitespaces.
2600 ***************************************************************************/
2602 static char *canonicalize_servicename(const char *src)
2604 static fstring canon; /* is fstring large enough? */
2607 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2611 fstrcpy( canon, src );
2612 strlower_m( canon );
2617 /***************************************************************************
2618 Add a name/index pair for the services array to the hash table.
2619 ***************************************************************************/
2621 static bool hash_a_service(const char *name, int idx)
2625 if ( !ServiceHash ) {
2626 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2627 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2628 (O_RDWR|O_CREAT), 0600);
2629 if ( !ServiceHash ) {
2630 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2635 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2638 if ( !(canon_name = canonicalize_servicename( name )) )
2641 tdb_store_int32(ServiceHash, canon_name, idx);
2646 /***************************************************************************
2647 Add a new home service, with the specified home directory, defaults coming
2649 ***************************************************************************/
2651 bool lp_add_home(const char *pszHomename, int iDefaultService,
2652 const char *user, const char *pszHomedir)
2657 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2662 if (!(*(ServicePtrs[iDefaultService]->szPath))
2663 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2664 pstrcpy(newHomedir, pszHomedir);
2665 string_set(&ServicePtrs[i]->szPath, newHomedir);
2668 if (!(*(ServicePtrs[i]->comment))) {
2670 slprintf(comment, sizeof(comment) - 1,
2671 "Home directory of %s", user);
2672 string_set(&ServicePtrs[i]->comment, comment);
2675 /* set the browseable flag from the global default */
2677 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2679 ServicePtrs[i]->autoloaded = True;
2681 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2682 user, ServicePtrs[i]->szPath ));
2687 /***************************************************************************
2688 Add a new service, based on an old one.
2689 ***************************************************************************/
2691 int lp_add_service(const char *pszService, int iDefaultService)
2693 if (iDefaultService < 0) {
2694 return add_a_service(&sDefault, pszService);
2697 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2700 /***************************************************************************
2701 Add the IPC service.
2702 ***************************************************************************/
2704 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
2707 int i = add_a_service(&sDefault, ipc_name);
2712 slprintf(comment, sizeof(comment) - 1,
2713 "IPC Service (%s)", Globals.szServerString);
2715 string_set(&ServicePtrs[i]->szPath, tmpdir());
2716 string_set(&ServicePtrs[i]->szUsername, "");
2717 string_set(&ServicePtrs[i]->comment, comment);
2718 string_set(&ServicePtrs[i]->fstype, "IPC");
2719 ServicePtrs[i]->iMaxConnections = 0;
2720 ServicePtrs[i]->bAvailable = True;
2721 ServicePtrs[i]->bRead_only = True;
2722 ServicePtrs[i]->bGuest_only = False;
2723 ServicePtrs[i]->bGuest_ok = guest_ok;
2724 ServicePtrs[i]->bPrint_ok = False;
2725 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2727 DEBUG(3, ("adding IPC service\n"));
2732 /***************************************************************************
2733 Add a new printer service, with defaults coming from service iFrom.
2734 ***************************************************************************/
2736 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
2738 const char *comment = "From Printcap";
2739 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2744 /* note that we do NOT default the availability flag to True - */
2745 /* we take it from the default service passed. This allows all */
2746 /* dynamic printers to be disabled by disabling the [printers] */
2747 /* entry (if/when the 'available' keyword is implemented!). */
2749 /* the printer name is set to the service name. */
2750 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2751 string_set(&ServicePtrs[i]->comment, comment);
2753 /* set the browseable flag from the gloabl default */
2754 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2756 /* Printers cannot be read_only. */
2757 ServicePtrs[i]->bRead_only = False;
2758 /* No share modes on printer services. */
2759 ServicePtrs[i]->bShareModes = False;
2760 /* No oplocks on printer services. */
2761 ServicePtrs[i]->bOpLocks = False;
2762 /* Printer services must be printable. */
2763 ServicePtrs[i]->bPrint_ok = True;
2765 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2771 /***************************************************************************
2772 Check whether the given parameter name is valid.
2773 Parametric options (names containing a colon) are considered valid.
2774 ***************************************************************************/
2776 bool lp_parameter_is_valid(const char *pszParmName)
2778 return ((map_parameter(pszParmName) != -1) ||
2779 (strchr(pszParmName, ':') != NULL));
2782 /***************************************************************************
2783 Check whether the given name is the name of a global parameter.
2784 Returns True for strings belonging to parameters of class
2785 P_GLOBAL, False for all other strings, also for parametric options
2786 and strings not belonging to any option.
2787 ***************************************************************************/
2789 bool lp_parameter_is_global(const char *pszParmName)
2791 int num = map_parameter(pszParmName);
2794 return (parm_table[num].p_class == P_GLOBAL);
2800 /**************************************************************************
2801 Check whether the given name is the canonical name of a parameter.
2802 Returns False if it is not a valid parameter Name.
2803 For parametric options, True is returned.
2804 **************************************************************************/
2806 bool lp_parameter_is_canonical(const char *parm_name)
2808 if (!lp_parameter_is_valid(parm_name)) {
2812 return (map_parameter(parm_name) ==
2813 map_parameter_canonical(parm_name, NULL));
2816 /**************************************************************************
2817 Determine the canonical name for a parameter.
2818 Indicate when it is an inverse (boolean) synonym instead of a
2820 **************************************************************************/
2822 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
2827 if (!lp_parameter_is_valid(parm_name)) {
2832 num = map_parameter_canonical(parm_name, inverse);
2834 /* parametric option */
2835 *canon_parm = parm_name;
2837 *canon_parm = parm_table[num].label;
2844 /**************************************************************************
2845 Determine the canonical name for a parameter.
2846 Turn the value given into the inverse boolean expression when
2847 the synonym is an invers boolean synonym.
2849 Return True if parm_name is a valid parameter name and
2850 in case it is an invers boolean synonym, if the val string could
2851 successfully be converted to the reverse bool.
2852 Return false in all other cases.
2853 **************************************************************************/
2855 bool lp_canonicalize_parameter_with_value(const char *parm_name,
2857 const char **canon_parm,
2858 const char **canon_val)
2863 if (!lp_parameter_is_valid(parm_name)) {
2869 num = map_parameter_canonical(parm_name, &inverse);
2871 /* parametric option */
2872 *canon_parm = parm_name;
2875 *canon_parm = parm_table[num].label;
2877 if (!lp_invert_boolean(val, canon_val)) {
2889 /***************************************************************************
2890 Map a parameter's string representation to something we can use.
2891 Returns False if the parameter string is not recognised, else TRUE.
2892 ***************************************************************************/
2894 static int map_parameter(const char *pszParmName)
2898 if (*pszParmName == '-')
2901 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2902 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2905 /* Warn only if it isn't parametric option */
2906 if (strchr(pszParmName, ':') == NULL)
2907 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2908 /* We do return 'fail' for parametric options as well because they are
2909 stored in different storage
2914 /***************************************************************************
2915 Map a parameter's string representation to the index of the canonical
2916 form of the parameter (it might be a synonym).
2917 Returns -1 if the parameter string is not recognised.
2918 ***************************************************************************/
2920 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
2922 int parm_num, canon_num;
2923 bool loc_inverse = False;
2925 parm_num = map_parameter(pszParmName);
2926 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
2927 /* invalid, parametric or no canidate for synonyms ... */
2931 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
2932 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
2933 parm_num = canon_num;
2939 if (inverse != NULL) {
2940 *inverse = loc_inverse;
2945 /***************************************************************************
2946 return true if parameter number parm1 is a synonym of parameter
2947 number parm2 (parm2 being the principal name).
2948 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
2950 ***************************************************************************/
2952 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
2954 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
2955 (parm_table[parm1].flags & FLAG_HIDE) &&
2956 !(parm_table[parm2].flags & FLAG_HIDE))
2958 if (inverse != NULL) {
2959 if ((parm_table[parm1].type == P_BOOLREV) &&
2960 (parm_table[parm2].type == P_BOOL))
2972 /***************************************************************************
2973 Show one parameter's name, type, [values,] and flags.
2974 (helper functions for show_parameter_list)
2975 ***************************************************************************/
2977 static void show_parameter(int parmIndex)
2979 int enumIndex, flagIndex;
2984 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2985 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2986 "P_UGSTRING", "P_ENUM", "P_SEP"};
2987 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2988 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2989 FLAG_HIDE, FLAG_DOS_STRING};
2990 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2991 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2992 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2994 printf("%s=%s", parm_table[parmIndex].label,
2995 type[parm_table[parmIndex].type]);
2996 if (parm_table[parmIndex].type == P_ENUM) {
2999 parm_table[parmIndex].enum_list[enumIndex].name;
3003 enumIndex ? "|" : "",
3004 parm_table[parmIndex].enum_list[enumIndex].name);
3009 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
3010 if (parm_table[parmIndex].flags & flags[flagIndex]) {
3013 flag_names[flagIndex]);
3018 /* output synonyms */
3020 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
3021 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
3022 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
3023 parm_table[parmIndex2].label);
3024 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
3026 printf(" (synonyms: ");
3031 printf("%s%s", parm_table[parmIndex2].label,
3032 inverse ? "[i]" : "");
3042 /***************************************************************************
3043 Show all parameter's name, type, [values,] and flags.
3044 ***************************************************************************/
3046 void show_parameter_list(void)
3048 int classIndex, parmIndex;
3049 const char *section_names[] = { "local", "global", NULL};
3051 for (classIndex=0; section_names[classIndex]; classIndex++) {
3052 printf("[%s]\n", section_names[classIndex]);
3053 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
3054 if (parm_table[parmIndex].p_class == classIndex) {
3055 show_parameter(parmIndex);
3061 /***************************************************************************
3062 Set a boolean variable from the text value stored in the passed string.
3063 Returns True in success, False if the passed string does not correctly
3064 represent a boolean.
3065 ***************************************************************************/
3067 static bool set_boolean(bool *pb, const char *pszParmValue)
3074 if (strwicmp(pszParmValue, "yes") == 0 ||
3075 strwicmp(pszParmValue, "true") == 0 ||
3076 strwicmp(pszParmValue, "1") == 0)
3078 else if (strwicmp(pszParmValue, "no") == 0 ||
3079 strwicmp(pszParmValue, "False") == 0 ||
3080 strwicmp(pszParmValue, "0") == 0)
3084 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
3089 if ((pb != NULL) && (bRetval != False)) {
3097 /***************************************************************************
3098 Check if a given string correctly represents a boolean value.
3099 ***************************************************************************/
3101 bool lp_string_is_valid_boolean(const char *parm_value)
3103 return set_boolean(NULL, parm_value);
3106 /***************************************************************************
3107 Get the standard string representation of a boolean value ("yes" or "no")
3108 ***************************************************************************/
3110 static const char *get_boolean(bool bool_value)
3112 static const char *yes_str = "yes";
3113 static const char *no_str = "no";
3115 return (bool_value ? yes_str : no_str);
3118 /***************************************************************************
3119 Provide the string of the negated boolean value associated to the boolean
3120 given as a string. Returns False if the passed string does not correctly
3121 represent a boolean.
3122 ***************************************************************************/
3124 bool lp_invert_boolean(const char *str, const char **inverse_str)
3128 if (!set_boolean(&val, str)) {
3132 *inverse_str = get_boolean(!val);
3136 /***************************************************************************
3137 Provide the canonical string representation of a boolean value given
3138 as a string. Return True on success, False if the string given does
3139 not correctly represent a boolean.
3140 ***************************************************************************/
3142 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
3146 if (!set_boolean(&val, str)) {
3150 *canon_str = get_boolean(val);
3154 /***************************************************************************
3155 Find a service by name. Otherwise works like get_service.
3156 ***************************************************************************/
3158 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
3163 if (ServiceHash != NULL) {
3164 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
3167 iService = tdb_fetch_int32(ServiceHash, canon_name );
3169 if (LP_SNUM_OK(iService)) {
3170 if (pserviceDest != NULL) {
3171 copy_service(pserviceDest, ServicePtrs[iService], NULL);
3181 /***************************************************************************
3182 Copy a service structure to another.
3183 If pcopymapDest is NULL then copy all fields
3184 ***************************************************************************/
3186 static void copy_service(service * pserviceDest, service * pserviceSource, bool *pcopymapDest)
3189 bool bcopyall = (pcopymapDest == NULL);
3190 param_opt_struct *data, *pdata, *paramo;
3193 for (i = 0; parm_table[i].label; i++)
3194 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
3195 (bcopyall || pcopymapDest[i])) {
3196 void *def_ptr = parm_table[i].ptr;
3198 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
3201 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
3204 switch (parm_table[i].type) {
3207 *(bool *)dest_ptr = *(bool *)src_ptr;
3213 *(int *)dest_ptr = *(int *)src_ptr;
3217 *(char *)dest_ptr = *(char *)src_ptr;
3221 string_set((char **)dest_ptr,
3226 string_set((char **)dest_ptr,
3228 strupper_m(*(char **)dest_ptr);
3231 str_list_free((char ***)dest_ptr);
3232 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
3240 init_copymap(pserviceDest);
3241 if (pserviceSource->copymap)
3242 memcpy((void *)pserviceDest->copymap,
3243 (void *)pserviceSource->copymap,
3244 sizeof(bool) * NUMPARAMETERS);
3247 data = pserviceSource->param_opt;
3250 pdata = pserviceDest->param_opt;
3251 /* Traverse destination */
3253 /* If we already have same option, override it */
3254 if (strcmp(pdata->key, data->key) == 0) {
3255 string_free(&pdata->value);
3256 str_list_free(&data->list);
3257 pdata->value = SMB_STRDUP(data->value);
3261 pdata = pdata->next;
3264 paramo = SMB_XMALLOC_P(param_opt_struct);
3265 paramo->key = SMB_STRDUP(data->key);
3266 paramo->value = SMB_STRDUP(data->value);
3267 paramo->list = NULL;
3268 DLIST_ADD(pserviceDest->param_opt, paramo);
3274 /***************************************************************************
3275 Check a service for consistency. Return False if the service is in any way
3276 incomplete or faulty, else True.
3277 ***************************************************************************/
3279 bool service_ok(int iService)
3284 if (ServicePtrs[iService]->szService[0] == '\0') {
3285 DEBUG(0, ("The following message indicates an internal error:\n"));
3286 DEBUG(0, ("No service name in service entry.\n"));
3290 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
3291 /* I can't see why you'd want a non-printable printer service... */
3292 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
3293 if (!ServicePtrs[iService]->bPrint_ok) {
3294 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
3295 ServicePtrs[iService]->szService));
3296 ServicePtrs[iService]->bPrint_ok = True;
3298 /* [printers] service must also be non-browsable. */
3299 if (ServicePtrs[iService]->bBrowseable)
3300 ServicePtrs[iService]->bBrowseable = False;
3303 if (ServicePtrs[iService]->szPath[0] == '\0' &&
3304 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
3305 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
3307 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
3308 ServicePtrs[iService]->szService));
3309 ServicePtrs[iService]->bAvailable = False;
3312 /* If a service is flagged unavailable, log the fact at level 1. */
3313 if (!ServicePtrs[iService]->bAvailable)
3314 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
3315 ServicePtrs[iService]->szService));
3321 * lp_regdb_open - regdb helper function
3323 * this should be considered an interim solution that becomes
3324 * superfluous once the registry code has been rewritten
3325 * do allow use of the tdb portion of the registry alone.
3327 * in the meanwhile this provides a lean access
3328 * to the registry globals.
3331 static struct tdb_wrap *lp_regdb_open(void)
3333 struct tdb_wrap *reg_tdb = NULL;
3334 const char *vstring = "INFO/version";
3338 reg_tdb = tdb_wrap_open(NULL, lock_path("registry.tdb"), 0,
3339 REG_TDB_FLAGS, O_RDWR, 0600);
3342 DEBUG(1, ("lp_regdb_open: failed to open %s: %s\n",
3343 lock_path("registry.tdb"), strerror(errno)));
3347 DEBUG(10, ("lp_regdb_open: reg tdb opened.\n"));
3350 vers_id = tdb_fetch_int32(reg_tdb->tdb, vstring);
3351 if (vers_id != REGVER_V1) {
3352 DEBUG(10, ("lp_regdb_open: INFO: registry tdb %s has wrong "
3353 "INFO/version (got %d, expected %d)\n",
3354 lock_path("registry.tdb"), vers_id, REGVER_V1));
3355 /* this is apparently not implemented in the tdb */
3363 * process_registry_globals
3365 * this is the interim version of process_registry globals
3367 * until we can do it as we would like using the api and only
3368 * using the tdb portion of the registry (see below),
3369 * this just provides the needed functionality of regdb_fetch_values
3370 * and regdb_unpack_values, circumventing any fancy stuff, to
3371 * give us access to the registry globals.
3373 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
3376 struct tdb_wrap *reg_tdb = NULL;
3380 /* vars for the tdb unpack loop */
3387 uint32 num_values = 0;
3391 struct registry_value *value = NULL;
3393 include_registry_globals = True;
3397 reg_tdb = lp_regdb_open();
3399 DEBUG(1, ("Error opening the registry!\n"));
3403 /* reg_tdb is from now on used as talloc ctx.
3404 * freeing it closes the tdb (if refcount is 0) */
3406 keystr = talloc_asprintf(reg_tdb,"%s/%s/%s", REG_VALUE_PREFIX,
3407 KEY_SMBCONF, GLOBAL_NAME);
3408 normalize_dbkey(keystr);
3410 DEBUG(10, ("process_registry_globals: fetching key '%s'\n",
3413 data = tdb_fetch_bystring(reg_tdb->tdb, keystr);
3420 buflen = data.dsize;
3422 /* unpack number of values */
3423 len = tdb_unpack(buf, buflen, "d", &num_values);
3424 DEBUG(10, ("process_registry_globals: got %d values from tdb\n",
3427 /* unpack the values */
3428 for (i=0; i < num_values; i++) {
3432 len += tdb_unpack(buf+len, buflen-len, "fdB",
3437 if (registry_smbconf_valname_forbidden(valname)) {
3438 DEBUG(10, ("process_registry_globals: Ignoring "
3439 "parameter '%s' in registry.\n", valname));
3442 DEBUG(10, ("process_registry_globals: got value '%s'\n",
3444 if (size && data_p) {
3445 err = registry_pull_value(reg_tdb,
3452 if (!W_ERROR_IS_OK(err)) {
3457 valstr = talloc_asprintf(reg_tdb, "%d",
3459 pfunc(valname, valstr);
3462 pfunc(valname, value->v.sz.str);
3465 /* ignore other types */
3471 ret = pfunc("registry shares", "yes");
3472 regdb_last_seqnum = tdb_get_seqnum(reg_tdb->tdb);
3475 TALLOC_FREE(reg_tdb);
3476 SAFE_FREE(data.dptr);
3482 * this is process_registry_globals as it _should_ be (roughly)
3483 * using the reg_api functions...
3486 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
3489 TALLOC_CTX *ctx = NULL;
3490 char *regpath = NULL;
3491 WERROR werr = WERR_OK;
3492 struct registry_key *key = NULL;
3493 struct registry_value *value = NULL;
3494 char *valname = NULL;
3495 char *valstr = NULL;
3497 NT_USER_TOKEN *token;
3499 ctx = talloc_init("process_registry_globals");
3501 smb_panic("Failed to create talloc context!");
3504 include_registry_globals = True;
3506 if (!registry_init_regdb()) {
3507 DEBUG(1, ("Error initializing the registry.\n"));
3511 if (!(token = registry_create_admin_token(ctx))) {
3512 DEBUG(1, ("Error creating admin token\n"));
3516 regpath = talloc_asprintf(ctx,"%s\\%s", KEY_SMBCONF, GLOBAL_NAME);
3517 werr = reg_open_path(ctx, regpath, REG_KEY_READ, token, &key);
3518 if (!W_ERROR_IS_OK(werr)) {
3519 DEBUG(1, ("Registry smbconf global section does not exist.\n"));
3520 DEBUGADD(1, ("Error opening registry path '%s\\%s: %s\n",
3521 KEY_SMBCONF, GLOBAL_NAME, dos_errstr(werr)));
3526 W_ERROR_IS_OK(werr = reg_enumvalue(ctx, key, idx, &valname,
3530 DEBUG(5, ("got global registry parameter '%s'\n", valname));
3531 switch(value->type) {
3533 valstr = talloc_asprintf(ctx, "%d", value->v.dword);
3534 pfunc(valname, valstr);
3535 TALLOC_FREE(valstr);
3538 pfunc(valname, value->v.sz.str);
3541 /* ignore other types */
3545 TALLOC_FREE(valstr);
3548 ret = pfunc("registry shares", "yes");
3550 regdb_last_seqnum = regdb_get_seqnum();
3553 talloc_destroy(ctx);
3558 static struct file_lists {
3559 struct file_lists *next;
3563 } *file_lists = NULL;
3565 /*******************************************************************
3566 Keep a linked list of all config files so we know when one has changed
3567 it's date and needs to be reloaded.
3568 ********************************************************************/
3570 static void add_to_file_list(const char *fname, const char *subfname)
3572 struct file_lists *f = file_lists;
3575 if (f->name && !strcmp(f->name, fname))
3581 f = SMB_MALLOC_P(struct file_lists);
3584 f->next = file_lists;
3585 f->name = SMB_STRDUP(fname);
3590 f->subfname = SMB_STRDUP(subfname);
3596 f->modtime = file_modtime(subfname);
3598 time_t t = file_modtime(subfname);
3604 /*******************************************************************
3605 Check if a config file has changed date.
3606 ********************************************************************/
3608 bool lp_file_list_changed(void)
3610 struct file_lists *f = file_lists;
3611 struct tdb_wrap *reg_tdb = NULL;
3613 DEBUG(6, ("lp_file_list_changed()\n"));
3615 if (include_registry_globals) {
3616 reg_tdb = lp_regdb_open();
3617 if (reg_tdb && (regdb_last_seqnum != tdb_get_seqnum(reg_tdb->tdb)))
3619 DEBUGADD(6, ("regdb seqnum changed: old = %d, new = %d\n",
3620 regdb_last_seqnum, tdb_get_seqnum(reg_tdb->tdb)));
3621 TALLOC_FREE(reg_tdb);
3630 pstrcpy(n2, f->name);
3631 standard_sub_basic( get_current_username(),
3632 current_user_info.domain,
3635 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3636 f->name, n2, ctime(&f->modtime)));
3638 mod_time = file_modtime(n2);
3640 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3642 ("file %s modified: %s\n", n2,
3644 f->modtime = mod_time;
3645 SAFE_FREE(f->subfname);
3646 f->subfname = SMB_STRDUP(n2);
3654 /***************************************************************************
3655 Run standard_sub_basic on netbios name... needed because global_myname
3656 is not accessed through any lp_ macro.
3657 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3658 ***************************************************************************/
3660 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3663 pstring netbios_name;
3665 pstrcpy(netbios_name, pszParmValue);
3667 standard_sub_basic(get_current_username(), current_user_info.domain,
3668 netbios_name, sizeof(netbios_name));
3670 ret = set_global_myname(netbios_name);
3671 string_set(&Globals.szNetbiosName,global_myname());
3673 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3679 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
3681 if (strcmp(*ptr, pszParmValue) != 0) {
3682 string_set(ptr, pszParmValue);
3690 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3694 ret = set_global_myworkgroup(pszParmValue);
3695 string_set(&Globals.szWorkgroup,lp_workgroup());
3700 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3704 ret = set_global_scope(pszParmValue);
3705 string_set(&Globals.szNetbiosScope,global_scope());
3710 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3712 str_list_free(&Globals.szNetbiosAliases);
3713 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3714 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3717 /***************************************************************************
3718 Handle the include operation.
3719 ***************************************************************************/
3721 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
3724 pstrcpy(fname, pszParmValue);
3726 if (strequal(fname, INCLUDE_REGISTRY_NAME)) {
3727 if (bInGlobalSection) {
3728 return process_registry_globals(do_parameter);
3731 DEBUG(1, ("\"include = registry\" only effective "
3732 "in %s section\n", GLOBAL_NAME));
3737 standard_sub_basic(get_current_username(), current_user_info.domain,
3738 fname,sizeof(fname));
3740 add_to_file_list(pszParmValue, fname);
3742 string_set(ptr, fname);
3744 if (file_exist(fname, NULL))
3745 return (pm_process(fname, do_section, do_parameter));
3747 DEBUG(2, ("Can't find include file %s\n", fname));
3752 /***************************************************************************
3753 Handle the interpretation of the copy parameter.
3754 ***************************************************************************/
3756 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
3760 service serviceTemp;
3762 string_set(ptr, pszParmValue);
3764 init_service(&serviceTemp);
3768 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3770 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3771 if (iTemp == iServiceIndex) {
3772 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3774 copy_service(ServicePtrs[iServiceIndex],
3776 ServicePtrs[iServiceIndex]->copymap);
3780 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3784 free_service(&serviceTemp);
3788 /***************************************************************************
3789 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3794 idmap uid = 1000-1999
3797 We only do simple parsing checks here. The strings are parsed into useful
3798 structures in the idmap daemon code.
3800 ***************************************************************************/
3802 /* Some lp_ routines to return idmap [ug]id information */
3804 static uid_t idmap_uid_low, idmap_uid_high;
3805 static gid_t idmap_gid_low, idmap_gid_high;
3807 bool lp_idmap_uid(uid_t *low, uid_t *high)
3809 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3813 *low = idmap_uid_low;
3816 *high = idmap_uid_high;
3821 bool lp_idmap_gid(gid_t *low, gid_t *high)
3823 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3827 *low = idmap_gid_low;
3830 *high = idmap_gid_high;
3835 /* Do some simple checks on "idmap [ug]id" parameter values */
3837 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3841 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3846 string_set(ptr, pszParmValue);
3848 idmap_uid_low = low;
3849 idmap_uid_high = high;
3854 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3858 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3863 string_set(ptr, pszParmValue);
3865 idmap_gid_low = low;
3866 idmap_gid_high = high;
3871 /***************************************************************************
3872 Handle the DEBUG level list.
3873 ***************************************************************************/
3875 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3877 pstring pszParmValue;
3879 pstrcpy(pszParmValue, pszParmValueIn);
3880 string_set(ptr, pszParmValueIn);
3881 return debug_parse_levels( pszParmValue );
3884 /***************************************************************************
3885 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3886 ***************************************************************************/
3888 static const char *append_ldap_suffix( const char *str )
3890 const char *suffix_string;
3893 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
3894 Globals.szLdapSuffix );
3895 if ( !suffix_string ) {
3896 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3900 return suffix_string;
3903 const char *lp_ldap_machine_suffix(void)
3905 if (Globals.szLdapMachineSuffix[0])
3906 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3908 return lp_string(Globals.szLdapSuffix);
3911 const char *lp_ldap_user_suffix(void)
3913 if (Globals.szLdapUserSuffix[0])
3914 return append_ldap_suffix(Globals.szLdapUserSuffix);
3916 return lp_string(Globals.szLdapSuffix);
3919 const char *lp_ldap_group_suffix(void)
3921 if (Globals.szLdapGroupSuffix[0])
3922 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3924 return lp_string(Globals.szLdapSuffix);
3927 const char *lp_ldap_idmap_suffix(void)
3929 if (Globals.szLdapIdmapSuffix[0])
3930 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3932 return lp_string(Globals.szLdapSuffix);
3935 /****************************************************************************
3936 set the value for a P_ENUM
3937 ***************************************************************************/
3939 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3944 for (i = 0; parm->enum_list[i].name; i++) {
3945 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3946 *ptr = parm->enum_list[i].value;
3952 /***************************************************************************
3953 ***************************************************************************/
3955 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
3957 static int parm_num = -1;
3960 if ( parm_num == -1 )
3961 parm_num = map_parameter( "printing" );
3963 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3968 s = ServicePtrs[snum];
3970 init_printer_values( s );
3976 /***************************************************************************
3977 Initialise a copymap.
3978 ***************************************************************************/
3980 static void init_copymap(service * pservice)
3983 SAFE_FREE(pservice->copymap);
3984 pservice->copymap = SMB_MALLOC_ARRAY(bool,NUMPARAMETERS);
3985 if (!pservice->copymap)
3987 ("Couldn't allocate copymap!! (size %d)\n",
3988 (int)NUMPARAMETERS));
3990 for (i = 0; i < NUMPARAMETERS; i++)
3991 pservice->copymap[i] = True;
3994 /***************************************************************************
3995 Return the local pointer to a parameter given the service number and the
3996 pointer into the default structure.
3997 ***************************************************************************/
3999 void *lp_local_ptr(int snum, void *ptr)
4001 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
4004 /***************************************************************************
4005 Process a parameter for a particular service number. If snum < 0
4006 then assume we are in the globals.
4007 ***************************************************************************/
4009 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
4011 int parmnum, i, slen;
4012 void *parm_ptr = NULL; /* where we are going to store the result */
4013 void *def_ptr = NULL;
4016 param_opt_struct *paramo, *data;
4019 parmnum = map_parameter(pszParmName);
4022 if ((sep=strchr(pszParmName, ':')) != NULL) {
4024 ZERO_STRUCT(param_key);
4025 pstr_sprintf(param_key, "%s:", pszParmName);
4026 slen = strlen(param_key);
4027 pstrcat(param_key, sep+1);
4028 trim_char(param_key+slen, ' ', ' ');
4030 data = (snum < 0) ? Globals.param_opt :
4031 ServicePtrs[snum]->param_opt;
4032 /* Traverse destination */
4034 /* If we already have same option, override it */
4035 if (strcmp(data->key, param_key) == 0) {
4036 string_free(&data->value);
4037 str_list_free(&data->list);
4038 data->value = SMB_STRDUP(pszParmValue);
4045 paramo = SMB_XMALLOC_P(param_opt_struct);
4046 paramo->key = SMB_STRDUP(param_key);
4047 paramo->value = SMB_STRDUP(pszParmValue);
4048 paramo->list = NULL;
4050 DLIST_ADD(Globals.param_opt, paramo);
4052 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
4059 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
4063 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
4064 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
4068 def_ptr = parm_table[parmnum].ptr;
4070 /* we might point at a service, the default service or a global */
4074 if (parm_table[parmnum].p_class == P_GLOBAL) {
4076 ("Global parameter %s found in service section!\n",
4081 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
4086 if (!ServicePtrs[snum]->copymap)
4087 init_copymap(ServicePtrs[snum]);
4089 /* this handles the aliases - set the copymap for other entries with
4090 the same data pointer */
4091 for (i = 0; parm_table[i].label; i++)
4092 if (parm_table[i].ptr == parm_table[parmnum].ptr)
4093 ServicePtrs[snum]->copymap[i] = False;
4096 /* if it is a special case then go ahead */
4097 if (parm_table[parmnum].special) {
4098 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
4102 /* now switch on the type of variable it is */
4103 switch (parm_table[parmnum].type)
4106 *(bool *)parm_ptr = lp_bool(pszParmValue);
4110 *(bool *)parm_ptr = !lp_bool(pszParmValue);
4114 *(int *)parm_ptr = lp_int(pszParmValue);
4118 *(char *)parm_ptr = *pszParmValue;
4122 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
4124 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
4129 str_list_free((char ***)parm_ptr);
4130 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
4134 string_set((char **)parm_ptr, pszParmValue);
4138 string_set((char **)parm_ptr, pszParmValue);
4139 strupper_m(*(char **)parm_ptr);
4143 pstrcpy((char *)parm_ptr, pszParmValue);
4147 pstrcpy((char *)parm_ptr, pszParmValue);
4148 strupper_m((char *)parm_ptr);
4152 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
4161 /***************************************************************************
4162 Process a parameter.
4163 ***************************************************************************/
4165 static bool do_parameter(const char *pszParmName, const char *pszParmValue)
4167 if (!bInGlobalSection && bGlobalOnly)
4170 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
4172 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
4173 pszParmName, pszParmValue));
4176 /***************************************************************************
4177 Print a parameter of the specified type.
4178 ***************************************************************************/
4180 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
4186 for (i = 0; p->enum_list[i].name; i++) {
4187 if (*(int *)ptr == p->enum_list[i].value) {
4189 p->enum_list[i].name);
4196 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
4200 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
4204 fprintf(f, "%d", *(int *)ptr);
4208 fprintf(f, "%c", *(char *)ptr);
4212 fprintf(f, "%s", octal_string(*(int *)ptr));
4216 if ((char ***)ptr && *(char ***)ptr) {
4217 char **list = *(char ***)ptr;
4219 for (; *list; list++) {
4220 /* surround strings with whitespace in double quotes */
4221 if ( strchr_m( *list, ' ' ) )
4222 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
4224 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
4232 fprintf(f, "%s", (char *)ptr);
4238 if (*(char **)ptr) {
4239 fprintf(f, "%s", *(char **)ptr);
4247 /***************************************************************************
4248 Check if two parameters are equal.
4249 ***************************************************************************/
4251 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
4256 return (*((bool *)ptr1) == *((bool *)ptr2));
4261 return (*((int *)ptr1) == *((int *)ptr2));
4264 return (*((char *)ptr1) == *((char *)ptr2));
4267 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
4272 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
4277 return (p1 == p2 || strequal(p1, p2));
4282 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
4287 return (p1 == p2 || strequal(p1, p2));
4295 /***************************************************************************
4296 Initialize any local varients in the sDefault table.
4297 ***************************************************************************/
4299 void init_locals(void)
4304 /***************************************************************************
4305 Process a new section (service). At this stage all sections are services.
4306 Later we'll have special sections that permit server parameters to be set.
4307 Returns True on success, False on failure.
4308 ***************************************************************************/
4310 static bool do_section(const char *pszSectionName)
4313 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
4314 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
4317 /* if we were in a global section then do the local inits */
4318 if (bInGlobalSection && !isglobal)
4321 /* if we've just struck a global section, note the fact. */
4322 bInGlobalSection = isglobal;
4324 /* check for multiple global sections */
4325 if (bInGlobalSection) {
4326 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
4330 if (!bInGlobalSection && bGlobalOnly)
4333 /* if we have a current service, tidy it up before moving on */
4336 if (iServiceIndex >= 0)
4337 bRetval = service_ok(iServiceIndex);
4339 /* if all is still well, move to the next record in the services array */
4341 /* We put this here to avoid an odd message order if messages are */
4342 /* issued by the post-processing of a previous section. */
4343 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
4345 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
4347 DEBUG(0, ("Failed to add a new service\n"));
4356 /***************************************************************************
4357 Determine if a partcular base parameter is currentl set to the default value.
4358 ***************************************************************************/
4360 static bool is_default(int i)
4362 if (!defaults_saved)
4364 switch (parm_table[i].type) {
4366 return str_list_compare (parm_table[i].def.lvalue,
4367 *(char ***)parm_table[i].ptr);
4370 return strequal(parm_table[i].def.svalue,
4371 *(char **)parm_table[i].ptr);
4374 return strequal(parm_table[i].def.svalue,
4375 (char *)parm_table[i].ptr);
4378 return parm_table[i].def.bvalue ==
4379 *(bool *)parm_table[i].ptr;
4381 return parm_table[i].def.cvalue ==
4382 *(char *)parm_table[i].ptr;
4386 return parm_table[i].def.ivalue ==
4387 *(int *)parm_table[i].ptr;
4394 /***************************************************************************
4395 Display the contents of the global structure.
4396 ***************************************************************************/
4398 static void dump_globals(FILE *f)
4401 param_opt_struct *data;
4403 fprintf(f, "[global]\n");
4405 for (i = 0; parm_table[i].label; i++)
4406 if (parm_table[i].p_class == P_GLOBAL &&
4407 parm_table[i].ptr &&
4408 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
4409 if (defaults_saved && is_default(i))
4411 fprintf(f, "\t%s = ", parm_table[i].label);
4412 print_parameter(&parm_table[i], parm_table[i].ptr, f);
4415 if (Globals.param_opt != NULL) {
4416 data = Globals.param_opt;
4418 fprintf(f, "\t%s = %s\n", data->key, data->value);
4425 /***************************************************************************
4426 Return True if a local parameter is currently set to the global default.
4427 ***************************************************************************/
4429 bool lp_is_default(int snum, struct parm_struct *parm)
4431 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
4433 return equal_parameter(parm->type,
4434 ((char *)ServicePtrs[snum]) + pdiff,
4435 ((char *)&sDefault) + pdiff);
4438 /***************************************************************************
4439 Display the contents of a single services record.
4440 ***************************************************************************/
4442 static void dump_a_service(service * pService, FILE * f)
4445 param_opt_struct *data;
4447 if (pService != &sDefault)
4448 fprintf(f, "[%s]\n", pService->szService);
4450 for (i = 0; parm_table[i].label; i++) {
4452 if (parm_table[i].p_class == P_LOCAL &&
4453 parm_table[i].ptr &&
4454 (*parm_table[i].label != '-') &&
4455 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4458 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
4460 if (pService == &sDefault) {
4461 if (defaults_saved && is_default(i))
4464 if (equal_parameter(parm_table[i].type,
4465 ((char *)pService) +
4467 ((char *)&sDefault) +
4472 fprintf(f, "\t%s = ", parm_table[i].label);
4473 print_parameter(&parm_table[i],
4474 ((char *)pService) + pdiff, f);
4479 if (pService->param_opt != NULL) {
4480 data = pService->param_opt;
4482 fprintf(f, "\t%s = %s\n", data->key, data->value);
4488 /***************************************************************************
4489 Display the contents of a parameter of a single services record.
4490 ***************************************************************************/
4492 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
4495 bool result = False;
4498 fstring local_parm_name;
4500 const char *parm_opt_value;
4502 /* check for parametrical option */
4503 fstrcpy( local_parm_name, parm_name);
4504 parm_opt = strchr( local_parm_name, ':');
4509 if (strlen(parm_opt)) {
4510 parm_opt_value = lp_parm_const_string( snum,
4511 local_parm_name, parm_opt, NULL);
4512 if (parm_opt_value) {
4513 printf( "%s\n", parm_opt_value);
4520 /* check for a key and print the value */
4527 for (i = 0; parm_table[i].label; i++) {
4528 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
4529 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
4530 parm_table[i].ptr &&
4531 (*parm_table[i].label != '-') &&
4532 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4537 ptr = parm_table[i].ptr;
4539 service * pService = ServicePtrs[snum];
4540 ptr = ((char *)pService) +
4541 PTR_DIFF(parm_table[i].ptr, &sDefault);
4544 print_parameter(&parm_table[i],
4555 /***************************************************************************
4556 Return info about the requested parameter (given as a string).
4557 Return NULL when the string is not a valid parameter name.
4558 ***************************************************************************/
4560 struct parm_struct *lp_get_parameter(const char *param_name)
4562 int num = map_parameter(param_name);
4568 return &parm_table[num];
4571 /***************************************************************************
4572 Return info about the next parameter in a service.
4573 snum==GLOBAL_SECTION_SNUM gives the globals.
4574 Return NULL when out of parameters.
4575 ***************************************************************************/
4577 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
4580 /* do the globals */
4581 for (; parm_table[*i].label; (*i)++) {
4582 if (parm_table[*i].p_class == P_SEPARATOR)
4583 return &parm_table[(*i)++];
4585 if (!parm_table[*i].ptr
4586 || (*parm_table[*i].label == '-'))
4590 && (parm_table[*i].ptr ==
4591 parm_table[(*i) - 1].ptr))
4594 if (is_default(*i) && !allparameters)
4597 return &parm_table[(*i)++];
4600 service *pService = ServicePtrs[snum];
4602 for (; parm_table[*i].label; (*i)++) {
4603 if (parm_table[*i].p_class == P_SEPARATOR)
4604 return &parm_table[(*i)++];
4606 if (parm_table[*i].p_class == P_LOCAL &&
4607 parm_table[*i].ptr &&
4608 (*parm_table[*i].label != '-') &&
4610 (parm_table[*i].ptr !=
4611 parm_table[(*i) - 1].ptr)))
4614 PTR_DIFF(parm_table[*i].ptr,
4617 if (allparameters ||
4618 !equal_parameter(parm_table[*i].type,
4619 ((char *)pService) +
4621 ((char *)&sDefault) +
4624 return &parm_table[(*i)++];
4635 /***************************************************************************
4636 Display the contents of a single copy structure.
4637 ***************************************************************************/
4638 static void dump_copy_map(bool *pcopymap)
4644 printf("\n\tNon-Copied parameters:\n");
4646 for (i = 0; parm_table[i].label; i++)
4647 if (parm_table[i].p_class == P_LOCAL &&
4648 parm_table[i].ptr && !pcopymap[i] &&
4649 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4651 printf("\t\t%s\n", parm_table[i].label);
4656 /***************************************************************************
4657 Return TRUE if the passed service number is within range.
4658 ***************************************************************************/
4660 bool lp_snum_ok(int iService)
4662 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4665 /***************************************************************************
4666 Auto-load some home services.
4667 ***************************************************************************/
4669 static void lp_add_auto_services(char *str)
4678 s = SMB_STRDUP(str);
4682 homes = lp_servicenumber(HOMES_NAME);
4684 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4685 char *home = get_user_home_dir(p);
4687 if (lp_servicenumber(p) >= 0)
4690 if (home && homes >= 0)
4691 lp_add_home(p, homes, p, home);
4696 /***************************************************************************
4697 Auto-load one printer.
4698 ***************************************************************************/
4700 void lp_add_one_printer(char *name, char *comment)
4702 int printers = lp_servicenumber(PRINTERS_NAME);
4705 if (lp_servicenumber(name) < 0) {
4706 lp_add_printer(name, printers);
4707 if ((i = lp_servicenumber(name)) >= 0) {
4708 string_set(&ServicePtrs[i]->comment, comment);
4709 ServicePtrs[i]->autoloaded = True;
4714 /***************************************************************************
4715 Have we loaded a services file yet?
4716 ***************************************************************************/
4718 bool lp_loaded(void)
4723 /***************************************************************************
4724 Unload unused services.
4725 ***************************************************************************/
4727 void lp_killunused(bool (*snumused) (int))
4730 for (i = 0; i < iNumServices; i++) {
4734 /* don't kill autoloaded or usershare services */
4735 if ( ServicePtrs[i]->autoloaded ||
4736 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4740 if (!snumused || !snumused(i)) {
4741 free_service_byindex(i);
4746 /***************************************************************************
4748 ***************************************************************************/
4750 void lp_killservice(int iServiceIn)
4752 if (VALID(iServiceIn)) {
4753 free_service_byindex(iServiceIn);
4757 /***************************************************************************
4758 Save the curent values of all global and sDefault parameters into the
4759 defaults union. This allows swat and testparm to show only the
4760 changed (ie. non-default) parameters.
4761 ***************************************************************************/
4763 static void lp_save_defaults(void)
4766 for (i = 0; parm_table[i].label; i++) {
4767 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4769 switch (parm_table[i].type) {
4771 str_list_copy(&(parm_table[i].def.lvalue),
4772 *(const char ***)parm_table[i].ptr);
4776 if (parm_table[i].ptr) {
4777 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4779 parm_table[i].def.svalue = NULL;
4784 if (parm_table[i].ptr) {
4785 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4787 parm_table[i].def.svalue = NULL;
4792 parm_table[i].def.bvalue =
4793 *(bool *)parm_table[i].ptr;
4796 parm_table[i].def.cvalue =
4797 *(char *)parm_table[i].ptr;
4802 parm_table[i].def.ivalue =
4803 *(int *)parm_table[i].ptr;
4809 defaults_saved = True;
4812 /*******************************************************************
4813 Set the server type we will announce as via nmbd.
4814 ********************************************************************/
4816 static const struct srv_role_tab {
4818 const char *role_str;
4819 } srv_role_tab [] = {
4820 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4821 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4822 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4823 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4827 const char* server_role_str(uint32 role)
4830 for (i=0; srv_role_tab[i].role_str; i++) {
4831 if (role == srv_role_tab[i].role) {
4832 return srv_role_tab[i].role_str;
4838 static void set_server_role(void)
4840 server_role = ROLE_STANDALONE;
4842 switch (lp_security()) {
4844 if (lp_domain_logons())
4845 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4848 if (lp_domain_logons())
4849 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4850 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
4851 server_role = ROLE_STANDALONE;
4854 if (lp_domain_logons()) {
4855 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4856 server_role = ROLE_DOMAIN_BDC;
4859 server_role = ROLE_DOMAIN_MEMBER;
4862 if (lp_domain_logons()) {
4863 server_role = ROLE_DOMAIN_PDC;
4866 server_role = ROLE_DOMAIN_MEMBER;
4869 if (lp_domain_logons()) {
4871 if (Globals.iDomainMaster) /* auto or yes */
4872 server_role = ROLE_DOMAIN_PDC;
4874 server_role = ROLE_DOMAIN_BDC;
4878 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4882 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4885 /***********************************************************
4886 If we should send plaintext/LANMAN passwords in the clinet
4887 ************************************************************/
4889 static void set_allowed_client_auth(void)
4891 if (Globals.bClientNTLMv2Auth) {
4892 Globals.bClientLanManAuth = False;
4894 if (!Globals.bClientLanManAuth) {
4895 Globals.bClientPlaintextAuth = False;
4899 /***************************************************************************
4901 The following code allows smbd to read a user defined share file.
4902 Yes, this is my intent. Yes, I'm comfortable with that...
4904 THE FOLLOWING IS SECURITY CRITICAL CODE.
4906 It washes your clothes, it cleans your house, it guards you while you sleep...
4907 Do not f%^k with it....
4908 ***************************************************************************/
4910 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4912 /***************************************************************************
4913 Check allowed stat state of a usershare file.
4914 Ensure we print out who is dicking with us so the admin can
4915 get their sorry ass fired.
4916 ***************************************************************************/
4918 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4920 if (!S_ISREG(psbuf->st_mode)) {
4921 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4922 "not a regular file\n",
4923 fname, (unsigned int)psbuf->st_uid ));
4927 /* Ensure this doesn't have the other write bit set. */
4928 if (psbuf->st_mode & S_IWOTH) {
4929 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4930 "public write. Refusing to allow as a usershare file.\n",
4931 fname, (unsigned int)psbuf->st_uid ));
4935 /* Should be 10k or less. */
4936 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4937 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4938 "too large (%u) to be a user share file.\n",
4939 fname, (unsigned int)psbuf->st_uid,
4940 (unsigned int)psbuf->st_size ));
4947 /***************************************************************************
4948 Parse the contents of a usershare file.
4949 ***************************************************************************/
4951 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4952 SMB_STRUCT_STAT *psbuf,
4953 const char *servicename,
4962 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4963 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4966 SMB_STRUCT_STAT sbuf;
4968 *pallow_guest = False;
4971 return USERSHARE_MALFORMED_FILE;
4974 if (strcmp(lines[0], "#VERSION 1") == 0) {
4976 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4979 return USERSHARE_MALFORMED_FILE;
4982 return USERSHARE_BAD_VERSION;
4985 if (strncmp(lines[1], "path=", 5) != 0) {
4986 return USERSHARE_MALFORMED_PATH;
4989 pstrcpy(sharepath, &lines[1][5]);
4990 trim_string(sharepath, " ", " ");
4992 if (strncmp(lines[2], "comment=", 8) != 0) {
4993 return USERSHARE_MALFORMED_COMMENT_DEF;
4996 pstrcpy(comment, &lines[2][8]);
4997 trim_string(comment, " ", " ");
4998 trim_char(comment, '"', '"');
5000 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
5001 return USERSHARE_MALFORMED_ACL_DEF;
5004 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
5005 return USERSHARE_ACL_ERR;
5009 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
5010 return USERSHARE_MALFORMED_ACL_DEF;
5012 if (lines[4][9] == 'y') {
5013 *pallow_guest = True;
5017 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
5018 /* Path didn't change, no checks needed. */
5019 return USERSHARE_OK;
5022 /* The path *must* be absolute. */
5023 if (sharepath[0] != '/') {
5024 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
5025 servicename, sharepath));
5026 return USERSHARE_PATH_NOT_ABSOLUTE;
5029 /* If there is a usershare prefix deny list ensure one of these paths
5030 doesn't match the start of the user given path. */
5031 if (prefixdenylist) {
5033 for ( i=0; prefixdenylist[i]; i++ ) {
5034 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
5035 servicename, i, prefixdenylist[i], sharepath ));
5036 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
5037 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
5038 "usershare prefix deny list entries.\n",
5039 servicename, sharepath));
5040 return USERSHARE_PATH_IS_DENIED;
5045 /* If there is a usershare prefix allow list ensure one of these paths
5046 does match the start of the user given path. */
5048 if (prefixallowlist) {
5050 for ( i=0; prefixallowlist[i]; i++ ) {
5051 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
5052 servicename, i, prefixallowlist[i], sharepath ));
5053 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
5057 if (prefixallowlist[i] == NULL) {
5058 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
5059 "usershare prefix allow list entries.\n",
5060 servicename, sharepath));
5061 return USERSHARE_PATH_NOT_ALLOWED;
5065 /* Ensure this is pointing to a directory. */
5066 dp = sys_opendir(sharepath);
5069 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
5070 servicename, sharepath));
5071 return USERSHARE_PATH_NOT_DIRECTORY;
5074 /* Ensure the owner of the usershare file has permission to share
5077 if (sys_stat(sharepath, &sbuf) == -1) {
5078 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
5079 servicename, sharepath, strerror(errno) ));
5081 return USERSHARE_POSIX_ERR;
5086 if (!S_ISDIR(sbuf.st_mode)) {
5087 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
5088 servicename, sharepath ));
5089 return USERSHARE_PATH_NOT_DIRECTORY;
5092 /* Check if sharing is restricted to owner-only. */
5093 /* psbuf is the stat of the usershare definition file,
5094 sbuf is the stat of the target directory to be shared. */
5096 if (lp_usershare_owner_only()) {
5097 /* root can share anything. */
5098 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
5099 return USERSHARE_PATH_NOT_ALLOWED;
5103 return USERSHARE_OK;
5106 /***************************************************************************
5107 Deal with a usershare file.
5110 -1 - Bad name, invalid contents.
5111 - service name already existed and not a usershare, problem
5112 with permissions to share directory etc.
5113 ***************************************************************************/
5115 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
5117 SMB_STRUCT_STAT sbuf;
5118 SMB_STRUCT_STAT lsbuf;
5122 fstring service_name;
5123 char **lines = NULL;
5127 TALLOC_CTX *ctx = NULL;
5128 SEC_DESC *psd = NULL;
5129 bool guest_ok = False;
5131 /* Ensure share name doesn't contain invalid characters. */
5132 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
5133 DEBUG(0,("process_usershare_file: share name %s contains "
5134 "invalid characters (any of %s)\n",
5135 file_name, INVALID_SHARENAME_CHARS ));
5139 fstrcpy(service_name, file_name);
5141 pstrcpy(fname, dir_name);
5142 pstrcat(fname, "/");
5143 pstrcat(fname, file_name);
5145 /* Minimize the race condition by doing an lstat before we
5146 open and fstat. Ensure this isn't a symlink link. */
5148 if (sys_lstat(fname, &lsbuf) != 0) {
5149 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
5150 fname, strerror(errno) ));
5154 /* This must be a regular file, not a symlink, directory or
5155 other strange filetype. */
5156 if (!check_usershare_stat(fname, &lsbuf)) {
5160 /* See if there is already a servicenum for this name. */
5161 /* tdb_fetch_int32 returns -1 if not found. */
5162 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
5164 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
5165 /* Nothing changed - Mark valid and return. */
5166 DEBUG(10,("process_usershare_file: service %s not changed.\n",
5168 ServicePtrs[iService]->usershare = USERSHARE_VALID;
5172 /* Try and open the file read only - no symlinks allowed. */
5174 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
5176 fd = sys_open(fname, O_RDONLY, 0);
5180 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
5181 fname, strerror(errno) ));
5185 /* Now fstat to be *SURE* it's a regular file. */
5186 if (sys_fstat(fd, &sbuf) != 0) {
5188 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
5189 fname, strerror(errno) ));
5193 /* Is it the same dev/inode as was lstated ? */
5194 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
5196 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
5197 "Symlink spoofing going on ?\n", fname ));
5201 /* This must be a regular file, not a symlink, directory or
5202 other strange filetype. */
5203 if (!check_usershare_stat(fname, &sbuf)) {
5207 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
5210 if (lines == NULL) {
5211 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
5212 fname, (unsigned int)sbuf.st_uid ));
5216 /* Should we allow printers to be shared... ? */
5217 ctx = talloc_init("usershare_sd_xctx");
5219 file_lines_free(lines);
5223 if (parse_usershare_file(ctx, &sbuf, service_name,
5224 iService, lines, numlines, sharepath,
5225 comment, &psd, &guest_ok) != USERSHARE_OK) {
5226 talloc_destroy(ctx);
5227 file_lines_free(lines);
5231 file_lines_free(lines);
5233 /* Everything ok - add the service possibly using a template. */
5235 const service *sp = &sDefault;
5236 if (snum_template != -1) {
5237 sp = ServicePtrs[snum_template];
5240 if ((iService = add_a_service(sp, service_name)) < 0) {
5241 DEBUG(0, ("process_usershare_file: Failed to add "
5242 "new service %s\n", service_name));
5243 talloc_destroy(ctx);
5247 /* Read only is controlled by usershare ACL below. */
5248 ServicePtrs[iService]->bRead_only = False;
5251 /* Write the ACL of the new/modified share. */
5252 if (!set_share_security(service_name, psd)) {
5253 DEBUG(0, ("process_usershare_file: Failed to set share "
5254 "security for user share %s\n",
5256 lp_remove_service(iService);
5257 talloc_destroy(ctx);
5261 talloc_destroy(ctx);
5263 /* If from a template it may be marked invalid. */
5264 ServicePtrs[iService]->valid = True;
5266 /* Set the service as a valid usershare. */
5267 ServicePtrs[iService]->usershare = USERSHARE_VALID;
5269 /* Set guest access. */
5270 if (lp_usershare_allow_guests()) {
5271 ServicePtrs[iService]->bGuest_ok = guest_ok;
5274 /* And note when it was loaded. */
5275 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
5276 string_set(&ServicePtrs[iService]->szPath, sharepath);
5277 string_set(&ServicePtrs[iService]->comment, comment);
5282 /***************************************************************************
5283 Checks if a usershare entry has been modified since last load.
5284 ***************************************************************************/
5286 static bool usershare_exists(int iService, time_t *last_mod)
5288 SMB_STRUCT_STAT lsbuf;
5289 const char *usersharepath = Globals.szUsersharePath;
5292 pstrcpy(fname, usersharepath);
5293 pstrcat(fname, "/");
5294 pstrcat(fname, ServicePtrs[iService]->szService);
5296 if (sys_lstat(fname, &lsbuf) != 0) {
5300 if (!S_ISREG(lsbuf.st_mode)) {
5304 *last_mod = lsbuf.st_mtime;
5308 /***************************************************************************
5309 Load a usershare service by name. Returns a valid servicenumber or -1.
5310 ***************************************************************************/
5312 int load_usershare_service(const char *servicename)
5314 SMB_STRUCT_STAT sbuf;
5315 const char *usersharepath = Globals.szUsersharePath;
5316 int max_user_shares = Globals.iUsershareMaxShares;
5317 int snum_template = -1;
5319 if (*usersharepath == 0 || max_user_shares == 0) {
5323 if (sys_stat(usersharepath, &sbuf) != 0) {
5324 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
5325 usersharepath, strerror(errno) ));
5329 if (!S_ISDIR(sbuf.st_mode)) {
5330 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
5336 * This directory must be owned by root, and have the 't' bit set.
5337 * It also must not be writable by "other".
5341 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
5343 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
5345 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
5346 "or does not have the sticky bit 't' set or is writable by anyone.\n",
5351 /* Ensure the template share exists if it's set. */
5352 if (Globals.szUsershareTemplateShare[0]) {
5353 /* We can't use lp_servicenumber here as we are recommending that
5354 template shares have -valid=False set. */
5355 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
5356 if (ServicePtrs[snum_template]->szService &&
5357 strequal(ServicePtrs[snum_template]->szService,
5358 Globals.szUsershareTemplateShare)) {
5363 if (snum_template == -1) {
5364 DEBUG(0,("load_usershare_service: usershare template share %s "
5365 "does not exist.\n",
5366 Globals.szUsershareTemplateShare ));
5371 return process_usershare_file(usersharepath, servicename, snum_template);
5374 /***************************************************************************
5375 Load all user defined shares from the user share directory.
5376 We only do this if we're enumerating the share list.
5377 This is the function that can delete usershares that have
5379 ***************************************************************************/
5381 int load_usershare_shares(void)
5384 SMB_STRUCT_STAT sbuf;
5385 SMB_STRUCT_DIRENT *de;
5386 int num_usershares = 0;
5387 int max_user_shares = Globals.iUsershareMaxShares;
5388 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
5389 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
5390 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
5392 int snum_template = -1;
5393 const char *usersharepath = Globals.szUsersharePath;
5394 int ret = lp_numservices();
5396 if (max_user_shares == 0 || *usersharepath == '\0') {
5397 return lp_numservices();
5400 if (sys_stat(usersharepath, &sbuf) != 0) {
5401 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
5402 usersharepath, strerror(errno) ));
5407 * This directory must be owned by root, and have the 't' bit set.
5408 * It also must not be writable by "other".
5412 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
5414 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
5416 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
5417 "or does not have the sticky bit 't' set or is writable by anyone.\n",
5422 /* Ensure the template share exists if it's set. */
5423 if (Globals.szUsershareTemplateShare[0]) {
5424 /* We can't use lp_servicenumber here as we are recommending that
5425 template shares have -valid=False set. */
5426 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
5427 if (ServicePtrs[snum_template]->szService &&
5428 strequal(ServicePtrs[snum_template]->szService,
5429 Globals.szUsershareTemplateShare)) {
5434 if (snum_template == -1) {
5435 DEBUG(0,("load_usershare_shares: usershare template share %s "
5436 "does not exist.\n",
5437 Globals.szUsershareTemplateShare ));
5442 /* Mark all existing usershares as pending delete. */
5443 for (iService = iNumServices - 1; iService >= 0; iService--) {
5444 if (VALID(iService) && ServicePtrs[iService]->usershare) {
5445 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
5449 dp = sys_opendir(usersharepath);
5451 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
5452 usersharepath, strerror(errno) ));
5456 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
5457 (de = sys_readdir(dp));
5458 num_dir_entries++ ) {
5460 const char *n = de->d_name;
5462 /* Ignore . and .. */
5464 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
5470 /* Temporary file used when creating a share. */
5471 num_tmp_dir_entries++;
5474 /* Allow 20% tmp entries. */
5475 if (num_tmp_dir_entries > allowed_tmp_entries) {
5476 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
5477 "in directory %s\n",
5478 num_tmp_dir_entries, usersharepath));
5482 r = process_usershare_file(usersharepath, n, snum_template);
5484 /* Update the services count. */
5486 if (num_usershares >= max_user_shares) {
5487 DEBUG(0,("load_usershare_shares: max user shares reached "
5488 "on file %s in directory %s\n",
5489 n, usersharepath ));
5492 } else if (r == -1) {
5493 num_bad_dir_entries++;
5496 /* Allow 20% bad entries. */
5497 if (num_bad_dir_entries > allowed_bad_entries) {
5498 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
5499 "in directory %s\n",
5500 num_bad_dir_entries, usersharepath));
5504 /* Allow 20% bad entries. */
5505 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
5506 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
5507 "in directory %s\n",
5508 num_dir_entries, usersharepath));
5515 /* Sweep through and delete any non-refreshed usershares that are
5516 not currently in use. */
5517 for (iService = iNumServices - 1; iService >= 0; iService--) {
5518 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
5519 if (conn_snum_used(iService)) {
5522 /* Remove from the share ACL db. */
5523 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
5524 lp_servicename(iService) ));
5525 delete_share_security(lp_servicename(iService));
5526 free_service_byindex(iService);
5530 return lp_numservices();
5533 /********************************************************
5534 Destroy global resources allocated in this file
5535 ********************************************************/
5537 void gfree_loadparm(void)
5539 struct file_lists *f;
5540 struct file_lists *next;
5543 /* Free the file lists */
5548 SAFE_FREE( f->name );
5549 SAFE_FREE( f->subfname );
5554 /* Free resources allocated to services */
5556 for ( i = 0; i < iNumServices; i++ ) {
5558 free_service_byindex(i);
5562 SAFE_FREE( ServicePtrs );
5565 /* Now release all resources allocated to global
5566 parameters and the default service */
5568 for (i = 0; parm_table[i].label; i++)
5570 if ( parm_table[i].type == P_STRING
5571 || parm_table[i].type == P_USTRING )
5573 string_free( (char**)parm_table[i].ptr );
5575 else if (parm_table[i].type == P_LIST) {
5576 str_list_free( (char***)parm_table[i].ptr );
5581 /***************************************************************************
5582 Load the services array from the services file. Return True on success,
5584 ***************************************************************************/
5586 bool lp_load(const char *pszFname,
5590 bool initialize_globals)
5594 param_opt_struct *data, *pdata;
5596 pstrcpy(n2, pszFname);
5598 standard_sub_basic( get_current_username(), current_user_info.domain,
5601 add_to_file_list(pszFname, n2);
5605 DEBUG(3, ("lp_load: refreshing parameters\n"));
5607 bInGlobalSection = True;
5608 bGlobalOnly = global_only;
5610 init_globals(! initialize_globals);
5613 if (save_defaults) {
5618 if (Globals.param_opt != NULL) {
5619 data = Globals.param_opt;
5621 string_free(&data->key);
5622 string_free(&data->value);
5623 str_list_free(&data->list);
5628 Globals.param_opt = NULL;
5631 /* We get sections first, so have to start 'behind' to make up */
5633 bRetval = pm_process(n2, do_section, do_parameter);
5635 /* finish up the last section */
5636 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
5638 if (iServiceIndex >= 0)
5639 bRetval = service_ok(iServiceIndex);
5641 lp_add_auto_services(lp_auto_services());
5644 /* When 'restrict anonymous = 2' guest connections to ipc$
5646 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
5647 if ( lp_enable_asu_support() )
5648 lp_add_ipc("ADMIN$", False);
5652 set_default_server_announce_type();
5653 set_allowed_client_auth();
5657 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
5658 /* if bWINSsupport is true and we are in the client */
5659 if (in_client && Globals.bWINSsupport) {
5660 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5668 /***************************************************************************
5669 Reset the max number of services.
5670 ***************************************************************************/
5672 void lp_resetnumservices(void)
5677 /***************************************************************************
5678 Return the max number of services.
5679 ***************************************************************************/
5681 int lp_numservices(void)
5683 return (iNumServices);
5686 /***************************************************************************
5687 Display the contents of the services array in human-readable form.
5688 ***************************************************************************/
5690 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
5695 defaults_saved = False;
5699 dump_a_service(&sDefault, f);
5701 for (iService = 0; iService < maxtoprint; iService++) {
5703 lp_dump_one(f, show_defaults, iService);
5707 /***************************************************************************
5708 Display the contents of one service in human-readable form.
5709 ***************************************************************************/
5711 void lp_dump_one(FILE * f, bool show_defaults, int snum)
5714 if (ServicePtrs[snum]->szService[0] == '\0')
5716 dump_a_service(ServicePtrs[snum], f);
5720 /***************************************************************************
5721 Return the number of the service with the given name, or -1 if it doesn't
5722 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5723 getservicebyname()! This works ONLY if all services have been loaded, and
5724 does not copy the found service.
5725 ***************************************************************************/
5727 int lp_servicenumber(const char *pszServiceName)
5730 fstring serviceName;
5732 if (!pszServiceName) {
5733 return GLOBAL_SECTION_SNUM;
5736 for (iService = iNumServices - 1; iService >= 0; iService--) {
5737 if (VALID(iService) && ServicePtrs[iService]->szService) {
5739 * The substitution here is used to support %U is
5742 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5743 standard_sub_basic(get_current_username(),
5744 current_user_info.domain,
5745 serviceName,sizeof(serviceName));
5746 if (strequal(serviceName, pszServiceName)) {
5752 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5755 if (!usershare_exists(iService, &last_mod)) {
5756 /* Remove the share security tdb entry for it. */
5757 delete_share_security(lp_servicename(iService));
5758 /* Remove it from the array. */
5759 free_service_byindex(iService);
5760 /* Doesn't exist anymore. */
5761 return GLOBAL_SECTION_SNUM;
5764 /* Has it been modified ? If so delete and reload. */
5765 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5766 /* Remove it from the array. */
5767 free_service_byindex(iService);
5768 /* and now reload it. */
5769 iService = load_usershare_service(pszServiceName);
5774 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5775 return GLOBAL_SECTION_SNUM;
5781 bool share_defined(const char *service_name)
5783 return (lp_servicenumber(service_name) != -1);
5786 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
5787 const char *sharename)
5789 struct share_params *result;
5793 if (!(sname = SMB_STRDUP(sharename))) {
5797 snum = find_service(sname);
5804 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
5805 DEBUG(0, ("talloc failed\n"));
5809 result->service = snum;
5813 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
5815 struct share_iterator *result;
5817 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
5818 DEBUG(0, ("talloc failed\n"));
5822 result->next_id = 0;
5826 struct share_params *next_share(struct share_iterator *list)
5828 struct share_params *result;
5830 while (!lp_snum_ok(list->next_id) &&
5831 (list->next_id < lp_numservices())) {
5835 if (list->next_id >= lp_numservices()) {
5839 if (!(result = TALLOC_P(list, struct share_params))) {
5840 DEBUG(0, ("talloc failed\n"));
5844 result->service = list->next_id;
5849 struct share_params *next_printer(struct share_iterator *list)
5851 struct share_params *result;
5853 while ((result = next_share(list)) != NULL) {
5854 if (lp_print_ok(result->service)) {
5862 * This is a hack for a transition period until we transformed all code from
5863 * service numbers to struct share_params.
5866 struct share_params *snum2params_static(int snum)
5868 static struct share_params result;
5869 result.service = snum;
5873 /*******************************************************************
5874 A useful volume label function.
5875 ********************************************************************/
5877 const char *volume_label(int snum)
5880 const char *label = lp_volume(snum);
5882 label = lp_servicename(snum);
5885 /* This returns a 33 byte guarenteed null terminated string. */
5886 ret = talloc_strndup(talloc_tos(), label, 32);
5893 /*******************************************************************
5894 Set the server type we will announce as via nmbd.
5895 ********************************************************************/
5897 static void set_default_server_announce_type(void)
5899 default_server_announce = 0;
5900 default_server_announce |= SV_TYPE_WORKSTATION;
5901 default_server_announce |= SV_TYPE_SERVER;
5902 default_server_announce |= SV_TYPE_SERVER_UNIX;
5904 /* note that the flag should be set only if we have a
5905 printer service but nmbd doesn't actually load the
5906 services so we can't tell --jerry */
5908 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5910 switch (lp_announce_as()) {
5911 case ANNOUNCE_AS_NT_SERVER:
5912 default_server_announce |= SV_TYPE_SERVER_NT;
5913 /* fall through... */
5914 case ANNOUNCE_AS_NT_WORKSTATION:
5915 default_server_announce |= SV_TYPE_NT;
5917 case ANNOUNCE_AS_WIN95:
5918 default_server_announce |= SV_TYPE_WIN95_PLUS;
5920 case ANNOUNCE_AS_WFW:
5921 default_server_announce |= SV_TYPE_WFW;
5927 switch (lp_server_role()) {
5928 case ROLE_DOMAIN_MEMBER:
5929 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5931 case ROLE_DOMAIN_PDC:
5932 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5934 case ROLE_DOMAIN_BDC:
5935 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5937 case ROLE_STANDALONE:
5941 if (lp_time_server())
5942 default_server_announce |= SV_TYPE_TIME_SOURCE;
5944 if (lp_host_msdfs())
5945 default_server_announce |= SV_TYPE_DFS_SERVER;
5948 /***********************************************************
5949 returns role of Samba server
5950 ************************************************************/
5952 int lp_server_role(void)
5957 /***********************************************************
5958 If we are PDC then prefer us as DMB
5959 ************************************************************/
5961 bool lp_domain_master(void)
5963 if (Globals.iDomainMaster == Auto)
5964 return (lp_server_role() == ROLE_DOMAIN_PDC);
5966 return (bool)Globals.iDomainMaster;
5969 /***********************************************************
5970 If we are DMB then prefer us as LMB
5971 ************************************************************/
5973 bool lp_preferred_master(void)
5975 if (Globals.iPreferredMaster == Auto)
5976 return (lp_local_master() && lp_domain_master());
5978 return (bool)Globals.iPreferredMaster;
5981 /*******************************************************************
5983 ********************************************************************/
5985 void lp_remove_service(int snum)
5987 ServicePtrs[snum]->valid = False;
5988 invalid_services[num_invalid_services++] = snum;
5991 /*******************************************************************
5993 ********************************************************************/
5995 void lp_copy_service(int snum, const char *new_name)
5997 do_section(new_name);
5999 snum = lp_servicenumber(new_name);
6001 lp_do_parameter(snum, "copy", lp_servicename(snum));
6006 /*******************************************************************
6007 Get the default server type we will announce as via nmbd.
6008 ********************************************************************/
6010 int lp_default_server_announce(void)
6012 return default_server_announce;
6015 /*******************************************************************
6016 Split the announce version into major and minor numbers.
6017 ********************************************************************/
6019 int lp_major_announce_version(void)
6021 static bool got_major = False;
6022 static int major_version = DEFAULT_MAJOR_VERSION;
6027 return major_version;
6030 if ((vers = lp_announce_version()) == NULL)
6031 return major_version;
6033 if ((p = strchr_m(vers, '.')) == 0)
6034 return major_version;
6037 major_version = atoi(vers);
6038 return major_version;
6041 int lp_minor_announce_version(void)
6043 static bool got_minor = False;
6044 static int minor_version = DEFAULT_MINOR_VERSION;
6049 return minor_version;
6052 if ((vers = lp_announce_version()) == NULL)
6053 return minor_version;
6055 if ((p = strchr_m(vers, '.')) == 0)
6056 return minor_version;
6059 minor_version = atoi(p);
6060 return minor_version;
6063 /***********************************************************
6064 Set the global name resolution order (used in smbclient).
6065 ************************************************************/
6067 void lp_set_name_resolve_order(const char *new_order)
6069 string_set(&Globals.szNameResolveOrder, new_order);
6072 const char *lp_printername(int snum)
6074 const char *ret = _lp_printername(snum);
6075 if (ret == NULL || (ret != NULL && *ret == '\0'))
6076 ret = lp_const_servicename(snum);
6082 /***********************************************************
6083 Allow daemons such as winbindd to fix their logfile name.
6084 ************************************************************/
6086 void lp_set_logfile(const char *name)
6088 string_set(&Globals.szLogFile, name);
6089 pstrcpy(debugf, name);
6092 /*******************************************************************
6093 Return the max print jobs per queue.
6094 ********************************************************************/
6096 int lp_maxprintjobs(int snum)
6098 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
6099 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
6100 maxjobs = PRINT_MAX_JOBID - 1;
6105 const char *lp_printcapname(void)
6107 if ((Globals.szPrintcapname != NULL) &&
6108 (Globals.szPrintcapname[0] != '\0'))
6109 return Globals.szPrintcapname;
6111 if (sDefault.iPrinting == PRINT_CUPS) {
6119 if (sDefault.iPrinting == PRINT_BSD)
6120 return "/etc/printcap";
6122 return PRINTCAP_NAME;
6125 /*******************************************************************
6126 Ensure we don't use sendfile if server smb signing is active.
6127 ********************************************************************/
6129 static uint32 spoolss_state;
6131 bool lp_disable_spoolss( void )
6133 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
6134 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
6136 return spoolss_state == SVCCTL_STOPPED ? True : False;
6139 void lp_set_spoolss_state( uint32 state )
6141 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
6143 spoolss_state = state;
6146 uint32 lp_get_spoolss_state( void )
6148 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
6151 /*******************************************************************
6152 Ensure we don't use sendfile if server smb signing is active.
6153 ********************************************************************/
6155 bool lp_use_sendfile(int snum)
6157 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
6158 if (Protocol < PROTOCOL_NT1) {
6161 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
6164 /*******************************************************************
6165 Turn off sendfile if we find the underlying OS doesn't support it.
6166 ********************************************************************/
6168 void set_use_sendfile(int snum, bool val)
6170 if (LP_SNUM_OK(snum))
6171 ServicePtrs[snum]->bUseSendfile = val;
6173 sDefault.bUseSendfile = val;
6176 /*******************************************************************
6177 Turn off storing DOS attributes if this share doesn't support it.
6178 ********************************************************************/
6180 void set_store_dos_attributes(int snum, bool val)
6182 if (!LP_SNUM_OK(snum))
6184 ServicePtrs[(snum)]->bStoreDosAttributes = val;
6187 void lp_set_mangling_method(const char *new_method)
6189 string_set(&Globals.szManglingMethod, new_method);
6192 /*******************************************************************
6193 Global state for POSIX pathname processing.
6194 ********************************************************************/
6196 static bool posix_pathnames;
6198 bool lp_posix_pathnames(void)
6200 return posix_pathnames;
6203 /*******************************************************************
6204 Change everything needed to ensure POSIX pathname processing (currently
6206 ********************************************************************/
6208 void lp_set_posix_pathnames(void)
6210 posix_pathnames = True;
6213 /*******************************************************************
6214 Global state for POSIX lock processing - CIFS unix extensions.
6215 ********************************************************************/
6217 bool posix_default_lock_was_set;
6218 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
6220 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
6222 if (posix_default_lock_was_set) {
6223 return posix_cifsx_locktype;
6225 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
6229 /*******************************************************************
6230 ********************************************************************/
6232 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
6234 posix_default_lock_was_set = True;
6235 posix_cifsx_locktype = val;