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 2 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, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 * This module provides suitable callback functions for the params
32 * module. It builds the internal table of service details which is
33 * then used by the rest of the server.
37 * 1) add it to the global or service structure definition
38 * 2) add it to the parm_table
39 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40 * 4) If it's a global then initialise it in init_globals. If a local
41 * (ie. service) parameter then initialise it in the sDefault structure
45 * The configuration file is processed sequentially for speed. It is NOT
46 * accessed randomly as happens in 'real' Windows. For this reason, there
47 * is a fair bit of sequence-dependent code here - ie., code which assumes
48 * that certain things happen before others. In particular, the code which
49 * happens at the boundary between sections is delicately poised, so be
56 BOOL in_client = False; /* Not in the client by default */
59 extern pstring user_socket_options;
60 extern enum protocol_types Protocol;
61 extern userdom_struct current_user_info;
64 #define GLOBAL_NAME "global"
68 #define PRINTERS_NAME "printers"
72 #define HOMES_NAME "homes"
75 /* some helpful bits */
76 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
77 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
79 #define USERSHARE_VALID 1
80 #define USERSHARE_PENDING_DELETE 2
82 BOOL use_getwd_cache = True;
84 extern int extra_time_offset;
86 static BOOL defaults_saved = False;
88 typedef struct _param_opt_struct param_opt_struct;
89 struct _param_opt_struct {
90 param_opt_struct *prev, *next;
97 * This structure describes global (ie., server-wide) parameters.
103 char *display_charset;
104 char *szPrintcapname;
105 char *szAddPortCommand;
106 char *szEnumPortsCommand;
107 char *szAddPrinterCommand;
108 char *szDeletePrinterCommand;
109 char *szOs2DriverMap;
113 char *szDefaultService;
117 char *szServerString;
118 char *szAutoServices;
119 char *szPasswdProgram;
123 char *szSMBPasswdFile;
125 char *szPassdbBackend;
126 char **szPreloadModules;
127 char *szPasswordServer;
128 char *szSocketOptions;
130 char *szAfsUsernameMap;
131 int iAfsTokenLifetime;
132 char *szLogNtTokenCommand;
138 char **szWINSservers;
140 char *szRemoteAnnounce;
141 char *szRemoteBrowseSync;
142 char *szSocketAddress;
143 char *szNISHomeMapName;
144 char *szAnnounceVersion; /* This is initialised in init_globals */
147 char **szNetbiosAliases;
148 char *szNetbiosScope;
149 char *szNameResolveOrder;
151 char *szAddUserScript;
152 char *szRenameUserScript;
153 char *szDelUserScript;
154 char *szAddGroupScript;
155 char *szDelGroupScript;
156 char *szAddUserToGroupScript;
157 char *szDelUserFromGroupScript;
158 char *szSetPrimaryGroupScript;
159 char *szAddMachineScript;
160 char *szShutdownScript;
161 char *szAbortShutdownScript;
162 char *szUsernameMapScript;
163 char *szCheckPasswordScript;
170 BOOL bPassdbExpandExplicit;
171 int AlgorithmicRidBase;
172 char *szTemplateHomedir;
173 char *szTemplateShell;
174 char *szWinbindSeparator;
175 BOOL bWinbindEnumUsers;
176 BOOL bWinbindEnumGroups;
177 BOOL bWinbindUseDefaultDomain;
178 BOOL bWinbindTrustedDomainsOnly;
179 BOOL bWinbindNestedGroups;
180 int winbind_expand_groups;
181 BOOL bWinbindRefreshTickets;
182 BOOL bWinbindOfflineLogon;
183 BOOL bWinbindNormalizeNames;
184 BOOL bWinbindRpcOnly;
185 char **szIdmapDomains;
186 char **szIdmapBackend; /* deprecated */
187 char *szIdmapAllocBackend;
188 char *szAddShareCommand;
189 char *szChangeShareCommand;
190 char *szDeleteShareCommand;
192 char *szGuestaccount;
193 char *szManglingMethod;
194 char **szServicesList;
195 char *szUsersharePath;
196 char *szUsershareTemplateShare;
197 char **szUsersharePrefixAllowList;
198 char **szUsersharePrefixDenyList;
205 int open_files_db_hash_size;
213 BOOL paranoid_server_security;
216 int iMaxSmbdProcesses;
217 BOOL bDisableSpoolss;
220 int enhanced_browsing;
226 int announce_as; /* This is initialised in init_globals */
227 int machine_password_timeout;
229 int oplock_break_wait_time;
230 int winbind_cache_time;
231 int winbind_max_idle_children;
232 char **szWinbindNssInfo;
234 char *szLdapMachineSuffix;
235 char *szLdapUserSuffix;
236 char *szLdapIdmapSuffix;
237 char *szLdapGroupSuffix;
243 char *szIPrintServer;
246 int ldap_passwd_sync;
247 int ldap_replication_sleep;
248 int ldap_timeout; /* This is initialised in init_globals */
251 BOOL bMsAddPrinterWizard;
256 BOOL bPreferredMaster;
259 BOOL bEncryptPasswords;
264 BOOL bObeyPamRestrictions;
266 int PrintcapCacheTime;
267 BOOL bLargeReadwrite;
275 BOOL bBindInterfacesOnly;
276 BOOL bPamPasswordChange;
277 BOOL bUnixPasswdSync;
278 BOOL bPasswdChatDebug;
279 int iPasswdChatTimeout;
283 BOOL bNTStatusSupport;
285 int iMaxStatCacheSize;
287 BOOL bAllowTrustedDomains;
291 BOOL bClientLanManAuth;
292 BOOL bClientNTLMv2Auth;
293 BOOL bClientPlaintextAuth;
294 BOOL bClientUseSpnego;
295 BOOL bDebugPrefixTimestamp;
296 BOOL bDebugHiresTimestamp;
299 BOOL bEnableCoreFiles;
302 BOOL bHostnameLookups;
303 BOOL bUnixExtensions;
304 BOOL bDisableNetbios;
305 BOOL bUseKerberosKeytab;
306 BOOL bDeferSharingViolations;
307 BOOL bEnablePrivileges;
309 BOOL bUsershareOwnerOnly;
310 BOOL bUsershareAllowGuests;
311 BOOL bRegistryShares;
312 int restrict_anonymous;
313 int name_cache_timeout;
316 int iUsershareMaxShares;
318 int iIdmapNegativeCacheTime;
322 param_opt_struct *param_opt;
325 static global Globals;
328 * This structure describes a single service.
334 time_t usershare_last_mod;
338 char **szInvalidUsers;
346 char *szRootPostExec;
348 char *szPrintcommand;
351 char *szLppausecommand;
352 char *szLpresumecommand;
353 char *szQueuepausecommand;
354 char *szQueueresumecommand;
356 char *szPrintjobUsername;
365 char *szVetoOplockFiles;
371 char **printer_admin;
379 int iMaxReportedPrintJobs;
382 int iCreate_force_mode;
384 int iSecurity_force_mode;
387 int iDir_Security_mask;
388 int iDir_Security_force_mode;
392 int iOplockContentionLimit;
397 BOOL bRootpreexecClose;
400 BOOL bShortCasePreserve;
402 BOOL bHideSpecialFiles;
403 BOOL bHideUnReadable;
404 BOOL bHideUnWriteableFiles;
415 BOOL bStoreDosAttributes;
428 BOOL bStrictAllocate;
432 BOOL bDeleteReadonly;
434 BOOL bDeleteVetoFiles;
437 BOOL bDosFiletimeResolution;
438 BOOL bFakeDirCreateTimes;
444 BOOL bUseClientDriver;
445 BOOL bDefaultDevmode;
446 BOOL bForcePrintername;
448 BOOL bForceUnknownAclUser;
451 BOOL bMap_acl_inherit;
454 BOOL bAclCheckPermissions;
455 BOOL bAclMapFullControl;
456 BOOL bAclGroupControl;
458 BOOL bKernelChangeNotify;
459 int iallocation_roundup_size;
463 param_opt_struct *param_opt;
465 char dummy[3]; /* for alignment */
469 /* This is a default service used to prime a services structure */
470 static service sDefault = {
472 False, /* not autoloaded */
473 0, /* not a usershare */
474 (time_t)0, /* No last mod time */
475 NULL, /* szService */
477 NULL, /* szUsername */
478 NULL, /* szInvalidUsers */
479 NULL, /* szValidUsers */
480 NULL, /* szAdminUsers */
482 NULL, /* szInclude */
483 NULL, /* szPreExec */
484 NULL, /* szPostExec */
485 NULL, /* szRootPreExec */
486 NULL, /* szRootPostExec */
487 NULL, /* szCupsOptions */
488 NULL, /* szPrintcommand */
489 NULL, /* szLpqcommand */
490 NULL, /* szLprmcommand */
491 NULL, /* szLppausecommand */
492 NULL, /* szLpresumecommand */
493 NULL, /* szQueuepausecommand */
494 NULL, /* szQueueresumecommand */
495 NULL, /* szPrintername */
496 NULL, /* szPrintjobUsername */
497 NULL, /* szDontdescend */
498 NULL, /* szHostsallow */
499 NULL, /* szHostsdeny */
500 NULL, /* szMagicScript */
501 NULL, /* szMagicOutput */
502 NULL, /* szMangledMap */
503 NULL, /* szVetoFiles */
504 NULL, /* szHideFiles */
505 NULL, /* szVetoOplockFiles */
507 NULL, /* force user */
508 NULL, /* force group */
510 NULL, /* writelist */
511 NULL, /* printer admin */
514 NULL, /* vfs objects */
515 NULL, /* szMSDfsProxy */
517 0, /* iMinPrintSpace */
518 1000, /* iMaxPrintJobs */
519 0, /* iMaxReportedPrintJobs */
520 0, /* iWriteCacheSize */
521 0744, /* iCreate_mask */
522 0000, /* iCreate_force_mode */
523 0777, /* iSecurity_mask */
524 0, /* iSecurity_force_mode */
525 0755, /* iDir_mask */
526 0000, /* iDir_force_mode */
527 0777, /* iDir_Security_mask */
528 0, /* iDir_Security_force_mode */
529 0, /* iMaxConnections */
530 CASE_LOWER, /* iDefaultCase */
531 DEFAULT_PRINTING, /* iPrinting */
532 2, /* iOplockContentionLimit */
534 1024, /* iBlock_size */
535 0, /* iDfreeCacheTime */
536 False, /* bPreexecClose */
537 False, /* bRootpreexecClose */
538 Auto, /* case sensitive */
539 True, /* case preserve */
540 True, /* short case preserve */
541 True, /* bHideDotFiles */
542 False, /* bHideSpecialFiles */
543 False, /* bHideUnReadable */
544 False, /* bHideUnWriteableFiles */
545 True, /* bBrowseable */
546 True, /* bAvailable */
547 True, /* bRead_only */
548 True, /* bNo_set_dir */
549 False, /* bGuest_only */
550 False, /* bGuest_ok */
551 False, /* bPrint_ok */
552 False, /* bMap_system */
553 False, /* bMap_hidden */
554 True, /* bMap_archive */
555 False, /* bStoreDosAttributes */
556 False, /* bDmapiSupport */
558 Auto, /* iStrictLocking */
559 True, /* bPosixLocking */
560 True, /* bShareModes */
562 True, /* bLevel2OpLocks */
563 False, /* bOnlyUser */
564 True, /* bMangledNames */
565 True, /* bWidelinks */
566 True, /* bSymlinks */
567 False, /* bSyncAlways */
568 False, /* bStrictAllocate */
569 False, /* bStrictSync */
570 '~', /* magic char */
572 False, /* bDeleteReadonly */
573 False, /* bFakeOplocks */
574 False, /* bDeleteVetoFiles */
575 False, /* bDosFilemode */
576 True, /* bDosFiletimes */
577 False, /* bDosFiletimeResolution */
578 False, /* bFakeDirCreateTimes */
579 True, /* bBlockingLocks */
580 False, /* bInheritPerms */
581 False, /* bInheritACLS */
582 False, /* bInheritOwner */
583 False, /* bMSDfsRoot */
584 False, /* bUseClientDriver */
585 True, /* bDefaultDevmode */
586 False, /* bForcePrintername */
587 True, /* bNTAclSupport */
588 False, /* bForceUnknownAclUser */
589 False, /* bUseSendfile */
590 False, /* bProfileAcls */
591 False, /* bMap_acl_inherit */
592 False, /* bAfs_Share */
593 False, /* bEASupport */
594 True, /* bAclCheckPermissions */
595 True, /* bAclMapFullControl */
596 False, /* bAclGroupControl */
597 True, /* bChangeNotify */
598 True, /* bKernelChangeNotify */
599 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
600 0, /* iAioReadSize */
601 0, /* iAioWriteSize */
602 MAP_READONLY_YES, /* iMap_readonly */
604 NULL, /* Parametric options */
609 /* local variables */
610 static service **ServicePtrs = NULL;
611 static int iNumServices = 0;
612 static int iServiceIndex = 0;
613 static TDB_CONTEXT *ServiceHash;
614 static int *invalid_services = NULL;
615 static int num_invalid_services = 0;
616 static BOOL bInGlobalSection = True;
617 static BOOL bGlobalOnly = False;
618 static int server_role;
619 static int default_server_announce;
621 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
623 /* prototypes for the special type handlers */
624 static BOOL handle_include( int snum, const char *pszParmValue, char **ptr);
625 static BOOL handle_copy( int snum, const char *pszParmValue, char **ptr);
626 static BOOL handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
627 static BOOL handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
628 static BOOL handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
629 static BOOL handle_debug_list( int snum, const char *pszParmValue, char **ptr );
630 static BOOL handle_workgroup( int snum, const char *pszParmValue, char **ptr );
631 static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
632 static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
633 static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
634 static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
636 static void set_server_role(void);
637 static void set_default_server_announce_type(void);
638 static void set_allowed_client_auth(void);
640 static const struct enum_list enum_protocol[] = {
641 {PROTOCOL_NT1, "NT1"},
642 {PROTOCOL_LANMAN2, "LANMAN2"},
643 {PROTOCOL_LANMAN1, "LANMAN1"},
644 {PROTOCOL_CORE, "CORE"},
645 {PROTOCOL_COREPLUS, "COREPLUS"},
646 {PROTOCOL_COREPLUS, "CORE+"},
650 static const struct enum_list enum_security[] = {
651 {SEC_SHARE, "SHARE"},
653 {SEC_SERVER, "SERVER"},
654 {SEC_DOMAIN, "DOMAIN"},
661 static const struct enum_list enum_printing[] = {
662 {PRINT_SYSV, "sysv"},
664 {PRINT_HPUX, "hpux"},
668 {PRINT_LPRNG, "lprng"},
669 {PRINT_CUPS, "cups"},
670 {PRINT_IPRINT, "iprint"},
672 {PRINT_LPROS2, "os2"},
674 {PRINT_TEST, "test"},
676 #endif /* DEVELOPER */
680 static const struct enum_list enum_ldap_ssl[] = {
681 {LDAP_SSL_OFF, "no"},
682 {LDAP_SSL_OFF, "No"},
683 {LDAP_SSL_OFF, "off"},
684 {LDAP_SSL_OFF, "Off"},
685 {LDAP_SSL_START_TLS, "start tls"},
686 {LDAP_SSL_START_TLS, "Start_tls"},
690 static const struct enum_list enum_ldap_passwd_sync[] = {
691 {LDAP_PASSWD_SYNC_OFF, "no"},
692 {LDAP_PASSWD_SYNC_OFF, "No"},
693 {LDAP_PASSWD_SYNC_OFF, "off"},
694 {LDAP_PASSWD_SYNC_OFF, "Off"},
695 {LDAP_PASSWD_SYNC_ON, "Yes"},
696 {LDAP_PASSWD_SYNC_ON, "yes"},
697 {LDAP_PASSWD_SYNC_ON, "on"},
698 {LDAP_PASSWD_SYNC_ON, "On"},
699 {LDAP_PASSWD_SYNC_ONLY, "Only"},
700 {LDAP_PASSWD_SYNC_ONLY, "only"},
704 /* Types of machine we can announce as. */
705 #define ANNOUNCE_AS_NT_SERVER 1
706 #define ANNOUNCE_AS_WIN95 2
707 #define ANNOUNCE_AS_WFW 3
708 #define ANNOUNCE_AS_NT_WORKSTATION 4
710 static const struct enum_list enum_announce_as[] = {
711 {ANNOUNCE_AS_NT_SERVER, "NT"},
712 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
713 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
714 {ANNOUNCE_AS_WIN95, "win95"},
715 {ANNOUNCE_AS_WFW, "WfW"},
719 static const struct enum_list enum_map_readonly[] = {
720 {MAP_READONLY_NO, "no"},
721 {MAP_READONLY_NO, "false"},
722 {MAP_READONLY_NO, "0"},
723 {MAP_READONLY_YES, "yes"},
724 {MAP_READONLY_YES, "true"},
725 {MAP_READONLY_YES, "1"},
726 {MAP_READONLY_PERMISSIONS, "permissions"},
727 {MAP_READONLY_PERMISSIONS, "perms"},
731 static const struct enum_list enum_case[] = {
732 {CASE_LOWER, "lower"},
733 {CASE_UPPER, "upper"},
737 static const struct enum_list enum_bool_auto[] = {
748 /* Client-side offline caching policy types */
749 #define CSC_POLICY_MANUAL 0
750 #define CSC_POLICY_DOCUMENTS 1
751 #define CSC_POLICY_PROGRAMS 2
752 #define CSC_POLICY_DISABLE 3
754 static const struct enum_list enum_csc_policy[] = {
755 {CSC_POLICY_MANUAL, "manual"},
756 {CSC_POLICY_DOCUMENTS, "documents"},
757 {CSC_POLICY_PROGRAMS, "programs"},
758 {CSC_POLICY_DISABLE, "disable"},
762 /* SMB signing types. */
763 static const struct enum_list enum_smb_signing_vals[] = {
775 {Required, "required"},
776 {Required, "mandatory"},
778 {Required, "forced"},
779 {Required, "enforced"},
783 /* ACL compatibility options. */
784 static const struct enum_list enum_acl_compat_vals[] = {
785 { ACL_COMPAT_AUTO, "auto" },
786 { ACL_COMPAT_WINNT, "winnt" },
787 { ACL_COMPAT_WIN2K, "win2k" },
792 Do you want session setups at user level security with a invalid
793 password to be rejected or allowed in as guest? WinNT rejects them
794 but it can be a pain as it means "net view" needs to use a password
796 You have 3 choices in the setting of map_to_guest:
798 "Never" means session setups with an invalid password
799 are rejected. This is the default.
801 "Bad User" means session setups with an invalid password
802 are rejected, unless the username does not exist, in which case it
803 is treated as a guest login
805 "Bad Password" means session setups with an invalid password
806 are treated as a guest login
808 Note that map_to_guest only has an effect in user or server
812 static const struct enum_list enum_map_to_guest[] = {
813 {NEVER_MAP_TO_GUEST, "Never"},
814 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
815 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
816 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
820 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
822 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
823 * screen in SWAT. This is used to exclude parameters as well as to squash all
824 * parameters that have been duplicated by pseudonyms.
826 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
827 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
828 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
831 * NOTE2: Handling of duplicated (synonym) paramters:
832 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
833 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
834 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
835 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
838 static struct parm_struct parm_table[] = {
839 {N_("Base Options"), P_SEP, P_SEPARATOR},
841 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
842 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
843 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
844 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
845 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
846 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
847 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
849 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
851 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
852 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
853 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
854 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
855 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
856 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
858 {N_("Security Options"), P_SEP, P_SEPARATOR},
860 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
861 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
862 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
863 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
864 {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
865 {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
866 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
867 {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
868 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
869 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
870 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
871 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
872 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
873 {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
874 {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
875 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
876 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
877 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
878 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
879 {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
881 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
882 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
883 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
884 {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
885 {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
886 {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED},
887 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
888 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
889 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
890 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
891 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
892 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
893 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
894 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
895 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
896 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
898 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
899 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
900 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
902 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
903 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
904 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
905 {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
906 {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
907 {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED },
908 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
909 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
910 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
912 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
913 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
914 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
915 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
917 {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
918 {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED },
919 {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
920 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
921 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
922 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
923 {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
924 {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
925 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
926 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
927 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
928 {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
929 {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
930 {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
931 {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
932 {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
933 {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
934 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
935 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
937 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
938 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
940 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
941 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
942 {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
943 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
944 {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
945 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
946 {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED},
948 {N_("Logging Options"), P_SEP, P_SEPARATOR},
950 {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
951 {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
952 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
953 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
954 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
956 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
957 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
958 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
959 {"debug prefix timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugPrefixTimestamp, NULL, NULL, FLAG_ADVANCED},
960 {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
961 {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
962 {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
963 {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
965 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
967 {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED},
968 {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED},
969 {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED},
970 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
971 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
972 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
973 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
974 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
975 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED},
976 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
977 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
978 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
979 {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED},
981 {"acl compatibility", P_ENUM, P_GLOBAL, &Globals.iAclCompat, NULL, enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
982 {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
983 {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
984 {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
985 {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
986 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
987 {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
989 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
990 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED},
991 {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
992 {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
993 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
994 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
996 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
997 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
998 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
999 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
1000 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
1001 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
1002 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
1003 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1004 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1005 {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
1007 {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED},
1008 {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
1010 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1012 {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1013 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
1014 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
1015 {"keepalive", P_INTEGER, P_GLOBAL, &Globals.iKeepalive, NULL, NULL, FLAG_ADVANCED},
1016 {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1017 {"kernel change notify", P_BOOL, P_LOCAL, &sDefault.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1019 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
1020 {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
1021 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1022 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
1023 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
1024 {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
1025 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1026 {"open files database hash size", P_INTEGER, P_GLOBAL, &Globals.open_files_db_hash_size, NULL, NULL, FLAG_ADVANCED},
1028 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
1029 {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1030 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1031 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1032 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
1033 {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1034 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
1035 {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
1037 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
1038 {"ctdbd socket", P_STRING, P_GLOBAL, &Globals.ctdbdSocket, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1039 {"clustering", P_BOOL, P_GLOBAL, &Globals.clustering, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1041 {N_("Printing Options 2"), P_SEP, P_SEPARATOR},
1043 {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1044 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1045 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1046 {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1047 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1048 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
1049 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1050 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
1051 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1052 {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1053 {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1054 {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1055 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1056 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1057 {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE},
1058 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1059 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1060 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1061 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1062 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1063 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1065 {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED},
1066 {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
1067 {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
1068 {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
1069 {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
1070 {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
1072 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1073 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
1074 {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1075 {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1076 {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1077 {"printjob username", P_STRING, P_LOCAL, &sDefault.szPrintjobUsername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1079 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
1080 {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
1081 {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
1083 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
1084 {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1085 {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE},
1086 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1087 {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1088 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1089 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1090 {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1091 {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1092 {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1093 {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1094 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1095 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1096 {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1097 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1098 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1099 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1100 {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1101 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1102 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED },
1103 {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
1104 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
1105 {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1106 {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1109 {N_("Domain Options"), P_SEP, P_SEPARATOR},
1111 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1113 {N_("Logon Options"), P_SEP, P_SEPARATOR},
1115 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
1116 {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
1117 {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
1118 {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
1119 {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
1120 {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
1121 {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
1122 {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
1123 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
1124 {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
1125 {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
1126 {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED},
1128 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
1129 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
1130 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
1131 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
1132 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
1134 {N_("Browse Options"), P_SEP, P_SEPARATOR},
1136 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1137 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
1138 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
1139 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1140 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
1141 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1142 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1143 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
1144 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1145 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1146 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
1148 {N_("WINS Options"), P_SEP, P_SEPARATOR},
1150 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
1151 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
1153 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1154 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1155 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
1157 {N_("Locking Options"), P_SEP, P_SEPARATOR},
1159 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1160 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1161 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1162 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1163 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1164 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1166 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1167 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1168 {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1169 {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1170 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1171 {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1172 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1174 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
1176 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
1177 {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
1178 {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
1179 {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
1180 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
1181 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
1182 {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE},
1183 {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1184 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
1185 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
1186 {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1187 {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
1188 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
1190 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
1191 {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
1192 {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
1193 {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
1195 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
1196 {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1198 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1199 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1200 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1201 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
1202 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
1203 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
1205 {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
1206 {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
1207 {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
1210 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1211 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1212 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
1213 {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED},
1214 {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED},
1215 {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
1216 {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
1217 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
1218 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
1219 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
1220 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
1221 {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
1222 {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1223 {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1224 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
1225 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
1226 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1228 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1229 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1230 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1231 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
1233 {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1234 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1235 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1236 {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1237 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1238 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1239 {"registry shares", P_BOOL, P_GLOBAL, &Globals.bRegistryShares, NULL, NULL, FLAG_ADVANCED},
1240 {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
1241 {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
1242 {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED},
1243 {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
1244 {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED},
1245 {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED},
1246 {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
1247 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1248 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1249 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1250 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1251 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1252 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1253 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1254 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1255 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1256 {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1257 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1258 {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1260 {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1261 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
1263 {N_("VFS module options"), P_SEP, P_SEPARATOR},
1265 {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1266 {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
1269 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1270 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1271 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
1273 {N_("Winbind options"), P_SEP, P_SEPARATOR},
1275 {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
1276 {"idmap domains", P_LIST, P_GLOBAL, &Globals.szIdmapDomains, NULL, NULL, FLAG_ADVANCED},
1277 {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED },
1278 {"idmap alloc backend", P_STRING, P_GLOBAL, &Globals.szIdmapAllocBackend, NULL, NULL, FLAG_ADVANCED},
1279 {"idmap cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapCacheTime, NULL, NULL, FLAG_ADVANCED},
1280 {"idmap negative cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeCacheTime, NULL, NULL, FLAG_ADVANCED},
1281 {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED },
1282 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE },
1283 {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED },
1284 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE },
1285 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
1286 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
1287 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
1288 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
1289 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
1290 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
1291 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
1292 {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
1293 {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
1294 {"winbind expand groups", P_INTEGER, P_GLOBAL, &Globals.winbind_expand_groups, NULL, NULL, FLAG_ADVANCED},
1295 {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED},
1296 {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED},
1297 {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
1298 {"winbind normalize names", P_BOOL, P_GLOBAL, &Globals.bWinbindNormalizeNames, NULL, NULL, FLAG_ADVANCED},
1299 {"winbind rpc only", P_BOOL, P_GLOBAL, &Globals.bWinbindRpcOnly, NULL, NULL, FLAG_ADVANCED},
1301 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1304 /***************************************************************************
1305 Initialise the sDefault parameter structure for the printer values.
1306 ***************************************************************************/
1308 static void init_printer_values(service *pService)
1310 /* choose defaults depending on the type of printing */
1311 switch (pService->iPrinting) {
1316 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1317 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1318 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1323 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1324 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1325 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1326 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1327 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1328 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1329 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1335 /* set the lpq command to contain the destination printer
1336 name only. This is used by cups_queue_get() */
1337 string_set(&pService->szLpqcommand, "%p");
1338 string_set(&pService->szLprmcommand, "");
1339 string_set(&pService->szPrintcommand, "");
1340 string_set(&pService->szLppausecommand, "");
1341 string_set(&pService->szLpresumecommand, "");
1342 string_set(&pService->szQueuepausecommand, "");
1343 string_set(&pService->szQueueresumecommand, "");
1345 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1346 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1347 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
1348 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1349 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1350 string_set(&pService->szQueuepausecommand, "disable '%p'");
1351 string_set(&pService->szQueueresumecommand, "enable '%p'");
1352 #endif /* HAVE_CUPS */
1357 string_set(&pService->szLpqcommand, "lpstat -o%p");
1358 string_set(&pService->szLprmcommand, "cancel %p-%j");
1359 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1360 string_set(&pService->szQueuepausecommand, "disable %p");
1361 string_set(&pService->szQueueresumecommand, "enable %p");
1363 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1364 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1369 string_set(&pService->szLpqcommand, "lpq -P%p");
1370 string_set(&pService->szLprmcommand, "lprm -P%p %j");
1371 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1377 string_set(&pService->szPrintcommand, "vlp print %p %s");
1378 string_set(&pService->szLpqcommand, "vlp lpq %p");
1379 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1380 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1381 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1382 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1383 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1385 #endif /* DEVELOPER */
1390 /***************************************************************************
1391 Initialise the global parameter structure.
1392 ***************************************************************************/
1394 static void init_globals(BOOL first_time_only)
1396 static BOOL done_init = False;
1399 /* If requested to initialize only once and we've already done it... */
1400 if (first_time_only && done_init) {
1401 /* ... then we have nothing more to do */
1408 /* The logfile can be set before this is invoked. Free it if so. */
1409 if (Globals.szLogFile != NULL) {
1410 string_free(&Globals.szLogFile);
1411 Globals.szLogFile = NULL;
1414 memset((void *)&Globals, '\0', sizeof(Globals));
1416 for (i = 0; parm_table[i].label; i++)
1417 if ((parm_table[i].type == P_STRING ||
1418 parm_table[i].type == P_USTRING) &&
1420 string_set((char **)parm_table[i].ptr, "");
1422 string_set(&sDefault.fstype, FSTYPE_STRING);
1423 string_set(&sDefault.szPrintjobUsername, "%U");
1425 init_printer_values(&sDefault);
1431 DEBUG(3, ("Initialising global parameters\n"));
1433 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1434 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1436 /* use the new 'hash2' method by default, with a prefix of 1 */
1437 string_set(&Globals.szManglingMethod, "hash2");
1438 Globals.mangle_prefix = 1;
1440 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1442 /* using UTF8 by default allows us to support all chars */
1443 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1445 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1446 /* If the system supports nl_langinfo(), try to grab the value
1447 from the user's locale */
1448 string_set(&Globals.display_charset, "LOCALE");
1450 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1453 /* Use codepage 850 as a default for the dos character set */
1454 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1457 * Allow the default PASSWD_CHAT to be overridden in local.h.
1459 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1461 set_global_myname(myhostname());
1462 string_set(&Globals.szNetbiosName,global_myname());
1464 set_global_myworkgroup(WORKGROUP);
1465 string_set(&Globals.szWorkgroup, lp_workgroup());
1467 string_set(&Globals.szPasswdProgram, "");
1468 string_set(&Globals.szPidDir, dyn_PIDDIR);
1469 string_set(&Globals.szLockDir, dyn_LOCKDIR);
1470 string_set(&Globals.szSocketAddress, "0.0.0.0");
1471 pstrcpy(s, "Samba ");
1472 pstrcat(s, SAMBA_VERSION_STRING);
1473 string_set(&Globals.szServerString, s);
1474 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1475 DEFAULT_MINOR_VERSION);
1476 string_set(&Globals.szAnnounceVersion, s);
1478 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1481 pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1483 string_set(&Globals.szLogonDrive, "");
1484 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1485 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1486 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1488 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1489 string_set(&Globals.szPasswordServer, "*");
1491 Globals.AlgorithmicRidBase = BASE_RID;
1493 Globals.bLoadPrinters = True;
1494 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
1496 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1497 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1498 Globals.max_xmit = 0x4104;
1499 Globals.max_mux = 50; /* This is *needed* for profile support. */
1500 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
1501 Globals.bDisableSpoolss = False;
1502 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1503 Globals.pwordlevel = 0;
1504 Globals.unamelevel = 0;
1505 Globals.deadtime = 0;
1506 Globals.bLargeReadwrite = True;
1507 Globals.max_log_size = 5000;
1508 Globals.max_open_files = MAX_OPEN_FILES;
1509 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
1510 Globals.maxprotocol = PROTOCOL_NT1;
1511 Globals.minprotocol = PROTOCOL_CORE;
1512 Globals.security = SEC_USER;
1513 Globals.paranoid_server_security = True;
1514 Globals.bEncryptPasswords = True;
1515 Globals.bUpdateEncrypt = False;
1516 Globals.clientSchannel = Auto;
1517 Globals.serverSchannel = Auto;
1518 Globals.bReadRaw = True;
1519 Globals.bWriteRaw = True;
1520 Globals.bReadbmpx = False;
1521 Globals.bNullPasswords = False;
1522 Globals.bObeyPamRestrictions = False;
1524 Globals.bSyslogOnly = False;
1525 Globals.bTimestampLogs = True;
1526 string_set(&Globals.szLogLevel, "0");
1527 Globals.bDebugPrefixTimestamp = False;
1528 Globals.bDebugHiresTimestamp = False;
1529 Globals.bDebugPid = False;
1530 Globals.bDebugUid = False;
1531 Globals.bEnableCoreFiles = True;
1532 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1533 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1534 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1535 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1536 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1537 Globals.lm_interval = 60;
1538 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1539 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1540 Globals.bNISHomeMap = False;
1541 #ifdef WITH_NISPLUS_HOME
1542 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1544 string_set(&Globals.szNISHomeMapName, "auto.home");
1547 Globals.bTimeServer = False;
1548 Globals.bBindInterfacesOnly = False;
1549 Globals.bUnixPasswdSync = False;
1550 Globals.bPamPasswordChange = False;
1551 Globals.bPasswdChatDebug = False;
1552 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1553 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
1554 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1555 Globals.bStatCache = True; /* use stat cache by default */
1556 Globals.iMaxStatCacheSize = 1024; /* one Meg by default. */
1557 Globals.restrict_anonymous = 0;
1558 Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
1559 Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */
1560 Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
1561 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1562 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1563 /* Note, that we will use NTLM2 session security (which is different), if it is available */
1565 Globals.map_to_guest = 0; /* By Default, "Never" */
1566 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
1567 Globals.enhanced_browsing = True;
1568 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
1569 #ifdef MMAP_BLACKLIST
1570 Globals.bUseMmap = False;
1572 Globals.bUseMmap = True;
1574 Globals.bUnixExtensions = True;
1575 Globals.bResetOnZeroVC = False;
1577 /* hostname lookups can be very expensive and are broken on
1578 a large number of sites (tridge) */
1579 Globals.bHostnameLookups = False;
1581 string_set(&Globals.szPassdbBackend, "smbpasswd");
1582 string_set(&Globals.szLdapSuffix, "");
1583 string_set(&Globals.szLdapMachineSuffix, "");
1584 string_set(&Globals.szLdapUserSuffix, "");
1585 string_set(&Globals.szLdapGroupSuffix, "");
1586 string_set(&Globals.szLdapIdmapSuffix, "");
1588 string_set(&Globals.szLdapAdminDn, "");
1589 Globals.ldap_ssl = LDAP_SSL_ON;
1590 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1591 Globals.ldap_delete_dn = False;
1592 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1593 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1594 Globals.ldap_page_size = LDAP_PAGE_SIZE;
1596 /* This is what we tell the afs client. in reality we set the token
1597 * to never expire, though, when this runs out the afs client will
1598 * forget the token. Set to 0 to get NEVERDATE.*/
1599 Globals.iAfsTokenLifetime = 604800;
1601 /* these parameters are set to defaults that are more appropriate
1602 for the increasing samba install base:
1604 as a member of the workgroup, that will possibly become a
1605 _local_ master browser (lm = True). this is opposed to a forced
1606 local master browser startup (pm = True).
1608 doesn't provide WINS server service by default (wsupp = False),
1609 and doesn't provide domain master browser services by default, either.
1613 Globals.bMsAddPrinterWizard = True;
1614 Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
1615 Globals.os_level = 20;
1616 Globals.bLocalMaster = True;
1617 Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
1618 Globals.bDomainLogons = False;
1619 Globals.bBrowseList = True;
1620 Globals.bWINSsupport = False;
1621 Globals.bWINSproxy = False;
1623 Globals.bDNSproxy = True;
1625 /* this just means to use them if they exist */
1626 Globals.bKernelOplocks = True;
1628 Globals.bAllowTrustedDomains = True;
1630 string_set(&Globals.szTemplateShell, "/bin/false");
1631 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1632 string_set(&Globals.szWinbindSeparator, "\\");
1634 string_set(&Globals.szCupsServer, "");
1635 string_set(&Globals.szIPrintServer, "");
1637 string_set(&Globals.ctdbdSocket, "");
1638 Globals.clustering = False;
1640 Globals.winbind_cache_time = 300; /* 5 minutes */
1641 Globals.bWinbindEnumUsers = False;
1642 Globals.bWinbindEnumGroups = False;
1643 Globals.bWinbindUseDefaultDomain = False;
1644 Globals.bWinbindTrustedDomainsOnly = False;
1645 Globals.bWinbindNestedGroups = True;
1646 Globals.winbind_expand_groups = 1;
1647 Globals.szWinbindNssInfo = str_list_make("template", NULL);
1648 Globals.bWinbindRefreshTickets = False;
1649 Globals.bWinbindOfflineLogon = False;
1651 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
1652 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
1654 Globals.bPassdbExpandExplicit = False;
1656 Globals.name_cache_timeout = 660; /* In seconds */
1658 Globals.bUseSpnego = True;
1659 Globals.bClientUseSpnego = True;
1661 Globals.client_signing = Auto;
1662 Globals.server_signing = False;
1664 Globals.bDeferSharingViolations = True;
1665 string_set(&Globals.smb_ports, SMB_PORTS);
1667 Globals.bEnablePrivileges = True;
1668 Globals.bHostMSDfs = True;
1669 Globals.bASUSupport = False;
1671 /* User defined shares. */
1672 pstrcpy(s, dyn_LOCKDIR);
1673 pstrcat(s, "/usershares");
1674 string_set(&Globals.szUsersharePath, s);
1675 string_set(&Globals.szUsershareTemplateShare, "");
1676 Globals.iUsershareMaxShares = 0;
1677 /* By default disallow sharing of directories not owned by the sharer. */
1678 Globals.bUsershareOwnerOnly = True;
1679 /* By default disallow guest access to usershares. */
1680 Globals.bUsershareAllowGuests = False;
1682 Globals.iKeepalive = DEFAULT_KEEPALIVE;
1684 /* By default no shares out of the registry */
1685 Globals.bRegistryShares = False;
1688 static TALLOC_CTX *lp_talloc;
1690 /******************************************************************* a
1691 Free up temporary memory - called from the main loop.
1692 ********************************************************************/
1694 void lp_TALLOC_FREE(void)
1698 TALLOC_FREE(lp_talloc);
1702 TALLOC_CTX *tmp_talloc_ctx(void)
1704 if (lp_talloc == NULL) {
1705 lp_talloc = talloc_init("tmp_talloc_ctx");
1708 if (lp_talloc == NULL) {
1709 smb_panic("Could not create temporary talloc context\n");
1715 /*******************************************************************
1716 Convenience routine to grab string parameters into temporary memory
1717 and run standard_sub_basic on them. The buffers can be written to by
1718 callers without affecting the source string.
1719 ********************************************************************/
1721 static char *lp_string(const char *s)
1725 /* The follow debug is useful for tracking down memory problems
1726 especially if you have an inner loop that is calling a lp_*()
1727 function that returns a string. Perhaps this debug should be
1728 present all the time? */
1731 DEBUG(10, ("lp_string(%s)\n", s));
1735 lp_talloc = talloc_init("lp_talloc");
1737 tmpstr = alloc_sub_basic(get_current_username(),
1738 current_user_info.domain, s);
1739 if (trim_char(tmpstr, '\"', '\"')) {
1740 if (strchr(tmpstr,'\"') != NULL) {
1742 tmpstr = alloc_sub_basic(get_current_username(),
1743 current_user_info.domain, s);
1746 ret = talloc_strdup(lp_talloc, tmpstr);
1753 In this section all the functions that are used to access the
1754 parameters from the rest of the program are defined
1757 #define FN_GLOBAL_STRING(fn_name,ptr) \
1758 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1759 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1760 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1761 #define FN_GLOBAL_LIST(fn_name,ptr) \
1762 const char **fn_name(void) {return(*(const char ***)(ptr));}
1763 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1764 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1765 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1766 char fn_name(void) {return(*(char *)(ptr));}
1767 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1768 int fn_name(void) {return(*(int *)(ptr));}
1770 #define FN_LOCAL_STRING(fn_name,val) \
1771 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1772 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1773 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1774 #define FN_LOCAL_LIST(fn_name,val) \
1775 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1776 #define FN_LOCAL_BOOL(fn_name,val) \
1777 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1778 #define FN_LOCAL_INTEGER(fn_name,val) \
1779 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1781 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1782 BOOL fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1783 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1784 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1785 #define FN_LOCAL_PARM_STRING(fn_name,val) \
1786 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));}
1787 #define FN_LOCAL_CHAR(fn_name,val) \
1788 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1790 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1791 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1792 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1793 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1794 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1795 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1796 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1797 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1798 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1799 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1800 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1801 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1802 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1803 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1804 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1805 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1806 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1807 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1808 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1809 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1810 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1811 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1812 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1813 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1814 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1815 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1816 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1817 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1818 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1819 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1820 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1821 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1822 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1823 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1824 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1825 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1826 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1827 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1828 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1829 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1830 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1831 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1832 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1833 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1834 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1835 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1836 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1837 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1838 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1839 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1840 * lp_passdb_backend() should be replace by the this macro again after
1843 const char *lp_passdb_backend(void)
1845 char *delim, *quote;
1847 delim = strchr( Globals.szPassdbBackend, ' ');
1848 /* no space at all */
1849 if (delim == NULL) {
1853 quote = strchr(Globals.szPassdbBackend, '"');
1854 /* no quote char or non in the first part */
1855 if (quote == NULL || quote > delim) {
1860 quote = strchr(quote+1, '"');
1861 if (quote == NULL) {
1862 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
1864 } else if (*(quote+1) == '\0') {
1865 /* space, fitting quote char, and one backend only */
1868 /* terminate string after the fitting quote char */
1873 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
1874 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
1875 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
1876 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
1879 return Globals.szPassdbBackend;
1881 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1882 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1883 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1884 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1885 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1887 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1888 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1889 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1890 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1891 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1892 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1894 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1896 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1897 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1898 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1900 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1902 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1903 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1904 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1905 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1906 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
1907 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1908 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1909 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1910 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1911 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1912 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
1913 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1914 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1915 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
1916 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
1918 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
1919 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
1920 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
1921 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
1922 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
1923 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
1924 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1926 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1927 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1928 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1929 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1930 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1931 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1932 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1933 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1934 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1935 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1936 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1937 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1938 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1939 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1941 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1943 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
1944 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1945 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1946 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1947 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1948 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1949 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1950 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1951 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1952 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1953 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1954 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1955 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1956 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1957 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1958 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1959 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1960 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1961 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1962 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1963 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1964 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1965 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1966 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1967 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1968 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
1969 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1970 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1971 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1972 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
1973 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1974 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1975 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1976 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1977 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1978 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1979 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1980 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1981 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1982 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1983 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1984 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1985 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1986 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1987 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1988 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1989 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1990 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1991 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1992 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1993 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1994 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1995 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1996 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1997 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1998 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1999 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
2000 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
2001 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
2002 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
2003 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
2004 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
2005 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
2006 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
2007 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
2008 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
2009 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
2010 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
2011 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
2012 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
2013 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
2014 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
2015 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
2016 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
2017 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
2018 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
2019 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
2020 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
2021 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
2022 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
2023 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
2024 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
2025 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
2026 FN_GLOBAL_INTEGER(_lp_disable_spoolss, &Globals.bDisableSpoolss)
2027 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
2028 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
2029 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
2030 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
2031 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
2032 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
2033 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
2034 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
2035 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
2037 FN_LOCAL_STRING(lp_preexec, szPreExec)
2038 FN_LOCAL_STRING(lp_postexec, szPostExec)
2039 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
2040 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
2041 FN_LOCAL_STRING(lp_servicename, szService)
2042 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
2043 FN_LOCAL_STRING(lp_pathname, szPath)
2044 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
2045 FN_LOCAL_STRING(lp_username, szUsername)
2046 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
2047 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
2048 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
2049 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
2050 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
2051 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
2052 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
2053 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
2054 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering);
2055 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
2056 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
2057 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
2058 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
2059 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
2060 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
2061 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
2062 static FN_LOCAL_STRING(_lp_printername, szPrintername)
2063 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
2064 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
2065 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
2066 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
2067 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
2068 FN_LOCAL_STRING(lp_comment, comment)
2069 FN_LOCAL_STRING(lp_force_user, force_user)
2070 FN_LOCAL_STRING(lp_force_group, force_group)
2071 FN_LOCAL_LIST(lp_readlist, readlist)
2072 FN_LOCAL_LIST(lp_writelist, writelist)
2073 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
2074 FN_LOCAL_STRING(lp_fstype, fstype)
2075 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
2076 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
2077 static FN_LOCAL_STRING(lp_volume, volume)
2078 FN_LOCAL_PARM_STRING(lp_mangled_map, szMangledMap)
2079 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
2080 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
2081 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
2082 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
2083 FN_LOCAL_STRING(lp_dfree_command, szDfree)
2084 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
2085 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
2086 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
2087 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
2088 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
2089 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
2090 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
2091 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2092 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2093 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2094 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2095 FN_LOCAL_BOOL(lp_readonly, bRead_only)
2096 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2097 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2098 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2099 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2100 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2101 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2102 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2103 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2104 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
2105 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
2106 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
2107 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2108 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2109 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2110 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2111 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
2112 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2113 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2114 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2115 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2116 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2117 FN_LOCAL_BOOL(lp_map_system, bMap_system)
2118 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2119 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2120 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2121 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2122 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2123 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2124 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2125 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2126 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2127 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2128 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2129 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2130 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2131 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2132 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2133 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2134 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2135 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2136 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2137 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2138 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2139 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2140 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2141 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2142 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2143 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2144 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2145 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2146 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2147 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2148 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2149 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2150 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2151 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2152 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2153 FN_LOCAL_INTEGER(lp_printing, iPrinting)
2154 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2155 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2156 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2157 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2158 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2159 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2160 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2161 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2162 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2163 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2164 FN_LOCAL_CHAR(lp_magicchar, magic_char)
2165 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2166 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2167 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2168 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2169 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2170 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2172 /* local prototypes */
2174 static int map_parameter(const char *pszParmName);
2175 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
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);
2187 /* This is a helper function for parametrical options support. */
2188 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2189 /* Actual parametrical functions are quite simple */
2190 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2192 BOOL global_section = False;
2194 param_opt_struct *data;
2196 if (snum >= iNumServices) return NULL;
2199 data = Globals.param_opt;
2200 global_section = True;
2202 data = ServicePtrs[snum]->param_opt;
2205 asprintf(¶m_key, "%s:%s", type, option);
2207 DEBUG(0,("asprintf failed!\n"));
2212 if (strcmp(data->key, param_key) == 0) {
2213 string_free(¶m_key);
2219 if (!global_section) {
2220 /* Try to fetch the same option but from globals */
2221 /* but only if we are not already working with Globals */
2222 data = Globals.param_opt;
2224 if (strcmp(data->key, param_key) == 0) {
2225 string_free(¶m_key);
2232 string_free(¶m_key);
2238 #define MISSING_PARAMETER(name) \
2239 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2241 /*******************************************************************
2242 convenience routine to return int parameters.
2243 ********************************************************************/
2244 static int lp_int(const char *s)
2248 MISSING_PARAMETER(lp_int);
2252 return (int)strtol(s, NULL, 0);
2255 /*******************************************************************
2256 convenience routine to return unsigned long parameters.
2257 ********************************************************************/
2258 static unsigned long lp_ulong(const char *s)
2262 MISSING_PARAMETER(lp_ulong);
2266 return strtoul(s, NULL, 0);
2269 /*******************************************************************
2270 convenience routine to return boolean parameters.
2271 ********************************************************************/
2272 static BOOL lp_bool(const char *s)
2277 MISSING_PARAMETER(lp_bool);
2281 if (!set_boolean(&ret,s)) {
2282 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2289 /*******************************************************************
2290 convenience routine to return enum parameters.
2291 ********************************************************************/
2292 static int lp_enum(const char *s,const struct enum_list *_enum)
2296 if (!s || !*s || !_enum) {
2297 MISSING_PARAMETER(lp_enum);
2301 for (i=0; _enum[i].name; i++) {
2302 if (strequal(_enum[i].name,s))
2303 return _enum[i].value;
2306 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2310 #undef MISSING_PARAMETER
2312 /* DO NOT USE lp_parm_string ANYMORE!!!!
2313 * use lp_parm_const_string or lp_parm_talloc_string
2315 * lp_parm_string is only used to let old modules find this symbol
2317 #undef lp_parm_string
2318 char *lp_parm_string(const char *servicename, const char *type, const char *option);
2319 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2321 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2324 /* Return parametric option from a given service. Type is a part of option before ':' */
2325 /* Parametric option has following syntax: 'Type: option = value' */
2326 /* the returned value is talloced in lp_talloc */
2327 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2329 param_opt_struct *data = get_parametrics(snum, type, option);
2331 if (data == NULL||data->value==NULL) {
2333 return lp_string(def);
2339 return lp_string(data->value);
2342 /* Return parametric option from a given service. Type is a part of option before ':' */
2343 /* Parametric option has following syntax: 'Type: option = value' */
2344 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2346 param_opt_struct *data = get_parametrics(snum, type, option);
2348 if (data == NULL||data->value==NULL)
2354 /* Return parametric option from a given service. Type is a part of option before ':' */
2355 /* Parametric option has following syntax: 'Type: option = value' */
2357 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2359 param_opt_struct *data = get_parametrics(snum, type, option);
2361 if (data == NULL||data->value==NULL)
2362 return (const char **)def;
2364 if (data->list==NULL) {
2365 data->list = str_list_make(data->value, NULL);
2368 return (const char **)data->list;
2371 /* Return parametric option from a given service. Type is a part of option before ':' */
2372 /* Parametric option has following syntax: 'Type: option = value' */
2374 int lp_parm_int(int snum, const char *type, const char *option, int def)
2376 param_opt_struct *data = get_parametrics(snum, type, option);
2378 if (data && data->value && *data->value)
2379 return lp_int(data->value);
2384 /* Return parametric option from a given service. Type is a part of option before ':' */
2385 /* Parametric option has following syntax: 'Type: option = value' */
2387 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2389 param_opt_struct *data = get_parametrics(snum, type, option);
2391 if (data && data->value && *data->value)
2392 return lp_ulong(data->value);
2397 /* Return parametric option from a given service. Type is a part of option before ':' */
2398 /* Parametric option has following syntax: 'Type: option = value' */
2400 BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2402 param_opt_struct *data = get_parametrics(snum, type, option);
2404 if (data && data->value && *data->value)
2405 return lp_bool(data->value);
2410 /* Return parametric option from a given service. Type is a part of option before ':' */
2411 /* Parametric option has following syntax: 'Type: option = value' */
2413 int lp_parm_enum(int snum, const char *type, const char *option,
2414 const struct enum_list *_enum, int def)
2416 param_opt_struct *data = get_parametrics(snum, type, option);
2418 if (data && data->value && *data->value && _enum)
2419 return lp_enum(data->value, _enum);
2425 /***************************************************************************
2426 Initialise a service to the defaults.
2427 ***************************************************************************/
2429 static void init_service(service * pservice)
2431 memset((char *)pservice, '\0', sizeof(service));
2432 copy_service(pservice, &sDefault, NULL);
2435 /***************************************************************************
2436 Free the dynamically allocated parts of a service struct.
2437 ***************************************************************************/
2439 static void free_service(service *pservice)
2442 param_opt_struct *data, *pdata;
2446 if (pservice->szService)
2447 DEBUG(5, ("free_service: Freeing service %s\n",
2448 pservice->szService));
2450 string_free(&pservice->szService);
2451 SAFE_FREE(pservice->copymap);
2453 for (i = 0; parm_table[i].label; i++) {
2454 if ((parm_table[i].type == P_STRING ||
2455 parm_table[i].type == P_USTRING) &&
2456 parm_table[i].p_class == P_LOCAL)
2457 string_free((char **)
2458 (((char *)pservice) +
2459 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2460 else if (parm_table[i].type == P_LIST &&
2461 parm_table[i].p_class == P_LOCAL)
2462 str_list_free((char ***)
2463 (((char *)pservice) +
2464 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2467 data = pservice->param_opt;
2469 DEBUG(5,("Freeing parametrics:\n"));
2471 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2472 string_free(&data->key);
2473 string_free(&data->value);
2474 str_list_free(&data->list);
2480 ZERO_STRUCTP(pservice);
2484 /***************************************************************************
2485 remove a service indexed in the ServicePtrs array from the ServiceHash
2486 and free the dynamically allocated parts
2487 ***************************************************************************/
2489 static void free_service_byindex(int idx)
2491 if ( !LP_SNUM_OK(idx) )
2494 ServicePtrs[idx]->valid = False;
2495 invalid_services[num_invalid_services++] = idx;
2497 /* we have to cleanup the hash record */
2499 if (ServicePtrs[idx]->szService) {
2500 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2502 tdb_delete_bystring(ServiceHash, canon_name );
2505 free_service(ServicePtrs[idx]);
2508 /***************************************************************************
2509 Add a new service to the services array initialising it with the given
2511 ***************************************************************************/
2513 static int add_a_service(const service *pservice, const char *name)
2517 int num_to_alloc = iNumServices + 1;
2518 param_opt_struct *data, *pdata;
2520 tservice = *pservice;
2522 /* it might already exist */
2524 i = getservicebyname(name, NULL);
2526 /* Clean all parametric options for service */
2527 /* They will be added during parsing again */
2528 data = ServicePtrs[i]->param_opt;
2530 string_free(&data->key);
2531 string_free(&data->value);
2532 str_list_free(&data->list);
2537 ServicePtrs[i]->param_opt = NULL;
2542 /* find an invalid one */
2544 if (num_invalid_services > 0) {
2545 i = invalid_services[--num_invalid_services];
2548 /* if not, then create one */
2549 if (i == iNumServices) {
2553 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2555 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2559 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2560 if (!ServicePtrs[iNumServices]) {
2561 DEBUG(0,("add_a_service: out of memory!\n"));
2566 /* enlarge invalid_services here for now... */
2567 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2569 if (tinvalid == NULL) {
2570 DEBUG(0,("add_a_service: failed to enlarge "
2571 "invalid_services!\n"));
2574 invalid_services = tinvalid;
2576 free_service_byindex(i);
2579 ServicePtrs[i]->valid = True;
2581 init_service(ServicePtrs[i]);
2582 copy_service(ServicePtrs[i], &tservice, NULL);
2584 string_set(&ServicePtrs[i]->szService, name);
2586 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2587 i, ServicePtrs[i]->szService));
2589 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2596 /***************************************************************************
2597 Canonicalize by converting to lowercase.
2598 ***************************************************************************/
2600 static char *canonicalize_servicename(const char *src)
2602 static fstring canon; /* is fstring large enough? */
2605 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2609 fstrcpy( canon, src );
2610 strlower_m( canon );
2615 /***************************************************************************
2616 Add a name/index pair for the services array to the hash table.
2617 ***************************************************************************/
2619 static BOOL hash_a_service(const char *name, int idx)
2623 if ( !ServiceHash ) {
2624 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2625 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2626 (O_RDWR|O_CREAT), 0600);
2627 if ( !ServiceHash ) {
2628 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2633 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2636 if ( !(canon_name = canonicalize_servicename( name )) )
2639 tdb_store_int32(ServiceHash, canon_name, idx);
2644 /***************************************************************************
2645 Add a new home service, with the specified home directory, defaults coming
2647 ***************************************************************************/
2649 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
2650 const char *user, const char *pszHomedir)
2655 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2660 if (!(*(ServicePtrs[iDefaultService]->szPath))
2661 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2662 pstrcpy(newHomedir, pszHomedir);
2663 string_set(&ServicePtrs[i]->szPath, newHomedir);
2666 if (!(*(ServicePtrs[i]->comment))) {
2668 slprintf(comment, sizeof(comment) - 1,
2669 "Home directory of %s", user);
2670 string_set(&ServicePtrs[i]->comment, comment);
2673 /* set the browseable flag from the global default */
2675 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2677 ServicePtrs[i]->autoloaded = True;
2679 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2680 user, ServicePtrs[i]->szPath ));
2685 /***************************************************************************
2686 Add a new service, based on an old one.
2687 ***************************************************************************/
2689 int lp_add_service(const char *pszService, int iDefaultService)
2691 if (iDefaultService < 0) {
2692 return add_a_service(&sDefault, pszService);
2695 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2698 /***************************************************************************
2699 Add the IPC service.
2700 ***************************************************************************/
2702 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2705 int i = add_a_service(&sDefault, ipc_name);
2710 slprintf(comment, sizeof(comment) - 1,
2711 "IPC Service (%s)", Globals.szServerString);
2713 string_set(&ServicePtrs[i]->szPath, tmpdir());
2714 string_set(&ServicePtrs[i]->szUsername, "");
2715 string_set(&ServicePtrs[i]->comment, comment);
2716 string_set(&ServicePtrs[i]->fstype, "IPC");
2717 ServicePtrs[i]->iMaxConnections = 0;
2718 ServicePtrs[i]->bAvailable = True;
2719 ServicePtrs[i]->bRead_only = True;
2720 ServicePtrs[i]->bGuest_only = False;
2721 ServicePtrs[i]->bGuest_ok = guest_ok;
2722 ServicePtrs[i]->bPrint_ok = False;
2723 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2725 DEBUG(3, ("adding IPC service\n"));
2730 /***************************************************************************
2731 Add a new printer service, with defaults coming from service iFrom.
2732 ***************************************************************************/
2734 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2736 const char *comment = "From Printcap";
2737 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2742 /* note that we do NOT default the availability flag to True - */
2743 /* we take it from the default service passed. This allows all */
2744 /* dynamic printers to be disabled by disabling the [printers] */
2745 /* entry (if/when the 'available' keyword is implemented!). */
2747 /* the printer name is set to the service name. */
2748 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2749 string_set(&ServicePtrs[i]->comment, comment);
2751 /* set the browseable flag from the gloabl default */
2752 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2754 /* Printers cannot be read_only. */
2755 ServicePtrs[i]->bRead_only = False;
2756 /* No share modes on printer services. */
2757 ServicePtrs[i]->bShareModes = False;
2758 /* No oplocks on printer services. */
2759 ServicePtrs[i]->bOpLocks = False;
2760 /* Printer services must be printable. */
2761 ServicePtrs[i]->bPrint_ok = True;
2763 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2768 /***************************************************************************
2769 Map a parameter's string representation to something we can use.
2770 Returns False if the parameter string is not recognised, else TRUE.
2771 ***************************************************************************/
2773 static int map_parameter(const char *pszParmName)
2777 if (*pszParmName == '-')
2780 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2781 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2784 /* Warn only if it isn't parametric option */
2785 if (strchr(pszParmName, ':') == NULL)
2786 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2787 /* We do return 'fail' for parametric options as well because they are
2788 stored in different storage
2793 /***************************************************************************
2794 Show all parameter's name, type, [values,] and flags.
2795 ***************************************************************************/
2797 void show_parameter_list(void)
2799 int classIndex, parmIndex, enumIndex, flagIndex;
2801 const char *section_names[] = { "local", "global", NULL};
2802 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2803 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2804 "P_UGSTRING", "P_ENUM", "P_SEP"};
2805 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2806 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2807 FLAG_HIDE, FLAG_DOS_STRING};
2808 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2809 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2810 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2812 for ( classIndex=0; section_names[classIndex]; classIndex++) {
2813 printf("[%s]\n", section_names[classIndex]);
2814 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2815 if (parm_table[parmIndex].p_class == classIndex) {
2817 parm_table[parmIndex].label,
2818 type[parm_table[parmIndex].type]);
2819 switch (parm_table[parmIndex].type) {
2822 for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
2824 enumIndex ? "|" : "",
2825 parm_table[parmIndex].enum_list[enumIndex].name);
2832 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
2833 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2836 flag_names[flagIndex]);
2846 /***************************************************************************
2847 Set a boolean variable from the text value stored in the passed string.
2848 Returns True in success, False if the passed string does not correctly
2849 represent a boolean.
2850 ***************************************************************************/
2852 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2857 if (strwicmp(pszParmValue, "yes") == 0 ||
2858 strwicmp(pszParmValue, "true") == 0 ||
2859 strwicmp(pszParmValue, "1") == 0)
2861 else if (strwicmp(pszParmValue, "no") == 0 ||
2862 strwicmp(pszParmValue, "False") == 0 ||
2863 strwicmp(pszParmValue, "0") == 0)
2867 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2874 /***************************************************************************
2875 Find a service by name. Otherwise works like get_service.
2876 ***************************************************************************/
2878 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2883 if (ServiceHash != NULL) {
2884 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
2887 iService = tdb_fetch_int32(ServiceHash, canon_name );
2889 if (LP_SNUM_OK(iService)) {
2890 if (pserviceDest != NULL) {
2891 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2901 /***************************************************************************
2902 Copy a service structure to another.
2903 If pcopymapDest is NULL then copy all fields
2904 ***************************************************************************/
2906 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2909 BOOL bcopyall = (pcopymapDest == NULL);
2910 param_opt_struct *data, *pdata, *paramo;
2913 for (i = 0; parm_table[i].label; i++)
2914 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
2915 (bcopyall || pcopymapDest[i])) {
2916 void *def_ptr = parm_table[i].ptr;
2918 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2921 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2924 switch (parm_table[i].type) {
2927 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2933 *(int *)dest_ptr = *(int *)src_ptr;
2937 *(char *)dest_ptr = *(char *)src_ptr;
2941 string_set((char **)dest_ptr,
2946 string_set((char **)dest_ptr,
2948 strupper_m(*(char **)dest_ptr);
2951 str_list_free((char ***)dest_ptr);
2952 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2960 init_copymap(pserviceDest);
2961 if (pserviceSource->copymap)
2962 memcpy((void *)pserviceDest->copymap,
2963 (void *)pserviceSource->copymap,
2964 sizeof(BOOL) * NUMPARAMETERS);
2967 data = pserviceSource->param_opt;
2970 pdata = pserviceDest->param_opt;
2971 /* Traverse destination */
2973 /* If we already have same option, override it */
2974 if (strcmp(pdata->key, data->key) == 0) {
2975 string_free(&pdata->value);
2976 str_list_free(&data->list);
2977 pdata->value = SMB_STRDUP(data->value);
2981 pdata = pdata->next;
2984 paramo = SMB_XMALLOC_P(param_opt_struct);
2985 paramo->key = SMB_STRDUP(data->key);
2986 paramo->value = SMB_STRDUP(data->value);
2987 paramo->list = NULL;
2988 DLIST_ADD(pserviceDest->param_opt, paramo);
2994 /***************************************************************************
2995 Check a service for consistency. Return False if the service is in any way
2996 incomplete or faulty, else True.
2997 ***************************************************************************/
2999 BOOL service_ok(int iService)
3004 if (ServicePtrs[iService]->szService[0] == '\0') {
3005 DEBUG(0, ("The following message indicates an internal error:\n"));
3006 DEBUG(0, ("No service name in service entry.\n"));
3010 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
3011 /* I can't see why you'd want a non-printable printer service... */
3012 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
3013 if (!ServicePtrs[iService]->bPrint_ok) {
3014 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
3015 ServicePtrs[iService]->szService));
3016 ServicePtrs[iService]->bPrint_ok = True;
3018 /* [printers] service must also be non-browsable. */
3019 if (ServicePtrs[iService]->bBrowseable)
3020 ServicePtrs[iService]->bBrowseable = False;
3023 if (ServicePtrs[iService]->szPath[0] == '\0' &&
3024 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
3025 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
3027 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
3028 ServicePtrs[iService]->szService));
3029 ServicePtrs[iService]->bAvailable = False;
3032 /* If a service is flagged unavailable, log the fact at level 1. */
3033 if (!ServicePtrs[iService]->bAvailable)
3034 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
3035 ServicePtrs[iService]->szService));
3040 static struct file_lists {
3041 struct file_lists *next;
3045 } *file_lists = NULL;
3047 /*******************************************************************
3048 Keep a linked list of all config files so we know when one has changed
3049 it's date and needs to be reloaded.
3050 ********************************************************************/
3052 static void add_to_file_list(const char *fname, const char *subfname)
3054 struct file_lists *f = file_lists;
3057 if (f->name && !strcmp(f->name, fname))
3063 f = SMB_MALLOC_P(struct file_lists);
3066 f->next = file_lists;
3067 f->name = SMB_STRDUP(fname);
3072 f->subfname = SMB_STRDUP(subfname);
3078 f->modtime = file_modtime(subfname);
3080 time_t t = file_modtime(subfname);
3086 /*******************************************************************
3087 Check if a config file has changed date.
3088 ********************************************************************/
3090 BOOL lp_file_list_changed(void)
3092 struct file_lists *f = file_lists;
3094 DEBUG(6, ("lp_file_list_changed()\n"));
3100 pstrcpy(n2, f->name);
3101 standard_sub_basic( get_current_username(),
3102 current_user_info.domain,
3105 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3106 f->name, n2, ctime(&f->modtime)));
3108 mod_time = file_modtime(n2);
3110 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3112 ("file %s modified: %s\n", n2,
3114 f->modtime = mod_time;
3115 SAFE_FREE(f->subfname);
3116 f->subfname = SMB_STRDUP(n2);
3124 /***************************************************************************
3125 Run standard_sub_basic on netbios name... needed because global_myname
3126 is not accessed through any lp_ macro.
3127 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3128 ***************************************************************************/
3130 static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3133 pstring netbios_name;
3135 pstrcpy(netbios_name, pszParmValue);
3137 standard_sub_basic(get_current_username(), current_user_info.domain,
3138 netbios_name, sizeof(netbios_name));
3140 ret = set_global_myname(netbios_name);
3141 string_set(&Globals.szNetbiosName,global_myname());
3143 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3149 static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
3151 if (strcmp(*ptr, pszParmValue) != 0) {
3152 string_set(ptr, pszParmValue);
3160 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3164 ret = set_global_myworkgroup(pszParmValue);
3165 string_set(&Globals.szWorkgroup,lp_workgroup());
3170 static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3174 ret = set_global_scope(pszParmValue);
3175 string_set(&Globals.szNetbiosScope,global_scope());
3180 static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3182 str_list_free(&Globals.szNetbiosAliases);
3183 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3184 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3187 /***************************************************************************
3188 Handle the include operation.
3189 ***************************************************************************/
3191 static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
3194 pstrcpy(fname, pszParmValue);
3196 standard_sub_basic(get_current_username(), current_user_info.domain,
3197 fname,sizeof(fname));
3199 add_to_file_list(pszParmValue, fname);
3201 string_set(ptr, fname);
3203 if (file_exist(fname, NULL))
3204 return (pm_process(fname, do_section, do_parameter));
3206 DEBUG(2, ("Can't find include file %s\n", fname));
3211 /***************************************************************************
3212 Handle the interpretation of the copy parameter.
3213 ***************************************************************************/
3215 static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
3219 service serviceTemp;
3221 string_set(ptr, pszParmValue);
3223 init_service(&serviceTemp);
3227 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3229 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3230 if (iTemp == iServiceIndex) {
3231 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3233 copy_service(ServicePtrs[iServiceIndex],
3235 ServicePtrs[iServiceIndex]->copymap);
3239 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3243 free_service(&serviceTemp);
3247 /***************************************************************************
3248 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3253 idmap uid = 1000-1999
3256 We only do simple parsing checks here. The strings are parsed into useful
3257 structures in the idmap daemon code.
3259 ***************************************************************************/
3261 /* Some lp_ routines to return idmap [ug]id information */
3263 static uid_t idmap_uid_low, idmap_uid_high;
3264 static gid_t idmap_gid_low, idmap_gid_high;
3266 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
3268 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3272 *low = idmap_uid_low;
3275 *high = idmap_uid_high;
3280 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
3282 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3286 *low = idmap_gid_low;
3289 *high = idmap_gid_high;
3294 /* Do some simple checks on "idmap [ug]id" parameter values */
3296 static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3300 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3305 string_set(ptr, pszParmValue);
3307 idmap_uid_low = low;
3308 idmap_uid_high = high;
3313 static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3317 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3322 string_set(ptr, pszParmValue);
3324 idmap_gid_low = low;
3325 idmap_gid_high = high;
3330 /***************************************************************************
3331 Handle the DEBUG level list.
3332 ***************************************************************************/
3334 static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3336 pstring pszParmValue;
3338 pstrcpy(pszParmValue, pszParmValueIn);
3339 string_set(ptr, pszParmValueIn);
3340 return debug_parse_levels( pszParmValue );
3343 /***************************************************************************
3344 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3345 ***************************************************************************/
3347 static const char *append_ldap_suffix( const char *str )
3349 const char *suffix_string;
3353 lp_talloc = talloc_init("lp_talloc");
3355 suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
3356 if ( !suffix_string ) {
3357 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3361 return suffix_string;
3364 const char *lp_ldap_machine_suffix(void)
3366 if (Globals.szLdapMachineSuffix[0])
3367 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3369 return lp_string(Globals.szLdapSuffix);
3372 const char *lp_ldap_user_suffix(void)
3374 if (Globals.szLdapUserSuffix[0])
3375 return append_ldap_suffix(Globals.szLdapUserSuffix);
3377 return lp_string(Globals.szLdapSuffix);
3380 const char *lp_ldap_group_suffix(void)
3382 if (Globals.szLdapGroupSuffix[0])
3383 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3385 return lp_string(Globals.szLdapSuffix);
3388 const char *lp_ldap_idmap_suffix(void)
3390 if (Globals.szLdapIdmapSuffix[0])
3391 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3393 return lp_string(Globals.szLdapSuffix);
3396 /****************************************************************************
3397 set the value for a P_ENUM
3398 ***************************************************************************/
3400 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3405 for (i = 0; parm->enum_list[i].name; i++) {
3406 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3407 *ptr = parm->enum_list[i].value;
3413 /***************************************************************************
3414 ***************************************************************************/
3416 static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3418 static int parm_num = -1;
3421 if ( parm_num == -1 )
3422 parm_num = map_parameter( "printing" );
3424 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3429 s = ServicePtrs[snum];
3431 init_printer_values( s );
3437 /***************************************************************************
3438 Initialise a copymap.
3439 ***************************************************************************/
3441 static void init_copymap(service * pservice)
3444 SAFE_FREE(pservice->copymap);
3445 pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3446 if (!pservice->copymap)
3448 ("Couldn't allocate copymap!! (size %d)\n",
3449 (int)NUMPARAMETERS));
3451 for (i = 0; i < NUMPARAMETERS; i++)
3452 pservice->copymap[i] = True;
3455 /***************************************************************************
3456 Return the local pointer to a parameter given the service number and the
3457 pointer into the default structure.
3458 ***************************************************************************/
3460 void *lp_local_ptr(int snum, void *ptr)
3462 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3465 /***************************************************************************
3466 Process a parameter for a particular service number. If snum < 0
3467 then assume we are in the globals.
3468 ***************************************************************************/
3470 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3472 int parmnum, i, slen;
3473 void *parm_ptr = NULL; /* where we are going to store the result */
3474 void *def_ptr = NULL;
3477 param_opt_struct *paramo, *data;
3480 parmnum = map_parameter(pszParmName);
3483 if ((sep=strchr(pszParmName, ':')) != NULL) {
3485 ZERO_STRUCT(param_key);
3486 pstr_sprintf(param_key, "%s:", pszParmName);
3487 slen = strlen(param_key);
3488 pstrcat(param_key, sep+1);
3489 trim_char(param_key+slen, ' ', ' ');
3491 data = (snum < 0) ? Globals.param_opt :
3492 ServicePtrs[snum]->param_opt;
3493 /* Traverse destination */
3495 /* If we already have same option, override it */
3496 if (strcmp(data->key, param_key) == 0) {
3497 string_free(&data->value);
3498 str_list_free(&data->list);
3499 data->value = SMB_STRDUP(pszParmValue);
3506 paramo = SMB_XMALLOC_P(param_opt_struct);
3507 paramo->key = SMB_STRDUP(param_key);
3508 paramo->value = SMB_STRDUP(pszParmValue);
3509 paramo->list = NULL;
3511 DLIST_ADD(Globals.param_opt, paramo);
3513 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3520 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3524 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3525 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3529 def_ptr = parm_table[parmnum].ptr;
3531 /* we might point at a service, the default service or a global */
3535 if (parm_table[parmnum].p_class == P_GLOBAL) {
3537 ("Global parameter %s found in service section!\n",
3542 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3545 if (!ServicePtrs[snum]->copymap)
3546 init_copymap(ServicePtrs[snum]);
3548 /* this handles the aliases - set the copymap for other entries with
3549 the same data pointer */
3550 for (i = 0; parm_table[i].label; i++)
3551 if (parm_table[i].ptr == parm_table[parmnum].ptr)
3552 ServicePtrs[snum]->copymap[i] = False;
3555 /* if it is a special case then go ahead */
3556 if (parm_table[parmnum].special) {
3557 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3561 /* now switch on the type of variable it is */
3562 switch (parm_table[parmnum].type)
3565 *(BOOL *)parm_ptr = lp_bool(pszParmValue);
3569 *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
3573 *(int *)parm_ptr = lp_int(pszParmValue);
3577 *(char *)parm_ptr = *pszParmValue;
3581 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3583 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3588 str_list_free((char ***)parm_ptr);
3589 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3593 string_set((char **)parm_ptr, pszParmValue);
3597 string_set((char **)parm_ptr, pszParmValue);
3598 strupper_m(*(char **)parm_ptr);
3602 pstrcpy((char *)parm_ptr, pszParmValue);
3606 pstrcpy((char *)parm_ptr, pszParmValue);
3607 strupper_m((char *)parm_ptr);
3611 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3620 /***************************************************************************
3621 Process a parameter.
3622 ***************************************************************************/
3624 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3626 if (!bInGlobalSection && bGlobalOnly)
3629 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3631 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3632 pszParmName, pszParmValue));
3635 /***************************************************************************
3636 Print a parameter of the specified type.
3637 ***************************************************************************/
3639 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3645 for (i = 0; p->enum_list[i].name; i++) {
3646 if (*(int *)ptr == p->enum_list[i].value) {
3648 p->enum_list[i].name);
3655 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3659 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3663 fprintf(f, "%d", *(int *)ptr);
3667 fprintf(f, "%c", *(char *)ptr);
3671 fprintf(f, "%s", octal_string(*(int *)ptr));
3675 if ((char ***)ptr && *(char ***)ptr) {
3676 char **list = *(char ***)ptr;
3678 for (; *list; list++) {
3679 /* surround strings with whitespace in double quotes */
3680 if ( strchr_m( *list, ' ' ) )
3681 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3683 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3691 fprintf(f, "%s", (char *)ptr);
3697 if (*(char **)ptr) {
3698 fprintf(f, "%s", *(char **)ptr);
3706 /***************************************************************************
3707 Check if two parameters are equal.
3708 ***************************************************************************/
3710 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3715 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3720 return (*((int *)ptr1) == *((int *)ptr2));
3723 return (*((char *)ptr1) == *((char *)ptr2));
3726 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3731 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3736 return (p1 == p2 || strequal(p1, p2));
3741 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3746 return (p1 == p2 || strequal(p1, p2));
3754 /***************************************************************************
3755 Initialize any local varients in the sDefault table.
3756 ***************************************************************************/
3758 void init_locals(void)
3763 /***************************************************************************
3764 Process a new section (service). At this stage all sections are services.
3765 Later we'll have special sections that permit server parameters to be set.
3766 Returns True on success, False on failure.
3767 ***************************************************************************/
3769 static BOOL do_section(const char *pszSectionName)
3772 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3773 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3776 /* if we were in a global section then do the local inits */
3777 if (bInGlobalSection && !isglobal)
3780 /* if we've just struck a global section, note the fact. */
3781 bInGlobalSection = isglobal;
3783 /* check for multiple global sections */
3784 if (bInGlobalSection) {
3785 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3789 if (!bInGlobalSection && bGlobalOnly)
3792 /* if we have a current service, tidy it up before moving on */
3795 if (iServiceIndex >= 0)
3796 bRetval = service_ok(iServiceIndex);
3798 /* if all is still well, move to the next record in the services array */
3800 /* We put this here to avoid an odd message order if messages are */
3801 /* issued by the post-processing of a previous section. */
3802 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3804 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3806 DEBUG(0, ("Failed to add a new service\n"));
3815 /***************************************************************************
3816 Determine if a partcular base parameter is currentl set to the default value.
3817 ***************************************************************************/
3819 static BOOL is_default(int i)
3821 if (!defaults_saved)
3823 switch (parm_table[i].type) {
3825 return str_list_compare (parm_table[i].def.lvalue,
3826 *(char ***)parm_table[i].ptr);
3829 return strequal(parm_table[i].def.svalue,
3830 *(char **)parm_table[i].ptr);
3833 return strequal(parm_table[i].def.svalue,
3834 (char *)parm_table[i].ptr);
3837 return parm_table[i].def.bvalue ==
3838 *(BOOL *)parm_table[i].ptr;
3840 return parm_table[i].def.cvalue ==
3841 *(char *)parm_table[i].ptr;
3845 return parm_table[i].def.ivalue ==
3846 *(int *)parm_table[i].ptr;
3853 /***************************************************************************
3854 Display the contents of the global structure.
3855 ***************************************************************************/
3857 static void dump_globals(FILE *f)
3860 param_opt_struct *data;
3862 fprintf(f, "[global]\n");
3864 for (i = 0; parm_table[i].label; i++)
3865 if (parm_table[i].p_class == P_GLOBAL &&
3866 parm_table[i].ptr &&
3867 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3868 if (defaults_saved && is_default(i))
3870 fprintf(f, "\t%s = ", parm_table[i].label);
3871 print_parameter(&parm_table[i], parm_table[i].ptr, f);
3874 if (Globals.param_opt != NULL) {
3875 data = Globals.param_opt;
3877 fprintf(f, "\t%s = %s\n", data->key, data->value);
3884 /***************************************************************************
3885 Return True if a local parameter is currently set to the global default.
3886 ***************************************************************************/
3888 BOOL lp_is_default(int snum, struct parm_struct *parm)
3890 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3892 return equal_parameter(parm->type,
3893 ((char *)ServicePtrs[snum]) + pdiff,
3894 ((char *)&sDefault) + pdiff);
3897 /***************************************************************************
3898 Display the contents of a single services record.
3899 ***************************************************************************/
3901 static void dump_a_service(service * pService, FILE * f)
3904 param_opt_struct *data;
3906 if (pService != &sDefault)
3907 fprintf(f, "[%s]\n", pService->szService);
3909 for (i = 0; parm_table[i].label; i++) {
3911 if (parm_table[i].p_class == P_LOCAL &&
3912 parm_table[i].ptr &&
3913 (*parm_table[i].label != '-') &&
3914 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3917 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3919 if (pService == &sDefault) {
3920 if (defaults_saved && is_default(i))
3923 if (equal_parameter(parm_table[i].type,
3924 ((char *)pService) +
3926 ((char *)&sDefault) +
3931 fprintf(f, "\t%s = ", parm_table[i].label);
3932 print_parameter(&parm_table[i],
3933 ((char *)pService) + pdiff, f);
3938 if (pService->param_opt != NULL) {
3939 data = pService->param_opt;
3941 fprintf(f, "\t%s = %s\n", data->key, data->value);
3947 /***************************************************************************
3948 Display the contents of a parameter of a single services record.
3949 ***************************************************************************/
3951 BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
3954 BOOL result = False;
3957 fstring local_parm_name;
3959 const char *parm_opt_value;
3961 /* check for parametrical option */
3962 fstrcpy( local_parm_name, parm_name);
3963 parm_opt = strchr( local_parm_name, ':');
3968 if (strlen(parm_opt)) {
3969 parm_opt_value = lp_parm_const_string( snum,
3970 local_parm_name, parm_opt, NULL);
3971 if (parm_opt_value) {
3972 printf( "%s\n", parm_opt_value);
3979 /* check for a key and print the value */
3986 for (i = 0; parm_table[i].label; i++) {
3987 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
3988 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
3989 parm_table[i].ptr &&
3990 (*parm_table[i].label != '-') &&
3991 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3996 ptr = parm_table[i].ptr;
3998 service * pService = ServicePtrs[snum];
3999 ptr = ((char *)pService) +
4000 PTR_DIFF(parm_table[i].ptr, &sDefault);
4003 print_parameter(&parm_table[i],
4014 /***************************************************************************
4015 Return info about the next parameter in a service.
4016 snum==GLOBAL_SECTION_SNUM gives the globals.
4017 Return NULL when out of parameters.
4018 ***************************************************************************/
4020 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
4023 /* do the globals */
4024 for (; parm_table[*i].label; (*i)++) {
4025 if (parm_table[*i].p_class == P_SEPARATOR)
4026 return &parm_table[(*i)++];
4028 if (!parm_table[*i].ptr
4029 || (*parm_table[*i].label == '-'))
4033 && (parm_table[*i].ptr ==
4034 parm_table[(*i) - 1].ptr))
4037 return &parm_table[(*i)++];
4040 service *pService = ServicePtrs[snum];
4042 for (; parm_table[*i].label; (*i)++) {
4043 if (parm_table[*i].p_class == P_SEPARATOR)
4044 return &parm_table[(*i)++];
4046 if (parm_table[*i].p_class == P_LOCAL &&
4047 parm_table[*i].ptr &&
4048 (*parm_table[*i].label != '-') &&
4050 (parm_table[*i].ptr !=
4051 parm_table[(*i) - 1].ptr)))
4054 PTR_DIFF(parm_table[*i].ptr,
4057 if (allparameters ||
4058 !equal_parameter(parm_table[*i].type,
4059 ((char *)pService) +
4061 ((char *)&sDefault) +
4064 return &parm_table[(*i)++];
4075 /***************************************************************************
4076 Display the contents of a single copy structure.
4077 ***************************************************************************/
4078 static void dump_copy_map(BOOL *pcopymap)
4084 printf("\n\tNon-Copied parameters:\n");
4086 for (i = 0; parm_table[i].label; i++)
4087 if (parm_table[i].p_class == P_LOCAL &&
4088 parm_table[i].ptr && !pcopymap[i] &&
4089 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4091 printf("\t\t%s\n", parm_table[i].label);
4096 /***************************************************************************
4097 Return TRUE if the passed service number is within range.
4098 ***************************************************************************/
4100 BOOL lp_snum_ok(int iService)
4102 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4105 /***************************************************************************
4106 Auto-load some home services.
4107 ***************************************************************************/
4109 static void lp_add_auto_services(char *str)
4118 s = SMB_STRDUP(str);
4122 homes = lp_servicenumber(HOMES_NAME);
4124 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4125 char *home = get_user_home_dir(p);
4127 if (lp_servicenumber(p) >= 0)
4130 if (home && homes >= 0)
4131 lp_add_home(p, homes, p, home);
4136 /***************************************************************************
4137 Auto-load one printer.
4138 ***************************************************************************/
4140 void lp_add_one_printer(char *name, char *comment)
4142 int printers = lp_servicenumber(PRINTERS_NAME);
4145 if (lp_servicenumber(name) < 0) {
4146 lp_add_printer(name, printers);
4147 if ((i = lp_servicenumber(name)) >= 0) {
4148 string_set(&ServicePtrs[i]->comment, comment);
4149 ServicePtrs[i]->autoloaded = True;
4154 /***************************************************************************
4155 Have we loaded a services file yet?
4156 ***************************************************************************/
4158 BOOL lp_loaded(void)
4163 /***************************************************************************
4164 Unload unused services.
4165 ***************************************************************************/
4167 void lp_killunused(BOOL (*snumused) (int))
4170 for (i = 0; i < iNumServices; i++) {
4174 /* don't kill autoloaded or usershare services */
4175 if ( ServicePtrs[i]->autoloaded ||
4176 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4180 if (!snumused || !snumused(i)) {
4181 free_service_byindex(i);
4186 /***************************************************************************
4188 ***************************************************************************/
4190 void lp_killservice(int iServiceIn)
4192 if (VALID(iServiceIn)) {
4193 free_service_byindex(iServiceIn);
4197 /***************************************************************************
4198 Save the curent values of all global and sDefault parameters into the
4199 defaults union. This allows swat and testparm to show only the
4200 changed (ie. non-default) parameters.
4201 ***************************************************************************/
4203 static void lp_save_defaults(void)
4206 for (i = 0; parm_table[i].label; i++) {
4207 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4209 switch (parm_table[i].type) {
4211 str_list_copy(&(parm_table[i].def.lvalue),
4212 *(const char ***)parm_table[i].ptr);
4216 if (parm_table[i].ptr) {
4217 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4219 parm_table[i].def.svalue = NULL;
4224 if (parm_table[i].ptr) {
4225 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4227 parm_table[i].def.svalue = NULL;
4232 parm_table[i].def.bvalue =
4233 *(BOOL *)parm_table[i].ptr;
4236 parm_table[i].def.cvalue =
4237 *(char *)parm_table[i].ptr;
4242 parm_table[i].def.ivalue =
4243 *(int *)parm_table[i].ptr;
4249 defaults_saved = True;
4252 /*******************************************************************
4253 Set the server type we will announce as via nmbd.
4254 ********************************************************************/
4256 static const struct srv_role_tab {
4258 const char *role_str;
4259 } srv_role_tab [] = {
4260 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4261 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4262 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4263 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4267 const char* server_role_str(uint32 role)
4270 for (i=0; srv_role_tab[i].role_str; i++) {
4271 if (role == srv_role_tab[i].role) {
4272 return srv_role_tab[i].role_str;
4278 static void set_server_role(void)
4280 server_role = ROLE_STANDALONE;
4282 switch (lp_security()) {
4284 if (lp_domain_logons())
4285 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4288 if (lp_domain_logons())
4289 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4290 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
4291 server_role = ROLE_STANDALONE;
4294 if (lp_domain_logons()) {
4295 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4296 server_role = ROLE_DOMAIN_BDC;
4299 server_role = ROLE_DOMAIN_MEMBER;
4302 if (lp_domain_logons()) {
4303 server_role = ROLE_DOMAIN_PDC;
4306 server_role = ROLE_DOMAIN_MEMBER;
4309 if (lp_domain_logons()) {
4311 if (Globals.bDomainMaster) /* auto or yes */
4312 server_role = ROLE_DOMAIN_PDC;
4314 server_role = ROLE_DOMAIN_BDC;
4318 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4322 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4325 /***********************************************************
4326 If we should send plaintext/LANMAN passwords in the clinet
4327 ************************************************************/
4329 static void set_allowed_client_auth(void)
4331 if (Globals.bClientNTLMv2Auth) {
4332 Globals.bClientLanManAuth = False;
4334 if (!Globals.bClientLanManAuth) {
4335 Globals.bClientPlaintextAuth = False;
4339 /***************************************************************************
4341 The following code allows smbd to read a user defined share file.
4342 Yes, this is my intent. Yes, I'm comfortable with that...
4344 THE FOLLOWING IS SECURITY CRITICAL CODE.
4346 It washes your clothes, it cleans your house, it guards you while you sleep...
4347 Do not f%^k with it....
4348 ***************************************************************************/
4350 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4352 /***************************************************************************
4353 Check allowed stat state of a usershare file.
4354 Ensure we print out who is dicking with us so the admin can
4355 get their sorry ass fired.
4356 ***************************************************************************/
4358 static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4360 if (!S_ISREG(psbuf->st_mode)) {
4361 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4362 "not a regular file\n",
4363 fname, (unsigned int)psbuf->st_uid ));
4367 /* Ensure this doesn't have the other write bit set. */
4368 if (psbuf->st_mode & S_IWOTH) {
4369 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4370 "public write. Refusing to allow as a usershare file.\n",
4371 fname, (unsigned int)psbuf->st_uid ));
4375 /* Should be 10k or less. */
4376 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4377 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4378 "too large (%u) to be a user share file.\n",
4379 fname, (unsigned int)psbuf->st_uid,
4380 (unsigned int)psbuf->st_size ));
4387 /***************************************************************************
4388 Parse the contents of a usershare file.
4389 ***************************************************************************/
4391 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4392 SMB_STRUCT_STAT *psbuf,
4393 const char *servicename,
4402 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4403 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4406 SMB_STRUCT_STAT sbuf;
4408 *pallow_guest = False;
4411 return USERSHARE_MALFORMED_FILE;
4414 if (strcmp(lines[0], "#VERSION 1") == 0) {
4416 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4419 return USERSHARE_MALFORMED_FILE;
4422 return USERSHARE_BAD_VERSION;
4425 if (strncmp(lines[1], "path=", 5) != 0) {
4426 return USERSHARE_MALFORMED_PATH;
4429 pstrcpy(sharepath, &lines[1][5]);
4430 trim_string(sharepath, " ", " ");
4432 if (strncmp(lines[2], "comment=", 8) != 0) {
4433 return USERSHARE_MALFORMED_COMMENT_DEF;
4436 pstrcpy(comment, &lines[2][8]);
4437 trim_string(comment, " ", " ");
4438 trim_char(comment, '"', '"');
4440 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4441 return USERSHARE_MALFORMED_ACL_DEF;
4444 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4445 return USERSHARE_ACL_ERR;
4449 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4450 return USERSHARE_MALFORMED_ACL_DEF;
4452 if (lines[4][9] == 'y') {
4453 *pallow_guest = True;
4457 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4458 /* Path didn't change, no checks needed. */
4459 return USERSHARE_OK;
4462 /* The path *must* be absolute. */
4463 if (sharepath[0] != '/') {
4464 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4465 servicename, sharepath));
4466 return USERSHARE_PATH_NOT_ABSOLUTE;
4469 /* If there is a usershare prefix deny list ensure one of these paths
4470 doesn't match the start of the user given path. */
4471 if (prefixdenylist) {
4473 for ( i=0; prefixdenylist[i]; i++ ) {
4474 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4475 servicename, i, prefixdenylist[i], sharepath ));
4476 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4477 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4478 "usershare prefix deny list entries.\n",
4479 servicename, sharepath));
4480 return USERSHARE_PATH_IS_DENIED;
4485 /* If there is a usershare prefix allow list ensure one of these paths
4486 does match the start of the user given path. */
4488 if (prefixallowlist) {
4490 for ( i=0; prefixallowlist[i]; i++ ) {
4491 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4492 servicename, i, prefixallowlist[i], sharepath ));
4493 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4497 if (prefixallowlist[i] == NULL) {
4498 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4499 "usershare prefix allow list entries.\n",
4500 servicename, sharepath));
4501 return USERSHARE_PATH_NOT_ALLOWED;
4505 /* Ensure this is pointing to a directory. */
4506 dp = sys_opendir(sharepath);
4509 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4510 servicename, sharepath));
4511 return USERSHARE_PATH_NOT_DIRECTORY;
4514 /* Ensure the owner of the usershare file has permission to share
4517 if (sys_stat(sharepath, &sbuf) == -1) {
4518 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4519 servicename, sharepath, strerror(errno) ));
4521 return USERSHARE_POSIX_ERR;
4526 if (!S_ISDIR(sbuf.st_mode)) {
4527 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4528 servicename, sharepath ));
4529 return USERSHARE_PATH_NOT_DIRECTORY;
4532 /* Check if sharing is restricted to owner-only. */
4533 /* psbuf is the stat of the usershare definition file,
4534 sbuf is the stat of the target directory to be shared. */
4536 if (lp_usershare_owner_only()) {
4537 /* root can share anything. */
4538 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
4539 return USERSHARE_PATH_NOT_ALLOWED;
4543 return USERSHARE_OK;
4546 /***************************************************************************
4547 Deal with a usershare file.
4550 -1 - Bad name, invalid contents.
4551 - service name already existed and not a usershare, problem
4552 with permissions to share directory etc.
4553 ***************************************************************************/
4555 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4557 SMB_STRUCT_STAT sbuf;
4558 SMB_STRUCT_STAT lsbuf;
4562 fstring service_name;
4563 char **lines = NULL;
4567 TALLOC_CTX *ctx = NULL;
4568 SEC_DESC *psd = NULL;
4569 BOOL guest_ok = False;
4571 /* Ensure share name doesn't contain invalid characters. */
4572 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4573 DEBUG(0,("process_usershare_file: share name %s contains "
4574 "invalid characters (any of %s)\n",
4575 file_name, INVALID_SHARENAME_CHARS ));
4579 fstrcpy(service_name, file_name);
4581 pstrcpy(fname, dir_name);
4582 pstrcat(fname, "/");
4583 pstrcat(fname, file_name);
4585 /* Minimize the race condition by doing an lstat before we
4586 open and fstat. Ensure this isn't a symlink link. */
4588 if (sys_lstat(fname, &lsbuf) != 0) {
4589 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4590 fname, strerror(errno) ));
4594 /* This must be a regular file, not a symlink, directory or
4595 other strange filetype. */
4596 if (!check_usershare_stat(fname, &lsbuf)) {
4600 /* See if there is already a servicenum for this name. */
4601 /* tdb_fetch_int32 returns -1 if not found. */
4602 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
4604 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
4605 /* Nothing changed - Mark valid and return. */
4606 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4608 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4612 /* Try and open the file read only - no symlinks allowed. */
4614 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
4616 fd = sys_open(fname, O_RDONLY, 0);
4620 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4621 fname, strerror(errno) ));
4625 /* Now fstat to be *SURE* it's a regular file. */
4626 if (sys_fstat(fd, &sbuf) != 0) {
4628 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4629 fname, strerror(errno) ));
4633 /* Is it the same dev/inode as was lstated ? */
4634 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
4636 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4637 "Symlink spoofing going on ?\n", fname ));
4641 /* This must be a regular file, not a symlink, directory or
4642 other strange filetype. */
4643 if (!check_usershare_stat(fname, &sbuf)) {
4647 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
4650 if (lines == NULL) {
4651 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4652 fname, (unsigned int)sbuf.st_uid ));
4656 /* Should we allow printers to be shared... ? */
4657 ctx = talloc_init("usershare_sd_xctx");
4659 file_lines_free(lines);
4663 if (parse_usershare_file(ctx, &sbuf, service_name,
4664 iService, lines, numlines, sharepath,
4665 comment, &psd, &guest_ok) != USERSHARE_OK) {
4666 talloc_destroy(ctx);
4667 file_lines_free(lines);
4671 file_lines_free(lines);
4673 /* Everything ok - add the service possibly using a template. */
4675 const service *sp = &sDefault;
4676 if (snum_template != -1) {
4677 sp = ServicePtrs[snum_template];
4680 if ((iService = add_a_service(sp, service_name)) < 0) {
4681 DEBUG(0, ("process_usershare_file: Failed to add "
4682 "new service %s\n", service_name));
4683 talloc_destroy(ctx);
4687 /* Read only is controlled by usershare ACL below. */
4688 ServicePtrs[iService]->bRead_only = False;
4691 /* Write the ACL of the new/modified share. */
4692 if (!set_share_security(service_name, psd)) {
4693 DEBUG(0, ("process_usershare_file: Failed to set share "
4694 "security for user share %s\n",
4696 lp_remove_service(iService);
4697 talloc_destroy(ctx);
4701 talloc_destroy(ctx);
4703 /* If from a template it may be marked invalid. */
4704 ServicePtrs[iService]->valid = True;
4706 /* Set the service as a valid usershare. */
4707 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4709 /* Set guest access. */
4710 if (lp_usershare_allow_guests()) {
4711 ServicePtrs[iService]->bGuest_ok = guest_ok;
4714 /* And note when it was loaded. */
4715 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
4716 string_set(&ServicePtrs[iService]->szPath, sharepath);
4717 string_set(&ServicePtrs[iService]->comment, comment);
4722 /***************************************************************************
4723 Checks if a usershare entry has been modified since last load.
4724 ***************************************************************************/
4726 static BOOL usershare_exists(int iService, time_t *last_mod)
4728 SMB_STRUCT_STAT lsbuf;
4729 const char *usersharepath = Globals.szUsersharePath;
4732 pstrcpy(fname, usersharepath);
4733 pstrcat(fname, "/");
4734 pstrcat(fname, ServicePtrs[iService]->szService);
4736 if (sys_lstat(fname, &lsbuf) != 0) {
4740 if (!S_ISREG(lsbuf.st_mode)) {
4744 *last_mod = lsbuf.st_mtime;
4748 /***************************************************************************
4749 Load a usershare service by name. Returns a valid servicenumber or -1.
4750 ***************************************************************************/
4752 int load_usershare_service(const char *servicename)
4754 SMB_STRUCT_STAT sbuf;
4755 const char *usersharepath = Globals.szUsersharePath;
4756 int max_user_shares = Globals.iUsershareMaxShares;
4757 int snum_template = -1;
4759 if (*usersharepath == 0 || max_user_shares == 0) {
4763 if (sys_stat(usersharepath, &sbuf) != 0) {
4764 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4765 usersharepath, strerror(errno) ));
4769 if (!S_ISDIR(sbuf.st_mode)) {
4770 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4776 * This directory must be owned by root, and have the 't' bit set.
4777 * It also must not be writable by "other".
4781 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4783 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4785 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4786 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4791 /* Ensure the template share exists if it's set. */
4792 if (Globals.szUsershareTemplateShare[0]) {
4793 /* We can't use lp_servicenumber here as we are recommending that
4794 template shares have -valid=False set. */
4795 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4796 if (ServicePtrs[snum_template]->szService &&
4797 strequal(ServicePtrs[snum_template]->szService,
4798 Globals.szUsershareTemplateShare)) {
4803 if (snum_template == -1) {
4804 DEBUG(0,("load_usershare_service: usershare template share %s "
4805 "does not exist.\n",
4806 Globals.szUsershareTemplateShare ));
4811 return process_usershare_file(usersharepath, servicename, snum_template);
4814 /***************************************************************************
4815 Load all user defined shares from the user share directory.
4816 We only do this if we're enumerating the share list.
4817 This is the function that can delete usershares that have
4819 ***************************************************************************/
4821 int load_usershare_shares(void)
4824 SMB_STRUCT_STAT sbuf;
4825 SMB_STRUCT_DIRENT *de;
4826 int num_usershares = 0;
4827 int max_user_shares = Globals.iUsershareMaxShares;
4828 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4829 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4830 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4832 int snum_template = -1;
4833 const char *usersharepath = Globals.szUsersharePath;
4834 int ret = lp_numservices();
4836 if (max_user_shares == 0 || *usersharepath == '\0') {
4837 return lp_numservices();
4840 if (sys_stat(usersharepath, &sbuf) != 0) {
4841 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4842 usersharepath, strerror(errno) ));
4847 * This directory must be owned by root, and have the 't' bit set.
4848 * It also must not be writable by "other".
4852 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4854 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4856 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4857 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4862 /* Ensure the template share exists if it's set. */
4863 if (Globals.szUsershareTemplateShare[0]) {
4864 /* We can't use lp_servicenumber here as we are recommending that
4865 template shares have -valid=False set. */
4866 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4867 if (ServicePtrs[snum_template]->szService &&
4868 strequal(ServicePtrs[snum_template]->szService,
4869 Globals.szUsershareTemplateShare)) {
4874 if (snum_template == -1) {
4875 DEBUG(0,("load_usershare_shares: usershare template share %s "
4876 "does not exist.\n",
4877 Globals.szUsershareTemplateShare ));
4882 /* Mark all existing usershares as pending delete. */
4883 for (iService = iNumServices - 1; iService >= 0; iService--) {
4884 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4885 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4889 dp = sys_opendir(usersharepath);
4891 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4892 usersharepath, strerror(errno) ));
4896 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4897 (de = sys_readdir(dp));
4898 num_dir_entries++ ) {
4900 const char *n = de->d_name;
4902 /* Ignore . and .. */
4904 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4910 /* Temporary file used when creating a share. */
4911 num_tmp_dir_entries++;
4914 /* Allow 20% tmp entries. */
4915 if (num_tmp_dir_entries > allowed_tmp_entries) {
4916 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4917 "in directory %s\n",
4918 num_tmp_dir_entries, usersharepath));
4922 r = process_usershare_file(usersharepath, n, snum_template);
4924 /* Update the services count. */
4926 if (num_usershares >= max_user_shares) {
4927 DEBUG(0,("load_usershare_shares: max user shares reached "
4928 "on file %s in directory %s\n",
4929 n, usersharepath ));
4932 } else if (r == -1) {
4933 num_bad_dir_entries++;
4936 /* Allow 20% bad entries. */
4937 if (num_bad_dir_entries > allowed_bad_entries) {
4938 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4939 "in directory %s\n",
4940 num_bad_dir_entries, usersharepath));
4944 /* Allow 20% bad entries. */
4945 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4946 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4947 "in directory %s\n",
4948 num_dir_entries, usersharepath));
4955 /* Sweep through and delete any non-refreshed usershares that are
4956 not currently in use. */
4957 for (iService = iNumServices - 1; iService >= 0; iService--) {
4958 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4959 if (conn_snum_used(iService)) {
4962 /* Remove from the share ACL db. */
4963 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4964 lp_servicename(iService) ));
4965 delete_share_security(snum2params_static(iService));
4966 free_service_byindex(iService);
4970 return lp_numservices();
4973 /********************************************************
4974 Destroy global resources allocated in this file
4975 ********************************************************/
4977 void gfree_loadparm(void)
4979 struct file_lists *f;
4980 struct file_lists *next;
4985 /* Free the file lists */
4990 SAFE_FREE( f->name );
4991 SAFE_FREE( f->subfname );
4996 /* Free resources allocated to services */
4998 for ( i = 0; i < iNumServices; i++ ) {
5000 free_service_byindex(i);
5004 SAFE_FREE( ServicePtrs );
5007 /* Now release all resources allocated to global
5008 parameters and the default service */
5010 for (i = 0; parm_table[i].label; i++)
5012 if ( parm_table[i].type == P_STRING
5013 || parm_table[i].type == P_USTRING )
5015 string_free( (char**)parm_table[i].ptr );
5017 else if (parm_table[i].type == P_LIST) {
5018 str_list_free( (char***)parm_table[i].ptr );
5023 /***************************************************************************
5024 Load the services array from the services file. Return True on success,
5026 ***************************************************************************/
5028 BOOL lp_load(const char *pszFname,
5032 BOOL initialize_globals)
5036 param_opt_struct *data, *pdata;
5038 pstrcpy(n2, pszFname);
5040 standard_sub_basic( get_current_username(), current_user_info.domain,
5043 add_to_file_list(pszFname, n2);
5047 DEBUG(3, ("lp_load: refreshing parameters\n"));
5049 bInGlobalSection = True;
5050 bGlobalOnly = global_only;
5052 init_globals(! initialize_globals);
5055 if (save_defaults) {
5060 if (Globals.param_opt != NULL) {
5061 data = Globals.param_opt;
5063 string_free(&data->key);
5064 string_free(&data->value);
5065 str_list_free(&data->list);
5070 Globals.param_opt = NULL;
5073 /* We get sections first, so have to start 'behind' to make up */
5075 bRetval = pm_process(n2, do_section, do_parameter);
5077 /* finish up the last section */
5078 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
5080 if (iServiceIndex >= 0)
5081 bRetval = service_ok(iServiceIndex);
5083 lp_add_auto_services(lp_auto_services());
5086 /* When 'restrict anonymous = 2' guest connections to ipc$
5088 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
5089 if ( lp_enable_asu_support() )
5090 lp_add_ipc("ADMIN$", False);
5094 set_default_server_announce_type();
5095 set_allowed_client_auth();
5099 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
5100 /* if bWINSsupport is true and we are in the client */
5101 if (in_client && Globals.bWINSsupport) {
5102 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5110 /***************************************************************************
5111 Reset the max number of services.
5112 ***************************************************************************/
5114 void lp_resetnumservices(void)
5119 /***************************************************************************
5120 Return the max number of services.
5121 ***************************************************************************/
5123 int lp_numservices(void)
5125 return (iNumServices);
5128 /***************************************************************************
5129 Display the contents of the services array in human-readable form.
5130 ***************************************************************************/
5132 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
5137 defaults_saved = False;
5141 dump_a_service(&sDefault, f);
5143 for (iService = 0; iService < maxtoprint; iService++) {
5145 lp_dump_one(f, show_defaults, iService);
5149 /***************************************************************************
5150 Display the contents of one service in human-readable form.
5151 ***************************************************************************/
5153 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
5156 if (ServicePtrs[snum]->szService[0] == '\0')
5158 dump_a_service(ServicePtrs[snum], f);
5162 /***************************************************************************
5163 Return the number of the service with the given name, or -1 if it doesn't
5164 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5165 getservicebyname()! This works ONLY if all services have been loaded, and
5166 does not copy the found service.
5167 ***************************************************************************/
5169 int lp_servicenumber(const char *pszServiceName)
5172 fstring serviceName;
5174 if (!pszServiceName) {
5175 return GLOBAL_SECTION_SNUM;
5178 for (iService = iNumServices - 1; iService >= 0; iService--) {
5179 if (VALID(iService) && ServicePtrs[iService]->szService) {
5181 * The substitution here is used to support %U is
5184 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5185 standard_sub_basic(get_current_username(),
5186 current_user_info.domain,
5187 serviceName,sizeof(serviceName));
5188 if (strequal(serviceName, pszServiceName)) {
5194 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5197 if (!usershare_exists(iService, &last_mod)) {
5198 /* Remove the share security tdb entry for it. */
5199 delete_share_security(snum2params_static(iService));
5200 /* Remove it from the array. */
5201 free_service_byindex(iService);
5202 /* Doesn't exist anymore. */
5203 return GLOBAL_SECTION_SNUM;
5206 /* Has it been modified ? If so delete and reload. */
5207 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5208 /* Remove it from the array. */
5209 free_service_byindex(iService);
5210 /* and now reload it. */
5211 iService = load_usershare_service(pszServiceName);
5216 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5217 return GLOBAL_SECTION_SNUM;
5223 BOOL share_defined(const char *service_name)
5225 return (lp_servicenumber(service_name) != -1);
5228 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
5229 const char *sharename)
5231 struct share_params *result;
5235 if (!(sname = SMB_STRDUP(sharename))) {
5239 snum = find_service(sname);
5246 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
5247 DEBUG(0, ("talloc failed\n"));
5251 result->service = snum;
5255 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
5257 struct share_iterator *result;
5259 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
5260 DEBUG(0, ("talloc failed\n"));
5264 result->next_id = 0;
5268 struct share_params *next_share(struct share_iterator *list)
5270 struct share_params *result;
5272 while (!lp_snum_ok(list->next_id) &&
5273 (list->next_id < lp_numservices())) {
5277 if (list->next_id >= lp_numservices()) {
5281 if (!(result = TALLOC_P(list, struct share_params))) {
5282 DEBUG(0, ("talloc failed\n"));
5286 result->service = list->next_id;
5291 struct share_params *next_printer(struct share_iterator *list)
5293 struct share_params *result;
5295 while ((result = next_share(list)) != NULL) {
5296 if (lp_print_ok(result->service)) {
5304 * This is a hack for a transition period until we transformed all code from
5305 * service numbers to struct share_params.
5308 struct share_params *snum2params_static(int snum)
5310 static struct share_params result;
5311 result.service = snum;
5315 /*******************************************************************
5316 A useful volume label function.
5317 ********************************************************************/
5319 const char *volume_label(int snum)
5322 const char *label = lp_volume(snum);
5324 label = lp_servicename(snum);
5327 /* This returns a 33 byte guarenteed null terminated string. */
5328 ret = talloc_strndup(main_loop_talloc_get(), label, 32);
5335 /*******************************************************************
5336 Set the server type we will announce as via nmbd.
5337 ********************************************************************/
5339 static void set_default_server_announce_type(void)
5341 default_server_announce = 0;
5342 default_server_announce |= SV_TYPE_WORKSTATION;
5343 default_server_announce |= SV_TYPE_SERVER;
5344 default_server_announce |= SV_TYPE_SERVER_UNIX;
5346 /* note that the flag should be set only if we have a
5347 printer service but nmbd doesn't actually load the
5348 services so we can't tell --jerry */
5350 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5352 switch (lp_announce_as()) {
5353 case ANNOUNCE_AS_NT_SERVER:
5354 default_server_announce |= SV_TYPE_SERVER_NT;
5355 /* fall through... */
5356 case ANNOUNCE_AS_NT_WORKSTATION:
5357 default_server_announce |= SV_TYPE_NT;
5359 case ANNOUNCE_AS_WIN95:
5360 default_server_announce |= SV_TYPE_WIN95_PLUS;
5362 case ANNOUNCE_AS_WFW:
5363 default_server_announce |= SV_TYPE_WFW;
5369 switch (lp_server_role()) {
5370 case ROLE_DOMAIN_MEMBER:
5371 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5373 case ROLE_DOMAIN_PDC:
5374 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5376 case ROLE_DOMAIN_BDC:
5377 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5379 case ROLE_STANDALONE:
5383 if (lp_time_server())
5384 default_server_announce |= SV_TYPE_TIME_SOURCE;
5386 if (lp_host_msdfs())
5387 default_server_announce |= SV_TYPE_DFS_SERVER;
5390 /***********************************************************
5391 returns role of Samba server
5392 ************************************************************/
5394 int lp_server_role(void)
5399 /***********************************************************
5400 If we are PDC then prefer us as DMB
5401 ************************************************************/
5403 BOOL lp_domain_master(void)
5405 if (Globals.bDomainMaster == Auto)
5406 return (lp_server_role() == ROLE_DOMAIN_PDC);
5408 return Globals.bDomainMaster;
5411 /***********************************************************
5412 If we are DMB then prefer us as LMB
5413 ************************************************************/
5415 BOOL lp_preferred_master(void)
5417 if (Globals.bPreferredMaster == Auto)
5418 return (lp_local_master() && lp_domain_master());
5420 return Globals.bPreferredMaster;
5423 /*******************************************************************
5425 ********************************************************************/
5427 void lp_remove_service(int snum)
5429 ServicePtrs[snum]->valid = False;
5430 invalid_services[num_invalid_services++] = snum;
5433 /*******************************************************************
5435 ********************************************************************/
5437 void lp_copy_service(int snum, const char *new_name)
5439 do_section(new_name);
5441 snum = lp_servicenumber(new_name);
5443 lp_do_parameter(snum, "copy", lp_servicename(snum));
5448 /*******************************************************************
5449 Get the default server type we will announce as via nmbd.
5450 ********************************************************************/
5452 int lp_default_server_announce(void)
5454 return default_server_announce;
5457 /*******************************************************************
5458 Split the announce version into major and minor numbers.
5459 ********************************************************************/
5461 int lp_major_announce_version(void)
5463 static BOOL got_major = False;
5464 static int major_version = DEFAULT_MAJOR_VERSION;
5469 return major_version;
5472 if ((vers = lp_announce_version()) == NULL)
5473 return major_version;
5475 if ((p = strchr_m(vers, '.')) == 0)
5476 return major_version;
5479 major_version = atoi(vers);
5480 return major_version;
5483 int lp_minor_announce_version(void)
5485 static BOOL got_minor = False;
5486 static int minor_version = DEFAULT_MINOR_VERSION;
5491 return minor_version;
5494 if ((vers = lp_announce_version()) == NULL)
5495 return minor_version;
5497 if ((p = strchr_m(vers, '.')) == 0)
5498 return minor_version;
5501 minor_version = atoi(p);
5502 return minor_version;
5505 /***********************************************************
5506 Set the global name resolution order (used in smbclient).
5507 ************************************************************/
5509 void lp_set_name_resolve_order(const char *new_order)
5511 string_set(&Globals.szNameResolveOrder, new_order);
5514 const char *lp_printername(int snum)
5516 const char *ret = _lp_printername(snum);
5517 if (ret == NULL || (ret != NULL && *ret == '\0'))
5518 ret = lp_const_servicename(snum);
5524 /***********************************************************
5525 Allow daemons such as winbindd to fix their logfile name.
5526 ************************************************************/
5528 void lp_set_logfile(const char *name)
5530 string_set(&Globals.szLogFile, name);
5531 pstrcpy(debugf, name);
5534 /*******************************************************************
5535 Return the max print jobs per queue.
5536 ********************************************************************/
5538 int lp_maxprintjobs(int snum)
5540 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5541 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5542 maxjobs = PRINT_MAX_JOBID - 1;
5547 const char *lp_printcapname(void)
5549 if ((Globals.szPrintcapname != NULL) &&
5550 (Globals.szPrintcapname[0] != '\0'))
5551 return Globals.szPrintcapname;
5553 if (sDefault.iPrinting == PRINT_CUPS) {
5561 if (sDefault.iPrinting == PRINT_BSD)
5562 return "/etc/printcap";
5564 return PRINTCAP_NAME;
5567 /*******************************************************************
5568 Ensure we don't use sendfile if server smb signing is active.
5569 ********************************************************************/
5571 static uint32 spoolss_state;
5573 BOOL lp_disable_spoolss( void )
5575 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5576 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5578 return spoolss_state == SVCCTL_STOPPED ? True : False;
5581 void lp_set_spoolss_state( uint32 state )
5583 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5585 spoolss_state = state;
5588 uint32 lp_get_spoolss_state( void )
5590 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5593 /*******************************************************************
5594 Ensure we don't use sendfile if server smb signing is active.
5595 ********************************************************************/
5597 BOOL lp_use_sendfile(int snum)
5599 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5600 if (Protocol < PROTOCOL_NT1) {
5603 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
5606 /*******************************************************************
5607 Turn off sendfile if we find the underlying OS doesn't support it.
5608 ********************************************************************/
5610 void set_use_sendfile(int snum, BOOL val)
5612 if (LP_SNUM_OK(snum))
5613 ServicePtrs[snum]->bUseSendfile = val;
5615 sDefault.bUseSendfile = val;
5618 /*******************************************************************
5619 Turn off storing DOS attributes if this share doesn't support it.
5620 ********************************************************************/
5622 void set_store_dos_attributes(int snum, BOOL val)
5624 if (!LP_SNUM_OK(snum))
5626 ServicePtrs[(snum)]->bStoreDosAttributes = val;
5629 void lp_set_mangling_method(const char *new_method)
5631 string_set(&Globals.szManglingMethod, new_method);
5634 /*******************************************************************
5635 Global state for POSIX pathname processing.
5636 ********************************************************************/
5638 static BOOL posix_pathnames;
5640 BOOL lp_posix_pathnames(void)
5642 return posix_pathnames;
5645 /*******************************************************************
5646 Change everything needed to ensure POSIX pathname processing (currently
5648 ********************************************************************/
5650 void lp_set_posix_pathnames(void)
5652 posix_pathnames = True;
5655 /*******************************************************************
5656 Global state for POSIX lock processing - CIFS unix extensions.
5657 ********************************************************************/
5659 BOOL posix_default_lock_was_set;
5660 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5662 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5664 if (posix_default_lock_was_set) {
5665 return posix_cifsx_locktype;
5667 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5671 /*******************************************************************
5672 ********************************************************************/
5674 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5676 posix_default_lock_was_set = True;
5677 posix_cifsx_locktype = val;