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 int keepalive = DEFAULT_KEEPALIVE;
83 BOOL use_getwd_cache = True;
85 extern int extra_time_offset;
87 static BOOL defaults_saved = False;
89 typedef struct _param_opt_struct param_opt_struct;
90 struct _param_opt_struct {
91 param_opt_struct *prev, *next;
98 * This structure describes global (ie., server-wide) parameters.
104 char *display_charset;
105 char *szPrintcapname;
106 char *szAddPortCommand;
107 char *szEnumPortsCommand;
108 char *szAddPrinterCommand;
109 char *szDeletePrinterCommand;
110 char *szOs2DriverMap;
114 char *szDefaultService;
118 char *szServerString;
119 char *szAutoServices;
120 char *szPasswdProgram;
124 char *szSMBPasswdFile;
126 char *szPassdbBackend;
127 char **szPreloadModules;
128 char *szPasswordServer;
129 char *szSocketOptions;
131 char *szAfsUsernameMap;
132 int iAfsTokenLifetime;
133 char *szLogNtTokenCommand;
139 char **szWINSservers;
141 char *szRemoteAnnounce;
142 char *szRemoteBrowseSync;
143 char *szSocketAddress;
144 char *szNISHomeMapName;
145 char *szAnnounceVersion; /* This is initialised in init_globals */
148 char **szNetbiosAliases;
149 char *szNetbiosScope;
150 char *szNameResolveOrder;
152 char *szAddUserScript;
153 char *szRenameUserScript;
154 char *szDelUserScript;
155 char *szAddGroupScript;
156 char *szDelGroupScript;
157 char *szAddUserToGroupScript;
158 char *szDelUserFromGroupScript;
159 char *szSetPrimaryGroupScript;
160 char *szAddMachineScript;
161 char *szShutdownScript;
162 char *szAbortShutdownScript;
163 char *szUsernameMapScript;
164 char *szCheckPasswordScript;
171 BOOL bPassdbExpandExplicit;
172 int AlgorithmicRidBase;
173 char *szTemplateHomedir;
174 char *szTemplateShell;
175 char *szWinbindSeparator;
176 BOOL bWinbindEnumUsers;
177 BOOL bWinbindEnumGroups;
178 BOOL bWinbindUseDefaultDomain;
179 BOOL bWinbindTrustedDomainsOnly;
180 BOOL bWinbindNestedGroups;
181 BOOL bWinbindRefreshTickets;
182 BOOL bWinbindOfflineLogon;
183 BOOL bWinbindNormalizeNames;
184 char **szIdmapDomains;
185 char **szIdmapBackend; /* deprecated */
186 char *szIdmapAllocBackend;
187 char *szAddShareCommand;
188 char *szChangeShareCommand;
189 char *szDeleteShareCommand;
191 char *szGuestaccount;
192 char *szManglingMethod;
193 char **szServicesList;
194 char *szUsersharePath;
195 char *szUsershareTemplateShare;
196 char **szUsersharePrefixAllowList;
197 char **szUsersharePrefixDenyList;
204 int open_files_db_hash_size;
212 BOOL paranoid_server_security;
215 int iMaxSmbdProcesses;
216 BOOL bDisableSpoolss;
219 int enhanced_browsing;
225 int announce_as; /* This is initialised in init_globals */
226 int machine_password_timeout;
228 int oplock_break_wait_time;
229 int winbind_cache_time;
230 int winbind_max_idle_children;
231 char **szWinbindNssInfo;
234 char *szLdapMachineSuffix;
235 char *szLdapUserSuffix;
236 char *szLdapIdmapSuffix;
237 char *szLdapGroupSuffix;
243 char *szIPrintServer;
244 int ldap_passwd_sync;
245 int ldap_replication_sleep;
246 int ldap_timeout; /* This is initialised in init_globals */
249 BOOL bMsAddPrinterWizard;
254 BOOL bPreferredMaster;
257 BOOL bEncryptPasswords;
262 BOOL bObeyPamRestrictions;
264 int PrintcapCacheTime;
265 BOOL bLargeReadwrite;
273 BOOL bBindInterfacesOnly;
274 BOOL bPamPasswordChange;
275 BOOL bUnixPasswdSync;
276 BOOL bPasswdChatDebug;
277 int iPasswdChatTimeout;
281 BOOL bNTStatusSupport;
283 int iMaxStatCacheSize;
285 BOOL bAllowTrustedDomains;
289 BOOL bClientLanManAuth;
290 BOOL bClientNTLMv2Auth;
291 BOOL bClientPlaintextAuth;
292 BOOL bClientUseSpnego;
293 BOOL bDebugHiresTimestamp;
296 BOOL bEnableCoreFiles;
299 BOOL bHostnameLookups;
300 BOOL bUnixExtensions;
301 BOOL bDisableNetbios;
302 BOOL bUseKerberosKeytab;
303 BOOL bDeferSharingViolations;
304 BOOL bEnablePrivileges;
306 BOOL bUsershareOwnerOnly;
307 BOOL bUsershareAllowGuests;
308 BOOL bRegistryShares;
309 int restrict_anonymous;
310 int name_cache_timeout;
313 int iUsershareMaxShares;
314 int iIdmapExpireTime;
315 int iIdmapNegativeTime;
318 param_opt_struct *param_opt;
321 static global Globals;
324 * This structure describes a single service.
330 time_t usershare_last_mod;
334 char **szInvalidUsers;
342 char *szRootPostExec;
344 char *szPrintcommand;
347 char *szLppausecommand;
348 char *szLpresumecommand;
349 char *szQueuepausecommand;
350 char *szQueueresumecommand;
360 char *szVetoOplockFiles;
366 char **printer_admin;
374 int iMaxReportedPrintJobs;
377 int iCreate_force_mode;
379 int iSecurity_force_mode;
382 int iDir_Security_mask;
383 int iDir_Security_force_mode;
387 int iOplockContentionLimit;
392 BOOL bRootpreexecClose;
395 BOOL bShortCasePreserve;
397 BOOL bHideSpecialFiles;
398 BOOL bHideUnReadable;
399 BOOL bHideUnWriteableFiles;
410 BOOL bStoreDosAttributes;
423 BOOL bStrictAllocate;
427 BOOL bDeleteReadonly;
429 BOOL bDeleteVetoFiles;
432 BOOL bDosFiletimeResolution;
433 BOOL bFakeDirCreateTimes;
439 BOOL bUseClientDriver;
440 BOOL bDefaultDevmode;
441 BOOL bForcePrintername;
443 BOOL bForceUnknownAclUser;
446 BOOL bMap_acl_inherit;
449 BOOL bAclCheckPermissions;
450 BOOL bAclMapFullControl;
451 BOOL bAclGroupControl;
453 BOOL bKernelChangeNotify;
454 int iallocation_roundup_size;
458 param_opt_struct *param_opt;
460 char dummy[3]; /* for alignment */
464 /* This is a default service used to prime a services structure */
465 static service sDefault = {
467 False, /* not autoloaded */
468 0, /* not a usershare */
469 (time_t)0, /* No last mod time */
470 NULL, /* szService */
472 NULL, /* szUsername */
473 NULL, /* szInvalidUsers */
474 NULL, /* szValidUsers */
475 NULL, /* szAdminUsers */
477 NULL, /* szInclude */
478 NULL, /* szPreExec */
479 NULL, /* szPostExec */
480 NULL, /* szRootPreExec */
481 NULL, /* szRootPostExec */
482 NULL, /* szCupsOptions */
483 NULL, /* szPrintcommand */
484 NULL, /* szLpqcommand */
485 NULL, /* szLprmcommand */
486 NULL, /* szLppausecommand */
487 NULL, /* szLpresumecommand */
488 NULL, /* szQueuepausecommand */
489 NULL, /* szQueueresumecommand */
490 NULL, /* szPrintername */
491 NULL, /* szDontdescend */
492 NULL, /* szHostsallow */
493 NULL, /* szHostsdeny */
494 NULL, /* szMagicScript */
495 NULL, /* szMagicOutput */
496 NULL, /* szMangledMap */
497 NULL, /* szVetoFiles */
498 NULL, /* szHideFiles */
499 NULL, /* szVetoOplockFiles */
501 NULL, /* force user */
502 NULL, /* force group */
504 NULL, /* writelist */
505 NULL, /* printer admin */
508 NULL, /* vfs objects */
509 NULL, /* szMSDfsProxy */
511 0, /* iMinPrintSpace */
512 1000, /* iMaxPrintJobs */
513 0, /* iMaxReportedPrintJobs */
514 0, /* iWriteCacheSize */
515 0744, /* iCreate_mask */
516 0000, /* iCreate_force_mode */
517 0777, /* iSecurity_mask */
518 0, /* iSecurity_force_mode */
519 0755, /* iDir_mask */
520 0000, /* iDir_force_mode */
521 0777, /* iDir_Security_mask */
522 0, /* iDir_Security_force_mode */
523 0, /* iMaxConnections */
524 CASE_LOWER, /* iDefaultCase */
525 DEFAULT_PRINTING, /* iPrinting */
526 2, /* iOplockContentionLimit */
528 1024, /* iBlock_size */
529 0, /* iDfreeCacheTime */
530 False, /* bPreexecClose */
531 False, /* bRootpreexecClose */
532 Auto, /* case sensitive */
533 True, /* case preserve */
534 True, /* short case preserve */
535 True, /* bHideDotFiles */
536 False, /* bHideSpecialFiles */
537 False, /* bHideUnReadable */
538 False, /* bHideUnWriteableFiles */
539 True, /* bBrowseable */
540 True, /* bAvailable */
541 True, /* bRead_only */
542 True, /* bNo_set_dir */
543 False, /* bGuest_only */
544 False, /* bGuest_ok */
545 False, /* bPrint_ok */
546 False, /* bMap_system */
547 False, /* bMap_hidden */
548 True, /* bMap_archive */
549 False, /* bStoreDosAttributes */
550 False, /* bDmapiSupport */
552 Auto, /* iStrictLocking */
553 True, /* bPosixLocking */
554 True, /* bShareModes */
556 True, /* bLevel2OpLocks */
557 False, /* bOnlyUser */
558 True, /* bMangledNames */
559 True, /* bWidelinks */
560 True, /* bSymlinks */
561 False, /* bSyncAlways */
562 False, /* bStrictAllocate */
563 False, /* bStrictSync */
564 '~', /* magic char */
566 False, /* bDeleteReadonly */
567 False, /* bFakeOplocks */
568 False, /* bDeleteVetoFiles */
569 False, /* bDosFilemode */
570 True, /* bDosFiletimes */
571 False, /* bDosFiletimeResolution */
572 False, /* bFakeDirCreateTimes */
573 True, /* bBlockingLocks */
574 False, /* bInheritPerms */
575 False, /* bInheritACLS */
576 False, /* bInheritOwner */
577 True, /* bMSDfsRoot */
578 False, /* bUseClientDriver */
579 True, /* bDefaultDevmode */
580 False, /* bForcePrintername */
581 True, /* bNTAclSupport */
582 False, /* bForceUnknownAclUser */
583 False, /* bUseSendfile */
584 False, /* bProfileAcls */
585 False, /* bMap_acl_inherit */
586 False, /* bAfs_Share */
587 False, /* bEASupport */
588 True, /* bAclCheckPermissions */
589 True, /* bAclMapFullControl */
590 False, /* bAclGroupControl */
591 True, /* bChangeNotify */
592 True, /* bKernelChangeNotify */
593 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
594 0, /* iAioReadSize */
595 0, /* iAioWriteSize */
596 MAP_READONLY_YES, /* iMap_readonly */
598 NULL, /* Parametric options */
603 /* local variables */
604 static service **ServicePtrs = NULL;
605 static int iNumServices = 0;
606 static int iServiceIndex = 0;
607 static TDB_CONTEXT *ServiceHash;
608 static int *invalid_services = NULL;
609 static int num_invalid_services = 0;
610 static BOOL bInGlobalSection = True;
611 static BOOL bGlobalOnly = False;
612 static int server_role;
613 static int default_server_announce;
615 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
617 /* prototypes for the special type handlers */
618 static BOOL handle_include( int snum, const char *pszParmValue, char **ptr);
619 static BOOL handle_copy( int snum, const char *pszParmValue, char **ptr);
620 static BOOL handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
621 static BOOL handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
622 static BOOL handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
623 static BOOL handle_debug_list( int snum, const char *pszParmValue, char **ptr );
624 static BOOL handle_workgroup( int snum, const char *pszParmValue, char **ptr );
625 static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
626 static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
627 static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
628 static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
630 static void set_server_role(void);
631 static void set_default_server_announce_type(void);
632 static void set_allowed_client_auth(void);
634 static const struct enum_list enum_protocol[] = {
635 {PROTOCOL_NT1, "NT1"},
636 {PROTOCOL_LANMAN2, "LANMAN2"},
637 {PROTOCOL_LANMAN1, "LANMAN1"},
638 {PROTOCOL_CORE, "CORE"},
639 {PROTOCOL_COREPLUS, "COREPLUS"},
640 {PROTOCOL_COREPLUS, "CORE+"},
644 static const struct enum_list enum_security[] = {
645 {SEC_SHARE, "SHARE"},
647 {SEC_SERVER, "SERVER"},
648 {SEC_DOMAIN, "DOMAIN"},
655 static const struct enum_list enum_printing[] = {
656 {PRINT_SYSV, "sysv"},
658 {PRINT_HPUX, "hpux"},
662 {PRINT_LPRNG, "lprng"},
663 {PRINT_CUPS, "cups"},
664 {PRINT_IPRINT, "iprint"},
666 {PRINT_LPROS2, "os2"},
668 {PRINT_TEST, "test"},
670 #endif /* DEVELOPER */
674 static const struct enum_list enum_ldap_ssl[] = {
675 {LDAP_SSL_OFF, "no"},
676 {LDAP_SSL_OFF, "No"},
677 {LDAP_SSL_OFF, "off"},
678 {LDAP_SSL_OFF, "Off"},
679 {LDAP_SSL_START_TLS, "start tls"},
680 {LDAP_SSL_START_TLS, "Start_tls"},
684 static const struct enum_list enum_ldap_passwd_sync[] = {
685 {LDAP_PASSWD_SYNC_OFF, "no"},
686 {LDAP_PASSWD_SYNC_OFF, "No"},
687 {LDAP_PASSWD_SYNC_OFF, "off"},
688 {LDAP_PASSWD_SYNC_OFF, "Off"},
689 {LDAP_PASSWD_SYNC_ON, "Yes"},
690 {LDAP_PASSWD_SYNC_ON, "yes"},
691 {LDAP_PASSWD_SYNC_ON, "on"},
692 {LDAP_PASSWD_SYNC_ON, "On"},
693 {LDAP_PASSWD_SYNC_ONLY, "Only"},
694 {LDAP_PASSWD_SYNC_ONLY, "only"},
698 /* Types of machine we can announce as. */
699 #define ANNOUNCE_AS_NT_SERVER 1
700 #define ANNOUNCE_AS_WIN95 2
701 #define ANNOUNCE_AS_WFW 3
702 #define ANNOUNCE_AS_NT_WORKSTATION 4
704 static const struct enum_list enum_announce_as[] = {
705 {ANNOUNCE_AS_NT_SERVER, "NT"},
706 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
707 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
708 {ANNOUNCE_AS_WIN95, "win95"},
709 {ANNOUNCE_AS_WFW, "WfW"},
713 static const struct enum_list enum_map_readonly[] = {
714 {MAP_READONLY_NO, "no"},
715 {MAP_READONLY_NO, "false"},
716 {MAP_READONLY_NO, "0"},
717 {MAP_READONLY_YES, "yes"},
718 {MAP_READONLY_YES, "true"},
719 {MAP_READONLY_YES, "1"},
720 {MAP_READONLY_PERMISSIONS, "permissions"},
721 {MAP_READONLY_PERMISSIONS, "perms"},
725 static const struct enum_list enum_case[] = {
726 {CASE_LOWER, "lower"},
727 {CASE_UPPER, "upper"},
731 static const struct enum_list enum_bool_auto[] = {
742 /* Client-side offline caching policy types */
743 #define CSC_POLICY_MANUAL 0
744 #define CSC_POLICY_DOCUMENTS 1
745 #define CSC_POLICY_PROGRAMS 2
746 #define CSC_POLICY_DISABLE 3
748 static const struct enum_list enum_csc_policy[] = {
749 {CSC_POLICY_MANUAL, "manual"},
750 {CSC_POLICY_DOCUMENTS, "documents"},
751 {CSC_POLICY_PROGRAMS, "programs"},
752 {CSC_POLICY_DISABLE, "disable"},
756 /* SMB signing types. */
757 static const struct enum_list enum_smb_signing_vals[] = {
769 {Required, "required"},
770 {Required, "mandatory"},
772 {Required, "forced"},
773 {Required, "enforced"},
777 /* ACL compatibility options. */
778 static const struct enum_list enum_acl_compat_vals[] = {
779 { ACL_COMPAT_AUTO, "auto" },
780 { ACL_COMPAT_WINNT, "winnt" },
781 { ACL_COMPAT_WIN2K, "win2k" },
786 Do you want session setups at user level security with a invalid
787 password to be rejected or allowed in as guest? WinNT rejects them
788 but it can be a pain as it means "net view" needs to use a password
790 You have 3 choices in the setting of map_to_guest:
792 "Never" means session setups with an invalid password
793 are rejected. This is the default.
795 "Bad User" means session setups with an invalid password
796 are rejected, unless the username does not exist, in which case it
797 is treated as a guest login
799 "Bad Password" means session setups with an invalid password
800 are treated as a guest login
802 Note that map_to_guest only has an effect in user or server
806 static const struct enum_list enum_map_to_guest[] = {
807 {NEVER_MAP_TO_GUEST, "Never"},
808 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
809 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
810 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
814 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
816 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
817 * screen in SWAT. This is used to exclude parameters as well as to squash all
818 * parameters that have been duplicated by pseudonyms.
820 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
821 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
822 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
825 * NOTE2: Handling of duplicated (synonym) paramters:
826 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
827 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
828 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
829 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
832 static struct parm_struct parm_table[] = {
833 {N_("Base Options"), P_SEP, P_SEPARATOR},
835 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
836 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
837 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
838 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
839 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
840 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
841 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
843 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
845 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
846 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
847 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
848 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
849 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
850 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
852 {N_("Security Options"), P_SEP, P_SEPARATOR},
854 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
855 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
856 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
857 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
858 {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
859 {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
860 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
861 {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
862 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
863 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
864 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
865 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
866 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
867 {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
868 {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
869 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
870 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
871 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
872 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
873 {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
875 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
876 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
877 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
878 {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
879 {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
880 {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED},
881 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
882 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
883 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
884 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
885 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
886 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
887 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
888 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
889 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
890 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
892 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
893 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
894 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
896 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
897 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
898 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
899 {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
900 {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
901 {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED },
902 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
903 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
904 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
906 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
907 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
908 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
909 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
911 {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
912 {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED },
913 {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
914 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
915 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
916 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
917 {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
918 {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
919 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
920 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
921 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
922 {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
923 {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
924 {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
925 {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
926 {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
927 {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
928 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
929 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
931 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
932 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
934 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
935 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
936 {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
937 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
938 {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
939 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
940 {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED},
942 {N_("Logging Options"), P_SEP, P_SEPARATOR},
944 {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
945 {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
946 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
947 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
948 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
950 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
951 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
952 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
953 {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
954 {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
955 {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
956 {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
958 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
960 {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED},
961 {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED},
962 {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED},
963 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
964 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
965 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
966 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
967 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
968 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED},
969 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
970 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
971 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
972 {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED},
974 {"acl compatibility", P_ENUM, P_GLOBAL, &Globals.iAclCompat, NULL, enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
975 {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
976 {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
977 {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
978 {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
979 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
980 {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
982 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
983 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED},
984 {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
985 {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
986 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
987 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
989 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
990 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
991 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
992 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
993 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
994 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
995 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
996 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
997 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
998 {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
1000 {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED},
1001 {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
1003 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1005 {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1006 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
1007 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
1008 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED},
1009 {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1010 {"kernel change notify", P_BOOL, P_LOCAL, &sDefault.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1012 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
1013 {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
1014 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1015 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
1016 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
1017 {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
1018 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1019 {"open files database hash size", P_INTEGER, P_GLOBAL, &Globals.open_files_db_hash_size, NULL, NULL, FLAG_ADVANCED},
1021 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
1022 {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1023 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1024 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1025 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
1026 {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1027 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
1028 {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
1030 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
1032 {N_("Printing Options"), P_SEP, P_SEPARATOR},
1034 {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1035 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1036 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1037 {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1038 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1039 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
1040 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1041 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
1042 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1043 {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1044 {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1045 {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1046 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1047 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1048 {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE},
1049 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1050 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1051 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1052 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1053 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1054 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1056 {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED},
1057 {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
1058 {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
1059 {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
1060 {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
1061 {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
1063 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1064 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
1065 {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1066 {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1067 {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1069 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
1070 {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
1071 {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
1073 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
1074 {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1075 {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE},
1076 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1077 {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1078 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1079 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1080 {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1081 {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1082 {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1083 {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1084 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1085 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1086 {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1087 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1088 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1089 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1090 {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1091 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1092 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED },
1093 {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
1094 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
1095 {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1096 {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1099 {N_("Domain Options"), P_SEP, P_SEPARATOR},
1101 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1103 {N_("Logon Options"), P_SEP, P_SEPARATOR},
1105 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
1106 {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
1107 {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
1108 {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
1109 {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
1110 {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
1111 {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
1112 {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
1113 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
1114 {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
1115 {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
1116 {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED},
1118 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
1119 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
1120 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
1121 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
1122 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
1124 {N_("Browse Options"), P_SEP, P_SEPARATOR},
1126 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1127 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
1128 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
1129 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1130 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
1131 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1132 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1133 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
1134 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1135 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1136 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
1138 {N_("WINS Options"), P_SEP, P_SEPARATOR},
1140 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
1141 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
1143 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1144 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1145 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
1147 {N_("Locking Options"), P_SEP, P_SEPARATOR},
1149 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1150 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1151 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1152 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1153 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1154 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1155 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1157 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1158 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1159 {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1160 {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1161 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1162 {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1163 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1165 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
1167 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
1168 {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
1169 {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
1170 {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
1171 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
1172 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
1173 {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE},
1174 {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1175 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
1176 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
1177 {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1178 {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
1179 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
1181 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
1182 {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
1183 {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
1184 {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
1186 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
1187 {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1189 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1190 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1191 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1192 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
1193 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
1194 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
1196 {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
1197 {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
1198 {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
1201 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1202 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1203 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
1204 {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED},
1205 {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED},
1206 {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
1207 {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
1208 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
1209 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
1210 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
1211 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
1212 {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
1213 {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1214 {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1215 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
1216 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
1217 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1219 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1220 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1221 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1222 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
1224 {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1225 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1226 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1227 {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1228 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1229 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1230 {"registry shares", P_BOOL, P_GLOBAL, &Globals.bRegistryShares, NULL, NULL, FLAG_ADVANCED},
1231 {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
1232 {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
1233 {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED},
1234 {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
1235 {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED},
1236 {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED},
1237 {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
1238 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1239 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1240 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1241 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1242 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1243 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1244 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1245 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1246 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1247 {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1248 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1249 {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1251 {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1252 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
1254 {N_("VFS module options"), P_SEP, P_SEPARATOR},
1256 {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1257 {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
1260 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1261 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1262 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
1264 {N_("Winbind options"), P_SEP, P_SEPARATOR},
1266 {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
1267 {"idmap domains", P_LIST, P_GLOBAL, &Globals.szIdmapDomains, NULL, NULL, FLAG_ADVANCED},
1268 {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEPRECATED },
1269 {"idmap alloc backend", P_STRING, P_GLOBAL, &Globals.szIdmapAllocBackend, NULL, NULL, FLAG_ADVANCED},
1270 {"idmap expire time", P_INTEGER, P_GLOBAL, &Globals.iIdmapExpireTime, NULL, NULL, FLAG_ADVANCED},
1271 {"idmap negative time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeTime, NULL, NULL, FLAG_ADVANCED},
1272 {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEPRECATED },
1273 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE | FLAG_DEPRECATED },
1274 {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEPRECATED },
1275 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE | FLAG_DEPRECATED },
1276 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
1277 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
1278 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
1279 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
1280 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
1281 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
1282 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
1283 {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
1284 {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
1285 {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED},
1286 {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED},
1287 {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
1288 {"winbind normalize names", P_BOOL, P_GLOBAL, &Globals.bWinbindNormalizeNames, NULL, NULL, FLAG_ADVANCED},
1290 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1293 /***************************************************************************
1294 Initialise the sDefault parameter structure for the printer values.
1295 ***************************************************************************/
1297 static void init_printer_values(service *pService)
1299 /* choose defaults depending on the type of printing */
1300 switch (pService->iPrinting) {
1305 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1306 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1307 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1312 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1313 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1314 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1315 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1316 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1317 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1318 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1324 /* set the lpq command to contain the destination printer
1325 name only. This is used by cups_queue_get() */
1326 string_set(&pService->szLpqcommand, "%p");
1327 string_set(&pService->szLprmcommand, "");
1328 string_set(&pService->szPrintcommand, "");
1329 string_set(&pService->szLppausecommand, "");
1330 string_set(&pService->szLpresumecommand, "");
1331 string_set(&pService->szQueuepausecommand, "");
1332 string_set(&pService->szQueueresumecommand, "");
1334 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1335 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1336 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
1337 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1338 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1339 string_set(&pService->szQueuepausecommand, "disable '%p'");
1340 string_set(&pService->szQueueresumecommand, "enable '%p'");
1341 #endif /* HAVE_CUPS */
1346 string_set(&pService->szLpqcommand, "lpstat -o%p");
1347 string_set(&pService->szLprmcommand, "cancel %p-%j");
1348 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1349 string_set(&pService->szQueuepausecommand, "disable %p");
1350 string_set(&pService->szQueueresumecommand, "enable %p");
1352 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1353 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1358 string_set(&pService->szLpqcommand, "lpq -P%p");
1359 string_set(&pService->szLprmcommand, "lprm -P%p %j");
1360 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1366 string_set(&pService->szPrintcommand, "vlp print %p %s");
1367 string_set(&pService->szLpqcommand, "vlp lpq %p");
1368 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1369 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1370 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1371 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1372 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1374 #endif /* DEVELOPER */
1379 /***************************************************************************
1380 Initialise the global parameter structure.
1381 ***************************************************************************/
1383 static void init_globals(BOOL first_time_only)
1385 static BOOL done_init = False;
1388 /* If requested to initialize only once and we've already done it... */
1389 if (first_time_only && done_init) {
1390 /* ... then we have nothing more to do */
1397 /* The logfile can be set before this is invoked. Free it if so. */
1398 if (Globals.szLogFile != NULL) {
1399 string_free(&Globals.szLogFile);
1400 Globals.szLogFile = NULL;
1403 memset((void *)&Globals, '\0', sizeof(Globals));
1405 for (i = 0; parm_table[i].label; i++)
1406 if ((parm_table[i].type == P_STRING ||
1407 parm_table[i].type == P_USTRING) &&
1409 string_set((char **)parm_table[i].ptr, "");
1411 string_set(&sDefault.fstype, FSTYPE_STRING);
1413 init_printer_values(&sDefault);
1419 DEBUG(3, ("Initialising global parameters\n"));
1421 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1422 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1424 /* use the new 'hash2' method by default, with a prefix of 1 */
1425 string_set(&Globals.szManglingMethod, "hash2");
1426 Globals.mangle_prefix = 1;
1428 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1430 /* using UTF8 by default allows us to support all chars */
1431 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1433 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1434 /* If the system supports nl_langinfo(), try to grab the value
1435 from the user's locale */
1436 string_set(&Globals.display_charset, "LOCALE");
1438 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1441 /* Use codepage 850 as a default for the dos character set */
1442 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1445 * Allow the default PASSWD_CHAT to be overridden in local.h.
1447 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1449 set_global_myname(myhostname());
1450 string_set(&Globals.szNetbiosName,global_myname());
1452 set_global_myworkgroup(WORKGROUP);
1453 string_set(&Globals.szWorkgroup, lp_workgroup());
1455 string_set(&Globals.szPasswdProgram, "");
1456 string_set(&Globals.szPidDir, dyn_PIDDIR);
1457 string_set(&Globals.szLockDir, dyn_LOCKDIR);
1458 string_set(&Globals.szSocketAddress, "0.0.0.0");
1459 pstrcpy(s, "Samba ");
1460 pstrcat(s, SAMBA_VERSION_STRING);
1461 string_set(&Globals.szServerString, s);
1462 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1463 DEFAULT_MINOR_VERSION);
1464 string_set(&Globals.szAnnounceVersion, s);
1466 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1469 pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1471 string_set(&Globals.szLogonDrive, "");
1472 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1473 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1474 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1476 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1477 string_set(&Globals.szPasswordServer, "*");
1479 Globals.AlgorithmicRidBase = BASE_RID;
1481 Globals.bLoadPrinters = True;
1482 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
1484 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1485 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1486 Globals.max_xmit = 0x4104;
1487 Globals.max_mux = 50; /* This is *needed* for profile support. */
1488 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
1489 Globals.bDisableSpoolss = False;
1490 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1491 Globals.pwordlevel = 0;
1492 Globals.unamelevel = 0;
1493 Globals.deadtime = 0;
1494 Globals.bLargeReadwrite = True;
1495 Globals.max_log_size = 5000;
1496 Globals.max_open_files = MAX_OPEN_FILES;
1497 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
1498 Globals.maxprotocol = PROTOCOL_NT1;
1499 Globals.minprotocol = PROTOCOL_CORE;
1500 Globals.security = SEC_USER;
1501 Globals.paranoid_server_security = True;
1502 Globals.bEncryptPasswords = True;
1503 Globals.bUpdateEncrypt = False;
1504 Globals.clientSchannel = Auto;
1505 Globals.serverSchannel = Auto;
1506 Globals.bReadRaw = True;
1507 Globals.bWriteRaw = True;
1508 Globals.bReadbmpx = False;
1509 Globals.bNullPasswords = False;
1510 Globals.bObeyPamRestrictions = False;
1512 Globals.bSyslogOnly = False;
1513 Globals.bTimestampLogs = True;
1514 string_set(&Globals.szLogLevel, "0");
1515 Globals.bDebugHiresTimestamp = False;
1516 Globals.bDebugPid = False;
1517 Globals.bDebugUid = False;
1518 Globals.bEnableCoreFiles = True;
1519 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1520 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1521 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1522 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1523 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1524 Globals.lm_interval = 60;
1525 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1526 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1527 Globals.bNISHomeMap = False;
1528 #ifdef WITH_NISPLUS_HOME
1529 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1531 string_set(&Globals.szNISHomeMapName, "auto.home");
1534 Globals.bTimeServer = False;
1535 Globals.bBindInterfacesOnly = False;
1536 Globals.bUnixPasswdSync = False;
1537 Globals.bPamPasswordChange = False;
1538 Globals.bPasswdChatDebug = False;
1539 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1540 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
1541 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1542 Globals.bStatCache = True; /* use stat cache by default */
1543 Globals.iMaxStatCacheSize = 1024; /* one Meg by default. */
1544 Globals.restrict_anonymous = 0;
1545 Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
1546 Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */
1547 Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
1548 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1549 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1550 /* Note, that we will use NTLM2 session security (which is different), if it is available */
1552 Globals.map_to_guest = 0; /* By Default, "Never" */
1553 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
1554 Globals.enhanced_browsing = True;
1555 Globals.iLockSpinCount = 0; /* Unused. */
1556 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
1557 #ifdef MMAP_BLACKLIST
1558 Globals.bUseMmap = False;
1560 Globals.bUseMmap = True;
1562 Globals.bUnixExtensions = True;
1563 Globals.bResetOnZeroVC = False;
1565 /* hostname lookups can be very expensive and are broken on
1566 a large number of sites (tridge) */
1567 Globals.bHostnameLookups = False;
1569 string_set(&Globals.szPassdbBackend, "smbpasswd");
1570 string_set(&Globals.szLdapSuffix, "");
1571 string_set(&Globals.szLdapMachineSuffix, "");
1572 string_set(&Globals.szLdapUserSuffix, "");
1573 string_set(&Globals.szLdapGroupSuffix, "");
1574 string_set(&Globals.szLdapIdmapSuffix, "");
1576 string_set(&Globals.szLdapAdminDn, "");
1577 Globals.ldap_ssl = LDAP_SSL_ON;
1578 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1579 Globals.ldap_delete_dn = False;
1580 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1581 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1582 Globals.ldap_page_size = LDAP_PAGE_SIZE;
1584 /* This is what we tell the afs client. in reality we set the token
1585 * to never expire, though, when this runs out the afs client will
1586 * forget the token. Set to 0 to get NEVERDATE.*/
1587 Globals.iAfsTokenLifetime = 604800;
1589 /* these parameters are set to defaults that are more appropriate
1590 for the increasing samba install base:
1592 as a member of the workgroup, that will possibly become a
1593 _local_ master browser (lm = True). this is opposed to a forced
1594 local master browser startup (pm = True).
1596 doesn't provide WINS server service by default (wsupp = False),
1597 and doesn't provide domain master browser services by default, either.
1601 Globals.bMsAddPrinterWizard = True;
1602 Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
1603 Globals.os_level = 20;
1604 Globals.bLocalMaster = True;
1605 Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
1606 Globals.bDomainLogons = False;
1607 Globals.bBrowseList = True;
1608 Globals.bWINSsupport = False;
1609 Globals.bWINSproxy = False;
1611 Globals.bDNSproxy = True;
1613 /* this just means to use them if they exist */
1614 Globals.bKernelOplocks = True;
1616 Globals.bAllowTrustedDomains = True;
1618 string_set(&Globals.szTemplateShell, "/bin/false");
1619 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1620 string_set(&Globals.szWinbindSeparator, "\\");
1622 string_set(&Globals.szCupsServer, "");
1623 string_set(&Globals.szIPrintServer, "");
1625 Globals.winbind_cache_time = 300; /* 5 minutes */
1626 Globals.bWinbindEnumUsers = False;
1627 Globals.bWinbindEnumGroups = False;
1628 Globals.bWinbindUseDefaultDomain = False;
1629 Globals.bWinbindTrustedDomainsOnly = False;
1630 Globals.bWinbindNestedGroups = True;
1631 Globals.bWinbindRefreshTickets = False;
1632 Globals.bWinbindOfflineLogon = False;
1634 Globals.iIdmapExpireTime = 900; /* 15 minutes by default */
1635 Globals.iIdmapNegativeTime = 120; /* 2 minutes by default */
1637 Globals.bPassdbExpandExplicit = False;
1639 Globals.name_cache_timeout = 660; /* In seconds */
1641 Globals.bUseSpnego = True;
1642 Globals.bClientUseSpnego = True;
1644 Globals.client_signing = Auto;
1645 Globals.server_signing = False;
1647 Globals.bDeferSharingViolations = True;
1648 string_set(&Globals.smb_ports, SMB_PORTS);
1650 Globals.bEnablePrivileges = True;
1651 Globals.bHostMSDfs = True;
1652 Globals.bASUSupport = False;
1654 /* User defined shares. */
1655 pstrcpy(s, dyn_LOCKDIR);
1656 pstrcat(s, "/usershares");
1657 string_set(&Globals.szUsersharePath, s);
1658 string_set(&Globals.szUsershareTemplateShare, "");
1659 Globals.iUsershareMaxShares = 0;
1660 /* By default disallow sharing of directories not owned by the sharer. */
1661 Globals.bUsershareOwnerOnly = True;
1662 /* By default disallow guest access to usershares. */
1663 Globals.bUsershareAllowGuests = False;
1665 /* By default no shares out of the registry */
1666 Globals.bRegistryShares = False;
1669 static TALLOC_CTX *lp_talloc;
1671 /******************************************************************* a
1672 Free up temporary memory - called from the main loop.
1673 ********************************************************************/
1675 void lp_TALLOC_FREE(void)
1679 TALLOC_FREE(lp_talloc);
1683 TALLOC_CTX *tmp_talloc_ctx(void)
1685 if (lp_talloc == NULL) {
1686 lp_talloc = talloc_init("tmp_talloc_ctx");
1689 if (lp_talloc == NULL) {
1690 smb_panic("Could not create temporary talloc context\n");
1696 /*******************************************************************
1697 Convenience routine to grab string parameters into temporary memory
1698 and run standard_sub_basic on them. The buffers can be written to by
1699 callers without affecting the source string.
1700 ********************************************************************/
1702 static char *lp_string(const char *s)
1706 /* The follow debug is useful for tracking down memory problems
1707 especially if you have an inner loop that is calling a lp_*()
1708 function that returns a string. Perhaps this debug should be
1709 present all the time? */
1712 DEBUG(10, ("lp_string(%s)\n", s));
1716 lp_talloc = talloc_init("lp_talloc");
1718 tmpstr = alloc_sub_basic(get_current_username(),
1719 current_user_info.domain, s);
1720 if (trim_char(tmpstr, '\"', '\"')) {
1721 if (strchr(tmpstr,'\"') != NULL) {
1723 tmpstr = alloc_sub_basic(get_current_username(),
1724 current_user_info.domain, s);
1727 ret = talloc_strdup(lp_talloc, tmpstr);
1734 In this section all the functions that are used to access the
1735 parameters from the rest of the program are defined
1738 #define FN_GLOBAL_STRING(fn_name,ptr) \
1739 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1740 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1741 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1742 #define FN_GLOBAL_LIST(fn_name,ptr) \
1743 const char **fn_name(void) {return(*(const char ***)(ptr));}
1744 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1745 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1746 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1747 char fn_name(void) {return(*(char *)(ptr));}
1748 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1749 int fn_name(void) {return(*(int *)(ptr));}
1751 #define FN_LOCAL_STRING(fn_name,val) \
1752 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1753 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1754 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1755 #define FN_LOCAL_LIST(fn_name,val) \
1756 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1757 #define FN_LOCAL_BOOL(fn_name,val) \
1758 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1759 #define FN_LOCAL_INTEGER(fn_name,val) \
1760 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1762 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1763 BOOL fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1764 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1765 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1766 #define FN_LOCAL_PARM_STRING(fn_name,val) \
1767 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));}
1768 #define FN_LOCAL_CHAR(fn_name,val) \
1769 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1771 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1772 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1773 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1774 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1775 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1776 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1777 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1778 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1779 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1780 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1781 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1782 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1783 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1784 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1785 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1786 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1787 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1788 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1789 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1790 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1791 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1792 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1793 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1794 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1795 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1796 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1797 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1798 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1799 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1800 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1801 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1802 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1803 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1804 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1805 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1806 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1807 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1808 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1809 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1810 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1811 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1812 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1813 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1814 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1815 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1816 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1817 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1818 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1819 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1820 FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1821 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1822 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1823 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1824 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1825 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1827 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1828 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1829 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1830 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1831 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1832 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1834 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1836 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1837 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1838 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1840 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1842 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1843 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1844 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1845 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1846 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
1847 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1848 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1849 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1850 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1851 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1852 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1853 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1854 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
1856 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
1857 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
1858 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
1859 FN_GLOBAL_INTEGER(lp_idmap_expire_time, &Globals.iIdmapExpireTime)
1860 FN_GLOBAL_INTEGER(lp_idmap_negative_time, &Globals.iIdmapNegativeTime)
1861 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1863 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1864 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1865 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1866 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1867 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1868 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1869 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1870 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1871 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1872 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1873 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1874 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1875 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1876 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1878 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1880 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
1881 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1882 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1883 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1884 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1885 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1886 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1887 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1888 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1889 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1890 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1891 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1892 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1893 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1894 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1895 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1896 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1897 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1898 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1899 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1900 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1901 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1902 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1903 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1904 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1905 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1906 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1907 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1908 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
1909 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1910 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1911 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1912 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1913 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1914 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1915 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1916 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1917 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1918 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1919 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1920 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1921 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1922 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1923 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1924 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1925 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1926 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1927 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1928 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1929 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1930 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1931 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1932 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1933 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1934 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1935 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1936 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
1937 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
1938 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
1939 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
1940 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
1941 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
1942 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1943 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1944 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1945 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1946 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
1947 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
1948 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
1949 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
1950 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1951 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1952 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1953 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
1954 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1955 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1956 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1957 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1958 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1959 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
1960 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1961 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
1962 FN_GLOBAL_INTEGER(_lp_disable_spoolss, &Globals.bDisableSpoolss)
1963 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
1964 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1965 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1966 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1967 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1968 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
1969 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1970 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1971 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
1972 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
1974 FN_LOCAL_STRING(lp_preexec, szPreExec)
1975 FN_LOCAL_STRING(lp_postexec, szPostExec)
1976 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
1977 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
1978 FN_LOCAL_STRING(lp_servicename, szService)
1979 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1980 FN_LOCAL_STRING(lp_pathname, szPath)
1981 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
1982 FN_LOCAL_STRING(lp_username, szUsername)
1983 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1984 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1985 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1986 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
1987 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
1988 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
1989 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
1990 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1991 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1992 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1993 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1994 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1995 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1996 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1997 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1998 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1999 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
2000 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
2001 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
2002 FN_LOCAL_STRING(lp_comment, comment)
2003 FN_LOCAL_STRING(lp_force_user, force_user)
2004 FN_LOCAL_STRING(lp_force_group, force_group)
2005 FN_LOCAL_LIST(lp_readlist, readlist)
2006 FN_LOCAL_LIST(lp_writelist, writelist)
2007 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
2008 FN_LOCAL_STRING(lp_fstype, fstype)
2009 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
2010 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
2011 static FN_LOCAL_STRING(lp_volume, volume)
2012 FN_LOCAL_PARM_STRING(lp_mangled_map, szMangledMap)
2013 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
2014 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
2015 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
2016 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
2017 FN_LOCAL_STRING(lp_dfree_command, szDfree)
2018 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
2019 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
2020 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
2021 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
2022 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
2023 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
2024 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
2025 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2026 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2027 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2028 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2029 FN_LOCAL_BOOL(lp_readonly, bRead_only)
2030 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2031 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2032 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2033 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2034 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2035 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2036 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2037 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2038 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
2039 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
2040 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
2041 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2042 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2043 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2044 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2045 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
2046 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2047 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2048 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2049 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2050 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2051 FN_LOCAL_BOOL(lp_map_system, bMap_system)
2052 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2053 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2054 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2055 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2056 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2057 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2058 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2059 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2060 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2061 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2062 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2063 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2064 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2065 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2066 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2067 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2068 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2069 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2070 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2071 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2072 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2073 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2074 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2075 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2076 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2077 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2078 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2079 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2080 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2081 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2082 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2083 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2084 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2085 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2086 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2087 FN_LOCAL_INTEGER(lp_printing, iPrinting)
2088 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2089 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2090 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2091 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2092 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2093 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2094 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2095 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2096 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2097 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2098 FN_LOCAL_CHAR(lp_magicchar, magic_char)
2099 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2100 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2101 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2102 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2103 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2104 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2106 /* local prototypes */
2108 static int map_parameter(const char *pszParmName);
2109 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
2110 static int getservicebyname(const char *pszServiceName,
2111 service * pserviceDest);
2112 static void copy_service(service * pserviceDest,
2113 service * pserviceSource, BOOL *pcopymapDest);
2114 static BOOL service_ok(int iService);
2115 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
2116 static BOOL do_section(const char *pszSectionName);
2117 static void init_copymap(service * pservice);
2118 static BOOL hash_a_service(const char *name, int number);
2119 static void free_service_byindex(int iService);
2120 static char * canonicalize_servicename(const char *name);
2122 /* This is a helper function for parametrical options support. */
2123 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2124 /* Actual parametrical functions are quite simple */
2125 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2127 BOOL global_section = False;
2129 param_opt_struct *data;
2131 if (snum >= iNumServices) return NULL;
2134 data = Globals.param_opt;
2135 global_section = True;
2137 data = ServicePtrs[snum]->param_opt;
2140 asprintf(¶m_key, "%s:%s", type, option);
2142 DEBUG(0,("asprintf failed!\n"));
2147 if (strcmp(data->key, param_key) == 0) {
2148 string_free(¶m_key);
2154 if (!global_section) {
2155 /* Try to fetch the same option but from globals */
2156 /* but only if we are not already working with Globals */
2157 data = Globals.param_opt;
2159 if (strcmp(data->key, param_key) == 0) {
2160 string_free(¶m_key);
2167 string_free(¶m_key);
2173 #define MISSING_PARAMETER(name) \
2174 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2176 /*******************************************************************
2177 convenience routine to return int parameters.
2178 ********************************************************************/
2179 static int lp_int(const char *s)
2183 MISSING_PARAMETER(lp_int);
2190 /*******************************************************************
2191 convenience routine to return unsigned long parameters.
2192 ********************************************************************/
2193 static unsigned long lp_ulong(const char *s)
2197 MISSING_PARAMETER(lp_ulong);
2201 return strtoul(s, NULL, 10);
2204 /*******************************************************************
2205 convenience routine to return boolean parameters.
2206 ********************************************************************/
2207 static BOOL lp_bool(const char *s)
2212 MISSING_PARAMETER(lp_bool);
2216 if (!set_boolean(&ret,s)) {
2217 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2224 /*******************************************************************
2225 convenience routine to return enum parameters.
2226 ********************************************************************/
2227 static int lp_enum(const char *s,const struct enum_list *_enum)
2231 if (!s || !*s || !_enum) {
2232 MISSING_PARAMETER(lp_enum);
2236 for (i=0; _enum[i].name; i++) {
2237 if (strequal(_enum[i].name,s))
2238 return _enum[i].value;
2241 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2245 #undef MISSING_PARAMETER
2247 /* DO NOT USE lp_parm_string ANYMORE!!!!
2248 * use lp_parm_const_string or lp_parm_talloc_string
2250 * lp_parm_string is only used to let old modules find this symbol
2252 #undef lp_parm_string
2253 char *lp_parm_string(const char *servicename, const char *type, const char *option);
2254 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2256 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2259 /* Return parametric option from a given service. Type is a part of option before ':' */
2260 /* Parametric option has following syntax: 'Type: option = value' */
2261 /* the returned value is talloced in lp_talloc */
2262 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2264 param_opt_struct *data = get_parametrics(snum, type, option);
2266 if (data == NULL||data->value==NULL) {
2268 return lp_string(def);
2274 return lp_string(data->value);
2277 /* Return parametric option from a given service. Type is a part of option before ':' */
2278 /* Parametric option has following syntax: 'Type: option = value' */
2279 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2281 param_opt_struct *data = get_parametrics(snum, type, option);
2283 if (data == NULL||data->value==NULL)
2289 /* Return parametric option from a given service. Type is a part of option before ':' */
2290 /* Parametric option has following syntax: 'Type: option = value' */
2292 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2294 param_opt_struct *data = get_parametrics(snum, type, option);
2296 if (data == NULL||data->value==NULL)
2297 return (const char **)def;
2299 if (data->list==NULL) {
2300 data->list = str_list_make(data->value, NULL);
2303 return (const char **)data->list;
2306 /* Return parametric option from a given service. Type is a part of option before ':' */
2307 /* Parametric option has following syntax: 'Type: option = value' */
2309 int lp_parm_int(int snum, const char *type, const char *option, int def)
2311 param_opt_struct *data = get_parametrics(snum, type, option);
2313 if (data && data->value && *data->value)
2314 return lp_int(data->value);
2319 /* Return parametric option from a given service. Type is a part of option before ':' */
2320 /* Parametric option has following syntax: 'Type: option = value' */
2322 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2324 param_opt_struct *data = get_parametrics(snum, type, option);
2326 if (data && data->value && *data->value)
2327 return lp_ulong(data->value);
2332 /* Return parametric option from a given service. Type is a part of option before ':' */
2333 /* Parametric option has following syntax: 'Type: option = value' */
2335 BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2337 param_opt_struct *data = get_parametrics(snum, type, option);
2339 if (data && data->value && *data->value)
2340 return lp_bool(data->value);
2345 /* Return parametric option from a given service. Type is a part of option before ':' */
2346 /* Parametric option has following syntax: 'Type: option = value' */
2348 int lp_parm_enum(int snum, const char *type, const char *option,
2349 const struct enum_list *_enum, int def)
2351 param_opt_struct *data = get_parametrics(snum, type, option);
2353 if (data && data->value && *data->value && _enum)
2354 return lp_enum(data->value, _enum);
2360 /***************************************************************************
2361 Initialise a service to the defaults.
2362 ***************************************************************************/
2364 static void init_service(service * pservice)
2366 memset((char *)pservice, '\0', sizeof(service));
2367 copy_service(pservice, &sDefault, NULL);
2370 /***************************************************************************
2371 Free the dynamically allocated parts of a service struct.
2372 ***************************************************************************/
2374 static void free_service(service *pservice)
2377 param_opt_struct *data, *pdata;
2381 if (pservice->szService)
2382 DEBUG(5, ("free_service: Freeing service %s\n",
2383 pservice->szService));
2385 string_free(&pservice->szService);
2386 SAFE_FREE(pservice->copymap);
2388 for (i = 0; parm_table[i].label; i++) {
2389 if ((parm_table[i].type == P_STRING ||
2390 parm_table[i].type == P_USTRING) &&
2391 parm_table[i].p_class == P_LOCAL)
2392 string_free((char **)
2393 (((char *)pservice) +
2394 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2395 else if (parm_table[i].type == P_LIST &&
2396 parm_table[i].p_class == P_LOCAL)
2397 str_list_free((char ***)
2398 (((char *)pservice) +
2399 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2402 data = pservice->param_opt;
2404 DEBUG(5,("Freeing parametrics:\n"));
2406 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2407 string_free(&data->key);
2408 string_free(&data->value);
2409 str_list_free(&data->list);
2415 ZERO_STRUCTP(pservice);
2419 /***************************************************************************
2420 remove a service indexed in the ServicePtrs array from the ServiceHash
2421 and free the dynamically allocated parts
2422 ***************************************************************************/
2424 static void free_service_byindex(int idx)
2426 if ( !LP_SNUM_OK(idx) )
2429 ServicePtrs[idx]->valid = False;
2430 invalid_services[num_invalid_services++] = idx;
2432 /* we have to cleanup the hash record */
2434 if (ServicePtrs[idx]->szService) {
2435 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2437 tdb_delete_bystring(ServiceHash, canon_name );
2440 free_service(ServicePtrs[idx]);
2443 /***************************************************************************
2444 Add a new service to the services array initialising it with the given
2446 ***************************************************************************/
2448 static int add_a_service(const service *pservice, const char *name)
2452 int num_to_alloc = iNumServices + 1;
2453 param_opt_struct *data, *pdata;
2455 tservice = *pservice;
2457 /* it might already exist */
2459 i = getservicebyname(name, NULL);
2461 /* Clean all parametric options for service */
2462 /* They will be added during parsing again */
2463 data = ServicePtrs[i]->param_opt;
2465 string_free(&data->key);
2466 string_free(&data->value);
2467 str_list_free(&data->list);
2472 ServicePtrs[i]->param_opt = NULL;
2477 /* find an invalid one */
2479 if (num_invalid_services > 0) {
2480 i = invalid_services[--num_invalid_services];
2483 /* if not, then create one */
2484 if (i == iNumServices) {
2488 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2490 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2494 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2495 if (!ServicePtrs[iNumServices]) {
2496 DEBUG(0,("add_a_service: out of memory!\n"));
2501 /* enlarge invalid_services here for now... */
2502 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2504 if (tinvalid == NULL) {
2505 DEBUG(0,("add_a_service: failed to enlarge "
2506 "invalid_services!\n"));
2509 invalid_services = tinvalid;
2511 free_service_byindex(i);
2514 ServicePtrs[i]->valid = True;
2516 init_service(ServicePtrs[i]);
2517 copy_service(ServicePtrs[i], &tservice, NULL);
2519 string_set(&ServicePtrs[i]->szService, name);
2521 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2522 i, ServicePtrs[i]->szService));
2524 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2531 /***************************************************************************
2532 Convert a string to uppercase and remove whitespaces.
2533 ***************************************************************************/
2535 static char *canonicalize_servicename(const char *src)
2537 static fstring canon; /* is fstring large enough? */
2540 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2544 fstrcpy( canon, src );
2545 strlower_m( canon );
2550 /***************************************************************************
2551 Add a name/index pair for the services array to the hash table.
2552 ***************************************************************************/
2554 static BOOL hash_a_service(const char *name, int idx)
2558 if ( !ServiceHash ) {
2559 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2560 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2561 (O_RDWR|O_CREAT), 0600);
2562 if ( !ServiceHash ) {
2563 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2568 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2571 if ( !(canon_name = canonicalize_servicename( name )) )
2574 tdb_store_int32(ServiceHash, canon_name, idx);
2579 /***************************************************************************
2580 Add a new home service, with the specified home directory, defaults coming
2582 ***************************************************************************/
2584 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
2585 const char *user, const char *pszHomedir)
2590 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2595 if (!(*(ServicePtrs[iDefaultService]->szPath))
2596 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2597 pstrcpy(newHomedir, pszHomedir);
2598 string_set(&ServicePtrs[i]->szPath, newHomedir);
2601 if (!(*(ServicePtrs[i]->comment))) {
2603 slprintf(comment, sizeof(comment) - 1,
2604 "Home directory of %s", user);
2605 string_set(&ServicePtrs[i]->comment, comment);
2608 /* set the browseable flag from the global default */
2610 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2612 ServicePtrs[i]->autoloaded = True;
2614 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2615 user, ServicePtrs[i]->szPath ));
2620 /***************************************************************************
2621 Add a new service, based on an old one.
2622 ***************************************************************************/
2624 int lp_add_service(const char *pszService, int iDefaultService)
2626 if (iDefaultService < 0) {
2627 return add_a_service(&sDefault, pszService);
2630 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2633 /***************************************************************************
2634 Add the IPC service.
2635 ***************************************************************************/
2637 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2640 int i = add_a_service(&sDefault, ipc_name);
2645 slprintf(comment, sizeof(comment) - 1,
2646 "IPC Service (%s)", Globals.szServerString);
2648 string_set(&ServicePtrs[i]->szPath, tmpdir());
2649 string_set(&ServicePtrs[i]->szUsername, "");
2650 string_set(&ServicePtrs[i]->comment, comment);
2651 string_set(&ServicePtrs[i]->fstype, "IPC");
2652 ServicePtrs[i]->iMaxConnections = 0;
2653 ServicePtrs[i]->bAvailable = True;
2654 ServicePtrs[i]->bRead_only = True;
2655 ServicePtrs[i]->bGuest_only = False;
2656 ServicePtrs[i]->bGuest_ok = guest_ok;
2657 ServicePtrs[i]->bPrint_ok = False;
2658 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2660 DEBUG(3, ("adding IPC service\n"));
2665 /***************************************************************************
2666 Add a new printer service, with defaults coming from service iFrom.
2667 ***************************************************************************/
2669 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2671 const char *comment = "From Printcap";
2672 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2677 /* note that we do NOT default the availability flag to True - */
2678 /* we take it from the default service passed. This allows all */
2679 /* dynamic printers to be disabled by disabling the [printers] */
2680 /* entry (if/when the 'available' keyword is implemented!). */
2682 /* the printer name is set to the service name. */
2683 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2684 string_set(&ServicePtrs[i]->comment, comment);
2686 /* set the browseable flag from the gloabl default */
2687 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2689 /* Printers cannot be read_only. */
2690 ServicePtrs[i]->bRead_only = False;
2691 /* No share modes on printer services. */
2692 ServicePtrs[i]->bShareModes = False;
2693 /* No oplocks on printer services. */
2694 ServicePtrs[i]->bOpLocks = False;
2695 /* Printer services must be printable. */
2696 ServicePtrs[i]->bPrint_ok = True;
2698 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2703 /***************************************************************************
2704 Map a parameter's string representation to something we can use.
2705 Returns False if the parameter string is not recognised, else TRUE.
2706 ***************************************************************************/
2708 static int map_parameter(const char *pszParmName)
2712 if (*pszParmName == '-')
2715 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2716 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2719 /* Warn only if it isn't parametric option */
2720 if (strchr(pszParmName, ':') == NULL)
2721 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2722 /* We do return 'fail' for parametric options as well because they are
2723 stored in different storage
2728 /***************************************************************************
2729 Show all parameter's name, type, [values,] and flags.
2730 ***************************************************************************/
2732 void show_parameter_list(void)
2734 int classIndex, parmIndex, enumIndex, flagIndex;
2736 const char *section_names[] = { "local", "global", NULL};
2737 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2738 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2739 "P_UGSTRING", "P_ENUM", "P_SEP"};
2740 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2741 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2742 FLAG_HIDE, FLAG_DOS_STRING};
2743 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2744 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2745 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2747 for ( classIndex=0; section_names[classIndex]; classIndex++) {
2748 printf("[%s]\n", section_names[classIndex]);
2749 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2750 if (parm_table[parmIndex].p_class == classIndex) {
2752 parm_table[parmIndex].label,
2753 type[parm_table[parmIndex].type]);
2754 switch (parm_table[parmIndex].type) {
2757 for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
2759 enumIndex ? "|" : "",
2760 parm_table[parmIndex].enum_list[enumIndex].name);
2767 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
2768 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2771 flag_names[flagIndex]);
2781 /***************************************************************************
2782 Set a boolean variable from the text value stored in the passed string.
2783 Returns True in success, False if the passed string does not correctly
2784 represent a boolean.
2785 ***************************************************************************/
2787 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2792 if (strwicmp(pszParmValue, "yes") == 0 ||
2793 strwicmp(pszParmValue, "true") == 0 ||
2794 strwicmp(pszParmValue, "1") == 0)
2796 else if (strwicmp(pszParmValue, "no") == 0 ||
2797 strwicmp(pszParmValue, "False") == 0 ||
2798 strwicmp(pszParmValue, "0") == 0)
2802 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2809 /***************************************************************************
2810 Find a service by name. Otherwise works like get_service.
2811 ***************************************************************************/
2813 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2818 if (ServiceHash != NULL) {
2819 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
2822 iService = tdb_fetch_int32(ServiceHash, canon_name );
2824 if (LP_SNUM_OK(iService)) {
2825 if (pserviceDest != NULL) {
2826 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2836 /***************************************************************************
2837 Copy a service structure to another.
2838 If pcopymapDest is NULL then copy all fields
2839 ***************************************************************************/
2841 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2844 BOOL bcopyall = (pcopymapDest == NULL);
2845 param_opt_struct *data, *pdata, *paramo;
2848 for (i = 0; parm_table[i].label; i++)
2849 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
2850 (bcopyall || pcopymapDest[i])) {
2851 void *def_ptr = parm_table[i].ptr;
2853 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2856 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2859 switch (parm_table[i].type) {
2862 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2868 *(int *)dest_ptr = *(int *)src_ptr;
2872 *(char *)dest_ptr = *(char *)src_ptr;
2876 string_set((char **)dest_ptr,
2881 string_set((char **)dest_ptr,
2883 strupper_m(*(char **)dest_ptr);
2886 str_list_free((char ***)dest_ptr);
2887 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2895 init_copymap(pserviceDest);
2896 if (pserviceSource->copymap)
2897 memcpy((void *)pserviceDest->copymap,
2898 (void *)pserviceSource->copymap,
2899 sizeof(BOOL) * NUMPARAMETERS);
2902 data = pserviceSource->param_opt;
2905 pdata = pserviceDest->param_opt;
2906 /* Traverse destination */
2908 /* If we already have same option, override it */
2909 if (strcmp(pdata->key, data->key) == 0) {
2910 string_free(&pdata->value);
2911 str_list_free(&data->list);
2912 pdata->value = SMB_STRDUP(data->value);
2916 pdata = pdata->next;
2919 paramo = SMB_XMALLOC_P(param_opt_struct);
2920 paramo->key = SMB_STRDUP(data->key);
2921 paramo->value = SMB_STRDUP(data->value);
2922 paramo->list = NULL;
2923 DLIST_ADD(pserviceDest->param_opt, paramo);
2929 /***************************************************************************
2930 Check a service for consistency. Return False if the service is in any way
2931 incomplete or faulty, else True.
2932 ***************************************************************************/
2934 static BOOL service_ok(int iService)
2939 if (ServicePtrs[iService]->szService[0] == '\0') {
2940 DEBUG(0, ("The following message indicates an internal error:\n"));
2941 DEBUG(0, ("No service name in service entry.\n"));
2945 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2946 /* I can't see why you'd want a non-printable printer service... */
2947 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2948 if (!ServicePtrs[iService]->bPrint_ok) {
2949 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2950 ServicePtrs[iService]->szService));
2951 ServicePtrs[iService]->bPrint_ok = True;
2953 /* [printers] service must also be non-browsable. */
2954 if (ServicePtrs[iService]->bBrowseable)
2955 ServicePtrs[iService]->bBrowseable = False;
2958 if (ServicePtrs[iService]->szPath[0] == '\0' &&
2959 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2960 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
2962 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2963 ServicePtrs[iService]->szService));
2964 ServicePtrs[iService]->bAvailable = False;
2967 /* If a service is flagged unavailable, log the fact at level 0. */
2968 if (!ServicePtrs[iService]->bAvailable)
2969 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2970 ServicePtrs[iService]->szService));
2975 static struct file_lists {
2976 struct file_lists *next;
2980 } *file_lists = NULL;
2982 /*******************************************************************
2983 Keep a linked list of all config files so we know when one has changed
2984 it's date and needs to be reloaded.
2985 ********************************************************************/
2987 static void add_to_file_list(const char *fname, const char *subfname)
2989 struct file_lists *f = file_lists;
2992 if (f->name && !strcmp(f->name, fname))
2998 f = SMB_MALLOC_P(struct file_lists);
3001 f->next = file_lists;
3002 f->name = SMB_STRDUP(fname);
3007 f->subfname = SMB_STRDUP(subfname);
3013 f->modtime = file_modtime(subfname);
3015 time_t t = file_modtime(subfname);
3021 /*******************************************************************
3022 Check if a config file has changed date.
3023 ********************************************************************/
3025 BOOL lp_file_list_changed(void)
3027 struct file_lists *f = file_lists;
3029 DEBUG(6, ("lp_file_list_changed()\n"));
3035 pstrcpy(n2, f->name);
3036 standard_sub_basic( get_current_username(),
3037 current_user_info.domain,
3040 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3041 f->name, n2, ctime(&f->modtime)));
3043 mod_time = file_modtime(n2);
3045 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3047 ("file %s modified: %s\n", n2,
3049 f->modtime = mod_time;
3050 SAFE_FREE(f->subfname);
3051 f->subfname = SMB_STRDUP(n2);
3059 /***************************************************************************
3060 Run standard_sub_basic on netbios name... needed because global_myname
3061 is not accessed through any lp_ macro.
3062 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3063 ***************************************************************************/
3065 static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3068 pstring netbios_name;
3070 pstrcpy(netbios_name, pszParmValue);
3072 standard_sub_basic(get_current_username(), current_user_info.domain,
3073 netbios_name, sizeof(netbios_name));
3075 ret = set_global_myname(netbios_name);
3076 string_set(&Globals.szNetbiosName,global_myname());
3078 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3084 static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
3086 if (strcmp(*ptr, pszParmValue) != 0) {
3087 string_set(ptr, pszParmValue);
3095 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3099 ret = set_global_myworkgroup(pszParmValue);
3100 string_set(&Globals.szWorkgroup,lp_workgroup());
3105 static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3109 ret = set_global_scope(pszParmValue);
3110 string_set(&Globals.szNetbiosScope,global_scope());
3115 static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3117 str_list_free(&Globals.szNetbiosAliases);
3118 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3119 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3122 /***************************************************************************
3123 Handle the include operation.
3124 ***************************************************************************/
3126 static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
3129 pstrcpy(fname, pszParmValue);
3131 standard_sub_basic(get_current_username(), current_user_info.domain,
3132 fname,sizeof(fname));
3134 add_to_file_list(pszParmValue, fname);
3136 string_set(ptr, fname);
3138 if (file_exist(fname, NULL))
3139 return (pm_process(fname, do_section, do_parameter));
3141 DEBUG(2, ("Can't find include file %s\n", fname));
3146 /***************************************************************************
3147 Handle the interpretation of the copy parameter.
3148 ***************************************************************************/
3150 static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
3154 service serviceTemp;
3156 string_set(ptr, pszParmValue);
3158 init_service(&serviceTemp);
3162 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3164 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3165 if (iTemp == iServiceIndex) {
3166 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3168 copy_service(ServicePtrs[iServiceIndex],
3170 ServicePtrs[iServiceIndex]->copymap);
3174 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3178 free_service(&serviceTemp);
3182 /***************************************************************************
3183 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3188 idmap uid = 1000-1999
3191 We only do simple parsing checks here. The strings are parsed into useful
3192 structures in the idmap daemon code.
3194 ***************************************************************************/
3196 /* Some lp_ routines to return idmap [ug]id information */
3198 static uid_t idmap_uid_low, idmap_uid_high;
3199 static gid_t idmap_gid_low, idmap_gid_high;
3201 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
3203 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3207 *low = idmap_uid_low;
3210 *high = idmap_uid_high;
3215 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
3217 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3221 *low = idmap_gid_low;
3224 *high = idmap_gid_high;
3229 /* Do some simple checks on "idmap [ug]id" parameter values */
3231 static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3235 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3240 string_set(ptr, pszParmValue);
3242 idmap_uid_low = low;
3243 idmap_uid_high = high;
3248 static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3252 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3257 string_set(ptr, pszParmValue);
3259 idmap_gid_low = low;
3260 idmap_gid_high = high;
3265 /***************************************************************************
3266 Handle the DEBUG level list.
3267 ***************************************************************************/
3269 static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3271 pstring pszParmValue;
3273 pstrcpy(pszParmValue, pszParmValueIn);
3274 string_set(ptr, pszParmValueIn);
3275 return debug_parse_levels( pszParmValue );
3278 /***************************************************************************
3279 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3280 ***************************************************************************/
3282 static const char *append_ldap_suffix( const char *str )
3284 const char *suffix_string;
3288 lp_talloc = talloc_init("lp_talloc");
3290 suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
3291 if ( !suffix_string ) {
3292 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3296 return suffix_string;
3299 const char *lp_ldap_machine_suffix(void)
3301 if (Globals.szLdapMachineSuffix[0])
3302 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3304 return lp_string(Globals.szLdapSuffix);
3307 const char *lp_ldap_user_suffix(void)
3309 if (Globals.szLdapUserSuffix[0])
3310 return append_ldap_suffix(Globals.szLdapUserSuffix);
3312 return lp_string(Globals.szLdapSuffix);
3315 const char *lp_ldap_group_suffix(void)
3317 if (Globals.szLdapGroupSuffix[0])
3318 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3320 return lp_string(Globals.szLdapSuffix);
3323 const char *lp_ldap_idmap_suffix(void)
3325 if (Globals.szLdapIdmapSuffix[0])
3326 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3328 return lp_string(Globals.szLdapSuffix);
3331 /****************************************************************************
3332 set the value for a P_ENUM
3333 ***************************************************************************/
3335 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3340 for (i = 0; parm->enum_list[i].name; i++) {
3341 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3342 *ptr = parm->enum_list[i].value;
3348 /***************************************************************************
3349 ***************************************************************************/
3351 static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3353 static int parm_num = -1;
3356 if ( parm_num == -1 )
3357 parm_num = map_parameter( "printing" );
3359 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3364 s = ServicePtrs[snum];
3366 init_printer_values( s );
3372 /***************************************************************************
3373 Initialise a copymap.
3374 ***************************************************************************/
3376 static void init_copymap(service * pservice)
3379 SAFE_FREE(pservice->copymap);
3380 pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3381 if (!pservice->copymap)
3383 ("Couldn't allocate copymap!! (size %d)\n",
3384 (int)NUMPARAMETERS));
3386 for (i = 0; i < NUMPARAMETERS; i++)
3387 pservice->copymap[i] = True;
3390 /***************************************************************************
3391 Return the local pointer to a parameter given the service number and the
3392 pointer into the default structure.
3393 ***************************************************************************/
3395 void *lp_local_ptr(int snum, void *ptr)
3397 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3400 /***************************************************************************
3401 Process a parameter for a particular service number. If snum < 0
3402 then assume we are in the globals.
3403 ***************************************************************************/
3405 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3407 int parmnum, i, slen;
3408 void *parm_ptr = NULL; /* where we are going to store the result */
3409 void *def_ptr = NULL;
3412 param_opt_struct *paramo, *data;
3415 parmnum = map_parameter(pszParmName);
3418 if ((sep=strchr(pszParmName, ':')) != NULL) {
3420 ZERO_STRUCT(param_key);
3421 pstr_sprintf(param_key, "%s:", pszParmName);
3422 slen = strlen(param_key);
3423 pstrcat(param_key, sep+1);
3424 trim_char(param_key+slen, ' ', ' ');
3426 data = (snum < 0) ? Globals.param_opt :
3427 ServicePtrs[snum]->param_opt;
3428 /* Traverse destination */
3430 /* If we already have same option, override it */
3431 if (strcmp(data->key, param_key) == 0) {
3432 string_free(&data->value);
3433 str_list_free(&data->list);
3434 data->value = SMB_STRDUP(pszParmValue);
3441 paramo = SMB_XMALLOC_P(param_opt_struct);
3442 paramo->key = SMB_STRDUP(param_key);
3443 paramo->value = SMB_STRDUP(pszParmValue);
3444 paramo->list = NULL;
3446 DLIST_ADD(Globals.param_opt, paramo);
3448 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3455 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3459 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3460 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3464 def_ptr = parm_table[parmnum].ptr;
3466 /* we might point at a service, the default service or a global */
3470 if (parm_table[parmnum].p_class == P_GLOBAL) {
3472 ("Global parameter %s found in service section!\n",
3477 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3482 if (!ServicePtrs[snum]->copymap)
3483 init_copymap(ServicePtrs[snum]);
3485 /* this handles the aliases - set the copymap for other entries with
3486 the same data pointer */
3487 for (i = 0; parm_table[i].label; i++)
3488 if (parm_table[i].ptr == parm_table[parmnum].ptr)
3489 ServicePtrs[snum]->copymap[i] = False;
3492 /* if it is a special case then go ahead */
3493 if (parm_table[parmnum].special) {
3494 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3498 /* now switch on the type of variable it is */
3499 switch (parm_table[parmnum].type)
3502 *(BOOL *)parm_ptr = lp_bool(pszParmValue);
3506 *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
3510 *(int *)parm_ptr = lp_int(pszParmValue);
3514 *(char *)parm_ptr = *pszParmValue;
3518 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3520 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3525 str_list_free((char ***)parm_ptr);
3526 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3530 string_set((char **)parm_ptr, pszParmValue);
3534 string_set((char **)parm_ptr, pszParmValue);
3535 strupper_m(*(char **)parm_ptr);
3539 pstrcpy((char *)parm_ptr, pszParmValue);
3543 pstrcpy((char *)parm_ptr, pszParmValue);
3544 strupper_m((char *)parm_ptr);
3548 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3557 /***************************************************************************
3558 Process a parameter.
3559 ***************************************************************************/
3561 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3563 if (!bInGlobalSection && bGlobalOnly)
3566 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3568 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3569 pszParmName, pszParmValue));
3572 /***************************************************************************
3573 Print a parameter of the specified type.
3574 ***************************************************************************/
3576 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3582 for (i = 0; p->enum_list[i].name; i++) {
3583 if (*(int *)ptr == p->enum_list[i].value) {
3585 p->enum_list[i].name);
3592 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3596 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3600 fprintf(f, "%d", *(int *)ptr);
3604 fprintf(f, "%c", *(char *)ptr);
3608 fprintf(f, "%s", octal_string(*(int *)ptr));
3612 if ((char ***)ptr && *(char ***)ptr) {
3613 char **list = *(char ***)ptr;
3615 for (; *list; list++) {
3616 /* surround strings with whitespace in double quotes */
3617 if ( strchr_m( *list, ' ' ) )
3618 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3620 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3628 fprintf(f, "%s", (char *)ptr);
3634 if (*(char **)ptr) {
3635 fprintf(f, "%s", *(char **)ptr);
3643 /***************************************************************************
3644 Check if two parameters are equal.
3645 ***************************************************************************/
3647 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3652 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3657 return (*((int *)ptr1) == *((int *)ptr2));
3660 return (*((char *)ptr1) == *((char *)ptr2));
3663 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3668 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3673 return (p1 == p2 || strequal(p1, p2));
3678 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3683 return (p1 == p2 || strequal(p1, p2));
3691 /***************************************************************************
3692 Initialize any local varients in the sDefault table.
3693 ***************************************************************************/
3695 void init_locals(void)
3700 /***************************************************************************
3701 Process a new section (service). At this stage all sections are services.
3702 Later we'll have special sections that permit server parameters to be set.
3703 Returns True on success, False on failure.
3704 ***************************************************************************/
3706 static BOOL do_section(const char *pszSectionName)
3709 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3710 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3713 /* if we were in a global section then do the local inits */
3714 if (bInGlobalSection && !isglobal)
3717 /* if we've just struck a global section, note the fact. */
3718 bInGlobalSection = isglobal;
3720 /* check for multiple global sections */
3721 if (bInGlobalSection) {
3722 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3726 if (!bInGlobalSection && bGlobalOnly)
3729 /* if we have a current service, tidy it up before moving on */
3732 if (iServiceIndex >= 0)
3733 bRetval = service_ok(iServiceIndex);
3735 /* if all is still well, move to the next record in the services array */
3737 /* We put this here to avoid an odd message order if messages are */
3738 /* issued by the post-processing of a previous section. */
3739 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3741 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3743 DEBUG(0, ("Failed to add a new service\n"));
3752 /***************************************************************************
3753 Determine if a partcular base parameter is currentl set to the default value.
3754 ***************************************************************************/
3756 static BOOL is_default(int i)
3758 if (!defaults_saved)
3760 switch (parm_table[i].type) {
3762 return str_list_compare (parm_table[i].def.lvalue,
3763 *(char ***)parm_table[i].ptr);
3766 return strequal(parm_table[i].def.svalue,
3767 *(char **)parm_table[i].ptr);
3770 return strequal(parm_table[i].def.svalue,
3771 (char *)parm_table[i].ptr);
3774 return parm_table[i].def.bvalue ==
3775 *(BOOL *)parm_table[i].ptr;
3777 return parm_table[i].def.cvalue ==
3778 *(char *)parm_table[i].ptr;
3782 return parm_table[i].def.ivalue ==
3783 *(int *)parm_table[i].ptr;
3790 /***************************************************************************
3791 Display the contents of the global structure.
3792 ***************************************************************************/
3794 static void dump_globals(FILE *f)
3797 param_opt_struct *data;
3799 fprintf(f, "[global]\n");
3801 for (i = 0; parm_table[i].label; i++)
3802 if (parm_table[i].p_class == P_GLOBAL &&
3803 parm_table[i].ptr &&
3804 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3805 if (defaults_saved && is_default(i))
3807 fprintf(f, "\t%s = ", parm_table[i].label);
3808 print_parameter(&parm_table[i], parm_table[i].ptr, f);
3811 if (Globals.param_opt != NULL) {
3812 data = Globals.param_opt;
3814 fprintf(f, "\t%s = %s\n", data->key, data->value);
3821 /***************************************************************************
3822 Return True if a local parameter is currently set to the global default.
3823 ***************************************************************************/
3825 BOOL lp_is_default(int snum, struct parm_struct *parm)
3827 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3829 return equal_parameter(parm->type,
3830 ((char *)ServicePtrs[snum]) + pdiff,
3831 ((char *)&sDefault) + pdiff);
3834 /***************************************************************************
3835 Display the contents of a single services record.
3836 ***************************************************************************/
3838 static void dump_a_service(service * pService, FILE * f)
3841 param_opt_struct *data;
3843 if (pService != &sDefault)
3844 fprintf(f, "[%s]\n", pService->szService);
3846 for (i = 0; parm_table[i].label; i++) {
3848 if (parm_table[i].p_class == P_LOCAL &&
3849 parm_table[i].ptr &&
3850 (*parm_table[i].label != '-') &&
3851 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3854 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3856 if (pService == &sDefault) {
3857 if (defaults_saved && is_default(i))
3860 if (equal_parameter(parm_table[i].type,
3861 ((char *)pService) +
3863 ((char *)&sDefault) +
3868 fprintf(f, "\t%s = ", parm_table[i].label);
3869 print_parameter(&parm_table[i],
3870 ((char *)pService) + pdiff, f);
3875 if (pService->param_opt != NULL) {
3876 data = pService->param_opt;
3878 fprintf(f, "\t%s = %s\n", data->key, data->value);
3884 /***************************************************************************
3885 Display the contents of a parameter of a single services record.
3886 ***************************************************************************/
3888 BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
3891 BOOL result = False;
3894 fstring local_parm_name;
3896 const char *parm_opt_value;
3898 /* check for parametrical option */
3899 fstrcpy( local_parm_name, parm_name);
3900 parm_opt = strchr( local_parm_name, ':');
3905 if (strlen(parm_opt)) {
3906 parm_opt_value = lp_parm_const_string( snum,
3907 local_parm_name, parm_opt, NULL);
3908 if (parm_opt_value) {
3909 printf( "%s\n", parm_opt_value);
3916 /* check for a key and print the value */
3923 for (i = 0; parm_table[i].label; i++) {
3924 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
3925 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
3926 parm_table[i].ptr &&
3927 (*parm_table[i].label != '-') &&
3928 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3933 ptr = parm_table[i].ptr;
3935 service * pService = ServicePtrs[snum];
3936 ptr = ((char *)pService) +
3937 PTR_DIFF(parm_table[i].ptr, &sDefault);
3940 print_parameter(&parm_table[i],
3951 /***************************************************************************
3952 Return info about the next service in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
3953 Return NULL when out of parameters.
3954 ***************************************************************************/
3956 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3959 /* do the globals */
3960 for (; parm_table[*i].label; (*i)++) {
3961 if (parm_table[*i].p_class == P_SEPARATOR)
3962 return &parm_table[(*i)++];
3964 if (!parm_table[*i].ptr
3965 || (*parm_table[*i].label == '-'))
3969 && (parm_table[*i].ptr ==
3970 parm_table[(*i) - 1].ptr))
3973 return &parm_table[(*i)++];
3976 service *pService = ServicePtrs[snum];
3978 for (; parm_table[*i].label; (*i)++) {
3979 if (parm_table[*i].p_class == P_SEPARATOR)
3980 return &parm_table[(*i)++];
3982 if (parm_table[*i].p_class == P_LOCAL &&
3983 parm_table[*i].ptr &&
3984 (*parm_table[*i].label != '-') &&
3986 (parm_table[*i].ptr !=
3987 parm_table[(*i) - 1].ptr)))
3990 PTR_DIFF(parm_table[*i].ptr,
3993 if (allparameters ||
3994 !equal_parameter(parm_table[*i].type,
3995 ((char *)pService) +
3997 ((char *)&sDefault) +
4000 return &parm_table[(*i)++];
4011 /***************************************************************************
4012 Display the contents of a single copy structure.
4013 ***************************************************************************/
4014 static void dump_copy_map(BOOL *pcopymap)
4020 printf("\n\tNon-Copied parameters:\n");
4022 for (i = 0; parm_table[i].label; i++)
4023 if (parm_table[i].p_class == P_LOCAL &&
4024 parm_table[i].ptr && !pcopymap[i] &&
4025 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4027 printf("\t\t%s\n", parm_table[i].label);
4032 /***************************************************************************
4033 Return TRUE if the passed service number is within range.
4034 ***************************************************************************/
4036 BOOL lp_snum_ok(int iService)
4038 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4041 /***************************************************************************
4042 Auto-load some home services.
4043 ***************************************************************************/
4045 static void lp_add_auto_services(char *str)
4054 s = SMB_STRDUP(str);
4058 homes = lp_servicenumber(HOMES_NAME);
4060 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4061 char *home = get_user_home_dir(p);
4063 if (lp_servicenumber(p) >= 0)
4066 if (home && homes >= 0)
4067 lp_add_home(p, homes, p, home);
4072 /***************************************************************************
4073 Auto-load one printer.
4074 ***************************************************************************/
4076 void lp_add_one_printer(char *name, char *comment)
4078 int printers = lp_servicenumber(PRINTERS_NAME);
4081 if (lp_servicenumber(name) < 0) {
4082 lp_add_printer(name, printers);
4083 if ((i = lp_servicenumber(name)) >= 0) {
4084 string_set(&ServicePtrs[i]->comment, comment);
4085 ServicePtrs[i]->autoloaded = True;
4090 /***************************************************************************
4091 Have we loaded a services file yet?
4092 ***************************************************************************/
4094 BOOL lp_loaded(void)
4099 /***************************************************************************
4100 Unload unused services.
4101 ***************************************************************************/
4103 void lp_killunused(BOOL (*snumused) (int))
4106 for (i = 0; i < iNumServices; i++) {
4110 /* don't kill autoloaded or usershare services */
4111 if ( ServicePtrs[i]->autoloaded ||
4112 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4116 if (!snumused || !snumused(i)) {
4117 free_service_byindex(i);
4122 /***************************************************************************
4124 ***************************************************************************/
4126 void lp_killservice(int iServiceIn)
4128 if (VALID(iServiceIn)) {
4129 free_service_byindex(iServiceIn);
4133 /***************************************************************************
4134 Save the curent values of all global and sDefault parameters into the
4135 defaults union. This allows swat and testparm to show only the
4136 changed (ie. non-default) parameters.
4137 ***************************************************************************/
4139 static void lp_save_defaults(void)
4142 for (i = 0; parm_table[i].label; i++) {
4143 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4145 switch (parm_table[i].type) {
4147 str_list_copy(&(parm_table[i].def.lvalue),
4148 *(const char ***)parm_table[i].ptr);
4152 if (parm_table[i].ptr) {
4153 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4155 parm_table[i].def.svalue = NULL;
4160 if (parm_table[i].ptr) {
4161 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4163 parm_table[i].def.svalue = NULL;
4168 parm_table[i].def.bvalue =
4169 *(BOOL *)parm_table[i].ptr;
4172 parm_table[i].def.cvalue =
4173 *(char *)parm_table[i].ptr;
4178 parm_table[i].def.ivalue =
4179 *(int *)parm_table[i].ptr;
4185 defaults_saved = True;
4188 /*******************************************************************
4189 Set the server type we will announce as via nmbd.
4190 ********************************************************************/
4192 static const struct srv_role_tab {
4194 const char *role_str;
4195 } srv_role_tab [] = {
4196 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4197 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4198 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4199 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4203 const char* server_role_str(uint32 role)
4206 for (i=0; srv_role_tab[i].role_str; i++) {
4207 if (role == srv_role_tab[i].role) {
4208 return srv_role_tab[i].role_str;
4214 static void set_server_role(void)
4216 server_role = ROLE_STANDALONE;
4218 switch (lp_security()) {
4220 if (lp_domain_logons())
4221 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4224 if (lp_domain_logons())
4225 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4226 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
4227 server_role = ROLE_STANDALONE;
4230 if (lp_domain_logons()) {
4231 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4232 server_role = ROLE_DOMAIN_BDC;
4235 server_role = ROLE_DOMAIN_MEMBER;
4238 if (lp_domain_logons()) {
4239 server_role = ROLE_DOMAIN_PDC;
4242 server_role = ROLE_DOMAIN_MEMBER;
4245 if (lp_domain_logons()) {
4247 if (Globals.bDomainMaster) /* auto or yes */
4248 server_role = ROLE_DOMAIN_PDC;
4250 server_role = ROLE_DOMAIN_BDC;
4254 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4258 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4261 /***********************************************************
4262 If we should send plaintext/LANMAN passwords in the clinet
4263 ************************************************************/
4265 static void set_allowed_client_auth(void)
4267 if (Globals.bClientNTLMv2Auth) {
4268 Globals.bClientLanManAuth = False;
4270 if (!Globals.bClientLanManAuth) {
4271 Globals.bClientPlaintextAuth = False;
4275 /***************************************************************************
4277 The following code allows smbd to read a user defined share file.
4278 Yes, this is my intent. Yes, I'm comfortable with that...
4280 THE FOLLOWING IS SECURITY CRITICAL CODE.
4282 It washes your clothes, it cleans your house, it guards you while you sleep...
4283 Do not f%^k with it....
4284 ***************************************************************************/
4286 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4288 /***************************************************************************
4289 Check allowed stat state of a usershare file.
4290 Ensure we print out who is dicking with us so the admin can
4291 get their sorry ass fired.
4292 ***************************************************************************/
4294 static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4296 if (!S_ISREG(psbuf->st_mode)) {
4297 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4298 "not a regular file\n",
4299 fname, (unsigned int)psbuf->st_uid ));
4303 /* Ensure this doesn't have the other write bit set. */
4304 if (psbuf->st_mode & S_IWOTH) {
4305 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4306 "public write. Refusing to allow as a usershare file.\n",
4307 fname, (unsigned int)psbuf->st_uid ));
4311 /* Should be 10k or less. */
4312 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4313 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4314 "too large (%u) to be a user share file.\n",
4315 fname, (unsigned int)psbuf->st_uid,
4316 (unsigned int)psbuf->st_size ));
4323 /***************************************************************************
4324 Parse the contents of a usershare file.
4325 ***************************************************************************/
4327 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4328 SMB_STRUCT_STAT *psbuf,
4329 const char *servicename,
4338 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4339 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4342 SMB_STRUCT_STAT sbuf;
4344 *pallow_guest = False;
4347 return USERSHARE_MALFORMED_FILE;
4350 if (strcmp(lines[0], "#VERSION 1") == 0) {
4352 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4355 return USERSHARE_MALFORMED_FILE;
4358 return USERSHARE_BAD_VERSION;
4361 if (strncmp(lines[1], "path=", 5) != 0) {
4362 return USERSHARE_MALFORMED_PATH;
4365 pstrcpy(sharepath, &lines[1][5]);
4366 trim_string(sharepath, " ", " ");
4368 if (strncmp(lines[2], "comment=", 8) != 0) {
4369 return USERSHARE_MALFORMED_COMMENT_DEF;
4372 pstrcpy(comment, &lines[2][8]);
4373 trim_string(comment, " ", " ");
4374 trim_char(comment, '"', '"');
4376 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4377 return USERSHARE_MALFORMED_ACL_DEF;
4380 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4381 return USERSHARE_ACL_ERR;
4385 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4386 return USERSHARE_MALFORMED_ACL_DEF;
4388 if (lines[4][9] == 'y') {
4389 *pallow_guest = True;
4393 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4394 /* Path didn't change, no checks needed. */
4395 return USERSHARE_OK;
4398 /* The path *must* be absolute. */
4399 if (sharepath[0] != '/') {
4400 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4401 servicename, sharepath));
4402 return USERSHARE_PATH_NOT_ABSOLUTE;
4405 /* If there is a usershare prefix deny list ensure one of these paths
4406 doesn't match the start of the user given path. */
4407 if (prefixdenylist) {
4409 for ( i=0; prefixdenylist[i]; i++ ) {
4410 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4411 servicename, i, prefixdenylist[i], sharepath ));
4412 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4413 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4414 "usershare prefix deny list entries.\n",
4415 servicename, sharepath));
4416 return USERSHARE_PATH_IS_DENIED;
4421 /* If there is a usershare prefix allow list ensure one of these paths
4422 does match the start of the user given path. */
4424 if (prefixallowlist) {
4426 for ( i=0; prefixallowlist[i]; i++ ) {
4427 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4428 servicename, i, prefixallowlist[i], sharepath ));
4429 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4433 if (prefixallowlist[i] == NULL) {
4434 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4435 "usershare prefix allow list entries.\n",
4436 servicename, sharepath));
4437 return USERSHARE_PATH_NOT_ALLOWED;
4441 /* Ensure this is pointing to a directory. */
4442 dp = sys_opendir(sharepath);
4445 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4446 servicename, sharepath));
4447 return USERSHARE_PATH_NOT_DIRECTORY;
4450 /* Ensure the owner of the usershare file has permission to share
4453 if (sys_stat(sharepath, &sbuf) == -1) {
4454 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4455 servicename, sharepath, strerror(errno) ));
4457 return USERSHARE_POSIX_ERR;
4462 if (!S_ISDIR(sbuf.st_mode)) {
4463 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4464 servicename, sharepath ));
4465 return USERSHARE_PATH_NOT_DIRECTORY;
4468 /* Check if sharing is restricted to owner-only. */
4469 /* psbuf is the stat of the usershare definition file,
4470 sbuf is the stat of the target directory to be shared. */
4472 if (lp_usershare_owner_only()) {
4473 /* root can share anything. */
4474 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
4475 return USERSHARE_PATH_NOT_ALLOWED;
4479 return USERSHARE_OK;
4482 /***************************************************************************
4483 Deal with a usershare file.
4486 -1 - Bad name, invalid contents.
4487 - service name already existed and not a usershare, problem
4488 with permissions to share directory etc.
4489 ***************************************************************************/
4491 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4493 SMB_STRUCT_STAT sbuf;
4494 SMB_STRUCT_STAT lsbuf;
4498 fstring service_name;
4499 char **lines = NULL;
4503 TALLOC_CTX *ctx = NULL;
4504 SEC_DESC *psd = NULL;
4505 BOOL guest_ok = False;
4507 /* Ensure share name doesn't contain invalid characters. */
4508 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4509 DEBUG(0,("process_usershare_file: share name %s contains "
4510 "invalid characters (any of %s)\n",
4511 file_name, INVALID_SHARENAME_CHARS ));
4515 fstrcpy(service_name, file_name);
4517 pstrcpy(fname, dir_name);
4518 pstrcat(fname, "/");
4519 pstrcat(fname, file_name);
4521 /* Minimize the race condition by doing an lstat before we
4522 open and fstat. Ensure this isn't a symlink link. */
4524 if (sys_lstat(fname, &lsbuf) != 0) {
4525 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4526 fname, strerror(errno) ));
4530 /* This must be a regular file, not a symlink, directory or
4531 other strange filetype. */
4532 if (!check_usershare_stat(fname, &lsbuf)) {
4536 /* See if there is already a servicenum for this name. */
4537 /* tdb_fetch_int32 returns -1 if not found. */
4538 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
4540 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
4541 /* Nothing changed - Mark valid and return. */
4542 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4544 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4548 /* Try and open the file read only - no symlinks allowed. */
4550 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
4552 fd = sys_open(fname, O_RDONLY, 0);
4556 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4557 fname, strerror(errno) ));
4561 /* Now fstat to be *SURE* it's a regular file. */
4562 if (sys_fstat(fd, &sbuf) != 0) {
4564 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4565 fname, strerror(errno) ));
4569 /* Is it the same dev/inode as was lstated ? */
4570 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
4572 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4573 "Symlink spoofing going on ?\n", fname ));
4577 /* This must be a regular file, not a symlink, directory or
4578 other strange filetype. */
4579 if (!check_usershare_stat(fname, &sbuf)) {
4583 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
4586 if (lines == NULL) {
4587 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4588 fname, (unsigned int)sbuf.st_uid ));
4592 /* Should we allow printers to be shared... ? */
4593 ctx = talloc_init("usershare_sd_xctx");
4595 file_lines_free(lines);
4599 if (parse_usershare_file(ctx, &sbuf, service_name,
4600 iService, lines, numlines, sharepath,
4601 comment, &psd, &guest_ok) != USERSHARE_OK) {
4602 talloc_destroy(ctx);
4603 file_lines_free(lines);
4607 file_lines_free(lines);
4609 /* Everything ok - add the service possibly using a template. */
4611 const service *sp = &sDefault;
4612 if (snum_template != -1) {
4613 sp = ServicePtrs[snum_template];
4616 if ((iService = add_a_service(sp, service_name)) < 0) {
4617 DEBUG(0, ("process_usershare_file: Failed to add "
4618 "new service %s\n", service_name));
4619 talloc_destroy(ctx);
4623 /* Read only is controlled by usershare ACL below. */
4624 ServicePtrs[iService]->bRead_only = False;
4627 /* Write the ACL of the new/modified share. */
4628 if (!set_share_security(service_name, psd)) {
4629 DEBUG(0, ("process_usershare_file: Failed to set share "
4630 "security for user share %s\n",
4632 lp_remove_service(iService);
4633 talloc_destroy(ctx);
4637 talloc_destroy(ctx);
4639 /* If from a template it may be marked invalid. */
4640 ServicePtrs[iService]->valid = True;
4642 /* Set the service as a valid usershare. */
4643 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4645 /* Set guest access. */
4646 if (lp_usershare_allow_guests()) {
4647 ServicePtrs[iService]->bGuest_ok = guest_ok;
4650 /* And note when it was loaded. */
4651 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
4652 string_set(&ServicePtrs[iService]->szPath, sharepath);
4653 string_set(&ServicePtrs[iService]->comment, comment);
4658 /***************************************************************************
4659 Checks if a usershare entry has been modified since last load.
4660 ***************************************************************************/
4662 static BOOL usershare_exists(int iService, time_t *last_mod)
4664 SMB_STRUCT_STAT lsbuf;
4665 const char *usersharepath = Globals.szUsersharePath;
4668 pstrcpy(fname, usersharepath);
4669 pstrcat(fname, "/");
4670 pstrcat(fname, ServicePtrs[iService]->szService);
4672 if (sys_lstat(fname, &lsbuf) != 0) {
4676 if (!S_ISREG(lsbuf.st_mode)) {
4680 *last_mod = lsbuf.st_mtime;
4684 /***************************************************************************
4685 Load a usershare service by name. Returns a valid servicenumber or -1.
4686 ***************************************************************************/
4688 int load_usershare_service(const char *servicename)
4690 SMB_STRUCT_STAT sbuf;
4691 const char *usersharepath = Globals.szUsersharePath;
4692 int max_user_shares = Globals.iUsershareMaxShares;
4693 int snum_template = -1;
4695 if (*usersharepath == 0 || max_user_shares == 0) {
4699 if (sys_stat(usersharepath, &sbuf) != 0) {
4700 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4701 usersharepath, strerror(errno) ));
4705 if (!S_ISDIR(sbuf.st_mode)) {
4706 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4712 * This directory must be owned by root, and have the 't' bit set.
4713 * It also must not be writable by "other".
4717 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4719 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4721 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4722 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4727 /* Ensure the template share exists if it's set. */
4728 if (Globals.szUsershareTemplateShare[0]) {
4729 /* We can't use lp_servicenumber here as we are recommending that
4730 template shares have -valid=False set. */
4731 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4732 if (ServicePtrs[snum_template]->szService &&
4733 strequal(ServicePtrs[snum_template]->szService,
4734 Globals.szUsershareTemplateShare)) {
4739 if (snum_template == -1) {
4740 DEBUG(0,("load_usershare_service: usershare template share %s "
4741 "does not exist.\n",
4742 Globals.szUsershareTemplateShare ));
4747 return process_usershare_file(usersharepath, servicename, snum_template);
4750 /***************************************************************************
4751 Load all user defined shares from the user share directory.
4752 We only do this if we're enumerating the share list.
4753 This is the function that can delete usershares that have
4755 ***************************************************************************/
4757 int load_usershare_shares(void)
4760 SMB_STRUCT_STAT sbuf;
4761 SMB_STRUCT_DIRENT *de;
4762 int num_usershares = 0;
4763 int max_user_shares = Globals.iUsershareMaxShares;
4764 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4765 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4766 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4768 int snum_template = -1;
4769 const char *usersharepath = Globals.szUsersharePath;
4770 int ret = lp_numservices();
4772 if (max_user_shares == 0 || *usersharepath == '\0') {
4773 return lp_numservices();
4776 if (sys_stat(usersharepath, &sbuf) != 0) {
4777 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4778 usersharepath, strerror(errno) ));
4783 * This directory must be owned by root, and have the 't' bit set.
4784 * It also must not be writable by "other".
4788 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4790 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4792 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4793 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4798 /* Ensure the template share exists if it's set. */
4799 if (Globals.szUsershareTemplateShare[0]) {
4800 /* We can't use lp_servicenumber here as we are recommending that
4801 template shares have -valid=False set. */
4802 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4803 if (ServicePtrs[snum_template]->szService &&
4804 strequal(ServicePtrs[snum_template]->szService,
4805 Globals.szUsershareTemplateShare)) {
4810 if (snum_template == -1) {
4811 DEBUG(0,("load_usershare_shares: usershare template share %s "
4812 "does not exist.\n",
4813 Globals.szUsershareTemplateShare ));
4818 /* Mark all existing usershares as pending delete. */
4819 for (iService = iNumServices - 1; iService >= 0; iService--) {
4820 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4821 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4825 dp = sys_opendir(usersharepath);
4827 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4828 usersharepath, strerror(errno) ));
4832 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4833 (de = sys_readdir(dp));
4834 num_dir_entries++ ) {
4836 const char *n = de->d_name;
4838 /* Ignore . and .. */
4840 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4846 /* Temporary file used when creating a share. */
4847 num_tmp_dir_entries++;
4850 /* Allow 20% tmp entries. */
4851 if (num_tmp_dir_entries > allowed_tmp_entries) {
4852 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4853 "in directory %s\n",
4854 num_tmp_dir_entries, usersharepath));
4858 r = process_usershare_file(usersharepath, n, snum_template);
4860 /* Update the services count. */
4862 if (num_usershares >= max_user_shares) {
4863 DEBUG(0,("load_usershare_shares: max user shares reached "
4864 "on file %s in directory %s\n",
4865 n, usersharepath ));
4868 } else if (r == -1) {
4869 num_bad_dir_entries++;
4872 /* Allow 20% bad entries. */
4873 if (num_bad_dir_entries > allowed_bad_entries) {
4874 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4875 "in directory %s\n",
4876 num_bad_dir_entries, usersharepath));
4880 /* Allow 20% bad entries. */
4881 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4882 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4883 "in directory %s\n",
4884 num_dir_entries, usersharepath));
4891 /* Sweep through and delete any non-refreshed usershares that are
4892 not currently in use. */
4893 for (iService = iNumServices - 1; iService >= 0; iService--) {
4894 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4895 if (conn_snum_used(iService)) {
4898 /* Remove from the share ACL db. */
4899 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4900 lp_servicename(iService) ));
4901 delete_share_security(snum2params_static(iService));
4902 free_service_byindex(iService);
4906 return lp_numservices();
4909 /********************************************************
4910 Destroy global resources allocated in this file
4911 ********************************************************/
4913 void gfree_loadparm(void)
4915 struct file_lists *f;
4916 struct file_lists *next;
4921 /* Free the file lists */
4926 SAFE_FREE( f->name );
4927 SAFE_FREE( f->subfname );
4932 /* Free resources allocated to services */
4934 for ( i = 0; i < iNumServices; i++ ) {
4936 free_service_byindex(i);
4940 SAFE_FREE( ServicePtrs );
4943 /* Now release all resources allocated to global
4944 parameters and the default service */
4946 for (i = 0; parm_table[i].label; i++)
4948 if ( parm_table[i].type == P_STRING
4949 || parm_table[i].type == P_USTRING )
4951 string_free( (char**)parm_table[i].ptr );
4953 else if (parm_table[i].type == P_LIST) {
4954 str_list_free( (char***)parm_table[i].ptr );
4959 /***************************************************************************
4960 Load the services array from the services file. Return True on success,
4962 ***************************************************************************/
4964 BOOL lp_load(const char *pszFname,
4968 BOOL initialize_globals)
4972 param_opt_struct *data, *pdata;
4974 pstrcpy(n2, pszFname);
4976 standard_sub_basic( get_current_username(), current_user_info.domain,
4979 add_to_file_list(pszFname, n2);
4983 DEBUG(3, ("lp_load: refreshing parameters\n"));
4985 bInGlobalSection = True;
4986 bGlobalOnly = global_only;
4988 init_globals(! initialize_globals);
4991 if (save_defaults) {
4996 if (Globals.param_opt != NULL) {
4997 data = Globals.param_opt;
4999 string_free(&data->key);
5000 string_free(&data->value);
5001 str_list_free(&data->list);
5006 Globals.param_opt = NULL;
5009 /* We get sections first, so have to start 'behind' to make up */
5011 bRetval = pm_process(n2, do_section, do_parameter);
5013 /* finish up the last section */
5014 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
5016 if (iServiceIndex >= 0)
5017 bRetval = service_ok(iServiceIndex);
5019 lp_add_auto_services(lp_auto_services());
5022 /* When 'restrict anonymous = 2' guest connections to ipc$
5024 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
5025 if ( lp_enable_asu_support() )
5026 lp_add_ipc("ADMIN$", False);
5030 set_default_server_announce_type();
5031 set_allowed_client_auth();
5035 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
5036 /* if bWINSsupport is true and we are in the client */
5037 if (in_client && Globals.bWINSsupport) {
5038 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5046 /***************************************************************************
5047 Reset the max number of services.
5048 ***************************************************************************/
5050 void lp_resetnumservices(void)
5055 /***************************************************************************
5056 Return the max number of services.
5057 ***************************************************************************/
5059 int lp_numservices(void)
5061 return (iNumServices);
5064 /***************************************************************************
5065 Display the contents of the services array in human-readable form.
5066 ***************************************************************************/
5068 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
5073 defaults_saved = False;
5077 dump_a_service(&sDefault, f);
5079 for (iService = 0; iService < maxtoprint; iService++) {
5081 lp_dump_one(f, show_defaults, iService);
5085 /***************************************************************************
5086 Display the contents of one service in human-readable form.
5087 ***************************************************************************/
5089 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
5092 if (ServicePtrs[snum]->szService[0] == '\0')
5094 dump_a_service(ServicePtrs[snum], f);
5098 /***************************************************************************
5099 Return the number of the service with the given name, or -1 if it doesn't
5100 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5101 getservicebyname()! This works ONLY if all services have been loaded, and
5102 does not copy the found service.
5103 ***************************************************************************/
5105 int lp_servicenumber(const char *pszServiceName)
5108 fstring serviceName;
5110 if (!pszServiceName) {
5111 return GLOBAL_SECTION_SNUM;
5114 for (iService = iNumServices - 1; iService >= 0; iService--) {
5115 if (VALID(iService) && ServicePtrs[iService]->szService) {
5117 * The substitution here is used to support %U is
5120 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5121 standard_sub_basic(get_current_username(),
5122 current_user_info.domain,
5123 serviceName,sizeof(serviceName));
5124 if (strequal(serviceName, pszServiceName)) {
5130 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5133 if (!usershare_exists(iService, &last_mod)) {
5134 /* Remove the share security tdb entry for it. */
5135 delete_share_security(snum2params_static(iService));
5136 /* Remove it from the array. */
5137 free_service_byindex(iService);
5138 /* Doesn't exist anymore. */
5139 return GLOBAL_SECTION_SNUM;
5142 /* Has it been modified ? If so delete and reload. */
5143 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5144 /* Remove it from the array. */
5145 free_service_byindex(iService);
5146 /* and now reload it. */
5147 iService = load_usershare_service(pszServiceName);
5152 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5153 return GLOBAL_SECTION_SNUM;
5159 BOOL share_defined(const char *service_name)
5161 return (lp_servicenumber(service_name) != -1);
5164 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
5165 const char *sharename)
5167 struct share_params *result;
5171 if (!(sname = SMB_STRDUP(sharename))) {
5175 snum = find_service(sname);
5182 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
5183 DEBUG(0, ("talloc failed\n"));
5187 result->service = snum;
5191 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
5193 struct share_iterator *result;
5195 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
5196 DEBUG(0, ("talloc failed\n"));
5200 result->next_id = 0;
5204 struct share_params *next_share(struct share_iterator *list)
5206 struct share_params *result;
5208 while (!lp_snum_ok(list->next_id) &&
5209 (list->next_id < lp_numservices())) {
5213 if (list->next_id >= lp_numservices()) {
5217 if (!(result = TALLOC_P(list, struct share_params))) {
5218 DEBUG(0, ("talloc failed\n"));
5222 result->service = list->next_id;
5227 struct share_params *next_printer(struct share_iterator *list)
5229 struct share_params *result;
5231 while ((result = next_share(list)) != NULL) {
5232 if (lp_print_ok(result->service)) {
5240 * This is a hack for a transition period until we transformed all code from
5241 * service numbers to struct share_params.
5244 struct share_params *snum2params_static(int snum)
5246 static struct share_params result;
5247 result.service = snum;
5251 /*******************************************************************
5252 A useful volume label function.
5253 ********************************************************************/
5255 char *volume_label(int snum)
5257 char *ret = lp_volume(snum);
5259 return lp_servicename(snum);
5264 /*******************************************************************
5265 Set the server type we will announce as via nmbd.
5266 ********************************************************************/
5268 static void set_default_server_announce_type(void)
5270 default_server_announce = 0;
5271 default_server_announce |= SV_TYPE_WORKSTATION;
5272 default_server_announce |= SV_TYPE_SERVER;
5273 default_server_announce |= SV_TYPE_SERVER_UNIX;
5275 /* note that the flag should be set only if we have a
5276 printer service but nmbd doesn't actually load the
5277 services so we can't tell --jerry */
5279 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5281 switch (lp_announce_as()) {
5282 case ANNOUNCE_AS_NT_SERVER:
5283 default_server_announce |= SV_TYPE_SERVER_NT;
5284 /* fall through... */
5285 case ANNOUNCE_AS_NT_WORKSTATION:
5286 default_server_announce |= SV_TYPE_NT;
5288 case ANNOUNCE_AS_WIN95:
5289 default_server_announce |= SV_TYPE_WIN95_PLUS;
5291 case ANNOUNCE_AS_WFW:
5292 default_server_announce |= SV_TYPE_WFW;
5298 switch (lp_server_role()) {
5299 case ROLE_DOMAIN_MEMBER:
5300 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5302 case ROLE_DOMAIN_PDC:
5303 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5305 case ROLE_DOMAIN_BDC:
5306 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5308 case ROLE_STANDALONE:
5312 if (lp_time_server())
5313 default_server_announce |= SV_TYPE_TIME_SOURCE;
5315 if (lp_host_msdfs())
5316 default_server_announce |= SV_TYPE_DFS_SERVER;
5319 /***********************************************************
5320 returns role of Samba server
5321 ************************************************************/
5323 int lp_server_role(void)
5328 /***********************************************************
5329 If we are PDC then prefer us as DMB
5330 ************************************************************/
5332 BOOL lp_domain_master(void)
5334 if (Globals.bDomainMaster == Auto)
5335 return (lp_server_role() == ROLE_DOMAIN_PDC);
5337 return Globals.bDomainMaster;
5340 /***********************************************************
5341 If we are DMB then prefer us as LMB
5342 ************************************************************/
5344 BOOL lp_preferred_master(void)
5346 if (Globals.bPreferredMaster == Auto)
5347 return (lp_local_master() && lp_domain_master());
5349 return Globals.bPreferredMaster;
5352 /*******************************************************************
5354 ********************************************************************/
5356 void lp_remove_service(int snum)
5358 ServicePtrs[snum]->valid = False;
5359 invalid_services[num_invalid_services++] = snum;
5362 /*******************************************************************
5364 ********************************************************************/
5366 void lp_copy_service(int snum, const char *new_name)
5368 do_section(new_name);
5370 snum = lp_servicenumber(new_name);
5372 lp_do_parameter(snum, "copy", lp_servicename(snum));
5377 /*******************************************************************
5378 Get the default server type we will announce as via nmbd.
5379 ********************************************************************/
5381 int lp_default_server_announce(void)
5383 return default_server_announce;
5386 /*******************************************************************
5387 Split the announce version into major and minor numbers.
5388 ********************************************************************/
5390 int lp_major_announce_version(void)
5392 static BOOL got_major = False;
5393 static int major_version = DEFAULT_MAJOR_VERSION;
5398 return major_version;
5401 if ((vers = lp_announce_version()) == NULL)
5402 return major_version;
5404 if ((p = strchr_m(vers, '.')) == 0)
5405 return major_version;
5408 major_version = atoi(vers);
5409 return major_version;
5412 int lp_minor_announce_version(void)
5414 static BOOL got_minor = False;
5415 static int minor_version = DEFAULT_MINOR_VERSION;
5420 return minor_version;
5423 if ((vers = lp_announce_version()) == NULL)
5424 return minor_version;
5426 if ((p = strchr_m(vers, '.')) == 0)
5427 return minor_version;
5430 minor_version = atoi(p);
5431 return minor_version;
5434 /***********************************************************
5435 Set the global name resolution order (used in smbclient).
5436 ************************************************************/
5438 void lp_set_name_resolve_order(const char *new_order)
5440 string_set(&Globals.szNameResolveOrder, new_order);
5443 const char *lp_printername(int snum)
5445 const char *ret = _lp_printername(snum);
5446 if (ret == NULL || (ret != NULL && *ret == '\0'))
5447 ret = lp_const_servicename(snum);
5453 /***********************************************************
5454 Allow daemons such as winbindd to fix their logfile name.
5455 ************************************************************/
5457 void lp_set_logfile(const char *name)
5459 string_set(&Globals.szLogFile, name);
5460 pstrcpy(debugf, name);
5463 /*******************************************************************
5464 Return the max print jobs per queue.
5465 ********************************************************************/
5467 int lp_maxprintjobs(int snum)
5469 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5470 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5471 maxjobs = PRINT_MAX_JOBID - 1;
5476 const char *lp_printcapname(void)
5478 if ((Globals.szPrintcapname != NULL) &&
5479 (Globals.szPrintcapname[0] != '\0'))
5480 return Globals.szPrintcapname;
5482 if (sDefault.iPrinting == PRINT_CUPS) {
5490 if (sDefault.iPrinting == PRINT_BSD)
5491 return "/etc/printcap";
5493 return PRINTCAP_NAME;
5496 /*******************************************************************
5497 Ensure we don't use sendfile if server smb signing is active.
5498 ********************************************************************/
5500 static uint32 spoolss_state;
5502 BOOL lp_disable_spoolss( void )
5504 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5505 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5507 return spoolss_state == SVCCTL_STOPPED ? True : False;
5510 void lp_set_spoolss_state( uint32 state )
5512 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5514 spoolss_state = state;
5517 uint32 lp_get_spoolss_state( void )
5519 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5522 /*******************************************************************
5523 Ensure we don't use sendfile if server smb signing is active.
5524 ********************************************************************/
5526 BOOL lp_use_sendfile(int snum)
5528 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5529 if (Protocol < PROTOCOL_NT1) {
5532 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
5535 /*******************************************************************
5536 Turn off sendfile if we find the underlying OS doesn't support it.
5537 ********************************************************************/
5539 void set_use_sendfile(int snum, BOOL val)
5541 if (LP_SNUM_OK(snum))
5542 ServicePtrs[snum]->bUseSendfile = val;
5544 sDefault.bUseSendfile = val;
5547 /*******************************************************************
5548 Turn off storing DOS attributes if this share doesn't support it.
5549 ********************************************************************/
5551 void set_store_dos_attributes(int snum, BOOL val)
5553 if (!LP_SNUM_OK(snum))
5555 ServicePtrs[(snum)]->bStoreDosAttributes = val;
5558 void lp_set_mangling_method(const char *new_method)
5560 string_set(&Globals.szManglingMethod, new_method);
5563 /*******************************************************************
5564 Global state for POSIX pathname processing.
5565 ********************************************************************/
5567 static BOOL posix_pathnames;
5569 BOOL lp_posix_pathnames(void)
5571 return posix_pathnames;
5574 /*******************************************************************
5575 Change everything needed to ensure POSIX pathname processing (currently
5577 ********************************************************************/
5579 void lp_set_posix_pathnames(void)
5581 posix_pathnames = True;
5584 /*******************************************************************
5585 Global state for POSIX lock processing - CIFS unix extensions.
5586 ********************************************************************/
5588 BOOL posix_default_lock_was_set;
5589 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5591 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5593 if (posix_default_lock_was_set) {
5594 return posix_cifsx_locktype;
5596 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5600 /*******************************************************************
5601 ********************************************************************/
5603 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5605 posix_default_lock_was_set = True;
5606 posix_cifsx_locktype = val;