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"), 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.bWinbindRefreshTickets = False;
1648 Globals.bWinbindOfflineLogon = False;
1650 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
1651 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
1653 Globals.bPassdbExpandExplicit = False;
1655 Globals.name_cache_timeout = 660; /* In seconds */
1657 Globals.bUseSpnego = True;
1658 Globals.bClientUseSpnego = True;
1660 Globals.client_signing = Auto;
1661 Globals.server_signing = False;
1663 Globals.bDeferSharingViolations = True;
1664 string_set(&Globals.smb_ports, SMB_PORTS);
1666 Globals.bEnablePrivileges = True;
1667 Globals.bHostMSDfs = True;
1668 Globals.bASUSupport = False;
1670 /* User defined shares. */
1671 pstrcpy(s, dyn_LOCKDIR);
1672 pstrcat(s, "/usershares");
1673 string_set(&Globals.szUsersharePath, s);
1674 string_set(&Globals.szUsershareTemplateShare, "");
1675 Globals.iUsershareMaxShares = 0;
1676 /* By default disallow sharing of directories not owned by the sharer. */
1677 Globals.bUsershareOwnerOnly = True;
1678 /* By default disallow guest access to usershares. */
1679 Globals.bUsershareAllowGuests = False;
1681 Globals.iKeepalive = DEFAULT_KEEPALIVE;
1683 /* By default no shares out of the registry */
1684 Globals.bRegistryShares = False;
1687 static TALLOC_CTX *lp_talloc;
1689 /******************************************************************* a
1690 Free up temporary memory - called from the main loop.
1691 ********************************************************************/
1693 void lp_TALLOC_FREE(void)
1697 TALLOC_FREE(lp_talloc);
1701 TALLOC_CTX *tmp_talloc_ctx(void)
1703 if (lp_talloc == NULL) {
1704 lp_talloc = talloc_init("tmp_talloc_ctx");
1707 if (lp_talloc == NULL) {
1708 smb_panic("Could not create temporary talloc context\n");
1714 /*******************************************************************
1715 Convenience routine to grab string parameters into temporary memory
1716 and run standard_sub_basic on them. The buffers can be written to by
1717 callers without affecting the source string.
1718 ********************************************************************/
1720 static char *lp_string(const char *s)
1724 /* The follow debug is useful for tracking down memory problems
1725 especially if you have an inner loop that is calling a lp_*()
1726 function that returns a string. Perhaps this debug should be
1727 present all the time? */
1730 DEBUG(10, ("lp_string(%s)\n", s));
1734 lp_talloc = talloc_init("lp_talloc");
1736 tmpstr = alloc_sub_basic(get_current_username(),
1737 current_user_info.domain, s);
1738 if (trim_char(tmpstr, '\"', '\"')) {
1739 if (strchr(tmpstr,'\"') != NULL) {
1741 tmpstr = alloc_sub_basic(get_current_username(),
1742 current_user_info.domain, s);
1745 ret = talloc_strdup(lp_talloc, tmpstr);
1752 In this section all the functions that are used to access the
1753 parameters from the rest of the program are defined
1756 #define FN_GLOBAL_STRING(fn_name,ptr) \
1757 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1758 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1759 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1760 #define FN_GLOBAL_LIST(fn_name,ptr) \
1761 const char **fn_name(void) {return(*(const char ***)(ptr));}
1762 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1763 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1764 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1765 char fn_name(void) {return(*(char *)(ptr));}
1766 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1767 int fn_name(void) {return(*(int *)(ptr));}
1769 #define FN_LOCAL_STRING(fn_name,val) \
1770 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1771 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1772 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1773 #define FN_LOCAL_LIST(fn_name,val) \
1774 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1775 #define FN_LOCAL_BOOL(fn_name,val) \
1776 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1777 #define FN_LOCAL_INTEGER(fn_name,val) \
1778 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1780 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1781 BOOL fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1782 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1783 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1784 #define FN_LOCAL_PARM_STRING(fn_name,val) \
1785 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));}
1786 #define FN_LOCAL_CHAR(fn_name,val) \
1787 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1789 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1790 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1791 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1792 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1793 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1794 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1795 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1796 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1797 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1798 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1799 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1800 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1801 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1802 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1803 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1804 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1805 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1806 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1807 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1808 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1809 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1810 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1811 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1812 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1813 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1814 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1815 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1816 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1817 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1818 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1819 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1820 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1821 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1822 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1823 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1824 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1825 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1826 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1827 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1828 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1829 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1830 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1831 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1832 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1833 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1834 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1835 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1836 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1837 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1838 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1839 * lp_passdb_backend() should be replace by the this macro again after
1842 const char *lp_passdb_backend(void)
1844 char *delim, *quote;
1846 delim = strchr( Globals.szPassdbBackend, ' ');
1847 /* no space at all */
1848 if (delim == NULL) {
1852 quote = strchr(Globals.szPassdbBackend, '"');
1853 /* no quote char or non in the first part */
1854 if (quote == NULL || quote > delim) {
1859 quote = strchr(quote+1, '"');
1860 if (quote == NULL) {
1861 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
1863 } else if (*(quote+1) == '\0') {
1864 /* space, fitting quote char, and one backend only */
1867 /* terminate string after the fitting quote char */
1872 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
1873 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
1874 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
1875 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
1878 return Globals.szPassdbBackend;
1880 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1881 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1882 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1883 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1884 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1886 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1887 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1888 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1889 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1890 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1891 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1893 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1895 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1896 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1897 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1899 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1901 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1902 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1903 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1904 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1905 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
1906 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1907 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1908 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1909 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1910 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1911 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
1912 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1913 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1914 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
1915 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
1917 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
1918 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
1919 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
1920 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
1921 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
1922 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
1923 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1925 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1926 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1927 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1928 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1929 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1930 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1931 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1932 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1933 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1934 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1935 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1936 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1937 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1938 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1940 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1942 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
1943 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1944 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1945 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1946 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1947 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1948 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1949 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1950 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1951 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1952 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1953 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1954 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1955 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1956 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1957 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1958 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1959 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1960 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1961 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1962 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1963 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1964 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1965 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1966 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1967 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
1968 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1969 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1970 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1971 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
1972 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1973 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1974 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1975 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1976 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1977 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1978 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1979 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1980 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1981 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1982 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1983 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1984 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1985 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1986 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1987 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1988 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1989 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1990 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1991 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1992 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1993 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1994 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1995 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1996 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1997 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1998 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1999 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
2000 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
2001 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
2002 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
2003 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
2004 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
2005 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
2006 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
2007 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
2008 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
2009 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
2010 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
2011 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
2012 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
2013 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
2014 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
2015 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
2016 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
2017 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
2018 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
2019 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
2020 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
2021 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
2022 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
2023 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
2024 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
2025 FN_GLOBAL_INTEGER(_lp_disable_spoolss, &Globals.bDisableSpoolss)
2026 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
2027 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
2028 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
2029 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
2030 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
2031 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
2032 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
2033 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
2034 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
2036 FN_LOCAL_STRING(lp_preexec, szPreExec)
2037 FN_LOCAL_STRING(lp_postexec, szPostExec)
2038 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
2039 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
2040 FN_LOCAL_STRING(lp_servicename, szService)
2041 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
2042 FN_LOCAL_STRING(lp_pathname, szPath)
2043 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
2044 FN_LOCAL_STRING(lp_username, szUsername)
2045 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
2046 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
2047 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
2048 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
2049 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
2050 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
2051 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
2052 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
2053 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering);
2054 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
2055 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
2056 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
2057 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
2058 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
2059 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
2060 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
2061 static FN_LOCAL_STRING(_lp_printername, szPrintername)
2062 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
2063 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
2064 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
2065 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
2066 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
2067 FN_LOCAL_STRING(lp_comment, comment)
2068 FN_LOCAL_STRING(lp_force_user, force_user)
2069 FN_LOCAL_STRING(lp_force_group, force_group)
2070 FN_LOCAL_LIST(lp_readlist, readlist)
2071 FN_LOCAL_LIST(lp_writelist, writelist)
2072 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
2073 FN_LOCAL_STRING(lp_fstype, fstype)
2074 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
2075 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
2076 static FN_LOCAL_STRING(lp_volume, volume)
2077 FN_LOCAL_PARM_STRING(lp_mangled_map, szMangledMap)
2078 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
2079 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
2080 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
2081 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
2082 FN_LOCAL_STRING(lp_dfree_command, szDfree)
2083 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
2084 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
2085 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
2086 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
2087 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
2088 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
2089 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
2090 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2091 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2092 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2093 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2094 FN_LOCAL_BOOL(lp_readonly, bRead_only)
2095 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2096 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2097 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2098 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2099 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2100 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2101 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2102 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2103 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
2104 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
2105 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
2106 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2107 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2108 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2109 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2110 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
2111 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2112 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2113 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2114 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2115 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2116 FN_LOCAL_BOOL(lp_map_system, bMap_system)
2117 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2118 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2119 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2120 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2121 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2122 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2123 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2124 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2125 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2126 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2127 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2128 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2129 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2130 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2131 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2132 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2133 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2134 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2135 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2136 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2137 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2138 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2139 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2140 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2141 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2142 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2143 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2144 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2145 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2146 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2147 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2148 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2149 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2150 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2151 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2152 FN_LOCAL_INTEGER(lp_printing, iPrinting)
2153 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2154 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2155 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2156 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2157 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2158 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2159 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2160 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2161 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2162 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2163 FN_LOCAL_CHAR(lp_magicchar, magic_char)
2164 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2165 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2166 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2167 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2168 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2169 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2171 /* local prototypes */
2173 static int map_parameter(const char *pszParmName);
2174 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
2175 static int getservicebyname(const char *pszServiceName,
2176 service * pserviceDest);
2177 static void copy_service(service * pserviceDest,
2178 service * pserviceSource, BOOL *pcopymapDest);
2179 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
2180 static BOOL do_section(const char *pszSectionName);
2181 static void init_copymap(service * pservice);
2182 static BOOL hash_a_service(const char *name, int number);
2183 static void free_service_byindex(int iService);
2184 static char * canonicalize_servicename(const char *name);
2186 /* This is a helper function for parametrical options support. */
2187 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2188 /* Actual parametrical functions are quite simple */
2189 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2191 BOOL global_section = False;
2193 param_opt_struct *data;
2195 if (snum >= iNumServices) return NULL;
2198 data = Globals.param_opt;
2199 global_section = True;
2201 data = ServicePtrs[snum]->param_opt;
2204 asprintf(¶m_key, "%s:%s", type, option);
2206 DEBUG(0,("asprintf failed!\n"));
2211 if (strcmp(data->key, param_key) == 0) {
2212 string_free(¶m_key);
2218 if (!global_section) {
2219 /* Try to fetch the same option but from globals */
2220 /* but only if we are not already working with Globals */
2221 data = Globals.param_opt;
2223 if (strcmp(data->key, param_key) == 0) {
2224 string_free(¶m_key);
2231 string_free(¶m_key);
2237 #define MISSING_PARAMETER(name) \
2238 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2240 /*******************************************************************
2241 convenience routine to return int parameters.
2242 ********************************************************************/
2243 static int lp_int(const char *s)
2247 MISSING_PARAMETER(lp_int);
2251 return (int)strtol(s, NULL, 0);
2254 /*******************************************************************
2255 convenience routine to return unsigned long parameters.
2256 ********************************************************************/
2257 static unsigned long lp_ulong(const char *s)
2261 MISSING_PARAMETER(lp_ulong);
2265 return strtoul(s, NULL, 0);
2268 /*******************************************************************
2269 convenience routine to return boolean parameters.
2270 ********************************************************************/
2271 static BOOL lp_bool(const char *s)
2276 MISSING_PARAMETER(lp_bool);
2280 if (!set_boolean(&ret,s)) {
2281 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2288 /*******************************************************************
2289 convenience routine to return enum parameters.
2290 ********************************************************************/
2291 static int lp_enum(const char *s,const struct enum_list *_enum)
2295 if (!s || !*s || !_enum) {
2296 MISSING_PARAMETER(lp_enum);
2300 for (i=0; _enum[i].name; i++) {
2301 if (strequal(_enum[i].name,s))
2302 return _enum[i].value;
2305 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2309 #undef MISSING_PARAMETER
2311 /* DO NOT USE lp_parm_string ANYMORE!!!!
2312 * use lp_parm_const_string or lp_parm_talloc_string
2314 * lp_parm_string is only used to let old modules find this symbol
2316 #undef lp_parm_string
2317 char *lp_parm_string(const char *servicename, const char *type, const char *option);
2318 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2320 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2323 /* Return parametric option from a given service. Type is a part of option before ':' */
2324 /* Parametric option has following syntax: 'Type: option = value' */
2325 /* the returned value is talloced in lp_talloc */
2326 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2328 param_opt_struct *data = get_parametrics(snum, type, option);
2330 if (data == NULL||data->value==NULL) {
2332 return lp_string(def);
2338 return lp_string(data->value);
2341 /* Return parametric option from a given service. Type is a part of option before ':' */
2342 /* Parametric option has following syntax: 'Type: option = value' */
2343 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2345 param_opt_struct *data = get_parametrics(snum, type, option);
2347 if (data == NULL||data->value==NULL)
2353 /* Return parametric option from a given service. Type is a part of option before ':' */
2354 /* Parametric option has following syntax: 'Type: option = value' */
2356 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2358 param_opt_struct *data = get_parametrics(snum, type, option);
2360 if (data == NULL||data->value==NULL)
2361 return (const char **)def;
2363 if (data->list==NULL) {
2364 data->list = str_list_make(data->value, NULL);
2367 return (const char **)data->list;
2370 /* Return parametric option from a given service. Type is a part of option before ':' */
2371 /* Parametric option has following syntax: 'Type: option = value' */
2373 int lp_parm_int(int snum, const char *type, const char *option, int def)
2375 param_opt_struct *data = get_parametrics(snum, type, option);
2377 if (data && data->value && *data->value)
2378 return lp_int(data->value);
2383 /* Return parametric option from a given service. Type is a part of option before ':' */
2384 /* Parametric option has following syntax: 'Type: option = value' */
2386 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2388 param_opt_struct *data = get_parametrics(snum, type, option);
2390 if (data && data->value && *data->value)
2391 return lp_ulong(data->value);
2396 /* Return parametric option from a given service. Type is a part of option before ':' */
2397 /* Parametric option has following syntax: 'Type: option = value' */
2399 BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2401 param_opt_struct *data = get_parametrics(snum, type, option);
2403 if (data && data->value && *data->value)
2404 return lp_bool(data->value);
2409 /* Return parametric option from a given service. Type is a part of option before ':' */
2410 /* Parametric option has following syntax: 'Type: option = value' */
2412 int lp_parm_enum(int snum, const char *type, const char *option,
2413 const struct enum_list *_enum, int def)
2415 param_opt_struct *data = get_parametrics(snum, type, option);
2417 if (data && data->value && *data->value && _enum)
2418 return lp_enum(data->value, _enum);
2424 /***************************************************************************
2425 Initialise a service to the defaults.
2426 ***************************************************************************/
2428 static void init_service(service * pservice)
2430 memset((char *)pservice, '\0', sizeof(service));
2431 copy_service(pservice, &sDefault, NULL);
2434 /***************************************************************************
2435 Free the dynamically allocated parts of a service struct.
2436 ***************************************************************************/
2438 static void free_service(service *pservice)
2441 param_opt_struct *data, *pdata;
2445 if (pservice->szService)
2446 DEBUG(5, ("free_service: Freeing service %s\n",
2447 pservice->szService));
2449 string_free(&pservice->szService);
2450 SAFE_FREE(pservice->copymap);
2452 for (i = 0; parm_table[i].label; i++) {
2453 if ((parm_table[i].type == P_STRING ||
2454 parm_table[i].type == P_USTRING) &&
2455 parm_table[i].p_class == P_LOCAL)
2456 string_free((char **)
2457 (((char *)pservice) +
2458 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2459 else if (parm_table[i].type == P_LIST &&
2460 parm_table[i].p_class == P_LOCAL)
2461 str_list_free((char ***)
2462 (((char *)pservice) +
2463 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2466 data = pservice->param_opt;
2468 DEBUG(5,("Freeing parametrics:\n"));
2470 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2471 string_free(&data->key);
2472 string_free(&data->value);
2473 str_list_free(&data->list);
2479 ZERO_STRUCTP(pservice);
2483 /***************************************************************************
2484 remove a service indexed in the ServicePtrs array from the ServiceHash
2485 and free the dynamically allocated parts
2486 ***************************************************************************/
2488 static void free_service_byindex(int idx)
2490 if ( !LP_SNUM_OK(idx) )
2493 ServicePtrs[idx]->valid = False;
2494 invalid_services[num_invalid_services++] = idx;
2496 /* we have to cleanup the hash record */
2498 if (ServicePtrs[idx]->szService) {
2499 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2501 tdb_delete_bystring(ServiceHash, canon_name );
2504 free_service(ServicePtrs[idx]);
2507 /***************************************************************************
2508 Add a new service to the services array initialising it with the given
2510 ***************************************************************************/
2512 static int add_a_service(const service *pservice, const char *name)
2516 int num_to_alloc = iNumServices + 1;
2517 param_opt_struct *data, *pdata;
2519 tservice = *pservice;
2521 /* it might already exist */
2523 i = getservicebyname(name, NULL);
2525 /* Clean all parametric options for service */
2526 /* They will be added during parsing again */
2527 data = ServicePtrs[i]->param_opt;
2529 string_free(&data->key);
2530 string_free(&data->value);
2531 str_list_free(&data->list);
2536 ServicePtrs[i]->param_opt = NULL;
2541 /* find an invalid one */
2543 if (num_invalid_services > 0) {
2544 i = invalid_services[--num_invalid_services];
2547 /* if not, then create one */
2548 if (i == iNumServices) {
2552 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2554 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2558 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2559 if (!ServicePtrs[iNumServices]) {
2560 DEBUG(0,("add_a_service: out of memory!\n"));
2565 /* enlarge invalid_services here for now... */
2566 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2568 if (tinvalid == NULL) {
2569 DEBUG(0,("add_a_service: failed to enlarge "
2570 "invalid_services!\n"));
2573 invalid_services = tinvalid;
2575 free_service_byindex(i);
2578 ServicePtrs[i]->valid = True;
2580 init_service(ServicePtrs[i]);
2581 copy_service(ServicePtrs[i], &tservice, NULL);
2583 string_set(&ServicePtrs[i]->szService, name);
2585 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2586 i, ServicePtrs[i]->szService));
2588 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2595 /***************************************************************************
2596 Canonicalize by converting to lowercase.
2597 ***************************************************************************/
2599 static char *canonicalize_servicename(const char *src)
2601 static fstring canon; /* is fstring large enough? */
2604 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2608 fstrcpy( canon, src );
2609 strlower_m( canon );
2614 /***************************************************************************
2615 Add a name/index pair for the services array to the hash table.
2616 ***************************************************************************/
2618 static BOOL hash_a_service(const char *name, int idx)
2622 if ( !ServiceHash ) {
2623 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2624 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2625 (O_RDWR|O_CREAT), 0600);
2626 if ( !ServiceHash ) {
2627 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2632 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2635 if ( !(canon_name = canonicalize_servicename( name )) )
2638 tdb_store_int32(ServiceHash, canon_name, idx);
2643 /***************************************************************************
2644 Add a new home service, with the specified home directory, defaults coming
2646 ***************************************************************************/
2648 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
2649 const char *user, const char *pszHomedir)
2654 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2659 if (!(*(ServicePtrs[iDefaultService]->szPath))
2660 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2661 pstrcpy(newHomedir, pszHomedir);
2662 string_set(&ServicePtrs[i]->szPath, newHomedir);
2665 if (!(*(ServicePtrs[i]->comment))) {
2667 slprintf(comment, sizeof(comment) - 1,
2668 "Home directory of %s", user);
2669 string_set(&ServicePtrs[i]->comment, comment);
2672 /* set the browseable flag from the global default */
2674 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2676 ServicePtrs[i]->autoloaded = True;
2678 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2679 user, ServicePtrs[i]->szPath ));
2684 /***************************************************************************
2685 Add a new service, based on an old one.
2686 ***************************************************************************/
2688 int lp_add_service(const char *pszService, int iDefaultService)
2690 if (iDefaultService < 0) {
2691 return add_a_service(&sDefault, pszService);
2694 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2697 /***************************************************************************
2698 Add the IPC service.
2699 ***************************************************************************/
2701 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2704 int i = add_a_service(&sDefault, ipc_name);
2709 slprintf(comment, sizeof(comment) - 1,
2710 "IPC Service (%s)", Globals.szServerString);
2712 string_set(&ServicePtrs[i]->szPath, tmpdir());
2713 string_set(&ServicePtrs[i]->szUsername, "");
2714 string_set(&ServicePtrs[i]->comment, comment);
2715 string_set(&ServicePtrs[i]->fstype, "IPC");
2716 ServicePtrs[i]->iMaxConnections = 0;
2717 ServicePtrs[i]->bAvailable = True;
2718 ServicePtrs[i]->bRead_only = True;
2719 ServicePtrs[i]->bGuest_only = False;
2720 ServicePtrs[i]->bGuest_ok = guest_ok;
2721 ServicePtrs[i]->bPrint_ok = False;
2722 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2724 DEBUG(3, ("adding IPC service\n"));
2729 /***************************************************************************
2730 Add a new printer service, with defaults coming from service iFrom.
2731 ***************************************************************************/
2733 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2735 const char *comment = "From Printcap";
2736 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2741 /* note that we do NOT default the availability flag to True - */
2742 /* we take it from the default service passed. This allows all */
2743 /* dynamic printers to be disabled by disabling the [printers] */
2744 /* entry (if/when the 'available' keyword is implemented!). */
2746 /* the printer name is set to the service name. */
2747 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2748 string_set(&ServicePtrs[i]->comment, comment);
2750 /* set the browseable flag from the gloabl default */
2751 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2753 /* Printers cannot be read_only. */
2754 ServicePtrs[i]->bRead_only = False;
2755 /* No share modes on printer services. */
2756 ServicePtrs[i]->bShareModes = False;
2757 /* No oplocks on printer services. */
2758 ServicePtrs[i]->bOpLocks = False;
2759 /* Printer services must be printable. */
2760 ServicePtrs[i]->bPrint_ok = True;
2762 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2767 /***************************************************************************
2768 Map a parameter's string representation to something we can use.
2769 Returns False if the parameter string is not recognised, else TRUE.
2770 ***************************************************************************/
2772 static int map_parameter(const char *pszParmName)
2776 if (*pszParmName == '-')
2779 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2780 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2783 /* Warn only if it isn't parametric option */
2784 if (strchr(pszParmName, ':') == NULL)
2785 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2786 /* We do return 'fail' for parametric options as well because they are
2787 stored in different storage
2792 /***************************************************************************
2793 Show all parameter's name, type, [values,] and flags.
2794 ***************************************************************************/
2796 void show_parameter_list(void)
2798 int classIndex, parmIndex, enumIndex, flagIndex;
2800 const char *section_names[] = { "local", "global", NULL};
2801 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2802 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2803 "P_UGSTRING", "P_ENUM", "P_SEP"};
2804 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2805 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2806 FLAG_HIDE, FLAG_DOS_STRING};
2807 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2808 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2809 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2811 for ( classIndex=0; section_names[classIndex]; classIndex++) {
2812 printf("[%s]\n", section_names[classIndex]);
2813 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2814 if (parm_table[parmIndex].p_class == classIndex) {
2816 parm_table[parmIndex].label,
2817 type[parm_table[parmIndex].type]);
2818 switch (parm_table[parmIndex].type) {
2821 for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
2823 enumIndex ? "|" : "",
2824 parm_table[parmIndex].enum_list[enumIndex].name);
2831 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
2832 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2835 flag_names[flagIndex]);
2845 /***************************************************************************
2846 Set a boolean variable from the text value stored in the passed string.
2847 Returns True in success, False if the passed string does not correctly
2848 represent a boolean.
2849 ***************************************************************************/
2851 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2856 if (strwicmp(pszParmValue, "yes") == 0 ||
2857 strwicmp(pszParmValue, "true") == 0 ||
2858 strwicmp(pszParmValue, "1") == 0)
2860 else if (strwicmp(pszParmValue, "no") == 0 ||
2861 strwicmp(pszParmValue, "False") == 0 ||
2862 strwicmp(pszParmValue, "0") == 0)
2866 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2873 /***************************************************************************
2874 Find a service by name. Otherwise works like get_service.
2875 ***************************************************************************/
2877 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2882 if (ServiceHash != NULL) {
2883 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
2886 iService = tdb_fetch_int32(ServiceHash, canon_name );
2888 if (LP_SNUM_OK(iService)) {
2889 if (pserviceDest != NULL) {
2890 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2900 /***************************************************************************
2901 Copy a service structure to another.
2902 If pcopymapDest is NULL then copy all fields
2903 ***************************************************************************/
2905 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2908 BOOL bcopyall = (pcopymapDest == NULL);
2909 param_opt_struct *data, *pdata, *paramo;
2912 for (i = 0; parm_table[i].label; i++)
2913 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
2914 (bcopyall || pcopymapDest[i])) {
2915 void *def_ptr = parm_table[i].ptr;
2917 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2920 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2923 switch (parm_table[i].type) {
2926 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2932 *(int *)dest_ptr = *(int *)src_ptr;
2936 *(char *)dest_ptr = *(char *)src_ptr;
2940 string_set((char **)dest_ptr,
2945 string_set((char **)dest_ptr,
2947 strupper_m(*(char **)dest_ptr);
2950 str_list_free((char ***)dest_ptr);
2951 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2959 init_copymap(pserviceDest);
2960 if (pserviceSource->copymap)
2961 memcpy((void *)pserviceDest->copymap,
2962 (void *)pserviceSource->copymap,
2963 sizeof(BOOL) * NUMPARAMETERS);
2966 data = pserviceSource->param_opt;
2969 pdata = pserviceDest->param_opt;
2970 /* Traverse destination */
2972 /* If we already have same option, override it */
2973 if (strcmp(pdata->key, data->key) == 0) {
2974 string_free(&pdata->value);
2975 str_list_free(&data->list);
2976 pdata->value = SMB_STRDUP(data->value);
2980 pdata = pdata->next;
2983 paramo = SMB_XMALLOC_P(param_opt_struct);
2984 paramo->key = SMB_STRDUP(data->key);
2985 paramo->value = SMB_STRDUP(data->value);
2986 paramo->list = NULL;
2987 DLIST_ADD(pserviceDest->param_opt, paramo);
2993 /***************************************************************************
2994 Check a service for consistency. Return False if the service is in any way
2995 incomplete or faulty, else True.
2996 ***************************************************************************/
2998 BOOL service_ok(int iService)
3003 if (ServicePtrs[iService]->szService[0] == '\0') {
3004 DEBUG(0, ("The following message indicates an internal error:\n"));
3005 DEBUG(0, ("No service name in service entry.\n"));
3009 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
3010 /* I can't see why you'd want a non-printable printer service... */
3011 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
3012 if (!ServicePtrs[iService]->bPrint_ok) {
3013 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
3014 ServicePtrs[iService]->szService));
3015 ServicePtrs[iService]->bPrint_ok = True;
3017 /* [printers] service must also be non-browsable. */
3018 if (ServicePtrs[iService]->bBrowseable)
3019 ServicePtrs[iService]->bBrowseable = False;
3022 if (ServicePtrs[iService]->szPath[0] == '\0' &&
3023 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
3024 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
3026 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
3027 ServicePtrs[iService]->szService));
3028 ServicePtrs[iService]->bAvailable = False;
3031 /* If a service is flagged unavailable, log the fact at level 1. */
3032 if (!ServicePtrs[iService]->bAvailable)
3033 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
3034 ServicePtrs[iService]->szService));
3039 static struct file_lists {
3040 struct file_lists *next;
3044 } *file_lists = NULL;
3046 /*******************************************************************
3047 Keep a linked list of all config files so we know when one has changed
3048 it's date and needs to be reloaded.
3049 ********************************************************************/
3051 static void add_to_file_list(const char *fname, const char *subfname)
3053 struct file_lists *f = file_lists;
3056 if (f->name && !strcmp(f->name, fname))
3062 f = SMB_MALLOC_P(struct file_lists);
3065 f->next = file_lists;
3066 f->name = SMB_STRDUP(fname);
3071 f->subfname = SMB_STRDUP(subfname);
3077 f->modtime = file_modtime(subfname);
3079 time_t t = file_modtime(subfname);
3085 /*******************************************************************
3086 Check if a config file has changed date.
3087 ********************************************************************/
3089 BOOL lp_file_list_changed(void)
3091 struct file_lists *f = file_lists;
3093 DEBUG(6, ("lp_file_list_changed()\n"));
3099 pstrcpy(n2, f->name);
3100 standard_sub_basic( get_current_username(),
3101 current_user_info.domain,
3104 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3105 f->name, n2, ctime(&f->modtime)));
3107 mod_time = file_modtime(n2);
3109 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3111 ("file %s modified: %s\n", n2,
3113 f->modtime = mod_time;
3114 SAFE_FREE(f->subfname);
3115 f->subfname = SMB_STRDUP(n2);
3123 /***************************************************************************
3124 Run standard_sub_basic on netbios name... needed because global_myname
3125 is not accessed through any lp_ macro.
3126 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3127 ***************************************************************************/
3129 static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3132 pstring netbios_name;
3134 pstrcpy(netbios_name, pszParmValue);
3136 standard_sub_basic(get_current_username(), current_user_info.domain,
3137 netbios_name, sizeof(netbios_name));
3139 ret = set_global_myname(netbios_name);
3140 string_set(&Globals.szNetbiosName,global_myname());
3142 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3148 static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
3150 if (strcmp(*ptr, pszParmValue) != 0) {
3151 string_set(ptr, pszParmValue);
3159 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3163 ret = set_global_myworkgroup(pszParmValue);
3164 string_set(&Globals.szWorkgroup,lp_workgroup());
3169 static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3173 ret = set_global_scope(pszParmValue);
3174 string_set(&Globals.szNetbiosScope,global_scope());
3179 static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3181 str_list_free(&Globals.szNetbiosAliases);
3182 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3183 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3186 /***************************************************************************
3187 Handle the include operation.
3188 ***************************************************************************/
3190 static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
3193 pstrcpy(fname, pszParmValue);
3195 standard_sub_basic(get_current_username(), current_user_info.domain,
3196 fname,sizeof(fname));
3198 add_to_file_list(pszParmValue, fname);
3200 string_set(ptr, fname);
3202 if (file_exist(fname, NULL))
3203 return (pm_process(fname, do_section, do_parameter));
3205 DEBUG(2, ("Can't find include file %s\n", fname));
3210 /***************************************************************************
3211 Handle the interpretation of the copy parameter.
3212 ***************************************************************************/
3214 static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
3218 service serviceTemp;
3220 string_set(ptr, pszParmValue);
3222 init_service(&serviceTemp);
3226 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3228 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3229 if (iTemp == iServiceIndex) {
3230 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3232 copy_service(ServicePtrs[iServiceIndex],
3234 ServicePtrs[iServiceIndex]->copymap);
3238 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3242 free_service(&serviceTemp);
3246 /***************************************************************************
3247 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3252 idmap uid = 1000-1999
3255 We only do simple parsing checks here. The strings are parsed into useful
3256 structures in the idmap daemon code.
3258 ***************************************************************************/
3260 /* Some lp_ routines to return idmap [ug]id information */
3262 static uid_t idmap_uid_low, idmap_uid_high;
3263 static gid_t idmap_gid_low, idmap_gid_high;
3265 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
3267 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3271 *low = idmap_uid_low;
3274 *high = idmap_uid_high;
3279 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
3281 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3285 *low = idmap_gid_low;
3288 *high = idmap_gid_high;
3293 /* Do some simple checks on "idmap [ug]id" parameter values */
3295 static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3299 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3304 string_set(ptr, pszParmValue);
3306 idmap_uid_low = low;
3307 idmap_uid_high = high;
3312 static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3316 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3321 string_set(ptr, pszParmValue);
3323 idmap_gid_low = low;
3324 idmap_gid_high = high;
3329 /***************************************************************************
3330 Handle the DEBUG level list.
3331 ***************************************************************************/
3333 static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3335 pstring pszParmValue;
3337 pstrcpy(pszParmValue, pszParmValueIn);
3338 string_set(ptr, pszParmValueIn);
3339 return debug_parse_levels( pszParmValue );
3342 /***************************************************************************
3343 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3344 ***************************************************************************/
3346 static const char *append_ldap_suffix( const char *str )
3348 const char *suffix_string;
3352 lp_talloc = talloc_init("lp_talloc");
3354 suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
3355 if ( !suffix_string ) {
3356 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3360 return suffix_string;
3363 const char *lp_ldap_machine_suffix(void)
3365 if (Globals.szLdapMachineSuffix[0])
3366 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3368 return lp_string(Globals.szLdapSuffix);
3371 const char *lp_ldap_user_suffix(void)
3373 if (Globals.szLdapUserSuffix[0])
3374 return append_ldap_suffix(Globals.szLdapUserSuffix);
3376 return lp_string(Globals.szLdapSuffix);
3379 const char *lp_ldap_group_suffix(void)
3381 if (Globals.szLdapGroupSuffix[0])
3382 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3384 return lp_string(Globals.szLdapSuffix);
3387 const char *lp_ldap_idmap_suffix(void)
3389 if (Globals.szLdapIdmapSuffix[0])
3390 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3392 return lp_string(Globals.szLdapSuffix);
3395 /****************************************************************************
3396 set the value for a P_ENUM
3397 ***************************************************************************/
3399 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3404 for (i = 0; parm->enum_list[i].name; i++) {
3405 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3406 *ptr = parm->enum_list[i].value;
3412 /***************************************************************************
3413 ***************************************************************************/
3415 static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3417 static int parm_num = -1;
3420 if ( parm_num == -1 )
3421 parm_num = map_parameter( "printing" );
3423 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3428 s = ServicePtrs[snum];
3430 init_printer_values( s );
3436 /***************************************************************************
3437 Initialise a copymap.
3438 ***************************************************************************/
3440 static void init_copymap(service * pservice)
3443 SAFE_FREE(pservice->copymap);
3444 pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3445 if (!pservice->copymap)
3447 ("Couldn't allocate copymap!! (size %d)\n",
3448 (int)NUMPARAMETERS));
3450 for (i = 0; i < NUMPARAMETERS; i++)
3451 pservice->copymap[i] = True;
3454 /***************************************************************************
3455 Return the local pointer to a parameter given the service number and the
3456 pointer into the default structure.
3457 ***************************************************************************/
3459 void *lp_local_ptr(int snum, void *ptr)
3461 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3464 /***************************************************************************
3465 Process a parameter for a particular service number. If snum < 0
3466 then assume we are in the globals.
3467 ***************************************************************************/
3469 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3471 int parmnum, i, slen;
3472 void *parm_ptr = NULL; /* where we are going to store the result */
3473 void *def_ptr = NULL;
3476 param_opt_struct *paramo, *data;
3479 parmnum = map_parameter(pszParmName);
3482 if ((sep=strchr(pszParmName, ':')) != NULL) {
3484 ZERO_STRUCT(param_key);
3485 pstr_sprintf(param_key, "%s:", pszParmName);
3486 slen = strlen(param_key);
3487 pstrcat(param_key, sep+1);
3488 trim_char(param_key+slen, ' ', ' ');
3490 data = (snum < 0) ? Globals.param_opt :
3491 ServicePtrs[snum]->param_opt;
3492 /* Traverse destination */
3494 /* If we already have same option, override it */
3495 if (strcmp(data->key, param_key) == 0) {
3496 string_free(&data->value);
3497 str_list_free(&data->list);
3498 data->value = SMB_STRDUP(pszParmValue);
3505 paramo = SMB_XMALLOC_P(param_opt_struct);
3506 paramo->key = SMB_STRDUP(param_key);
3507 paramo->value = SMB_STRDUP(pszParmValue);
3508 paramo->list = NULL;
3510 DLIST_ADD(Globals.param_opt, paramo);
3512 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3519 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3523 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3524 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3528 def_ptr = parm_table[parmnum].ptr;
3530 /* we might point at a service, the default service or a global */
3534 if (parm_table[parmnum].p_class == P_GLOBAL) {
3536 ("Global parameter %s found in service section!\n",
3541 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3544 if (!ServicePtrs[snum]->copymap)
3545 init_copymap(ServicePtrs[snum]);
3547 /* this handles the aliases - set the copymap for other entries with
3548 the same data pointer */
3549 for (i = 0; parm_table[i].label; i++)
3550 if (parm_table[i].ptr == parm_table[parmnum].ptr)
3551 ServicePtrs[snum]->copymap[i] = False;
3554 /* if it is a special case then go ahead */
3555 if (parm_table[parmnum].special) {
3556 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3560 /* now switch on the type of variable it is */
3561 switch (parm_table[parmnum].type)
3564 *(BOOL *)parm_ptr = lp_bool(pszParmValue);
3568 *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
3572 *(int *)parm_ptr = lp_int(pszParmValue);
3576 *(char *)parm_ptr = *pszParmValue;
3580 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3582 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3587 str_list_free((char ***)parm_ptr);
3588 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3592 string_set((char **)parm_ptr, pszParmValue);
3596 string_set((char **)parm_ptr, pszParmValue);
3597 strupper_m(*(char **)parm_ptr);
3601 pstrcpy((char *)parm_ptr, pszParmValue);
3605 pstrcpy((char *)parm_ptr, pszParmValue);
3606 strupper_m((char *)parm_ptr);
3610 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3619 /***************************************************************************
3620 Process a parameter.
3621 ***************************************************************************/
3623 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3625 if (!bInGlobalSection && bGlobalOnly)
3628 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3630 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3631 pszParmName, pszParmValue));
3634 /***************************************************************************
3635 Print a parameter of the specified type.
3636 ***************************************************************************/
3638 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3644 for (i = 0; p->enum_list[i].name; i++) {
3645 if (*(int *)ptr == p->enum_list[i].value) {
3647 p->enum_list[i].name);
3654 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3658 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3662 fprintf(f, "%d", *(int *)ptr);
3666 fprintf(f, "%c", *(char *)ptr);
3670 fprintf(f, "%s", octal_string(*(int *)ptr));
3674 if ((char ***)ptr && *(char ***)ptr) {
3675 char **list = *(char ***)ptr;
3677 for (; *list; list++) {
3678 /* surround strings with whitespace in double quotes */
3679 if ( strchr_m( *list, ' ' ) )
3680 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3682 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3690 fprintf(f, "%s", (char *)ptr);
3696 if (*(char **)ptr) {
3697 fprintf(f, "%s", *(char **)ptr);
3705 /***************************************************************************
3706 Check if two parameters are equal.
3707 ***************************************************************************/
3709 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3714 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3719 return (*((int *)ptr1) == *((int *)ptr2));
3722 return (*((char *)ptr1) == *((char *)ptr2));
3725 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3730 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3735 return (p1 == p2 || strequal(p1, p2));
3740 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3745 return (p1 == p2 || strequal(p1, p2));
3753 /***************************************************************************
3754 Initialize any local varients in the sDefault table.
3755 ***************************************************************************/
3757 void init_locals(void)
3762 /***************************************************************************
3763 Process a new section (service). At this stage all sections are services.
3764 Later we'll have special sections that permit server parameters to be set.
3765 Returns True on success, False on failure.
3766 ***************************************************************************/
3768 static BOOL do_section(const char *pszSectionName)
3771 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3772 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3775 /* if we were in a global section then do the local inits */
3776 if (bInGlobalSection && !isglobal)
3779 /* if we've just struck a global section, note the fact. */
3780 bInGlobalSection = isglobal;
3782 /* check for multiple global sections */
3783 if (bInGlobalSection) {
3784 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3788 if (!bInGlobalSection && bGlobalOnly)
3791 /* if we have a current service, tidy it up before moving on */
3794 if (iServiceIndex >= 0)
3795 bRetval = service_ok(iServiceIndex);
3797 /* if all is still well, move to the next record in the services array */
3799 /* We put this here to avoid an odd message order if messages are */
3800 /* issued by the post-processing of a previous section. */
3801 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3803 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3805 DEBUG(0, ("Failed to add a new service\n"));
3814 /***************************************************************************
3815 Determine if a partcular base parameter is currentl set to the default value.
3816 ***************************************************************************/
3818 static BOOL is_default(int i)
3820 if (!defaults_saved)
3822 switch (parm_table[i].type) {
3824 return str_list_compare (parm_table[i].def.lvalue,
3825 *(char ***)parm_table[i].ptr);
3828 return strequal(parm_table[i].def.svalue,
3829 *(char **)parm_table[i].ptr);
3832 return strequal(parm_table[i].def.svalue,
3833 (char *)parm_table[i].ptr);
3836 return parm_table[i].def.bvalue ==
3837 *(BOOL *)parm_table[i].ptr;
3839 return parm_table[i].def.cvalue ==
3840 *(char *)parm_table[i].ptr;
3844 return parm_table[i].def.ivalue ==
3845 *(int *)parm_table[i].ptr;
3852 /***************************************************************************
3853 Display the contents of the global structure.
3854 ***************************************************************************/
3856 static void dump_globals(FILE *f)
3859 param_opt_struct *data;
3861 fprintf(f, "[global]\n");
3863 for (i = 0; parm_table[i].label; i++)
3864 if (parm_table[i].p_class == P_GLOBAL &&
3865 parm_table[i].ptr &&
3866 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3867 if (defaults_saved && is_default(i))
3869 fprintf(f, "\t%s = ", parm_table[i].label);
3870 print_parameter(&parm_table[i], parm_table[i].ptr, f);
3873 if (Globals.param_opt != NULL) {
3874 data = Globals.param_opt;
3876 fprintf(f, "\t%s = %s\n", data->key, data->value);
3883 /***************************************************************************
3884 Return True if a local parameter is currently set to the global default.
3885 ***************************************************************************/
3887 BOOL lp_is_default(int snum, struct parm_struct *parm)
3889 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3891 return equal_parameter(parm->type,
3892 ((char *)ServicePtrs[snum]) + pdiff,
3893 ((char *)&sDefault) + pdiff);
3896 /***************************************************************************
3897 Display the contents of a single services record.
3898 ***************************************************************************/
3900 static void dump_a_service(service * pService, FILE * f)
3903 param_opt_struct *data;
3905 if (pService != &sDefault)
3906 fprintf(f, "[%s]\n", pService->szService);
3908 for (i = 0; parm_table[i].label; i++) {
3910 if (parm_table[i].p_class == P_LOCAL &&
3911 parm_table[i].ptr &&
3912 (*parm_table[i].label != '-') &&
3913 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3916 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3918 if (pService == &sDefault) {
3919 if (defaults_saved && is_default(i))
3922 if (equal_parameter(parm_table[i].type,
3923 ((char *)pService) +
3925 ((char *)&sDefault) +
3930 fprintf(f, "\t%s = ", parm_table[i].label);
3931 print_parameter(&parm_table[i],
3932 ((char *)pService) + pdiff, f);
3937 if (pService->param_opt != NULL) {
3938 data = pService->param_opt;
3940 fprintf(f, "\t%s = %s\n", data->key, data->value);
3946 /***************************************************************************
3947 Display the contents of a parameter of a single services record.
3948 ***************************************************************************/
3950 BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
3953 BOOL result = False;
3956 fstring local_parm_name;
3958 const char *parm_opt_value;
3960 /* check for parametrical option */
3961 fstrcpy( local_parm_name, parm_name);
3962 parm_opt = strchr( local_parm_name, ':');
3967 if (strlen(parm_opt)) {
3968 parm_opt_value = lp_parm_const_string( snum,
3969 local_parm_name, parm_opt, NULL);
3970 if (parm_opt_value) {
3971 printf( "%s\n", parm_opt_value);
3978 /* check for a key and print the value */
3985 for (i = 0; parm_table[i].label; i++) {
3986 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
3987 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
3988 parm_table[i].ptr &&
3989 (*parm_table[i].label != '-') &&
3990 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3995 ptr = parm_table[i].ptr;
3997 service * pService = ServicePtrs[snum];
3998 ptr = ((char *)pService) +
3999 PTR_DIFF(parm_table[i].ptr, &sDefault);
4002 print_parameter(&parm_table[i],
4013 /***************************************************************************
4014 Return info about the next parameter in a service.
4015 snum==GLOBAL_SECTION_SNUM gives the globals.
4016 Return NULL when out of parameters.
4017 ***************************************************************************/
4019 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
4022 /* do the globals */
4023 for (; parm_table[*i].label; (*i)++) {
4024 if (parm_table[*i].p_class == P_SEPARATOR)
4025 return &parm_table[(*i)++];
4027 if (!parm_table[*i].ptr
4028 || (*parm_table[*i].label == '-'))
4032 && (parm_table[*i].ptr ==
4033 parm_table[(*i) - 1].ptr))
4036 return &parm_table[(*i)++];
4039 service *pService = ServicePtrs[snum];
4041 for (; parm_table[*i].label; (*i)++) {
4042 if (parm_table[*i].p_class == P_SEPARATOR)
4043 return &parm_table[(*i)++];
4045 if (parm_table[*i].p_class == P_LOCAL &&
4046 parm_table[*i].ptr &&
4047 (*parm_table[*i].label != '-') &&
4049 (parm_table[*i].ptr !=
4050 parm_table[(*i) - 1].ptr)))
4053 PTR_DIFF(parm_table[*i].ptr,
4056 if (allparameters ||
4057 !equal_parameter(parm_table[*i].type,
4058 ((char *)pService) +
4060 ((char *)&sDefault) +
4063 return &parm_table[(*i)++];
4074 /***************************************************************************
4075 Display the contents of a single copy structure.
4076 ***************************************************************************/
4077 static void dump_copy_map(BOOL *pcopymap)
4083 printf("\n\tNon-Copied parameters:\n");
4085 for (i = 0; parm_table[i].label; i++)
4086 if (parm_table[i].p_class == P_LOCAL &&
4087 parm_table[i].ptr && !pcopymap[i] &&
4088 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4090 printf("\t\t%s\n", parm_table[i].label);
4095 /***************************************************************************
4096 Return TRUE if the passed service number is within range.
4097 ***************************************************************************/
4099 BOOL lp_snum_ok(int iService)
4101 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4104 /***************************************************************************
4105 Auto-load some home services.
4106 ***************************************************************************/
4108 static void lp_add_auto_services(char *str)
4117 s = SMB_STRDUP(str);
4121 homes = lp_servicenumber(HOMES_NAME);
4123 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4124 char *home = get_user_home_dir(p);
4126 if (lp_servicenumber(p) >= 0)
4129 if (home && homes >= 0)
4130 lp_add_home(p, homes, p, home);
4135 /***************************************************************************
4136 Auto-load one printer.
4137 ***************************************************************************/
4139 void lp_add_one_printer(char *name, char *comment)
4141 int printers = lp_servicenumber(PRINTERS_NAME);
4144 if (lp_servicenumber(name) < 0) {
4145 lp_add_printer(name, printers);
4146 if ((i = lp_servicenumber(name)) >= 0) {
4147 string_set(&ServicePtrs[i]->comment, comment);
4148 ServicePtrs[i]->autoloaded = True;
4153 /***************************************************************************
4154 Have we loaded a services file yet?
4155 ***************************************************************************/
4157 BOOL lp_loaded(void)
4162 /***************************************************************************
4163 Unload unused services.
4164 ***************************************************************************/
4166 void lp_killunused(BOOL (*snumused) (int))
4169 for (i = 0; i < iNumServices; i++) {
4173 /* don't kill autoloaded or usershare services */
4174 if ( ServicePtrs[i]->autoloaded ||
4175 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4179 if (!snumused || !snumused(i)) {
4180 free_service_byindex(i);
4185 /***************************************************************************
4187 ***************************************************************************/
4189 void lp_killservice(int iServiceIn)
4191 if (VALID(iServiceIn)) {
4192 free_service_byindex(iServiceIn);
4196 /***************************************************************************
4197 Save the curent values of all global and sDefault parameters into the
4198 defaults union. This allows swat and testparm to show only the
4199 changed (ie. non-default) parameters.
4200 ***************************************************************************/
4202 static void lp_save_defaults(void)
4205 for (i = 0; parm_table[i].label; i++) {
4206 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4208 switch (parm_table[i].type) {
4210 str_list_copy(&(parm_table[i].def.lvalue),
4211 *(const char ***)parm_table[i].ptr);
4215 if (parm_table[i].ptr) {
4216 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4218 parm_table[i].def.svalue = NULL;
4223 if (parm_table[i].ptr) {
4224 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4226 parm_table[i].def.svalue = NULL;
4231 parm_table[i].def.bvalue =
4232 *(BOOL *)parm_table[i].ptr;
4235 parm_table[i].def.cvalue =
4236 *(char *)parm_table[i].ptr;
4241 parm_table[i].def.ivalue =
4242 *(int *)parm_table[i].ptr;
4248 defaults_saved = True;
4251 /*******************************************************************
4252 Set the server type we will announce as via nmbd.
4253 ********************************************************************/
4255 static const struct srv_role_tab {
4257 const char *role_str;
4258 } srv_role_tab [] = {
4259 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4260 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4261 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4262 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4266 const char* server_role_str(uint32 role)
4269 for (i=0; srv_role_tab[i].role_str; i++) {
4270 if (role == srv_role_tab[i].role) {
4271 return srv_role_tab[i].role_str;
4277 static void set_server_role(void)
4279 server_role = ROLE_STANDALONE;
4281 switch (lp_security()) {
4283 if (lp_domain_logons())
4284 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4287 if (lp_domain_logons())
4288 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4289 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
4290 server_role = ROLE_STANDALONE;
4293 if (lp_domain_logons()) {
4294 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4295 server_role = ROLE_DOMAIN_BDC;
4298 server_role = ROLE_DOMAIN_MEMBER;
4301 if (lp_domain_logons()) {
4302 server_role = ROLE_DOMAIN_PDC;
4305 server_role = ROLE_DOMAIN_MEMBER;
4308 if (lp_domain_logons()) {
4310 if (Globals.bDomainMaster) /* auto or yes */
4311 server_role = ROLE_DOMAIN_PDC;
4313 server_role = ROLE_DOMAIN_BDC;
4317 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4321 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4324 /***********************************************************
4325 If we should send plaintext/LANMAN passwords in the clinet
4326 ************************************************************/
4328 static void set_allowed_client_auth(void)
4330 if (Globals.bClientNTLMv2Auth) {
4331 Globals.bClientLanManAuth = False;
4333 if (!Globals.bClientLanManAuth) {
4334 Globals.bClientPlaintextAuth = False;
4338 /***************************************************************************
4340 The following code allows smbd to read a user defined share file.
4341 Yes, this is my intent. Yes, I'm comfortable with that...
4343 THE FOLLOWING IS SECURITY CRITICAL CODE.
4345 It washes your clothes, it cleans your house, it guards you while you sleep...
4346 Do not f%^k with it....
4347 ***************************************************************************/
4349 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4351 /***************************************************************************
4352 Check allowed stat state of a usershare file.
4353 Ensure we print out who is dicking with us so the admin can
4354 get their sorry ass fired.
4355 ***************************************************************************/
4357 static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4359 if (!S_ISREG(psbuf->st_mode)) {
4360 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4361 "not a regular file\n",
4362 fname, (unsigned int)psbuf->st_uid ));
4366 /* Ensure this doesn't have the other write bit set. */
4367 if (psbuf->st_mode & S_IWOTH) {
4368 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4369 "public write. Refusing to allow as a usershare file.\n",
4370 fname, (unsigned int)psbuf->st_uid ));
4374 /* Should be 10k or less. */
4375 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4376 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4377 "too large (%u) to be a user share file.\n",
4378 fname, (unsigned int)psbuf->st_uid,
4379 (unsigned int)psbuf->st_size ));
4386 /***************************************************************************
4387 Parse the contents of a usershare file.
4388 ***************************************************************************/
4390 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4391 SMB_STRUCT_STAT *psbuf,
4392 const char *servicename,
4401 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4402 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4405 SMB_STRUCT_STAT sbuf;
4407 *pallow_guest = False;
4410 return USERSHARE_MALFORMED_FILE;
4413 if (strcmp(lines[0], "#VERSION 1") == 0) {
4415 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4418 return USERSHARE_MALFORMED_FILE;
4421 return USERSHARE_BAD_VERSION;
4424 if (strncmp(lines[1], "path=", 5) != 0) {
4425 return USERSHARE_MALFORMED_PATH;
4428 pstrcpy(sharepath, &lines[1][5]);
4429 trim_string(sharepath, " ", " ");
4431 if (strncmp(lines[2], "comment=", 8) != 0) {
4432 return USERSHARE_MALFORMED_COMMENT_DEF;
4435 pstrcpy(comment, &lines[2][8]);
4436 trim_string(comment, " ", " ");
4437 trim_char(comment, '"', '"');
4439 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4440 return USERSHARE_MALFORMED_ACL_DEF;
4443 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4444 return USERSHARE_ACL_ERR;
4448 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4449 return USERSHARE_MALFORMED_ACL_DEF;
4451 if (lines[4][9] == 'y') {
4452 *pallow_guest = True;
4456 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4457 /* Path didn't change, no checks needed. */
4458 return USERSHARE_OK;
4461 /* The path *must* be absolute. */
4462 if (sharepath[0] != '/') {
4463 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4464 servicename, sharepath));
4465 return USERSHARE_PATH_NOT_ABSOLUTE;
4468 /* If there is a usershare prefix deny list ensure one of these paths
4469 doesn't match the start of the user given path. */
4470 if (prefixdenylist) {
4472 for ( i=0; prefixdenylist[i]; i++ ) {
4473 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4474 servicename, i, prefixdenylist[i], sharepath ));
4475 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4476 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4477 "usershare prefix deny list entries.\n",
4478 servicename, sharepath));
4479 return USERSHARE_PATH_IS_DENIED;
4484 /* If there is a usershare prefix allow list ensure one of these paths
4485 does match the start of the user given path. */
4487 if (prefixallowlist) {
4489 for ( i=0; prefixallowlist[i]; i++ ) {
4490 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4491 servicename, i, prefixallowlist[i], sharepath ));
4492 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4496 if (prefixallowlist[i] == NULL) {
4497 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4498 "usershare prefix allow list entries.\n",
4499 servicename, sharepath));
4500 return USERSHARE_PATH_NOT_ALLOWED;
4504 /* Ensure this is pointing to a directory. */
4505 dp = sys_opendir(sharepath);
4508 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4509 servicename, sharepath));
4510 return USERSHARE_PATH_NOT_DIRECTORY;
4513 /* Ensure the owner of the usershare file has permission to share
4516 if (sys_stat(sharepath, &sbuf) == -1) {
4517 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4518 servicename, sharepath, strerror(errno) ));
4520 return USERSHARE_POSIX_ERR;
4525 if (!S_ISDIR(sbuf.st_mode)) {
4526 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4527 servicename, sharepath ));
4528 return USERSHARE_PATH_NOT_DIRECTORY;
4531 /* Check if sharing is restricted to owner-only. */
4532 /* psbuf is the stat of the usershare definition file,
4533 sbuf is the stat of the target directory to be shared. */
4535 if (lp_usershare_owner_only()) {
4536 /* root can share anything. */
4537 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
4538 return USERSHARE_PATH_NOT_ALLOWED;
4542 return USERSHARE_OK;
4545 /***************************************************************************
4546 Deal with a usershare file.
4549 -1 - Bad name, invalid contents.
4550 - service name already existed and not a usershare, problem
4551 with permissions to share directory etc.
4552 ***************************************************************************/
4554 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4556 SMB_STRUCT_STAT sbuf;
4557 SMB_STRUCT_STAT lsbuf;
4561 fstring service_name;
4562 char **lines = NULL;
4566 TALLOC_CTX *ctx = NULL;
4567 SEC_DESC *psd = NULL;
4568 BOOL guest_ok = False;
4570 /* Ensure share name doesn't contain invalid characters. */
4571 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4572 DEBUG(0,("process_usershare_file: share name %s contains "
4573 "invalid characters (any of %s)\n",
4574 file_name, INVALID_SHARENAME_CHARS ));
4578 fstrcpy(service_name, file_name);
4580 pstrcpy(fname, dir_name);
4581 pstrcat(fname, "/");
4582 pstrcat(fname, file_name);
4584 /* Minimize the race condition by doing an lstat before we
4585 open and fstat. Ensure this isn't a symlink link. */
4587 if (sys_lstat(fname, &lsbuf) != 0) {
4588 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4589 fname, strerror(errno) ));
4593 /* This must be a regular file, not a symlink, directory or
4594 other strange filetype. */
4595 if (!check_usershare_stat(fname, &lsbuf)) {
4599 /* See if there is already a servicenum for this name. */
4600 /* tdb_fetch_int32 returns -1 if not found. */
4601 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
4603 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
4604 /* Nothing changed - Mark valid and return. */
4605 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4607 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4611 /* Try and open the file read only - no symlinks allowed. */
4613 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
4615 fd = sys_open(fname, O_RDONLY, 0);
4619 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4620 fname, strerror(errno) ));
4624 /* Now fstat to be *SURE* it's a regular file. */
4625 if (sys_fstat(fd, &sbuf) != 0) {
4627 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4628 fname, strerror(errno) ));
4632 /* Is it the same dev/inode as was lstated ? */
4633 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
4635 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4636 "Symlink spoofing going on ?\n", fname ));
4640 /* This must be a regular file, not a symlink, directory or
4641 other strange filetype. */
4642 if (!check_usershare_stat(fname, &sbuf)) {
4646 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
4649 if (lines == NULL) {
4650 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4651 fname, (unsigned int)sbuf.st_uid ));
4655 /* Should we allow printers to be shared... ? */
4656 ctx = talloc_init("usershare_sd_xctx");
4658 file_lines_free(lines);
4662 if (parse_usershare_file(ctx, &sbuf, service_name,
4663 iService, lines, numlines, sharepath,
4664 comment, &psd, &guest_ok) != USERSHARE_OK) {
4665 talloc_destroy(ctx);
4666 file_lines_free(lines);
4670 file_lines_free(lines);
4672 /* Everything ok - add the service possibly using a template. */
4674 const service *sp = &sDefault;
4675 if (snum_template != -1) {
4676 sp = ServicePtrs[snum_template];
4679 if ((iService = add_a_service(sp, service_name)) < 0) {
4680 DEBUG(0, ("process_usershare_file: Failed to add "
4681 "new service %s\n", service_name));
4682 talloc_destroy(ctx);
4686 /* Read only is controlled by usershare ACL below. */
4687 ServicePtrs[iService]->bRead_only = False;
4690 /* Write the ACL of the new/modified share. */
4691 if (!set_share_security(service_name, psd)) {
4692 DEBUG(0, ("process_usershare_file: Failed to set share "
4693 "security for user share %s\n",
4695 lp_remove_service(iService);
4696 talloc_destroy(ctx);
4700 talloc_destroy(ctx);
4702 /* If from a template it may be marked invalid. */
4703 ServicePtrs[iService]->valid = True;
4705 /* Set the service as a valid usershare. */
4706 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4708 /* Set guest access. */
4709 if (lp_usershare_allow_guests()) {
4710 ServicePtrs[iService]->bGuest_ok = guest_ok;
4713 /* And note when it was loaded. */
4714 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
4715 string_set(&ServicePtrs[iService]->szPath, sharepath);
4716 string_set(&ServicePtrs[iService]->comment, comment);
4721 /***************************************************************************
4722 Checks if a usershare entry has been modified since last load.
4723 ***************************************************************************/
4725 static BOOL usershare_exists(int iService, time_t *last_mod)
4727 SMB_STRUCT_STAT lsbuf;
4728 const char *usersharepath = Globals.szUsersharePath;
4731 pstrcpy(fname, usersharepath);
4732 pstrcat(fname, "/");
4733 pstrcat(fname, ServicePtrs[iService]->szService);
4735 if (sys_lstat(fname, &lsbuf) != 0) {
4739 if (!S_ISREG(lsbuf.st_mode)) {
4743 *last_mod = lsbuf.st_mtime;
4747 /***************************************************************************
4748 Load a usershare service by name. Returns a valid servicenumber or -1.
4749 ***************************************************************************/
4751 int load_usershare_service(const char *servicename)
4753 SMB_STRUCT_STAT sbuf;
4754 const char *usersharepath = Globals.szUsersharePath;
4755 int max_user_shares = Globals.iUsershareMaxShares;
4756 int snum_template = -1;
4758 if (*usersharepath == 0 || max_user_shares == 0) {
4762 if (sys_stat(usersharepath, &sbuf) != 0) {
4763 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4764 usersharepath, strerror(errno) ));
4768 if (!S_ISDIR(sbuf.st_mode)) {
4769 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4775 * This directory must be owned by root, and have the 't' bit set.
4776 * It also must not be writable by "other".
4780 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4782 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4784 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4785 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4790 /* Ensure the template share exists if it's set. */
4791 if (Globals.szUsershareTemplateShare[0]) {
4792 /* We can't use lp_servicenumber here as we are recommending that
4793 template shares have -valid=False set. */
4794 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4795 if (ServicePtrs[snum_template]->szService &&
4796 strequal(ServicePtrs[snum_template]->szService,
4797 Globals.szUsershareTemplateShare)) {
4802 if (snum_template == -1) {
4803 DEBUG(0,("load_usershare_service: usershare template share %s "
4804 "does not exist.\n",
4805 Globals.szUsershareTemplateShare ));
4810 return process_usershare_file(usersharepath, servicename, snum_template);
4813 /***************************************************************************
4814 Load all user defined shares from the user share directory.
4815 We only do this if we're enumerating the share list.
4816 This is the function that can delete usershares that have
4818 ***************************************************************************/
4820 int load_usershare_shares(void)
4823 SMB_STRUCT_STAT sbuf;
4824 SMB_STRUCT_DIRENT *de;
4825 int num_usershares = 0;
4826 int max_user_shares = Globals.iUsershareMaxShares;
4827 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4828 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4829 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4831 int snum_template = -1;
4832 const char *usersharepath = Globals.szUsersharePath;
4833 int ret = lp_numservices();
4835 if (max_user_shares == 0 || *usersharepath == '\0') {
4836 return lp_numservices();
4839 if (sys_stat(usersharepath, &sbuf) != 0) {
4840 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4841 usersharepath, strerror(errno) ));
4846 * This directory must be owned by root, and have the 't' bit set.
4847 * It also must not be writable by "other".
4851 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4853 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4855 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4856 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4861 /* Ensure the template share exists if it's set. */
4862 if (Globals.szUsershareTemplateShare[0]) {
4863 /* We can't use lp_servicenumber here as we are recommending that
4864 template shares have -valid=False set. */
4865 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4866 if (ServicePtrs[snum_template]->szService &&
4867 strequal(ServicePtrs[snum_template]->szService,
4868 Globals.szUsershareTemplateShare)) {
4873 if (snum_template == -1) {
4874 DEBUG(0,("load_usershare_shares: usershare template share %s "
4875 "does not exist.\n",
4876 Globals.szUsershareTemplateShare ));
4881 /* Mark all existing usershares as pending delete. */
4882 for (iService = iNumServices - 1; iService >= 0; iService--) {
4883 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4884 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4888 dp = sys_opendir(usersharepath);
4890 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4891 usersharepath, strerror(errno) ));
4895 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4896 (de = sys_readdir(dp));
4897 num_dir_entries++ ) {
4899 const char *n = de->d_name;
4901 /* Ignore . and .. */
4903 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4909 /* Temporary file used when creating a share. */
4910 num_tmp_dir_entries++;
4913 /* Allow 20% tmp entries. */
4914 if (num_tmp_dir_entries > allowed_tmp_entries) {
4915 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4916 "in directory %s\n",
4917 num_tmp_dir_entries, usersharepath));
4921 r = process_usershare_file(usersharepath, n, snum_template);
4923 /* Update the services count. */
4925 if (num_usershares >= max_user_shares) {
4926 DEBUG(0,("load_usershare_shares: max user shares reached "
4927 "on file %s in directory %s\n",
4928 n, usersharepath ));
4931 } else if (r == -1) {
4932 num_bad_dir_entries++;
4935 /* Allow 20% bad entries. */
4936 if (num_bad_dir_entries > allowed_bad_entries) {
4937 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4938 "in directory %s\n",
4939 num_bad_dir_entries, usersharepath));
4943 /* Allow 20% bad entries. */
4944 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4945 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4946 "in directory %s\n",
4947 num_dir_entries, usersharepath));
4954 /* Sweep through and delete any non-refreshed usershares that are
4955 not currently in use. */
4956 for (iService = iNumServices - 1; iService >= 0; iService--) {
4957 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4958 if (conn_snum_used(iService)) {
4961 /* Remove from the share ACL db. */
4962 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4963 lp_servicename(iService) ));
4964 delete_share_security(snum2params_static(iService));
4965 free_service_byindex(iService);
4969 return lp_numservices();
4972 /********************************************************
4973 Destroy global resources allocated in this file
4974 ********************************************************/
4976 void gfree_loadparm(void)
4978 struct file_lists *f;
4979 struct file_lists *next;
4984 /* Free the file lists */
4989 SAFE_FREE( f->name );
4990 SAFE_FREE( f->subfname );
4995 /* Free resources allocated to services */
4997 for ( i = 0; i < iNumServices; i++ ) {
4999 free_service_byindex(i);
5003 SAFE_FREE( ServicePtrs );
5006 /* Now release all resources allocated to global
5007 parameters and the default service */
5009 for (i = 0; parm_table[i].label; i++)
5011 if ( parm_table[i].type == P_STRING
5012 || parm_table[i].type == P_USTRING )
5014 string_free( (char**)parm_table[i].ptr );
5016 else if (parm_table[i].type == P_LIST) {
5017 str_list_free( (char***)parm_table[i].ptr );
5022 /***************************************************************************
5023 Load the services array from the services file. Return True on success,
5025 ***************************************************************************/
5027 BOOL lp_load(const char *pszFname,
5031 BOOL initialize_globals)
5035 param_opt_struct *data, *pdata;
5037 pstrcpy(n2, pszFname);
5039 standard_sub_basic( get_current_username(), current_user_info.domain,
5042 add_to_file_list(pszFname, n2);
5046 DEBUG(3, ("lp_load: refreshing parameters\n"));
5048 bInGlobalSection = True;
5049 bGlobalOnly = global_only;
5051 init_globals(! initialize_globals);
5054 if (save_defaults) {
5059 if (Globals.param_opt != NULL) {
5060 data = Globals.param_opt;
5062 string_free(&data->key);
5063 string_free(&data->value);
5064 str_list_free(&data->list);
5069 Globals.param_opt = NULL;
5072 /* We get sections first, so have to start 'behind' to make up */
5074 bRetval = pm_process(n2, do_section, do_parameter);
5076 /* finish up the last section */
5077 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
5079 if (iServiceIndex >= 0)
5080 bRetval = service_ok(iServiceIndex);
5082 lp_add_auto_services(lp_auto_services());
5085 /* When 'restrict anonymous = 2' guest connections to ipc$
5087 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
5088 if ( lp_enable_asu_support() )
5089 lp_add_ipc("ADMIN$", False);
5093 set_default_server_announce_type();
5094 set_allowed_client_auth();
5098 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
5099 /* if bWINSsupport is true and we are in the client */
5100 if (in_client && Globals.bWINSsupport) {
5101 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5109 /***************************************************************************
5110 Reset the max number of services.
5111 ***************************************************************************/
5113 void lp_resetnumservices(void)
5118 /***************************************************************************
5119 Return the max number of services.
5120 ***************************************************************************/
5122 int lp_numservices(void)
5124 return (iNumServices);
5127 /***************************************************************************
5128 Display the contents of the services array in human-readable form.
5129 ***************************************************************************/
5131 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
5136 defaults_saved = False;
5140 dump_a_service(&sDefault, f);
5142 for (iService = 0; iService < maxtoprint; iService++) {
5144 lp_dump_one(f, show_defaults, iService);
5148 /***************************************************************************
5149 Display the contents of one service in human-readable form.
5150 ***************************************************************************/
5152 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
5155 if (ServicePtrs[snum]->szService[0] == '\0')
5157 dump_a_service(ServicePtrs[snum], f);
5161 /***************************************************************************
5162 Return the number of the service with the given name, or -1 if it doesn't
5163 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5164 getservicebyname()! This works ONLY if all services have been loaded, and
5165 does not copy the found service.
5166 ***************************************************************************/
5168 int lp_servicenumber(const char *pszServiceName)
5171 fstring serviceName;
5173 if (!pszServiceName) {
5174 return GLOBAL_SECTION_SNUM;
5177 for (iService = iNumServices - 1; iService >= 0; iService--) {
5178 if (VALID(iService) && ServicePtrs[iService]->szService) {
5180 * The substitution here is used to support %U is
5183 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5184 standard_sub_basic(get_current_username(),
5185 current_user_info.domain,
5186 serviceName,sizeof(serviceName));
5187 if (strequal(serviceName, pszServiceName)) {
5193 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5196 if (!usershare_exists(iService, &last_mod)) {
5197 /* Remove the share security tdb entry for it. */
5198 delete_share_security(snum2params_static(iService));
5199 /* Remove it from the array. */
5200 free_service_byindex(iService);
5201 /* Doesn't exist anymore. */
5202 return GLOBAL_SECTION_SNUM;
5205 /* Has it been modified ? If so delete and reload. */
5206 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5207 /* Remove it from the array. */
5208 free_service_byindex(iService);
5209 /* and now reload it. */
5210 iService = load_usershare_service(pszServiceName);
5215 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5216 return GLOBAL_SECTION_SNUM;
5222 BOOL share_defined(const char *service_name)
5224 return (lp_servicenumber(service_name) != -1);
5227 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
5228 const char *sharename)
5230 struct share_params *result;
5234 if (!(sname = SMB_STRDUP(sharename))) {
5238 snum = find_service(sname);
5245 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
5246 DEBUG(0, ("talloc failed\n"));
5250 result->service = snum;
5254 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
5256 struct share_iterator *result;
5258 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
5259 DEBUG(0, ("talloc failed\n"));
5263 result->next_id = 0;
5267 struct share_params *next_share(struct share_iterator *list)
5269 struct share_params *result;
5271 while (!lp_snum_ok(list->next_id) &&
5272 (list->next_id < lp_numservices())) {
5276 if (list->next_id >= lp_numservices()) {
5280 if (!(result = TALLOC_P(list, struct share_params))) {
5281 DEBUG(0, ("talloc failed\n"));
5285 result->service = list->next_id;
5290 struct share_params *next_printer(struct share_iterator *list)
5292 struct share_params *result;
5294 while ((result = next_share(list)) != NULL) {
5295 if (lp_print_ok(result->service)) {
5303 * This is a hack for a transition period until we transformed all code from
5304 * service numbers to struct share_params.
5307 struct share_params *snum2params_static(int snum)
5309 static struct share_params result;
5310 result.service = snum;
5314 /*******************************************************************
5315 A useful volume label function.
5316 ********************************************************************/
5318 const char *volume_label(int snum)
5321 const char *label = lp_volume(snum);
5323 label = lp_servicename(snum);
5326 /* This returns a 33 byte guarenteed null terminated string. */
5327 ret = talloc_strndup(main_loop_talloc_get(), label, 32);
5334 /*******************************************************************
5335 Set the server type we will announce as via nmbd.
5336 ********************************************************************/
5338 static void set_default_server_announce_type(void)
5340 default_server_announce = 0;
5341 default_server_announce |= SV_TYPE_WORKSTATION;
5342 default_server_announce |= SV_TYPE_SERVER;
5343 default_server_announce |= SV_TYPE_SERVER_UNIX;
5345 /* note that the flag should be set only if we have a
5346 printer service but nmbd doesn't actually load the
5347 services so we can't tell --jerry */
5349 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5351 switch (lp_announce_as()) {
5352 case ANNOUNCE_AS_NT_SERVER:
5353 default_server_announce |= SV_TYPE_SERVER_NT;
5354 /* fall through... */
5355 case ANNOUNCE_AS_NT_WORKSTATION:
5356 default_server_announce |= SV_TYPE_NT;
5358 case ANNOUNCE_AS_WIN95:
5359 default_server_announce |= SV_TYPE_WIN95_PLUS;
5361 case ANNOUNCE_AS_WFW:
5362 default_server_announce |= SV_TYPE_WFW;
5368 switch (lp_server_role()) {
5369 case ROLE_DOMAIN_MEMBER:
5370 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5372 case ROLE_DOMAIN_PDC:
5373 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5375 case ROLE_DOMAIN_BDC:
5376 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5378 case ROLE_STANDALONE:
5382 if (lp_time_server())
5383 default_server_announce |= SV_TYPE_TIME_SOURCE;
5385 if (lp_host_msdfs())
5386 default_server_announce |= SV_TYPE_DFS_SERVER;
5389 /***********************************************************
5390 returns role of Samba server
5391 ************************************************************/
5393 int lp_server_role(void)
5398 /***********************************************************
5399 If we are PDC then prefer us as DMB
5400 ************************************************************/
5402 BOOL lp_domain_master(void)
5404 if (Globals.bDomainMaster == Auto)
5405 return (lp_server_role() == ROLE_DOMAIN_PDC);
5407 return Globals.bDomainMaster;
5410 /***********************************************************
5411 If we are DMB then prefer us as LMB
5412 ************************************************************/
5414 BOOL lp_preferred_master(void)
5416 if (Globals.bPreferredMaster == Auto)
5417 return (lp_local_master() && lp_domain_master());
5419 return Globals.bPreferredMaster;
5422 /*******************************************************************
5424 ********************************************************************/
5426 void lp_remove_service(int snum)
5428 ServicePtrs[snum]->valid = False;
5429 invalid_services[num_invalid_services++] = snum;
5432 /*******************************************************************
5434 ********************************************************************/
5436 void lp_copy_service(int snum, const char *new_name)
5438 do_section(new_name);
5440 snum = lp_servicenumber(new_name);
5442 lp_do_parameter(snum, "copy", lp_servicename(snum));
5447 /*******************************************************************
5448 Get the default server type we will announce as via nmbd.
5449 ********************************************************************/
5451 int lp_default_server_announce(void)
5453 return default_server_announce;
5456 /*******************************************************************
5457 Split the announce version into major and minor numbers.
5458 ********************************************************************/
5460 int lp_major_announce_version(void)
5462 static BOOL got_major = False;
5463 static int major_version = DEFAULT_MAJOR_VERSION;
5468 return major_version;
5471 if ((vers = lp_announce_version()) == NULL)
5472 return major_version;
5474 if ((p = strchr_m(vers, '.')) == 0)
5475 return major_version;
5478 major_version = atoi(vers);
5479 return major_version;
5482 int lp_minor_announce_version(void)
5484 static BOOL got_minor = False;
5485 static int minor_version = DEFAULT_MINOR_VERSION;
5490 return minor_version;
5493 if ((vers = lp_announce_version()) == NULL)
5494 return minor_version;
5496 if ((p = strchr_m(vers, '.')) == 0)
5497 return minor_version;
5500 minor_version = atoi(p);
5501 return minor_version;
5504 /***********************************************************
5505 Set the global name resolution order (used in smbclient).
5506 ************************************************************/
5508 void lp_set_name_resolve_order(const char *new_order)
5510 string_set(&Globals.szNameResolveOrder, new_order);
5513 const char *lp_printername(int snum)
5515 const char *ret = _lp_printername(snum);
5516 if (ret == NULL || (ret != NULL && *ret == '\0'))
5517 ret = lp_const_servicename(snum);
5523 /***********************************************************
5524 Allow daemons such as winbindd to fix their logfile name.
5525 ************************************************************/
5527 void lp_set_logfile(const char *name)
5529 string_set(&Globals.szLogFile, name);
5530 pstrcpy(debugf, name);
5533 /*******************************************************************
5534 Return the max print jobs per queue.
5535 ********************************************************************/
5537 int lp_maxprintjobs(int snum)
5539 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5540 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5541 maxjobs = PRINT_MAX_JOBID - 1;
5546 const char *lp_printcapname(void)
5548 if ((Globals.szPrintcapname != NULL) &&
5549 (Globals.szPrintcapname[0] != '\0'))
5550 return Globals.szPrintcapname;
5552 if (sDefault.iPrinting == PRINT_CUPS) {
5560 if (sDefault.iPrinting == PRINT_BSD)
5561 return "/etc/printcap";
5563 return PRINTCAP_NAME;
5566 /*******************************************************************
5567 Ensure we don't use sendfile if server smb signing is active.
5568 ********************************************************************/
5570 static uint32 spoolss_state;
5572 BOOL lp_disable_spoolss( void )
5574 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5575 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5577 return spoolss_state == SVCCTL_STOPPED ? True : False;
5580 void lp_set_spoolss_state( uint32 state )
5582 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5584 spoolss_state = state;
5587 uint32 lp_get_spoolss_state( void )
5589 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5592 /*******************************************************************
5593 Ensure we don't use sendfile if server smb signing is active.
5594 ********************************************************************/
5596 BOOL lp_use_sendfile(int snum)
5598 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5599 if (Protocol < PROTOCOL_NT1) {
5602 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
5605 /*******************************************************************
5606 Turn off sendfile if we find the underlying OS doesn't support it.
5607 ********************************************************************/
5609 void set_use_sendfile(int snum, BOOL val)
5611 if (LP_SNUM_OK(snum))
5612 ServicePtrs[snum]->bUseSendfile = val;
5614 sDefault.bUseSendfile = val;
5617 /*******************************************************************
5618 Turn off storing DOS attributes if this share doesn't support it.
5619 ********************************************************************/
5621 void set_store_dos_attributes(int snum, BOOL val)
5623 if (!LP_SNUM_OK(snum))
5625 ServicePtrs[(snum)]->bStoreDosAttributes = val;
5628 void lp_set_mangling_method(const char *new_method)
5630 string_set(&Globals.szManglingMethod, new_method);
5633 /*******************************************************************
5634 Global state for POSIX pathname processing.
5635 ********************************************************************/
5637 static BOOL posix_pathnames;
5639 BOOL lp_posix_pathnames(void)
5641 return posix_pathnames;
5644 /*******************************************************************
5645 Change everything needed to ensure POSIX pathname processing (currently
5647 ********************************************************************/
5649 void lp_set_posix_pathnames(void)
5651 posix_pathnames = True;
5654 /*******************************************************************
5655 Global state for POSIX lock processing - CIFS unix extensions.
5656 ********************************************************************/
5658 BOOL posix_default_lock_was_set;
5659 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5661 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5663 if (posix_default_lock_was_set) {
5664 return posix_cifsx_locktype;
5666 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5670 /*******************************************************************
5671 ********************************************************************/
5673 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5675 posix_default_lock_was_set = True;
5676 posix_cifsx_locktype = val;