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 */
57 BOOL in_server = False; /* Not in the server by default */
60 extern userdom_struct current_user_info;
61 extern pstring user_socket_options;
62 extern enum protocol_types Protocol;
65 #define GLOBAL_NAME "global"
69 #define PRINTERS_NAME "printers"
73 #define HOMES_NAME "homes"
76 /* some helpful bits */
77 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
78 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
80 #define USERSHARE_VALID 1
81 #define USERSHARE_PENDING_DELETE 2
83 int keepalive = DEFAULT_KEEPALIVE;
84 BOOL use_getwd_cache = True;
86 extern int extra_time_offset;
88 static BOOL defaults_saved = False;
90 typedef struct _param_opt_struct param_opt_struct;
91 struct _param_opt_struct {
92 param_opt_struct *prev, *next;
99 * This structure describes global (ie., server-wide) parameters.
105 char *display_charset;
106 char *szPrintcapname;
107 char *szEnumPortsCommand;
108 char *szAddPrinterCommand;
109 char *szDeletePrinterCommand;
110 char *szOs2DriverMap;
114 char *szDefaultService;
119 char *szServerString;
120 char *szAutoServices;
121 char *szPasswdProgram;
125 char *szSMBPasswdFile;
127 char **szPassdbBackend;
128 char **szPreloadModules;
129 char *szPasswordServer;
130 char *szSocketOptions;
132 char *szAfsUsernameMap;
133 int iAfsTokenLifetime;
134 char *szLogNtTokenCommand;
140 char **szWINSservers;
142 char *szRemoteAnnounce;
143 char *szRemoteBrowseSync;
144 char *szSocketAddress;
145 char *szNISHomeMapName;
146 char *szAnnounceVersion; /* This is initialised in init_globals */
149 char **szNetbiosAliases;
150 char *szNetbiosScope;
151 char *szNameResolveOrder;
153 char *szAddUserScript;
154 char *szRenameUserScript;
155 char *szDelUserScript;
156 char *szAddGroupScript;
157 char *szDelGroupScript;
158 char *szAddUserToGroupScript;
159 char *szDelUserFromGroupScript;
160 char *szSetPrimaryGroupScript;
161 char *szAddMachineScript;
162 char *szShutdownScript;
163 char *szAbortShutdownScript;
164 char *szUsernameMapScript;
165 char *szCheckPasswordScript;
167 char *szWINSPartners;
173 BOOL bPassdbExpandExplicit;
174 int AlgorithmicRidBase;
175 char *szTemplateHomedir;
176 char *szTemplateShell;
177 char *szWinbindSeparator;
178 BOOL bWinbindEnumUsers;
179 BOOL bWinbindEnumGroups;
180 BOOL bWinbindUseDefaultDomain;
181 BOOL bWinbindTrustedDomainsOnly;
182 BOOL bWinbindNestedGroups;
183 BOOL bWinbindRefreshTickets;
184 BOOL bWinbindOfflineLogon;
185 char **szIdmapBackend;
186 char *szAddShareCommand;
187 char *szChangeShareCommand;
188 char *szDeleteShareCommand;
190 char *szGuestaccount;
191 char *szManglingMethod;
192 char **szServicesList;
193 char *szUsersharePath;
194 char *szUsershareTemplateShare;
195 char **szUsersharePrefixAllowList;
196 char **szUsersharePrefixDenyList;
210 BOOL paranoid_server_security;
213 int iMaxSmbdProcesses;
214 BOOL bDisableSpoolss;
217 int enhanced_browsing;
223 int announce_as; /* This is initialised in init_globals */
224 int machine_password_timeout;
225 int change_notify_timeout;
227 int oplock_break_wait_time;
228 int winbind_cache_time;
229 int winbind_max_idle_children;
230 char **szWinbindNssInfo;
233 char *szLdapMachineSuffix;
234 char *szLdapUserSuffix;
235 char *szLdapIdmapSuffix;
236 char *szLdapGroupSuffix;
237 #ifdef WITH_LDAP_SAMCONFIG
246 char *szIPrintServer;
247 int ldap_passwd_sync;
248 int ldap_replication_sleep;
249 int ldap_timeout; /* This is initialised in init_globals */
252 BOOL bMsAddPrinterWizard;
257 BOOL bPreferredMaster;
260 BOOL bEncryptPasswords;
265 BOOL bObeyPamRestrictions;
267 int PrintcapCacheTime;
268 BOOL bLargeReadwrite;
276 BOOL bBindInterfacesOnly;
277 BOOL bPamPasswordChange;
278 BOOL bUnixPasswdSync;
279 BOOL bPasswdChatDebug;
280 int iPasswdChatTimeout;
284 BOOL bNTStatusSupport;
286 int iMaxStatCacheSize;
288 BOOL bAllowTrustedDomains;
292 BOOL bClientLanManAuth;
293 BOOL bClientNTLMv2Auth;
294 BOOL bClientPlaintextAuth;
295 BOOL bClientUseSpnego;
296 BOOL bDebugHiresTimestamp;
301 BOOL bHostnameLookups;
302 BOOL bUnixExtensions;
303 BOOL bDisableNetbios;
304 BOOL bKernelChangeNotify;
305 BOOL bFamChangeNotify;
306 BOOL bUseKerberosKeytab;
307 BOOL bDeferSharingViolations;
308 BOOL bEnablePrivileges;
310 BOOL bUsershareOwnerOnly;
311 int restrict_anonymous;
312 int name_cache_timeout;
315 int iUsershareMaxShares;
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;
371 char *szAioWriteBehind;
375 int iMaxReportedPrintJobs;
378 int iCreate_force_mode;
380 int iSecurity_force_mode;
383 int iDir_Security_mask;
384 int iDir_Security_force_mode;
388 int iOplockContentionLimit;
393 BOOL bRootpreexecClose;
396 BOOL bShortCasePreserve;
398 BOOL bHideSpecialFiles;
399 BOOL bHideUnReadable;
400 BOOL bHideUnWriteableFiles;
411 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;
452 int iallocation_roundup_size;
456 param_opt_struct *param_opt;
458 char dummy[3]; /* for alignment */
462 /* This is a default service used to prime a services structure */
463 static service sDefault = {
465 False, /* not autoloaded */
466 0, /* not a usershare */
467 (time_t)0, /* No last mod time */
468 NULL, /* szService */
470 NULL, /* szUsername */
471 NULL, /* szInvalidUsers */
472 NULL, /* szValidUsers */
473 NULL, /* szAdminUsers */
475 NULL, /* szInclude */
476 NULL, /* szPreExec */
477 NULL, /* szPostExec */
478 NULL, /* szRootPreExec */
479 NULL, /* szRootPostExec */
480 NULL, /* szCupsOptions */
481 NULL, /* szPrintcommand */
482 NULL, /* szLpqcommand */
483 NULL, /* szLprmcommand */
484 NULL, /* szLppausecommand */
485 NULL, /* szLpresumecommand */
486 NULL, /* szQueuepausecommand */
487 NULL, /* szQueueresumecommand */
488 NULL, /* szPrintername */
489 NULL, /* szDontdescend */
490 NULL, /* szHostsallow */
491 NULL, /* szHostsdeny */
492 NULL, /* szMagicScript */
493 NULL, /* szMagicOutput */
494 NULL, /* szMangledMap */
495 NULL, /* szVetoFiles */
496 NULL, /* szHideFiles */
497 NULL, /* szVetoOplockFiles */
499 NULL, /* force user */
500 NULL, /* force group */
502 NULL, /* writelist */
503 NULL, /* printer admin */
506 NULL, /* vfs objects */
507 NULL, /* szMSDfsProxy */
508 NULL, /* szAioWriteBehind */
510 0, /* iMinPrintSpace */
511 1000, /* iMaxPrintJobs */
512 0, /* iMaxReportedPrintJobs */
513 0, /* iWriteCacheSize */
514 0744, /* iCreate_mask */
515 0000, /* iCreate_force_mode */
516 0777, /* iSecurity_mask */
517 0, /* iSecurity_force_mode */
518 0755, /* iDir_mask */
519 0000, /* iDir_force_mode */
520 0777, /* iDir_Security_mask */
521 0, /* iDir_Security_force_mode */
522 0, /* iMaxConnections */
523 CASE_LOWER, /* iDefaultCase */
524 DEFAULT_PRINTING, /* iPrinting */
525 2, /* iOplockContentionLimit */
527 1024, /* iBlock_size */
528 0, /* iDfreeCacheTime */
529 False, /* bPreexecClose */
530 False, /* bRootpreexecClose */
531 Auto, /* case sensitive */
532 True, /* case preserve */
533 True, /* short case preserve */
534 True, /* bHideDotFiles */
535 False, /* bHideSpecialFiles */
536 False, /* bHideUnReadable */
537 False, /* bHideUnWriteableFiles */
538 True, /* bBrowseable */
539 True, /* bAvailable */
540 True, /* bRead_only */
541 True, /* bNo_set_dir */
542 False, /* bGuest_only */
543 False, /* bGuest_ok */
544 False, /* bPrint_ok */
545 False, /* bMap_system */
546 False, /* bMap_hidden */
547 True, /* bMap_archive */
548 False, /* bStoreDosAttributes */
550 True, /* iStrictLocking */
551 True, /* bPosixLocking */
552 True, /* bShareModes */
554 True, /* bLevel2OpLocks */
555 False, /* bOnlyUser */
556 True, /* bMangledNames */
557 True, /* bWidelinks */
558 True, /* bSymlinks */
559 False, /* bSyncAlways */
560 False, /* bStrictAllocate */
561 False, /* bStrictSync */
562 '~', /* magic char */
564 False, /* bDeleteReadonly */
565 False, /* bFakeOplocks */
566 False, /* bDeleteVetoFiles */
567 False, /* bDosFilemode */
568 True, /* bDosFiletimes */
569 False, /* bDosFiletimeResolution */
570 False, /* bFakeDirCreateTimes */
571 True, /* bBlockingLocks */
572 False, /* bInheritPerms */
573 False, /* bInheritACLS */
574 False, /* bInheritOwner */
575 False, /* bMSDfsRoot */
576 False, /* bUseClientDriver */
577 False, /* bDefaultDevmode */
578 False, /* bForcePrintername */
579 True, /* bNTAclSupport */
580 False, /* bForceUnknownAclUser */
581 False, /* bUseSendfile */
582 False, /* bProfileAcls */
583 False, /* bMap_acl_inherit */
584 False, /* bAfs_Share */
585 False, /* bEASupport */
586 True, /* bAclCheckPermissions */
587 True, /* bAclMapFullControl */
588 False, /* bAclGroupControl */
589 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
590 0, /* iAioReadSize */
591 0, /* iAioWriteSize */
592 MAP_READONLY_YES, /* iMap_readonly */
594 NULL, /* Parametric options */
599 /* local variables */
600 static service **ServicePtrs = NULL;
601 static int iNumServices = 0;
602 static int iServiceIndex = 0;
603 static TDB_CONTEXT *ServiceHash;
604 static int *invalid_services = NULL;
605 static int num_invalid_services = 0;
606 static BOOL bInGlobalSection = True;
607 static BOOL bGlobalOnly = False;
608 static int server_role;
609 static int default_server_announce;
611 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
613 /* prototypes for the special type handlers */
614 static BOOL handle_include( int snum, const char *pszParmValue, char **ptr);
615 static BOOL handle_copy( int snum, const char *pszParmValue, char **ptr);
616 static BOOL handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
617 static BOOL handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
618 static BOOL handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
619 static BOOL handle_debug_list( int snum, const char *pszParmValue, char **ptr );
620 static BOOL handle_workgroup( int snum, const char *pszParmValue, char **ptr );
621 static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
622 static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
623 static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
624 static BOOL handle_acl_compatibility( int snum, const char *pszParmValue, char **ptr);
625 static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
627 static void set_server_role(void);
628 static void set_default_server_announce_type(void);
629 static void set_allowed_client_auth(void);
631 static const struct enum_list enum_protocol[] = {
632 {PROTOCOL_NT1, "NT1"},
633 {PROTOCOL_LANMAN2, "LANMAN2"},
634 {PROTOCOL_LANMAN1, "LANMAN1"},
635 {PROTOCOL_CORE, "CORE"},
636 {PROTOCOL_COREPLUS, "COREPLUS"},
637 {PROTOCOL_COREPLUS, "CORE+"},
641 static const struct enum_list enum_security[] = {
642 {SEC_SHARE, "SHARE"},
644 {SEC_SERVER, "SERVER"},
645 {SEC_DOMAIN, "DOMAIN"},
652 static const struct enum_list enum_printing[] = {
653 {PRINT_SYSV, "sysv"},
655 {PRINT_HPUX, "hpux"},
659 {PRINT_LPRNG, "lprng"},
660 {PRINT_CUPS, "cups"},
661 {PRINT_IPRINT, "iprint"},
663 {PRINT_LPROS2, "os2"},
665 {PRINT_TEST, "test"},
667 #endif /* DEVELOPER */
671 static const struct enum_list enum_ldap_ssl[] = {
672 #ifdef WITH_LDAP_SAMCONFIG
673 {LDAP_SSL_ON, "Yes"},
674 {LDAP_SSL_ON, "yes"},
678 {LDAP_SSL_OFF, "no"},
679 {LDAP_SSL_OFF, "No"},
680 {LDAP_SSL_OFF, "off"},
681 {LDAP_SSL_OFF, "Off"},
682 {LDAP_SSL_START_TLS, "start tls"},
683 {LDAP_SSL_START_TLS, "Start_tls"},
687 static const struct enum_list enum_ldap_passwd_sync[] = {
688 {LDAP_PASSWD_SYNC_OFF, "no"},
689 {LDAP_PASSWD_SYNC_OFF, "No"},
690 {LDAP_PASSWD_SYNC_OFF, "off"},
691 {LDAP_PASSWD_SYNC_OFF, "Off"},
692 {LDAP_PASSWD_SYNC_ON, "Yes"},
693 {LDAP_PASSWD_SYNC_ON, "yes"},
694 {LDAP_PASSWD_SYNC_ON, "on"},
695 {LDAP_PASSWD_SYNC_ON, "On"},
696 {LDAP_PASSWD_SYNC_ONLY, "Only"},
697 {LDAP_PASSWD_SYNC_ONLY, "only"},
701 /* Types of machine we can announce as. */
702 #define ANNOUNCE_AS_NT_SERVER 1
703 #define ANNOUNCE_AS_WIN95 2
704 #define ANNOUNCE_AS_WFW 3
705 #define ANNOUNCE_AS_NT_WORKSTATION 4
707 static const struct enum_list enum_announce_as[] = {
708 {ANNOUNCE_AS_NT_SERVER, "NT"},
709 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
710 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
711 {ANNOUNCE_AS_WIN95, "win95"},
712 {ANNOUNCE_AS_WFW, "WfW"},
716 static const struct enum_list enum_map_readonly[] = {
717 {MAP_READONLY_NO, "no"},
718 {MAP_READONLY_NO, "false"},
719 {MAP_READONLY_NO, "0"},
720 {MAP_READONLY_YES, "yes"},
721 {MAP_READONLY_YES, "true"},
722 {MAP_READONLY_YES, "1"},
723 {MAP_READONLY_PERMISSIONS, "permissions"},
724 {MAP_READONLY_PERMISSIONS, "perms"},
728 static const struct enum_list enum_case[] = {
729 {CASE_LOWER, "lower"},
730 {CASE_UPPER, "upper"},
734 static const struct enum_list enum_bool_auto[] = {
745 /* Client-side offline caching policy types */
746 #define CSC_POLICY_MANUAL 0
747 #define CSC_POLICY_DOCUMENTS 1
748 #define CSC_POLICY_PROGRAMS 2
749 #define CSC_POLICY_DISABLE 3
751 static const struct enum_list enum_csc_policy[] = {
752 {CSC_POLICY_MANUAL, "manual"},
753 {CSC_POLICY_DOCUMENTS, "documents"},
754 {CSC_POLICY_PROGRAMS, "programs"},
755 {CSC_POLICY_DISABLE, "disable"},
759 /* SMB signing types. */
760 static const struct enum_list enum_smb_signing_vals[] = {
772 {Required, "required"},
773 {Required, "mandatory"},
775 {Required, "forced"},
776 {Required, "enforced"},
782 Do you want session setups at user level security with a invalid
783 password to be rejected or allowed in as guest? WinNT rejects them
784 but it can be a pain as it means "net view" needs to use a password
786 You have 3 choices in the setting of map_to_guest:
788 "Never" means session setups with an invalid password
789 are rejected. This is the default.
791 "Bad User" means session setups with an invalid password
792 are rejected, unless the username does not exist, in which case it
793 is treated as a guest login
795 "Bad Password" means session setups with an invalid password
796 are treated as a guest login
798 Note that map_to_guest only has an effect in user or server
802 static const struct enum_list enum_map_to_guest[] = {
803 {NEVER_MAP_TO_GUEST, "Never"},
804 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
805 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
806 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
810 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
812 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
813 * screen in SWAT. This is used to exclude parameters as well as to squash all
814 * parameters that have been duplicated by pseudonyms.
816 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
817 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
818 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
821 * NOTE2: Handling of duplicated (synonym) paramters:
822 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
823 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
824 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
825 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
828 static struct parm_struct parm_table[] = {
829 {N_("Base Options"), P_SEP, P_SEPARATOR},
831 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
832 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
833 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
834 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
835 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
836 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
837 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
839 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
841 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
842 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
843 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
844 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
845 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
846 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
848 {N_("Security Options"), P_SEP, P_SEPARATOR},
850 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
851 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
852 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
853 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
854 {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
855 {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
856 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
857 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED},
858 {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
859 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
860 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
861 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
862 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
863 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
864 {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
865 {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
866 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
867 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
868 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
869 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
870 {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
872 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
873 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
874 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
875 {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
876 {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
877 {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED},
878 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
879 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
880 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
881 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
882 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
883 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
884 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
885 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
886 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
887 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
889 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
890 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
891 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
893 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
894 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
895 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
896 {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
897 {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
898 {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED },
899 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
900 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
901 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
903 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
904 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
905 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
906 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
908 {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
909 {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
910 {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
911 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
912 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
913 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
914 {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
915 {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
916 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
917 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
918 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
919 {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
920 {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
921 {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
922 {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
923 {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
924 {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
925 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
926 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
928 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
929 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
931 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
932 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
933 {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
934 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
935 {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
936 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
937 {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED},
939 {N_("Logging Options"), P_SEP, P_SEPARATOR},
941 {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
942 {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
943 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
944 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
945 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
947 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
948 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
949 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
950 {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
951 {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
952 {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
954 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
956 {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED},
957 {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED},
958 {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED},
959 {"aio write behind", P_STRING, P_LOCAL, &sDefault.szAioWriteBehind, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
960 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
961 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
962 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
963 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
964 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
965 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED},
966 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
967 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
968 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
969 {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED},
971 {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
972 {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
973 {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
974 {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
975 {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
976 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
977 {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
979 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
980 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED},
981 {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
982 {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
983 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
984 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
986 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
987 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
988 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
989 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
990 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
991 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
992 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
993 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
994 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
995 {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
997 {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED},
998 {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
1000 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1002 {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1003 {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_ADVANCED},
1004 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
1005 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
1006 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED},
1007 {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED},
1008 {"fam change notify", P_BOOL, P_GLOBAL, &Globals.bFamChangeNotify, NULL, NULL, FLAG_ADVANCED},
1010 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
1011 {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
1012 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1013 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
1014 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
1015 {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
1016 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1018 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
1019 {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1020 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1021 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1022 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
1023 {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1024 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
1025 {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
1027 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
1029 {N_("Printing Options"), P_SEP, P_SEPARATOR},
1031 {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1032 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1033 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1034 {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1035 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1036 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
1037 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1038 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
1039 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1040 {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1041 {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1042 {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1043 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1044 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1045 {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE},
1046 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1047 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1048 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1049 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1050 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1051 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1053 {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
1054 {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
1055 {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
1056 {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
1057 {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
1059 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1060 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
1061 {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1062 {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1063 {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1065 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
1066 {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
1067 {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
1069 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
1070 {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1071 {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE},
1072 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1073 {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1074 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1075 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1076 {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1077 {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1078 {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1079 {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1080 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1081 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1082 {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1083 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1084 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1085 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1086 {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1087 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1088 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED },
1089 {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
1090 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
1091 {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1093 {N_("Domain Options"), P_SEP, P_SEPARATOR},
1095 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1097 {N_("Logon Options"), P_SEP, P_SEPARATOR},
1099 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
1100 {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
1101 {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
1102 {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
1103 {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
1104 {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
1105 {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
1106 {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
1107 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
1108 {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
1109 {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
1110 {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED},
1112 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
1113 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
1114 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
1115 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
1116 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
1118 {N_("Browse Options"), P_SEP, P_SEPARATOR},
1120 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1121 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
1122 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
1123 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1124 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
1125 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1126 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1127 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
1128 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1129 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1130 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
1132 {N_("WINS Options"), P_SEP, P_SEPARATOR},
1134 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
1135 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
1137 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1138 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1139 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
1140 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1142 {N_("Locking Options"), P_SEP, P_SEPARATOR},
1144 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1145 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1146 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1147 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1148 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1149 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1150 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1152 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1153 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1154 {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1155 {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1156 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1157 {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1158 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1160 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
1162 #ifdef WITH_LDAP_SAMCONFIG
1163 {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, FLAG_ADVANCED},
1164 {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, FLAG_ADVANCED},
1166 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
1167 {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
1168 {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
1169 {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
1170 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
1171 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
1172 {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE},
1173 {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1174 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
1175 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
1176 {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1177 {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
1178 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
1180 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
1181 {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
1182 {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
1183 {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
1185 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
1186 {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1188 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1189 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1190 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1191 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
1192 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
1193 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
1195 {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
1196 {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
1197 {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
1200 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1201 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1202 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
1203 {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED},
1204 {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED},
1205 {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
1206 {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
1207 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
1208 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
1209 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
1210 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
1211 {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
1212 {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1213 {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1214 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
1215 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
1216 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1218 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1219 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1220 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1221 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
1223 {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1224 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1225 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1226 {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1227 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1228 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1229 {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
1230 {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED},
1231 {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
1232 {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED},
1233 {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED},
1234 {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
1235 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1236 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1237 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1238 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1239 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1240 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1241 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1242 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1243 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1244 {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1245 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1246 {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1248 {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1249 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
1251 {N_("VFS module options"), P_SEP, P_SEPARATOR},
1253 {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1254 {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
1257 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1258 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1259 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
1261 {N_("Winbind options"), P_SEP, P_SEPARATOR},
1263 {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
1264 {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED},
1265 {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED},
1266 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE},
1267 {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED},
1268 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE},
1269 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
1270 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
1271 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
1272 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
1273 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
1274 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
1275 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
1276 {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
1277 {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
1278 {"winbind max idle children", P_INTEGER, P_GLOBAL, &Globals.winbind_max_idle_children, NULL, NULL, FLAG_ADVANCED},
1279 {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED},
1280 {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED},
1281 {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
1283 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1286 /***************************************************************************
1287 Initialise the sDefault parameter structure for the printer values.
1288 ***************************************************************************/
1290 static void init_printer_values(service *pService)
1292 /* choose defaults depending on the type of printing */
1293 switch (pService->iPrinting) {
1298 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1299 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1300 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
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");
1308 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1309 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1310 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1311 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1317 /* set the lpq command to contain the destination printer
1318 name only. This is used by cups_queue_get() */
1319 string_set(&pService->szLpqcommand, "%p");
1320 string_set(&pService->szLprmcommand, "");
1321 string_set(&pService->szPrintcommand, "");
1322 string_set(&pService->szLppausecommand, "");
1323 string_set(&pService->szLpresumecommand, "");
1324 string_set(&pService->szQueuepausecommand, "");
1325 string_set(&pService->szQueueresumecommand, "");
1327 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1328 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1329 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
1330 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1331 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1332 string_set(&pService->szQueuepausecommand, "disable '%p'");
1333 string_set(&pService->szQueueresumecommand, "enable '%p'");
1334 #endif /* HAVE_CUPS */
1339 string_set(&pService->szLpqcommand, "lpstat -o%p");
1340 string_set(&pService->szLprmcommand, "cancel %p-%j");
1341 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1342 string_set(&pService->szQueuepausecommand, "disable %p");
1343 string_set(&pService->szQueueresumecommand, "enable %p");
1345 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1346 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1351 string_set(&pService->szLpqcommand, "lpq -P%p");
1352 string_set(&pService->szLprmcommand, "lprm -P%p %j");
1353 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1359 string_set(&pService->szPrintcommand, "vlp print %p %s");
1360 string_set(&pService->szLpqcommand, "vlp lpq %p");
1361 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1362 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1363 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1364 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1365 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1367 #endif /* DEVELOPER */
1372 /***************************************************************************
1373 Initialise the global parameter structure.
1374 ***************************************************************************/
1376 static void init_globals(BOOL first_time_only)
1378 static BOOL done_init = False;
1381 /* If requested to initialize only once and we've already done it... */
1382 if (first_time_only && done_init) {
1383 /* ... then we have nothing more to do */
1390 /* The logfile can be set before this is invoked. Free it if so. */
1391 if (Globals.szLogFile != NULL) {
1392 string_free(&Globals.szLogFile);
1393 Globals.szLogFile = NULL;
1396 memset((void *)&Globals, '\0', sizeof(Globals));
1398 for (i = 0; parm_table[i].label; i++)
1399 if ((parm_table[i].type == P_STRING ||
1400 parm_table[i].type == P_USTRING) &&
1402 string_set((char **)parm_table[i].ptr, "");
1404 string_set(&sDefault.fstype, FSTYPE_STRING);
1406 init_printer_values(&sDefault);
1412 DEBUG(3, ("Initialising global parameters\n"));
1414 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1415 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1417 /* use the new 'hash2' method by default, with a prefix of 1 */
1418 string_set(&Globals.szManglingMethod, "hash2");
1419 Globals.mangle_prefix = 1;
1421 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1423 /* using UTF8 by default allows us to support all chars */
1424 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1426 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1427 /* If the system supports nl_langinfo(), try to grab the value
1428 from the user's locale */
1429 string_set(&Globals.display_charset, "LOCALE");
1431 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1434 /* Use codepage 850 as a default for the dos character set */
1435 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1438 * Allow the default PASSWD_CHAT to be overridden in local.h.
1440 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1442 set_global_myname(myhostname());
1443 string_set(&Globals.szNetbiosName,global_myname());
1445 set_global_myworkgroup(WORKGROUP);
1446 string_set(&Globals.szWorkgroup, lp_workgroup());
1448 string_set(&Globals.szPasswdProgram, "");
1449 string_set(&Globals.szPidDir, dyn_PIDDIR);
1450 string_set(&Globals.szLockDir, dyn_LOCKDIR);
1451 string_set(&Globals.szSocketAddress, "0.0.0.0");
1452 pstrcpy(s, "Samba ");
1453 pstrcat(s, SAMBA_VERSION_STRING);
1454 string_set(&Globals.szServerString, s);
1455 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1456 DEFAULT_MINOR_VERSION);
1457 string_set(&Globals.szAnnounceVersion, s);
1459 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1462 pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1464 string_set(&Globals.szLogonDrive, "");
1465 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1466 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1467 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1469 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1470 string_set(&Globals.szPasswordServer, "*");
1472 Globals.AlgorithmicRidBase = BASE_RID;
1474 Globals.bLoadPrinters = True;
1475 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
1477 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1478 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1479 Globals.max_xmit = 0x4104;
1480 Globals.max_mux = 50; /* This is *needed* for profile support. */
1481 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
1482 Globals.bDisableSpoolss = False;
1483 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1484 Globals.pwordlevel = 0;
1485 Globals.unamelevel = 0;
1486 Globals.deadtime = 0;
1487 Globals.bLargeReadwrite = True;
1488 Globals.max_log_size = 5000;
1489 Globals.max_open_files = MAX_OPEN_FILES;
1490 Globals.maxprotocol = PROTOCOL_NT1;
1491 Globals.minprotocol = PROTOCOL_CORE;
1492 Globals.security = SEC_USER;
1493 Globals.paranoid_server_security = True;
1494 Globals.bEncryptPasswords = True;
1495 Globals.bUpdateEncrypt = False;
1496 Globals.clientSchannel = Auto;
1497 Globals.serverSchannel = Auto;
1498 Globals.bReadRaw = True;
1499 Globals.bWriteRaw = True;
1500 Globals.bReadbmpx = False;
1501 Globals.bNullPasswords = False;
1502 Globals.bObeyPamRestrictions = False;
1504 Globals.bSyslogOnly = False;
1505 Globals.bTimestampLogs = True;
1506 string_set(&Globals.szLogLevel, "0");
1507 Globals.bDebugHiresTimestamp = False;
1508 Globals.bDebugPid = False;
1509 Globals.bDebugUid = False;
1510 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1511 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1512 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1513 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1514 Globals.change_notify_timeout = 60; /* 1 minute default. */
1515 Globals.bKernelChangeNotify = True; /* On if we have it. */
1516 Globals.bFamChangeNotify = True; /* On if we have it. */
1517 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1518 Globals.lm_interval = 60;
1519 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1520 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1521 Globals.bNISHomeMap = False;
1522 #ifdef WITH_NISPLUS_HOME
1523 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1525 string_set(&Globals.szNISHomeMapName, "auto.home");
1528 Globals.bTimeServer = False;
1529 Globals.bBindInterfacesOnly = False;
1530 Globals.bUnixPasswdSync = False;
1531 Globals.bPamPasswordChange = False;
1532 Globals.bPasswdChatDebug = False;
1533 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1534 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
1535 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1536 Globals.bStatCache = True; /* use stat cache by default */
1537 Globals.iMaxStatCacheSize = 0; /* unlimited size in kb by default. */
1538 Globals.restrict_anonymous = 0;
1539 Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
1540 Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */
1541 Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
1542 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1543 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1544 /* Note, that we will use NTLM2 session security (which is different), if it is available */
1546 Globals.map_to_guest = 0; /* By Default, "Never" */
1547 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
1548 Globals.enhanced_browsing = True;
1549 Globals.iLockSpinCount = 3; /* Try 3 times. */
1550 Globals.iLockSpinTime = 10; /* usec. */
1551 #ifdef MMAP_BLACKLIST
1552 Globals.bUseMmap = False;
1554 Globals.bUseMmap = True;
1556 Globals.bUnixExtensions = True;
1557 Globals.bResetOnZeroVC = False;
1559 /* hostname lookups can be very expensive and are broken on
1560 a large number of sites (tridge) */
1561 Globals.bHostnameLookups = False;
1563 str_list_free(&Globals.szPassdbBackend);
1564 #ifdef WITH_LDAP_SAMCONFIG
1565 string_set(&Globals.szLdapServer, "localhost");
1566 Globals.ldap_port = 636;
1567 Globals.szPassdbBackend = str_list_make("ldapsam_compat", NULL);
1569 Globals.szPassdbBackend = str_list_make("smbpasswd", NULL);
1570 #endif /* WITH_LDAP_SAMCONFIG */
1571 string_set(&Globals.szLdapSuffix, "");
1572 string_set(&Globals.szLdapMachineSuffix, "");
1573 string_set(&Globals.szLdapUserSuffix, "");
1574 string_set(&Globals.szLdapGroupSuffix, "");
1575 string_set(&Globals.szLdapIdmapSuffix, "");
1577 string_set(&Globals.szLdapAdminDn, "");
1578 Globals.ldap_ssl = LDAP_SSL_ON;
1579 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1580 Globals.ldap_delete_dn = False;
1581 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1582 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1583 Globals.ldap_page_size = LDAP_PAGE_SIZE;
1585 /* This is what we tell the afs client. in reality we set the token
1586 * to never expire, though, when this runs out the afs client will
1587 * forget the token. Set to 0 to get NEVERDATE.*/
1588 Globals.iAfsTokenLifetime = 604800;
1590 /* these parameters are set to defaults that are more appropriate
1591 for the increasing samba install base:
1593 as a member of the workgroup, that will possibly become a
1594 _local_ master browser (lm = True). this is opposed to a forced
1595 local master browser startup (pm = True).
1597 doesn't provide WINS server service by default (wsupp = False),
1598 and doesn't provide domain master browser services by default, either.
1602 Globals.bMsAddPrinterWizard = True;
1603 Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
1604 Globals.os_level = 20;
1605 Globals.bLocalMaster = True;
1606 Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
1607 Globals.bDomainLogons = False;
1608 Globals.bBrowseList = True;
1609 Globals.bWINSsupport = False;
1610 Globals.bWINSproxy = False;
1612 Globals.bDNSproxy = True;
1614 /* this just means to use them if they exist */
1615 Globals.bKernelOplocks = True;
1617 Globals.bAllowTrustedDomains = True;
1619 string_set(&Globals.szTemplateShell, "/bin/false");
1620 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1621 string_set(&Globals.szWinbindSeparator, "\\");
1622 string_set(&Globals.szAclCompat, "");
1623 string_set(&Globals.szCupsServer, "");
1624 string_set(&Globals.szIPrintServer, "");
1626 Globals.winbind_cache_time = 300; /* 5 minutes */
1627 Globals.bWinbindEnumUsers = True;
1628 Globals.bWinbindEnumGroups = True;
1629 Globals.bWinbindUseDefaultDomain = False;
1630 Globals.bWinbindTrustedDomainsOnly = False;
1631 Globals.bWinbindNestedGroups = False;
1632 Globals.winbind_max_idle_children = 3;
1633 Globals.szWinbindNssInfo = str_list_make("template", NULL);
1634 Globals.bWinbindRefreshTickets = False;
1635 Globals.bWinbindOfflineLogon = False;
1637 Globals.bPassdbExpandExplicit = True;
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 /* don't enable privileges by default since Domain
1651 Admins can then assign thr rights to perform certain
1652 operations as root */
1654 Globals.bEnablePrivileges = False;
1656 Globals.bASUSupport = True;
1658 /* User defined shares. */
1659 pstrcpy(s, dyn_LOCKDIR);
1660 pstrcat(s, "/usershares");
1661 string_set(&Globals.szUsersharePath, s);
1662 string_set(&Globals.szUsershareTemplateShare, "");
1663 Globals.iUsershareMaxShares = 0;
1664 /* By default disallow sharing of directories not owned by the sharer. */
1665 Globals.bUsershareOwnerOnly = True;
1668 static TALLOC_CTX *lp_talloc;
1670 /******************************************************************* a
1671 Free up temporary memory - called from the main loop.
1672 ********************************************************************/
1674 void lp_talloc_free(void)
1678 talloc_free(lp_talloc);
1682 TALLOC_CTX *tmp_talloc_ctx(void)
1684 if (lp_talloc == NULL) {
1685 lp_talloc = talloc_init(NULL);
1688 if (lp_talloc == NULL) {
1689 smb_panic("Could not create temporary talloc context\n");
1695 /*******************************************************************
1696 Convenience routine to grab string parameters into temporary memory
1697 and run standard_sub_basic on them. The buffers can be written to by
1698 callers without affecting the source string.
1699 ********************************************************************/
1701 static char *lp_string(const char *s)
1705 /* The follow debug is useful for tracking down memory problems
1706 especially if you have an inner loop that is calling a lp_*()
1707 function that returns a string. Perhaps this debug should be
1708 present all the time? */
1711 DEBUG(10, ("lp_string(%s)\n", s));
1715 lp_talloc = talloc_init("lp_talloc");
1717 tmpstr = alloc_sub_basic(get_current_username(), s);
1718 if (trim_char(tmpstr, '\"', '\"')) {
1719 if (strchr(tmpstr,'\"') != NULL) {
1721 tmpstr = alloc_sub_basic(get_current_username(),s);
1724 ret = talloc_strdup(lp_talloc, tmpstr);
1731 In this section all the functions that are used to access the
1732 parameters from the rest of the program are defined
1735 #define FN_GLOBAL_STRING(fn_name,ptr) \
1736 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1737 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1738 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1739 #define FN_GLOBAL_LIST(fn_name,ptr) \
1740 const char **fn_name(void) {return(*(const char ***)(ptr));}
1741 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1742 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1743 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1744 char fn_name(void) {return(*(char *)(ptr));}
1745 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1746 int fn_name(void) {return(*(int *)(ptr));}
1748 #define FN_LOCAL_STRING(fn_name,val) \
1749 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1750 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1751 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1752 #define FN_LOCAL_LIST(fn_name,val) \
1753 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1754 #define FN_LOCAL_BOOL(fn_name,val) \
1755 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1756 #define FN_LOCAL_CHAR(fn_name,val) \
1757 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1758 #define FN_LOCAL_INTEGER(fn_name,val) \
1759 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1761 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1762 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1763 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1764 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1765 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1766 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1767 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1768 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1769 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1770 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1771 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1772 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1773 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1774 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1775 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1776 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1777 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1778 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1779 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1780 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1781 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1782 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1783 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1784 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1785 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1786 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1787 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1788 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1789 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1790 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1791 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1792 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1793 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1794 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1795 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1796 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1797 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1798 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1799 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1800 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1801 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1802 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1803 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1804 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1805 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1806 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1807 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1808 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1809 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1810 FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
1811 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1812 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1813 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1814 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1815 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1817 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1818 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1819 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1820 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1821 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1822 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1824 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1826 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1827 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1828 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1830 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1832 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1833 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1834 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1835 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1836 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1837 FN_GLOBAL_STRING(lp_acl_compatibility, &Globals.szAclCompat)
1838 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1839 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1840 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1841 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1842 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1843 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1844 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1846 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend)
1847 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1849 #ifdef WITH_LDAP_SAMCONFIG
1850 FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
1851 FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
1853 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1854 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1855 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1856 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1857 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1858 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1859 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1860 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1861 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1862 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1863 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1864 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1865 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1866 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1868 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1870 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1871 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1872 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1873 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1874 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1875 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1876 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1877 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1878 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1879 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1880 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1881 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1882 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1883 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1884 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1885 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1886 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1887 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1888 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1889 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1890 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1891 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1892 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1893 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1894 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1895 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1896 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1897 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1898 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1899 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1900 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1901 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1902 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1903 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1904 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1905 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1906 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1907 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1908 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1909 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1910 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1911 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1912 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1913 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1914 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1915 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1916 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1917 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1918 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1919 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1920 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1921 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1922 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1923 FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
1924 FN_GLOBAL_BOOL(lp_fam_change_notify, &Globals.bFamChangeNotify)
1925 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
1926 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
1927 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
1928 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
1929 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1930 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1931 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1932 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1933 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
1934 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
1935 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
1936 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1937 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1938 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1939 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
1940 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1941 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1942 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1943 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1944 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1945 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
1946 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1947 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
1948 FN_GLOBAL_INTEGER(_lp_disable_spoolss, &Globals.bDisableSpoolss)
1949 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
1950 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1951 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1952 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1953 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1954 FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout)
1955 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
1956 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1957 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1958 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1959 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
1961 FN_LOCAL_STRING(lp_preexec, szPreExec)
1962 FN_LOCAL_STRING(lp_postexec, szPostExec)
1963 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
1964 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
1965 FN_LOCAL_STRING(lp_servicename, szService)
1966 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1967 FN_LOCAL_STRING(lp_pathname, szPath)
1968 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
1969 FN_LOCAL_STRING(lp_username, szUsername)
1970 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1971 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1972 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1973 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
1974 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
1975 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
1976 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
1977 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1978 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1979 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1980 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1981 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1982 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1983 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1984 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1985 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1986 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1987 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
1988 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
1989 FN_LOCAL_STRING(lp_comment, comment)
1990 FN_LOCAL_STRING(lp_force_user, force_user)
1991 FN_LOCAL_STRING(lp_force_group, force_group)
1992 FN_LOCAL_LIST(lp_readlist, readlist)
1993 FN_LOCAL_LIST(lp_writelist, writelist)
1994 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
1995 FN_LOCAL_STRING(lp_fstype, fstype)
1996 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
1997 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1998 static FN_LOCAL_STRING(lp_volume, volume)
1999 FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
2000 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
2001 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
2002 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
2003 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
2004 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
2005 FN_LOCAL_STRING(lp_dfree_command, szDfree)
2006 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
2007 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
2008 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
2009 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
2010 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
2011 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
2012 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
2013 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2014 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2015 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2016 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2017 FN_LOCAL_BOOL(lp_readonly, bRead_only)
2018 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2019 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2020 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2021 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2022 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2023 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2024 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2025 FN_LOCAL_BOOL(lp_locking, bLocking)
2026 FN_LOCAL_INTEGER(lp_strict_locking, iStrictLocking)
2027 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
2028 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2029 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2030 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2031 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2032 FN_LOCAL_BOOL(lp_manglednames, bMangledNames)
2033 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2034 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2035 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2036 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2037 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2038 FN_LOCAL_BOOL(lp_map_system, bMap_system)
2039 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2040 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2041 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2042 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2043 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2044 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2045 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2046 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2047 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2048 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2049 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2050 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2051 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2052 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2053 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2054 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2055 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2056 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2057 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2058 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2059 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2060 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2061 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2062 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2063 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2064 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2065 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2066 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2067 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2068 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2069 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2070 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2071 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2072 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2073 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2074 FN_LOCAL_INTEGER(lp_printing, iPrinting)
2075 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2076 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2077 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2078 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2079 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2080 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2081 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2082 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2083 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2084 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2085 FN_LOCAL_CHAR(lp_magicchar, magic_char)
2086 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2087 FN_GLOBAL_INTEGER(lp_winbind_max_idle_children, &Globals.winbind_max_idle_children)
2088 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2089 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2090 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2091 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2092 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2094 /* local prototypes */
2096 static int map_parameter(const char *pszParmName);
2097 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
2098 static int getservicebyname(const char *pszServiceName,
2099 service * pserviceDest);
2100 static void copy_service(service * pserviceDest,
2101 service * pserviceSource, BOOL *pcopymapDest);
2102 static BOOL service_ok(int iService);
2103 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
2104 static BOOL do_section(const char *pszSectionName);
2105 static void init_copymap(service * pservice);
2106 static BOOL hash_a_service(const char *name, int number);
2107 static void free_service_byindex(int iService);
2108 static char * canonicalize_servicename(const char *name);
2110 /* This is a helper function for parametrical options support. */
2111 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2112 /* Actual parametrical functions are quite simple */
2113 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2115 BOOL global_section = False;
2117 param_opt_struct *data;
2119 if (snum >= iNumServices) return NULL;
2122 data = Globals.param_opt;
2123 global_section = True;
2125 data = ServicePtrs[snum]->param_opt;
2128 asprintf(¶m_key, "%s:%s", type, option);
2130 DEBUG(0,("asprintf failed!\n"));
2135 if (strcmp(data->key, param_key) == 0) {
2136 string_free(¶m_key);
2142 if (!global_section) {
2143 /* Try to fetch the same option but from globals */
2144 /* but only if we are not already working with Globals */
2145 data = Globals.param_opt;
2147 if (strcmp(data->key, param_key) == 0) {
2148 string_free(¶m_key);
2155 string_free(¶m_key);
2161 /*******************************************************************
2162 convenience routine to return int parameters.
2163 ********************************************************************/
2164 static int lp_int(const char *s)
2168 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
2175 /*******************************************************************
2176 convenience routine to return unsigned long parameters.
2177 ********************************************************************/
2178 static int lp_ulong(const char *s)
2182 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
2186 return strtoul(s, NULL, 10);
2189 /*******************************************************************
2190 convenience routine to return boolean parameters.
2191 ********************************************************************/
2192 static BOOL lp_bool(const char *s)
2197 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
2201 if (!set_boolean(&ret,s)) {
2202 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2209 /*******************************************************************
2210 convenience routine to return enum parameters.
2211 ********************************************************************/
2212 static int lp_enum(const char *s,const struct enum_list *_enum)
2217 DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
2221 for (i=0; _enum[i].name; i++) {
2222 if (strequal(_enum[i].name,s))
2223 return _enum[i].value;
2226 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2231 /* DO NOT USE lp_parm_string ANYMORE!!!!
2232 * use lp_parm_const_string or lp_parm_talloc_string
2234 * lp_parm_string is only used to let old modules find this symbol
2236 #undef lp_parm_string
2237 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2239 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2242 /* Return parametric option from a given service. Type is a part of option before ':' */
2243 /* Parametric option has following syntax: 'Type: option = value' */
2244 /* the returned value is talloced in lp_talloc */
2245 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2247 param_opt_struct *data = get_parametrics(snum, type, option);
2249 if (data == NULL||data->value==NULL) {
2251 return lp_string(def);
2257 return lp_string(data->value);
2260 /* Return parametric option from a given service. Type is a part of option before ':' */
2261 /* Parametric option has following syntax: 'Type: option = value' */
2262 const char *lp_parm_const_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)
2272 /* Return parametric option from a given service. Type is a part of option before ':' */
2273 /* Parametric option has following syntax: 'Type: option = value' */
2275 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2277 param_opt_struct *data = get_parametrics(snum, type, option);
2279 if (data == NULL||data->value==NULL)
2280 return (const char **)def;
2282 if (data->list==NULL) {
2283 data->list = str_list_make(data->value, NULL);
2286 return (const char **)data->list;
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 int lp_parm_int(int snum, const char *type, const char *option, int def)
2294 param_opt_struct *data = get_parametrics(snum, type, option);
2296 if (data && data->value && *data->value)
2297 return lp_int(data->value);
2302 /* Return parametric option from a given service. Type is a part of option before ':' */
2303 /* Parametric option has following syntax: 'Type: option = value' */
2305 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2307 param_opt_struct *data = get_parametrics(snum, type, option);
2309 if (data && data->value && *data->value)
2310 return lp_ulong(data->value);
2315 /* Return parametric option from a given service. Type is a part of option before ':' */
2316 /* Parametric option has following syntax: 'Type: option = value' */
2318 BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2320 param_opt_struct *data = get_parametrics(snum, type, option);
2322 if (data && data->value && *data->value)
2323 return lp_bool(data->value);
2328 /* Return parametric option from a given service. Type is a part of option before ':' */
2329 /* Parametric option has following syntax: 'Type: option = value' */
2331 int lp_parm_enum(int snum, const char *type, const char *option,
2332 const struct enum_list *_enum, int def)
2334 param_opt_struct *data = get_parametrics(snum, type, option);
2336 if (data && data->value && *data->value && _enum)
2337 return lp_enum(data->value, _enum);
2343 /***************************************************************************
2344 Initialise a service to the defaults.
2345 ***************************************************************************/
2347 static void init_service(service * pservice)
2349 memset((char *)pservice, '\0', sizeof(service));
2350 copy_service(pservice, &sDefault, NULL);
2353 /***************************************************************************
2354 Free the dynamically allocated parts of a service struct.
2355 ***************************************************************************/
2357 static void free_service(service *pservice)
2360 param_opt_struct *data, *pdata;
2364 if (pservice->szService)
2365 DEBUG(5, ("free_service: Freeing service %s\n",
2366 pservice->szService));
2368 string_free(&pservice->szService);
2369 SAFE_FREE(pservice->copymap);
2371 for (i = 0; parm_table[i].label; i++) {
2372 if ((parm_table[i].type == P_STRING ||
2373 parm_table[i].type == P_USTRING) &&
2374 parm_table[i].p_class == P_LOCAL)
2375 string_free((char **)
2376 (((char *)pservice) +
2377 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2378 else if (parm_table[i].type == P_LIST &&
2379 parm_table[i].p_class == P_LOCAL)
2380 str_list_free((char ***)
2381 (((char *)pservice) +
2382 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2385 data = pservice->param_opt;
2387 DEBUG(5,("Freeing parametrics:\n"));
2389 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2390 string_free(&data->key);
2391 string_free(&data->value);
2392 str_list_free(&data->list);
2398 ZERO_STRUCTP(pservice);
2402 /***************************************************************************
2403 remove a service indexed in the ServicePtrs array from the ServiceHash
2404 and free the dynamically allocated parts
2405 ***************************************************************************/
2407 static void free_service_byindex(int idx)
2409 if ( !LP_SNUM_OK(idx) )
2412 ServicePtrs[idx]->valid = False;
2413 invalid_services[num_invalid_services++] = idx;
2415 /* we have to cleanup the hash record */
2417 if (ServicePtrs[idx]->szService) {
2418 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2420 tdb_delete_bystring(ServiceHash, canon_name );
2423 free_service(ServicePtrs[idx]);
2426 /***************************************************************************
2427 Add a new service to the services array initialising it with the given
2429 ***************************************************************************/
2431 static int add_a_service(const service *pservice, const char *name)
2435 int num_to_alloc = iNumServices + 1;
2436 param_opt_struct *data, *pdata;
2438 tservice = *pservice;
2440 /* it might already exist */
2442 i = getservicebyname(name, NULL);
2444 /* Clean all parametric options for service */
2445 /* They will be added during parsing again */
2446 data = ServicePtrs[i]->param_opt;
2448 string_free(&data->key);
2449 string_free(&data->value);
2450 str_list_free(&data->list);
2455 ServicePtrs[i]->param_opt = NULL;
2460 /* find an invalid one */
2462 if (num_invalid_services > 0) {
2463 i = invalid_services[--num_invalid_services];
2466 /* if not, then create one */
2467 if (i == iNumServices) {
2471 tsp = SMB_REALLOC_ARRAY(ServicePtrs, service *, num_to_alloc);
2473 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2477 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2478 if (!ServicePtrs[iNumServices]) {
2479 DEBUG(0,("add_a_service: out of memory!\n"));
2484 /* enlarge invalid_services here for now... */
2485 tinvalid = SMB_REALLOC_ARRAY(invalid_services, int,
2487 if (tinvalid == NULL) {
2488 DEBUG(0,("add_a_service: failed to enlarge "
2489 "invalid_services!\n"));
2492 invalid_services = tinvalid;
2494 free_service_byindex(i);
2497 ServicePtrs[i]->valid = True;
2499 init_service(ServicePtrs[i]);
2500 copy_service(ServicePtrs[i], &tservice, NULL);
2502 string_set(&ServicePtrs[i]->szService, name);
2504 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2505 i, ServicePtrs[i]->szService));
2507 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2514 /***************************************************************************
2515 Convert a string to uppercase and remove whitespaces.
2516 ***************************************************************************/
2518 static char *canonicalize_servicename(const char *src)
2520 static fstring canon; /* is fstring large enough? */
2523 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2527 fstrcpy( canon, src );
2528 strlower_m( canon );
2533 /***************************************************************************
2534 Add a name/index pair for the services array to the hash table.
2535 ***************************************************************************/
2537 static BOOL hash_a_service(const char *name, int idx)
2541 if ( !ServiceHash ) {
2542 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2543 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2544 (O_RDWR|O_CREAT), 0600);
2545 if ( !ServiceHash ) {
2546 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2551 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2554 if ( !(canon_name = canonicalize_servicename( name )) )
2557 tdb_store_int32(ServiceHash, canon_name, idx);
2562 /***************************************************************************
2563 Add a new home service, with the specified home directory, defaults coming
2565 ***************************************************************************/
2567 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
2568 const char *user, const char *pszHomedir)
2573 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2578 if (!(*(ServicePtrs[iDefaultService]->szPath))
2579 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2580 pstrcpy(newHomedir, pszHomedir);
2581 string_set(&ServicePtrs[i]->szPath, newHomedir);
2584 if (!(*(ServicePtrs[i]->comment))) {
2586 slprintf(comment, sizeof(comment) - 1,
2587 "Home directory of %s", user);
2588 string_set(&ServicePtrs[i]->comment, comment);
2591 /* set the browseable flag from the global default */
2593 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2595 ServicePtrs[i]->autoloaded = True;
2597 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2598 user, ServicePtrs[i]->szPath ));
2603 /***************************************************************************
2604 Add a new service, based on an old one.
2605 ***************************************************************************/
2607 int lp_add_service(const char *pszService, int iDefaultService)
2609 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2612 /***************************************************************************
2613 Add the IPC service.
2614 ***************************************************************************/
2616 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2619 int i = add_a_service(&sDefault, ipc_name);
2624 slprintf(comment, sizeof(comment) - 1,
2625 "IPC Service (%s)", Globals.szServerString);
2627 string_set(&ServicePtrs[i]->szPath, tmpdir());
2628 string_set(&ServicePtrs[i]->szUsername, "");
2629 string_set(&ServicePtrs[i]->comment, comment);
2630 string_set(&ServicePtrs[i]->fstype, "IPC");
2631 ServicePtrs[i]->iMaxConnections = 0;
2632 ServicePtrs[i]->bAvailable = True;
2633 ServicePtrs[i]->bRead_only = True;
2634 ServicePtrs[i]->bGuest_only = False;
2635 ServicePtrs[i]->bGuest_ok = guest_ok;
2636 ServicePtrs[i]->bPrint_ok = False;
2637 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2639 DEBUG(3, ("adding IPC service\n"));
2644 /***************************************************************************
2645 Add a new printer service, with defaults coming from service iFrom.
2646 ***************************************************************************/
2648 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2650 const char *comment = "From Printcap";
2651 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2656 /* note that we do NOT default the availability flag to True - */
2657 /* we take it from the default service passed. This allows all */
2658 /* dynamic printers to be disabled by disabling the [printers] */
2659 /* entry (if/when the 'available' keyword is implemented!). */
2661 /* the printer name is set to the service name. */
2662 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2663 string_set(&ServicePtrs[i]->comment, comment);
2665 /* set the browseable flag from the gloabl default */
2666 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2668 /* Printers cannot be read_only. */
2669 ServicePtrs[i]->bRead_only = False;
2670 /* No share modes on printer services. */
2671 ServicePtrs[i]->bShareModes = False;
2672 /* No oplocks on printer services. */
2673 ServicePtrs[i]->bOpLocks = False;
2674 /* Printer services must be printable. */
2675 ServicePtrs[i]->bPrint_ok = True;
2677 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2682 /***************************************************************************
2683 Map a parameter's string representation to something we can use.
2684 Returns False if the parameter string is not recognised, else TRUE.
2685 ***************************************************************************/
2687 static int map_parameter(const char *pszParmName)
2691 if (*pszParmName == '-')
2694 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2695 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2698 /* Warn only if it isn't parametric option */
2699 if (strchr(pszParmName, ':') == NULL)
2700 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2701 /* We do return 'fail' for parametric options as well because they are
2702 stored in different storage
2707 /***************************************************************************
2708 Show all parameter's name, type, [values,] and flags.
2709 ***************************************************************************/
2711 void show_parameter_list(void)
2713 int classIndex, parmIndex, enumIndex, flagIndex;
2715 const char *section_names[] = { "local", "global", NULL};
2716 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2717 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2718 "P_UGSTRING", "P_ENUM", "P_SEP"};
2719 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2720 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2721 FLAG_HIDE, FLAG_DOS_STRING};
2722 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2723 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2724 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2726 for ( classIndex=0; section_names[classIndex]; classIndex++) {
2727 printf("[%s]\n", section_names[classIndex]);
2728 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2729 if (parm_table[parmIndex].p_class == classIndex) {
2731 parm_table[parmIndex].label,
2732 type[parm_table[parmIndex].type]);
2733 switch (parm_table[parmIndex].type) {
2736 for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
2738 enumIndex ? "|" : "",
2739 parm_table[parmIndex].enum_list[enumIndex].name);
2746 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
2747 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2750 flag_names[flagIndex]);
2760 /***************************************************************************
2761 Set a boolean variable from the text value stored in the passed string.
2762 Returns True in success, False if the passed string does not correctly
2763 represent a boolean.
2764 ***************************************************************************/
2766 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2771 if (strwicmp(pszParmValue, "yes") == 0 ||
2772 strwicmp(pszParmValue, "true") == 0 ||
2773 strwicmp(pszParmValue, "1") == 0)
2775 else if (strwicmp(pszParmValue, "no") == 0 ||
2776 strwicmp(pszParmValue, "False") == 0 ||
2777 strwicmp(pszParmValue, "0") == 0)
2781 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2788 /***************************************************************************
2789 Find a service by name. Otherwise works like get_service.
2790 ***************************************************************************/
2792 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2797 if (ServiceHash != NULL) {
2798 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
2801 iService = tdb_fetch_int32(ServiceHash, canon_name );
2803 if (LP_SNUM_OK(iService)) {
2804 if (pserviceDest != NULL) {
2805 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2815 /***************************************************************************
2816 Copy a service structure to another.
2817 If pcopymapDest is NULL then copy all fields
2818 ***************************************************************************/
2820 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2823 BOOL bcopyall = (pcopymapDest == NULL);
2824 param_opt_struct *data, *pdata, *paramo;
2827 for (i = 0; parm_table[i].label; i++)
2828 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
2829 (bcopyall || pcopymapDest[i])) {
2830 void *def_ptr = parm_table[i].ptr;
2832 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2835 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2838 switch (parm_table[i].type) {
2841 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2847 *(int *)dest_ptr = *(int *)src_ptr;
2851 *(char *)dest_ptr = *(char *)src_ptr;
2855 string_set((char **)dest_ptr,
2860 string_set((char **)dest_ptr,
2862 strupper_m(*(char **)dest_ptr);
2865 str_list_free((char ***)dest_ptr);
2866 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2874 init_copymap(pserviceDest);
2875 if (pserviceSource->copymap)
2876 memcpy((void *)pserviceDest->copymap,
2877 (void *)pserviceSource->copymap,
2878 sizeof(BOOL) * NUMPARAMETERS);
2881 data = pserviceSource->param_opt;
2884 pdata = pserviceDest->param_opt;
2885 /* Traverse destination */
2887 /* If we already have same option, override it */
2888 if (strcmp(pdata->key, data->key) == 0) {
2889 string_free(&pdata->value);
2890 str_list_free(&data->list);
2891 pdata->value = SMB_STRDUP(data->value);
2895 pdata = pdata->next;
2898 paramo = SMB_XMALLOC_P(param_opt_struct);
2899 paramo->key = SMB_STRDUP(data->key);
2900 paramo->value = SMB_STRDUP(data->value);
2901 paramo->list = NULL;
2902 DLIST_ADD(pserviceDest->param_opt, paramo);
2908 /***************************************************************************
2909 Check a service for consistency. Return False if the service is in any way
2910 incomplete or faulty, else True.
2911 ***************************************************************************/
2913 static BOOL service_ok(int iService)
2918 if (ServicePtrs[iService]->szService[0] == '\0') {
2919 DEBUG(0, ("The following message indicates an internal error:\n"));
2920 DEBUG(0, ("No service name in service entry.\n"));
2924 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2925 /* I can't see why you'd want a non-printable printer service... */
2926 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2927 if (!ServicePtrs[iService]->bPrint_ok) {
2928 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2929 ServicePtrs[iService]->szService));
2930 ServicePtrs[iService]->bPrint_ok = True;
2932 /* [printers] service must also be non-browsable. */
2933 if (ServicePtrs[iService]->bBrowseable)
2934 ServicePtrs[iService]->bBrowseable = False;
2937 if (ServicePtrs[iService]->szPath[0] == '\0' &&
2938 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) {
2939 DEBUG(0, ("No path in service %s - using %s\n",
2940 ServicePtrs[iService]->szService, tmpdir()));
2941 string_set(&ServicePtrs[iService]->szPath, tmpdir());
2944 /* If a service is flagged unavailable, log the fact at level 0. */
2945 if (!ServicePtrs[iService]->bAvailable)
2946 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2947 ServicePtrs[iService]->szService));
2952 static struct file_lists {
2953 struct file_lists *next;
2957 } *file_lists = NULL;
2959 /*******************************************************************
2960 Keep a linked list of all config files so we know when one has changed
2961 it's date and needs to be reloaded.
2962 ********************************************************************/
2964 static void add_to_file_list(const char *fname, const char *subfname)
2966 struct file_lists *f = file_lists;
2969 if (f->name && !strcmp(f->name, fname))
2975 f = SMB_MALLOC_P(struct file_lists);
2978 f->next = file_lists;
2979 f->name = SMB_STRDUP(fname);
2984 f->subfname = SMB_STRDUP(subfname);
2990 f->modtime = file_modtime(subfname);
2992 time_t t = file_modtime(subfname);
2998 /*******************************************************************
2999 Check if a config file has changed date.
3000 ********************************************************************/
3002 BOOL lp_file_list_changed(void)
3004 struct file_lists *f = file_lists;
3006 DEBUG(6, ("lp_file_list_changed()\n"));
3012 pstrcpy(n2, f->name);
3013 standard_sub_basic( get_current_username(), n2, sizeof(n2) );
3015 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3016 f->name, n2, ctime(&f->modtime)));
3018 mod_time = file_modtime(n2);
3020 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3022 ("file %s modified: %s\n", n2,
3024 f->modtime = mod_time;
3025 SAFE_FREE(f->subfname);
3026 f->subfname = SMB_STRDUP(n2);
3034 /***************************************************************************
3035 Run standard_sub_basic on netbios name... needed because global_myname
3036 is not accessed through any lp_ macro.
3037 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3038 ***************************************************************************/
3040 static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3043 pstring netbios_name;
3045 pstrcpy(netbios_name, pszParmValue);
3047 standard_sub_basic(get_current_username(), netbios_name,sizeof(netbios_name));
3049 ret = set_global_myname(netbios_name);
3050 string_set(&Globals.szNetbiosName,global_myname());
3052 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3058 static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
3060 if (strcmp(*ptr, pszParmValue) != 0) {
3061 string_set(ptr, pszParmValue);
3069 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3073 ret = set_global_myworkgroup(pszParmValue);
3074 string_set(&Globals.szWorkgroup,lp_workgroup());
3079 static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3083 ret = set_global_scope(pszParmValue);
3084 string_set(&Globals.szNetbiosScope,global_scope());
3089 static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3091 str_list_free(&Globals.szNetbiosAliases);
3092 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3093 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3096 /***************************************************************************
3097 Handle the include operation.
3098 ***************************************************************************/
3100 static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
3103 pstrcpy(fname, pszParmValue);
3105 standard_sub_basic(get_current_username(), fname,sizeof(fname));
3107 add_to_file_list(pszParmValue, fname);
3109 string_set(ptr, fname);
3111 if (file_exist(fname, NULL))
3112 return (pm_process(fname, do_section, do_parameter));
3114 DEBUG(2, ("Can't find include file %s\n", fname));
3119 /***************************************************************************
3120 Handle the interpretation of the copy parameter.
3121 ***************************************************************************/
3123 static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
3127 service serviceTemp;
3129 string_set(ptr, pszParmValue);
3131 init_service(&serviceTemp);
3135 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3137 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3138 if (iTemp == iServiceIndex) {
3139 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3141 copy_service(ServicePtrs[iServiceIndex],
3143 ServicePtrs[iServiceIndex]->copymap);
3147 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3151 free_service(&serviceTemp);
3155 /***************************************************************************
3156 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3161 idmap uid = 1000-1999
3164 We only do simple parsing checks here. The strings are parsed into useful
3165 structures in the idmap daemon code.
3167 ***************************************************************************/
3169 /* Some lp_ routines to return idmap [ug]id information */
3171 static uid_t idmap_uid_low, idmap_uid_high;
3172 static gid_t idmap_gid_low, idmap_gid_high;
3174 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
3176 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3180 *low = idmap_uid_low;
3183 *high = idmap_uid_high;
3188 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
3190 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3194 *low = idmap_gid_low;
3197 *high = idmap_gid_high;
3202 /* Do some simple checks on "idmap [ug]id" parameter values */
3204 static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3208 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
3213 string_set(ptr, pszParmValue);
3215 idmap_uid_low = low;
3216 idmap_uid_high = high;
3221 static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3225 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
3230 string_set(ptr, pszParmValue);
3232 idmap_gid_low = low;
3233 idmap_gid_high = high;
3238 /***************************************************************************
3239 Handle the DEBUG level list.
3240 ***************************************************************************/
3242 static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3244 pstring pszParmValue;
3246 pstrcpy(pszParmValue, pszParmValueIn);
3247 string_set(ptr, pszParmValueIn);
3248 return debug_parse_levels( pszParmValue );
3251 /***************************************************************************
3252 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3253 ***************************************************************************/
3255 static char* append_ldap_suffix( const char *str )
3257 char *suffix_string;
3261 lp_talloc = talloc_init("lp_talloc");
3263 suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
3264 if ( !suffix_string ) {
3265 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3269 return suffix_string;
3272 char *lp_ldap_machine_suffix(void)
3274 if (Globals.szLdapMachineSuffix[0])
3275 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3277 return lp_string(Globals.szLdapSuffix);
3280 char *lp_ldap_user_suffix(void)
3282 if (Globals.szLdapUserSuffix[0])
3283 return append_ldap_suffix(Globals.szLdapUserSuffix);
3285 return lp_string(Globals.szLdapSuffix);
3288 char *lp_ldap_group_suffix(void)
3290 if (Globals.szLdapGroupSuffix[0])
3291 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3293 return lp_string(Globals.szLdapSuffix);
3296 char *lp_ldap_idmap_suffix(void)
3298 if (Globals.szLdapIdmapSuffix[0])
3299 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3301 return lp_string(Globals.szLdapSuffix);
3304 /***************************************************************************
3305 ***************************************************************************/
3307 static BOOL handle_acl_compatibility(int snum, const char *pszParmValue, char **ptr)
3309 if (strequal(pszParmValue, "auto"))
3310 string_set(ptr, "");
3311 else if (strequal(pszParmValue, "winnt"))
3312 string_set(ptr, "winnt");
3313 else if (strequal(pszParmValue, "win2k"))
3314 string_set(ptr, "win2k");
3321 /****************************************************************************
3322 set the value for a P_ENUM
3323 ***************************************************************************/
3325 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3330 for (i = 0; parm->enum_list[i].name; i++) {
3331 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3332 *ptr = parm->enum_list[i].value;
3338 /***************************************************************************
3339 ***************************************************************************/
3341 static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3343 static int parm_num = -1;
3346 if ( parm_num == -1 )
3347 parm_num = map_parameter( "printing" );
3349 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3354 s = ServicePtrs[snum];
3356 init_printer_values( s );
3362 /***************************************************************************
3363 Initialise a copymap.
3364 ***************************************************************************/
3366 static void init_copymap(service * pservice)
3369 SAFE_FREE(pservice->copymap);
3370 pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3371 if (!pservice->copymap)
3373 ("Couldn't allocate copymap!! (size %d)\n",
3374 (int)NUMPARAMETERS));
3376 for (i = 0; i < NUMPARAMETERS; i++)
3377 pservice->copymap[i] = True;
3380 /***************************************************************************
3381 Return the local pointer to a parameter given the service number and the
3382 pointer into the default structure.
3383 ***************************************************************************/
3385 void *lp_local_ptr(int snum, void *ptr)
3387 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3390 /***************************************************************************
3391 Process a parameter for a particular service number. If snum < 0
3392 then assume we are in the globals.
3393 ***************************************************************************/
3395 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3397 int parmnum, i, slen;
3398 void *parm_ptr = NULL; /* where we are going to store the result */
3399 void *def_ptr = NULL;
3402 param_opt_struct *paramo, *data;
3405 parmnum = map_parameter(pszParmName);
3408 if ((sep=strchr(pszParmName, ':')) != NULL) {
3410 ZERO_STRUCT(param_key);
3411 pstr_sprintf(param_key, "%s:", pszParmName);
3412 slen = strlen(param_key);
3413 pstrcat(param_key, sep+1);
3414 trim_char(param_key+slen, ' ', ' ');
3416 data = (snum < 0) ? Globals.param_opt :
3417 ServicePtrs[snum]->param_opt;
3418 /* Traverse destination */
3420 /* If we already have same option, override it */
3421 if (strcmp(data->key, param_key) == 0) {
3422 string_free(&data->value);
3423 str_list_free(&data->list);
3424 data->value = SMB_STRDUP(pszParmValue);
3431 paramo = SMB_XMALLOC_P(param_opt_struct);
3432 paramo->key = SMB_STRDUP(param_key);
3433 paramo->value = SMB_STRDUP(pszParmValue);
3434 paramo->list = NULL;
3436 DLIST_ADD(Globals.param_opt, paramo);
3438 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3445 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3449 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3450 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3454 def_ptr = parm_table[parmnum].ptr;
3456 /* we might point at a service, the default service or a global */
3460 if (parm_table[parmnum].p_class == P_GLOBAL) {
3462 ("Global parameter %s found in service section!\n",
3467 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3472 if (!ServicePtrs[snum]->copymap)
3473 init_copymap(ServicePtrs[snum]);
3475 /* this handles the aliases - set the copymap for other entries with
3476 the same data pointer */
3477 for (i = 0; parm_table[i].label; i++)
3478 if (parm_table[i].ptr == parm_table[parmnum].ptr)
3479 ServicePtrs[snum]->copymap[i] = False;
3482 /* if it is a special case then go ahead */
3483 if (parm_table[parmnum].special) {
3484 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3488 /* now switch on the type of variable it is */
3489 switch (parm_table[parmnum].type)
3492 set_boolean((BOOL *)parm_ptr, pszParmValue);
3496 set_boolean((BOOL *)parm_ptr, pszParmValue);
3497 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
3501 *(int *)parm_ptr = atoi(pszParmValue);
3505 *(char *)parm_ptr = *pszParmValue;
3509 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3511 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3516 str_list_free((char ***)parm_ptr);
3517 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3521 string_set((char **)parm_ptr, pszParmValue);
3525 string_set((char **)parm_ptr, pszParmValue);
3526 strupper_m(*(char **)parm_ptr);
3530 pstrcpy((char *)parm_ptr, pszParmValue);
3534 pstrcpy((char *)parm_ptr, pszParmValue);
3535 strupper_m((char *)parm_ptr);
3539 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3548 /***************************************************************************
3549 Process a parameter.
3550 ***************************************************************************/
3552 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3554 if (!bInGlobalSection && bGlobalOnly)
3557 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3559 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3560 pszParmName, pszParmValue));
3563 /***************************************************************************
3564 Print a parameter of the specified type.
3565 ***************************************************************************/
3567 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3573 for (i = 0; p->enum_list[i].name; i++) {
3574 if (*(int *)ptr == p->enum_list[i].value) {
3576 p->enum_list[i].name);
3583 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3587 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3591 fprintf(f, "%d", *(int *)ptr);
3595 fprintf(f, "%c", *(char *)ptr);
3599 fprintf(f, "%s", octal_string(*(int *)ptr));
3603 if ((char ***)ptr && *(char ***)ptr) {
3604 char **list = *(char ***)ptr;
3606 for (; *list; list++) {
3607 /* surround strings with whitespace in double quotes */
3608 if ( strchr_m( *list, ' ' ) )
3609 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3611 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3619 fprintf(f, "%s", (char *)ptr);
3625 if (*(char **)ptr) {
3626 fprintf(f, "%s", *(char **)ptr);
3634 /***************************************************************************
3635 Check if two parameters are equal.
3636 ***************************************************************************/
3638 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3643 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3648 return (*((int *)ptr1) == *((int *)ptr2));
3651 return (*((char *)ptr1) == *((char *)ptr2));
3654 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3659 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3664 return (p1 == p2 || strequal(p1, p2));
3669 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3674 return (p1 == p2 || strequal(p1, p2));
3682 /***************************************************************************
3683 Initialize any local varients in the sDefault table.
3684 ***************************************************************************/
3686 void init_locals(void)
3691 /***************************************************************************
3692 Process a new section (service). At this stage all sections are services.
3693 Later we'll have special sections that permit server parameters to be set.
3694 Returns True on success, False on failure.
3695 ***************************************************************************/
3697 static BOOL do_section(const char *pszSectionName)
3700 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3701 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3704 /* if we were in a global section then do the local inits */
3705 if (bInGlobalSection && !isglobal)
3708 /* if we've just struck a global section, note the fact. */
3709 bInGlobalSection = isglobal;
3711 /* check for multiple global sections */
3712 if (bInGlobalSection) {
3713 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3717 if (!bInGlobalSection && bGlobalOnly)
3720 /* if we have a current service, tidy it up before moving on */
3723 if (iServiceIndex >= 0)
3724 bRetval = service_ok(iServiceIndex);
3726 /* if all is still well, move to the next record in the services array */
3728 /* We put this here to avoid an odd message order if messages are */
3729 /* issued by the post-processing of a previous section. */
3730 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3732 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3734 DEBUG(0, ("Failed to add a new service\n"));
3743 /***************************************************************************
3744 Determine if a partcular base parameter is currentl set to the default value.
3745 ***************************************************************************/
3747 static BOOL is_default(int i)
3749 if (!defaults_saved)
3751 switch (parm_table[i].type) {
3753 return str_list_compare (parm_table[i].def.lvalue,
3754 *(char ***)parm_table[i].ptr);
3757 return strequal(parm_table[i].def.svalue,
3758 *(char **)parm_table[i].ptr);
3761 return strequal(parm_table[i].def.svalue,
3762 (char *)parm_table[i].ptr);
3765 return parm_table[i].def.bvalue ==
3766 *(BOOL *)parm_table[i].ptr;
3768 return parm_table[i].def.cvalue ==
3769 *(char *)parm_table[i].ptr;
3773 return parm_table[i].def.ivalue ==
3774 *(int *)parm_table[i].ptr;
3781 /***************************************************************************
3782 Display the contents of the global structure.
3783 ***************************************************************************/
3785 static void dump_globals(FILE *f)
3788 param_opt_struct *data;
3790 fprintf(f, "[global]\n");
3792 for (i = 0; parm_table[i].label; i++)
3793 if (parm_table[i].p_class == P_GLOBAL &&
3794 parm_table[i].ptr &&
3795 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3796 if (defaults_saved && is_default(i))
3798 fprintf(f, "\t%s = ", parm_table[i].label);
3799 print_parameter(&parm_table[i], parm_table[i].ptr, f);
3802 if (Globals.param_opt != NULL) {
3803 data = Globals.param_opt;
3805 fprintf(f, "\t%s = %s\n", data->key, data->value);
3812 /***************************************************************************
3813 Return True if a local parameter is currently set to the global default.
3814 ***************************************************************************/
3816 BOOL lp_is_default(int snum, struct parm_struct *parm)
3818 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3820 return equal_parameter(parm->type,
3821 ((char *)ServicePtrs[snum]) + pdiff,
3822 ((char *)&sDefault) + pdiff);
3825 /***************************************************************************
3826 Display the contents of a single services record.
3827 ***************************************************************************/
3829 static void dump_a_service(service * pService, FILE * f)
3832 param_opt_struct *data;
3834 if (pService != &sDefault)
3835 fprintf(f, "[%s]\n", pService->szService);
3837 for (i = 0; parm_table[i].label; i++) {
3839 if (parm_table[i].p_class == P_LOCAL &&
3840 parm_table[i].ptr &&
3841 (*parm_table[i].label != '-') &&
3842 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3845 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3847 if (pService == &sDefault) {
3848 if (defaults_saved && is_default(i))
3851 if (equal_parameter(parm_table[i].type,
3852 ((char *)pService) +
3854 ((char *)&sDefault) +
3859 fprintf(f, "\t%s = ", parm_table[i].label);
3860 print_parameter(&parm_table[i],
3861 ((char *)pService) + pdiff, f);
3866 if (pService->param_opt != NULL) {
3867 data = pService->param_opt;
3869 fprintf(f, "\t%s = %s\n", data->key, data->value);
3875 /***************************************************************************
3876 Display the contents of a parameter of a single services record.
3877 ***************************************************************************/
3879 BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
3881 service * pService = ServicePtrs[snum];
3882 int i, result = False;
3892 for (i = 0; parm_table[i].label; i++) {
3893 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
3894 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
3895 parm_table[i].ptr &&
3896 (*parm_table[i].label != '-') &&
3897 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3902 ptr = parm_table[i].ptr;
3904 ptr = ((char *)pService) +
3905 PTR_DIFF(parm_table[i].ptr, &sDefault);
3907 print_parameter(&parm_table[i],
3918 /***************************************************************************
3919 Return info about the next service in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
3920 Return NULL when out of parameters.
3921 ***************************************************************************/
3923 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3926 /* do the globals */
3927 for (; parm_table[*i].label; (*i)++) {
3928 if (parm_table[*i].p_class == P_SEPARATOR)
3929 return &parm_table[(*i)++];
3931 if (!parm_table[*i].ptr
3932 || (*parm_table[*i].label == '-'))
3936 && (parm_table[*i].ptr ==
3937 parm_table[(*i) - 1].ptr))
3940 return &parm_table[(*i)++];
3943 service *pService = ServicePtrs[snum];
3945 for (; parm_table[*i].label; (*i)++) {
3946 if (parm_table[*i].p_class == P_SEPARATOR)
3947 return &parm_table[(*i)++];
3949 if (parm_table[*i].p_class == P_LOCAL &&
3950 parm_table[*i].ptr &&
3951 (*parm_table[*i].label != '-') &&
3953 (parm_table[*i].ptr !=
3954 parm_table[(*i) - 1].ptr)))
3957 PTR_DIFF(parm_table[*i].ptr,
3960 if (allparameters ||
3961 !equal_parameter(parm_table[*i].type,
3962 ((char *)pService) +
3964 ((char *)&sDefault) +
3967 return &parm_table[(*i)++];
3978 /***************************************************************************
3979 Display the contents of a single copy structure.
3980 ***************************************************************************/
3981 static void dump_copy_map(BOOL *pcopymap)
3987 printf("\n\tNon-Copied parameters:\n");
3989 for (i = 0; parm_table[i].label; i++)
3990 if (parm_table[i].p_class == P_LOCAL &&
3991 parm_table[i].ptr && !pcopymap[i] &&
3992 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3994 printf("\t\t%s\n", parm_table[i].label);
3999 /***************************************************************************
4000 Return TRUE if the passed service number is within range.
4001 ***************************************************************************/
4003 BOOL lp_snum_ok(int iService)
4005 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4008 /***************************************************************************
4009 Auto-load some home services.
4010 ***************************************************************************/
4012 static void lp_add_auto_services(char *str)
4021 s = SMB_STRDUP(str);
4025 homes = lp_servicenumber(HOMES_NAME);
4027 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4028 char *home = get_user_home_dir(p);
4030 if (lp_servicenumber(p) >= 0)
4033 if (home && homes >= 0)
4034 lp_add_home(p, homes, p, home);
4039 /***************************************************************************
4040 Auto-load one printer.
4041 ***************************************************************************/
4043 void lp_add_one_printer(char *name, char *comment)
4045 int printers = lp_servicenumber(PRINTERS_NAME);
4048 if (lp_servicenumber(name) < 0) {
4049 lp_add_printer(name, printers);
4050 if ((i = lp_servicenumber(name)) >= 0) {
4051 string_set(&ServicePtrs[i]->comment, comment);
4052 ServicePtrs[i]->autoloaded = True;
4057 /***************************************************************************
4058 Have we loaded a services file yet?
4059 ***************************************************************************/
4061 BOOL lp_loaded(void)
4066 /***************************************************************************
4067 Unload unused services.
4068 ***************************************************************************/
4070 void lp_killunused(BOOL (*snumused) (int))
4073 for (i = 0; i < iNumServices; i++) {
4077 /* don't kill autoloaded or usershare services */
4078 if ( ServicePtrs[i]->autoloaded ||
4079 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4083 if (!snumused || !snumused(i)) {
4084 free_service_byindex(i);
4089 /***************************************************************************
4091 ***************************************************************************/
4093 void lp_killservice(int iServiceIn)
4095 if (VALID(iServiceIn)) {
4096 free_service_byindex(iServiceIn);
4100 /***************************************************************************
4101 Save the curent values of all global and sDefault parameters into the
4102 defaults union. This allows swat and testparm to show only the
4103 changed (ie. non-default) parameters.
4104 ***************************************************************************/
4106 static void lp_save_defaults(void)
4109 for (i = 0; parm_table[i].label; i++) {
4110 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4112 switch (parm_table[i].type) {
4114 str_list_copy(&(parm_table[i].def.lvalue),
4115 *(const char ***)parm_table[i].ptr);
4119 if (parm_table[i].ptr) {
4120 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4122 parm_table[i].def.svalue = NULL;
4127 if (parm_table[i].ptr) {
4128 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4130 parm_table[i].def.svalue = NULL;
4135 parm_table[i].def.bvalue =
4136 *(BOOL *)parm_table[i].ptr;
4139 parm_table[i].def.cvalue =
4140 *(char *)parm_table[i].ptr;
4145 parm_table[i].def.ivalue =
4146 *(int *)parm_table[i].ptr;
4152 defaults_saved = True;
4155 /*******************************************************************
4156 Set the server type we will announce as via nmbd.
4157 ********************************************************************/
4159 static const struct srv_role_tab {
4161 const char *role_str;
4162 } srv_role_tab [] = {
4163 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4164 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4165 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4166 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4170 const char* server_role_str(uint32 role)
4173 for (i=0; srv_role_tab[i].role_str; i++) {
4174 if (role == srv_role_tab[i].role) {
4175 return srv_role_tab[i].role_str;
4181 static void set_server_role(void)
4183 server_role = ROLE_STANDALONE;
4185 switch (lp_security()) {
4187 if (lp_domain_logons())
4188 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4191 if (lp_domain_logons())
4192 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4193 server_role = ROLE_DOMAIN_MEMBER;
4196 if (lp_domain_logons()) {
4197 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4198 server_role = ROLE_DOMAIN_BDC;
4201 server_role = ROLE_DOMAIN_MEMBER;
4204 if (lp_domain_logons()) {
4205 server_role = ROLE_DOMAIN_PDC;
4208 server_role = ROLE_DOMAIN_MEMBER;
4211 if (lp_domain_logons()) {
4213 if (Globals.bDomainMaster) /* auto or yes */
4214 server_role = ROLE_DOMAIN_PDC;
4216 server_role = ROLE_DOMAIN_BDC;
4220 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4224 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4227 /***********************************************************
4228 If we should send plaintext/LANMAN passwords in the clinet
4229 ************************************************************/
4231 static void set_allowed_client_auth(void)
4233 if (Globals.bClientNTLMv2Auth) {
4234 Globals.bClientLanManAuth = False;
4236 if (!Globals.bClientLanManAuth) {
4237 Globals.bClientPlaintextAuth = False;
4241 /***************************************************************************
4243 The following code allows smbd to read a user defined share file.
4244 Yes, this is my intent. Yes, I'm comfortable with that...
4246 THE FOLLOWING IS SECURITY CRITICAL CODE.
4248 It washes your clothes, it cleans your house, it guards you while you sleep...
4249 Do not f%^k with it....
4250 ***************************************************************************/
4252 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4254 /***************************************************************************
4255 Check allowed stat state of a usershare file.
4256 Ensure we print out who is dicking with us so the admin can
4257 get their sorry ass fired.
4258 ***************************************************************************/
4260 static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4262 if (!S_ISREG(psbuf->st_mode)) {
4263 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4264 "not a regular file\n",
4265 fname, (unsigned int)psbuf->st_uid ));
4269 /* Ensure this doesn't have the other write bit set. */
4270 if (psbuf->st_mode & S_IWOTH) {
4271 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4272 "public write. Refusing to allow as a usershare file.\n",
4273 fname, (unsigned int)psbuf->st_uid ));
4277 /* Should be 10k or less. */
4278 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4279 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4280 "too large (%u) to be a user share file.\n",
4281 fname, (unsigned int)psbuf->st_uid,
4282 (unsigned int)psbuf->st_size ));
4289 /***************************************************************************
4290 Parse the contents of a usershare file.
4291 ***************************************************************************/
4293 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4294 SMB_STRUCT_STAT *psbuf,
4295 const char *servicename,
4303 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4304 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4306 SMB_STRUCT_STAT sbuf;
4309 return USERSHARE_MALFORMED_FILE;
4312 if (!strequal(lines[0], "#VERSION 1")) {
4313 return USERSHARE_BAD_VERSION;
4316 if (!strnequal(lines[1], "path=", 5)) {
4317 return USERSHARE_MALFORMED_PATH;
4320 pstrcpy(sharepath, &lines[1][5]);
4321 trim_string(sharepath, " ", " ");
4323 if (!strnequal(lines[2], "comment=", 8)) {
4324 return USERSHARE_MALFORMED_COMMENT_DEF;
4327 pstrcpy(comment, &lines[2][8]);
4328 trim_string(comment, " ", " ");
4329 trim_char(comment, '"', '"');
4331 if (!strnequal(lines[3], "usershare_acl=", 14)) {
4332 return USERSHARE_MALFORMED_ACL_DEF;
4335 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4336 return USERSHARE_ACL_ERR;
4339 if (snum != -1 && strequal(sharepath, ServicePtrs[snum]->szPath)) {
4340 /* Path didn't change, no checks needed. */
4341 return USERSHARE_OK;
4344 /* The path *must* be absolute. */
4345 if (sharepath[0] != '/') {
4346 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4347 servicename, sharepath));
4348 return USERSHARE_PATH_NOT_ABSOLUTE;
4351 /* If there is a usershare prefix deny list ensure one of these paths
4352 doesn't match the start of the user given path. */
4353 if (prefixdenylist) {
4355 for ( i=0; prefixdenylist[i]; i++ ) {
4356 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4357 servicename, i, prefixdenylist[i], sharepath ));
4358 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4359 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4360 "usershare prefix deny list entries.\n",
4361 servicename, sharepath));
4362 return USERSHARE_PATH_IS_DENIED;
4367 /* If there is a usershare prefix allow list ensure one of these paths
4368 does match the start of the user given path. */
4370 if (prefixallowlist) {
4372 for ( i=0; prefixallowlist[i]; i++ ) {
4373 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4374 servicename, i, prefixallowlist[i], sharepath ));
4375 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4379 if (prefixallowlist[i] == NULL) {
4380 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4381 "usershare prefix allow list entries.\n",
4382 servicename, sharepath));
4383 return USERSHARE_PATH_NOT_ALLOWED;
4387 /* Ensure this is pointing to a directory. */
4388 dp = sys_opendir(sharepath);
4391 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4392 servicename, sharepath));
4393 return USERSHARE_PATH_NOT_DIRECTORY;
4396 /* Ensure the owner of the usershare file has permission to share
4399 if (sys_stat(sharepath, &sbuf) == -1) {
4400 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4401 servicename, sharepath, strerror(errno) ));
4403 return USERSHARE_POSIX_ERR;
4408 if (!S_ISDIR(sbuf.st_mode)) {
4409 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4410 servicename, sharepath ));
4411 return USERSHARE_PATH_NOT_DIRECTORY;
4414 /* Check if sharing is restricted to owner-only. */
4415 /* psbuf is the stat of the usershare definition file,
4416 sbuf is the stat of the target directory to be shared. */
4418 if (lp_usershare_owner_only()) {
4419 /* root can share anything. */
4420 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
4421 return USERSHARE_PATH_NOT_ALLOWED;
4425 return USERSHARE_OK;
4428 /***************************************************************************
4429 Deal with a usershare file.
4432 -1 - Bad name, invalid contents.
4433 - service name already existed and not a usershare, problem
4434 with permissions to share directory etc.
4435 ***************************************************************************/
4437 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4439 SMB_STRUCT_STAT sbuf;
4440 SMB_STRUCT_STAT lsbuf;
4444 fstring service_name;
4445 char **lines = NULL;
4449 TALLOC_CTX *ctx = NULL;
4450 SEC_DESC *psd = NULL;
4452 /* Ensure share name doesn't contain invalid characters. */
4453 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4454 DEBUG(0,("process_usershare_file: share name %s contains "
4455 "invalid characters (any of %s)\n",
4456 file_name, INVALID_SHARENAME_CHARS ));
4460 fstrcpy(service_name, file_name);
4462 pstrcpy(fname, dir_name);
4463 pstrcat(fname, "/");
4464 pstrcat(fname, file_name);
4466 /* Minimize the race condition by doing an lstat before we
4467 open and fstat. Ensure this isn't a symlink link. */
4469 if (sys_lstat(fname, &lsbuf) != 0) {
4470 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4471 fname, strerror(errno) ));
4475 /* This must be a regular file, not a symlink, directory or
4476 other strange filetype. */
4477 if (!check_usershare_stat(fname, &lsbuf)) {
4481 /* See if there is already a servicenum for this name. */
4482 /* tdb_fetch_int32 returns -1 if not found. */
4483 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
4485 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
4486 /* Nothing changed - Mark valid and return. */
4487 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4489 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4493 /* Try and open the file read only - no symlinks allowed. */
4495 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
4497 fd = sys_open(fname, O_RDONLY, 0);
4501 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4502 fname, strerror(errno) ));
4506 /* Now fstat to be *SURE* it's a regular file. */
4507 if (sys_fstat(fd, &sbuf) != 0) {
4509 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4510 fname, strerror(errno) ));
4514 /* Is it the same dev/inode as was lstated ? */
4515 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
4517 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4518 "Symlink spoofing going on ?\n", fname ));
4522 /* This must be a regular file, not a symlink, directory or
4523 other strange filetype. */
4524 if (!check_usershare_stat(fname, &sbuf)) {
4528 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
4531 if (lines == NULL) {
4532 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4533 fname, (unsigned int)sbuf.st_uid ));
4536 /* Should we allow printers to be shared... ? */
4537 ctx = talloc_init("usershare_sd_xctx");
4543 if (parse_usershare_file(ctx, &sbuf, service_name, iService, lines, numlines, sharepath, comment, &psd) != USERSHARE_OK) {
4544 talloc_destroy(ctx);
4551 /* Everything ok - add the service possibly using a template. */
4553 const service *sp = &sDefault;
4554 if (snum_template != -1) {
4555 sp = ServicePtrs[snum_template];
4558 if ((iService = add_a_service(sp, service_name)) < 0) {
4559 DEBUG(0, ("process_usershare_file: Failed to add "
4560 "new service %s\n", service_name));
4561 talloc_destroy(ctx);
4565 /* Read only is controlled by usershare ACL below. */
4566 ServicePtrs[iService]->bRead_only = False;
4569 /* Write the ACL of the new/modified share. */
4570 if (!set_share_security(ctx, service_name, psd)) {
4571 DEBUG(0, ("process_usershare_file: Failed to set share "
4572 "security for user share %s\n",
4574 lp_remove_service(iService);
4575 talloc_destroy(ctx);
4579 talloc_destroy(ctx);
4581 /* If from a template it may be marked invalid. */
4582 ServicePtrs[iService]->valid = True;
4584 /* Set the service as a valid usershare. */
4585 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4587 /* And note when it was loaded. */
4588 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
4589 string_set(&ServicePtrs[iService]->szPath, sharepath);
4590 string_set(&ServicePtrs[iService]->comment, comment);
4595 /***************************************************************************
4596 Checks if a usershare entry has been modified since last load.
4597 ***************************************************************************/
4599 static BOOL usershare_exists(int iService, time_t *last_mod)
4601 SMB_STRUCT_STAT lsbuf;
4602 const char *usersharepath = Globals.szUsersharePath;
4605 pstrcpy(fname, usersharepath);
4606 pstrcat(fname, "/");
4607 pstrcat(fname, ServicePtrs[iService]->szService);
4609 if (sys_lstat(fname, &lsbuf) != 0) {
4613 if (!S_ISREG(lsbuf.st_mode)) {
4617 *last_mod = lsbuf.st_mtime;
4621 /***************************************************************************
4622 Load a usershare service by name. Returns a valid servicenumber or -1.
4623 ***************************************************************************/
4625 int load_usershare_service(const char *servicename)
4627 SMB_STRUCT_STAT sbuf;
4628 const char *usersharepath = Globals.szUsersharePath;
4629 int max_user_shares = Globals.iUsershareMaxShares;
4630 int snum_template = -1;
4632 if (*usersharepath == 0 || max_user_shares == 0) {
4636 if (sys_stat(usersharepath, &sbuf) != 0) {
4637 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4638 usersharepath, strerror(errno) ));
4642 if (!S_ISDIR(sbuf.st_mode)) {
4643 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4649 * This directory must be owned by root, and have the 't' bit set.
4650 * It also must not be writable by "other".
4654 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4656 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4658 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4659 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4664 /* Ensure the template share exists if it's set. */
4665 if (Globals.szUsershareTemplateShare[0]) {
4666 /* We can't use lp_servicenumber here as we are recommending that
4667 template shares have -valid=False set. */
4668 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4669 if (ServicePtrs[snum_template]->szService &&
4670 strequal(ServicePtrs[snum_template]->szService,
4671 Globals.szUsershareTemplateShare)) {
4676 if (snum_template == -1) {
4677 DEBUG(0,("load_usershare_service: usershare template share %s "
4678 "does not exist.\n",
4679 Globals.szUsershareTemplateShare ));
4684 return process_usershare_file(usersharepath, servicename, snum_template);
4687 /***************************************************************************
4688 Load all user defined shares from the user share directory.
4689 We only do this if we're enumerating the share list.
4690 This is the function that can delete usershares that have
4692 ***************************************************************************/
4694 int load_usershare_shares(void)
4697 SMB_STRUCT_STAT sbuf;
4698 SMB_STRUCT_DIRENT *de;
4699 int num_usershares = 0;
4700 int max_user_shares = Globals.iUsershareMaxShares;
4701 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4702 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4703 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4705 int snum_template = -1;
4706 const char *usersharepath = Globals.szUsersharePath;
4707 int ret = lp_numservices();
4709 if (max_user_shares == 0 || *usersharepath == '\0') {
4710 return lp_numservices();
4713 if (sys_stat(usersharepath, &sbuf) != 0) {
4714 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4715 usersharepath, strerror(errno) ));
4720 * This directory must be owned by root, and have the 't' bit set.
4721 * It also must not be writable by "other".
4725 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4727 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4729 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4730 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4735 /* Ensure the template share exists if it's set. */
4736 if (Globals.szUsershareTemplateShare[0]) {
4737 /* We can't use lp_servicenumber here as we are recommending that
4738 template shares have -valid=False set. */
4739 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4740 if (ServicePtrs[snum_template]->szService &&
4741 strequal(ServicePtrs[snum_template]->szService,
4742 Globals.szUsershareTemplateShare)) {
4747 if (snum_template == -1) {
4748 DEBUG(0,("load_usershare_shares: usershare template share %s "
4749 "does not exist.\n",
4750 Globals.szUsershareTemplateShare ));
4755 /* Mark all existing usershares as pending delete. */
4756 for (iService = iNumServices - 1; iService >= 0; iService--) {
4757 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4758 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4762 dp = sys_opendir(usersharepath);
4764 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4765 usersharepath, strerror(errno) ));
4769 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4770 (de = sys_readdir(dp));
4771 num_dir_entries++ ) {
4773 const char *n = de->d_name;
4775 /* Ignore . and .. */
4777 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4783 /* Temporary file used when creating a share. */
4784 num_tmp_dir_entries++;
4787 /* Allow 20% tmp entries. */
4788 if (num_tmp_dir_entries > allowed_tmp_entries) {
4789 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4790 "in directory %s\n",
4791 num_tmp_dir_entries, usersharepath));
4795 r = process_usershare_file(usersharepath, n, snum_template);
4797 /* Update the services count. */
4799 if (num_usershares >= max_user_shares) {
4800 DEBUG(0,("load_usershare_shares: max user shares reached "
4801 "on file %s in directory %s\n",
4802 n, usersharepath ));
4805 } else if (r == -1) {
4806 num_bad_dir_entries++;
4809 /* Allow 20% bad entries. */
4810 if (num_bad_dir_entries > allowed_bad_entries) {
4811 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4812 "in directory %s\n",
4813 num_bad_dir_entries, usersharepath));
4817 /* Allow 20% bad entries. */
4818 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4819 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4820 "in directory %s\n",
4821 num_dir_entries, usersharepath));
4828 /* Sweep through and delete any non-refreshed usershares that are
4829 not currently in use. */
4830 for (iService = iNumServices - 1; iService >= 0; iService--) {
4831 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4832 if (conn_snum_used(iService)) {
4835 /* Remove from the share ACL db. */
4836 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4837 lp_servicename(iService) ));
4838 delete_share_security(iService);
4839 free_service_byindex(iService);
4843 return lp_numservices();
4846 /***************************************************************************
4847 Load the services array from the services file. Return True on success,
4849 ***************************************************************************/
4851 BOOL lp_load(const char *pszFname,
4855 BOOL initialize_globals)
4859 param_opt_struct *data, *pdata;
4861 pstrcpy(n2, pszFname);
4863 standard_sub_basic( get_current_username(), n2,sizeof(n2) );
4865 add_to_file_list(pszFname, n2);
4869 DEBUG(3, ("lp_load: refreshing parameters\n"));
4871 bInGlobalSection = True;
4872 bGlobalOnly = global_only;
4874 init_globals(! initialize_globals);
4877 if (save_defaults) {
4882 if (Globals.param_opt != NULL) {
4883 data = Globals.param_opt;
4885 string_free(&data->key);
4886 string_free(&data->value);
4887 str_list_free(&data->list);
4892 Globals.param_opt = NULL;
4895 /* We get sections first, so have to start 'behind' to make up */
4897 bRetval = pm_process(n2, do_section, do_parameter);
4899 /* finish up the last section */
4900 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4902 if (iServiceIndex >= 0)
4903 bRetval = service_ok(iServiceIndex);
4905 lp_add_auto_services(lp_auto_services());
4908 /* When 'restrict anonymous = 2' guest connections to ipc$
4910 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4911 if ( lp_enable_asu_support() )
4912 lp_add_ipc("ADMIN$", False);
4916 set_default_server_announce_type();
4917 set_allowed_client_auth();
4921 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
4922 /* if bWINSsupport is true and we are in the client */
4923 if (in_client && Globals.bWINSsupport) {
4924 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4932 /***************************************************************************
4933 Reset the max number of services.
4934 ***************************************************************************/
4936 void lp_resetnumservices(void)
4941 /***************************************************************************
4942 Return the max number of services.
4943 ***************************************************************************/
4945 int lp_numservices(void)
4947 return (iNumServices);
4950 /***************************************************************************
4951 Display the contents of the services array in human-readable form.
4952 ***************************************************************************/
4954 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
4959 defaults_saved = False;
4963 dump_a_service(&sDefault, f);
4965 for (iService = 0; iService < maxtoprint; iService++) {
4967 lp_dump_one(f, show_defaults, iService);
4971 /***************************************************************************
4972 Display the contents of one service in human-readable form.
4973 ***************************************************************************/
4975 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
4978 if (ServicePtrs[snum]->szService[0] == '\0')
4980 dump_a_service(ServicePtrs[snum], f);
4984 /***************************************************************************
4985 Return the number of the service with the given name, or -1 if it doesn't
4986 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4987 getservicebyname()! This works ONLY if all services have been loaded, and
4988 does not copy the found service.
4989 ***************************************************************************/
4991 int lp_servicenumber(const char *pszServiceName)
4994 fstring serviceName;
4996 if (!pszServiceName) {
4997 return GLOBAL_SECTION_SNUM;
5000 for (iService = iNumServices - 1; iService >= 0; iService--) {
5001 if (VALID(iService) && ServicePtrs[iService]->szService) {
5003 * The substitution here is used to support %U is
5006 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5007 standard_sub_basic(get_current_username(), serviceName,sizeof(serviceName));
5008 if (strequal(serviceName, pszServiceName)) {
5014 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5017 if (!usershare_exists(iService, &last_mod)) {
5018 /* Remove the share security tdb entry for it. */
5019 delete_share_security(iService);
5020 /* Remove it from the array. */
5021 free_service_byindex(iService);
5022 /* Doesn't exist anymore. */
5023 return GLOBAL_SECTION_SNUM;
5026 /* Has it been modified ? If so delete and reload. */
5027 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5028 /* Remove it from the array. */
5029 free_service_byindex(iService);
5030 /* and now reload it. */
5031 iService = load_usershare_service(pszServiceName);
5036 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5037 return GLOBAL_SECTION_SNUM;
5043 /*******************************************************************
5044 A useful volume label function.
5045 ********************************************************************/
5047 char *volume_label(int snum)
5049 char *ret = lp_volume(snum);
5051 return lp_servicename(snum);
5056 /*******************************************************************
5057 Set the server type we will announce as via nmbd.
5058 ********************************************************************/
5060 static void set_default_server_announce_type(void)
5062 default_server_announce = 0;
5063 default_server_announce |= SV_TYPE_WORKSTATION;
5064 default_server_announce |= SV_TYPE_SERVER;
5065 default_server_announce |= SV_TYPE_SERVER_UNIX;
5067 /* note that the flag should be set only if we have a
5068 printer service but nmbd doesn't actually load the
5069 services so we can't tell --jerry */
5071 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5073 switch (lp_announce_as()) {
5074 case ANNOUNCE_AS_NT_SERVER:
5075 default_server_announce |= SV_TYPE_SERVER_NT;
5076 /* fall through... */
5077 case ANNOUNCE_AS_NT_WORKSTATION:
5078 default_server_announce |= SV_TYPE_NT;
5080 case ANNOUNCE_AS_WIN95:
5081 default_server_announce |= SV_TYPE_WIN95_PLUS;
5083 case ANNOUNCE_AS_WFW:
5084 default_server_announce |= SV_TYPE_WFW;
5090 switch (lp_server_role()) {
5091 case ROLE_DOMAIN_MEMBER:
5092 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5094 case ROLE_DOMAIN_PDC:
5095 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5097 case ROLE_DOMAIN_BDC:
5098 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5100 case ROLE_STANDALONE:
5104 if (lp_time_server())
5105 default_server_announce |= SV_TYPE_TIME_SOURCE;
5107 if (lp_host_msdfs())
5108 default_server_announce |= SV_TYPE_DFS_SERVER;
5111 /***********************************************************
5112 returns role of Samba server
5113 ************************************************************/
5115 int lp_server_role(void)
5120 /***********************************************************
5121 If we are PDC then prefer us as DMB
5122 ************************************************************/
5124 BOOL lp_domain_master(void)
5126 if (Globals.bDomainMaster == Auto)
5127 return (lp_server_role() == ROLE_DOMAIN_PDC);
5129 return Globals.bDomainMaster;
5132 /***********************************************************
5133 If we are DMB then prefer us as LMB
5134 ************************************************************/
5136 BOOL lp_preferred_master(void)
5138 if (Globals.bPreferredMaster == Auto)
5139 return (lp_local_master() && lp_domain_master());
5141 return Globals.bPreferredMaster;
5144 /*******************************************************************
5146 ********************************************************************/
5148 void lp_remove_service(int snum)
5150 ServicePtrs[snum]->valid = False;
5151 invalid_services[num_invalid_services++] = snum;
5154 /*******************************************************************
5156 ********************************************************************/
5158 void lp_copy_service(int snum, const char *new_name)
5160 do_section(new_name);
5162 snum = lp_servicenumber(new_name);
5164 lp_do_parameter(snum, "copy", lp_servicename(snum));
5169 /*******************************************************************
5170 Get the default server type we will announce as via nmbd.
5171 ********************************************************************/
5173 int lp_default_server_announce(void)
5175 return default_server_announce;
5178 /*******************************************************************
5179 Split the announce version into major and minor numbers.
5180 ********************************************************************/
5182 int lp_major_announce_version(void)
5184 static BOOL got_major = False;
5185 static int major_version = DEFAULT_MAJOR_VERSION;
5190 return major_version;
5193 if ((vers = lp_announce_version()) == NULL)
5194 return major_version;
5196 if ((p = strchr_m(vers, '.')) == 0)
5197 return major_version;
5200 major_version = atoi(vers);
5201 return major_version;
5204 int lp_minor_announce_version(void)
5206 static BOOL got_minor = False;
5207 static int minor_version = DEFAULT_MINOR_VERSION;
5212 return minor_version;
5215 if ((vers = lp_announce_version()) == NULL)
5216 return minor_version;
5218 if ((p = strchr_m(vers, '.')) == 0)
5219 return minor_version;
5222 minor_version = atoi(p);
5223 return minor_version;
5226 /***********************************************************
5227 Set the global name resolution order (used in smbclient).
5228 ************************************************************/
5230 void lp_set_name_resolve_order(const char *new_order)
5232 string_set(&Globals.szNameResolveOrder, new_order);
5235 const char *lp_printername(int snum)
5237 const char *ret = _lp_printername(snum);
5238 if (ret == NULL || (ret != NULL && *ret == '\0'))
5239 ret = lp_const_servicename(snum);
5245 /****************************************************************
5246 Compatibility fn. for 2.2.2 code.....
5247 *****************************************************************/
5249 void get_private_directory(pstring privdir)
5251 pstrcpy (privdir, lp_private_dir());
5254 /***********************************************************
5255 Allow daemons such as winbindd to fix their logfile name.
5256 ************************************************************/
5258 void lp_set_logfile(const char *name)
5260 string_set(&Globals.szLogFile, name);
5261 pstrcpy(debugf, name);
5264 /*******************************************************************
5265 Return the max print jobs per queue.
5266 ********************************************************************/
5268 int lp_maxprintjobs(int snum)
5270 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5271 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5272 maxjobs = PRINT_MAX_JOBID - 1;
5277 const char *lp_printcapname(void)
5279 if ((Globals.szPrintcapname != NULL) &&
5280 (Globals.szPrintcapname[0] != '\0'))
5281 return Globals.szPrintcapname;
5283 if (sDefault.iPrinting == PRINT_CUPS) {
5291 if (sDefault.iPrinting == PRINT_BSD)
5292 return "/etc/printcap";
5294 return PRINTCAP_NAME;
5297 /*******************************************************************
5298 Ensure we don't use sendfile if server smb signing is active.
5299 ********************************************************************/
5301 static uint32 spoolss_state;
5303 BOOL lp_disable_spoolss( void )
5305 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5306 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5308 return spoolss_state == SVCCTL_STOPPED ? True : False;
5311 void lp_set_spoolss_state( uint32 state )
5313 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5315 spoolss_state = state;
5318 uint32 lp_get_spoolss_state( void )
5320 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5323 /*******************************************************************
5324 Ensure we don't use sendfile if server smb signing is active.
5325 ********************************************************************/
5327 BOOL lp_use_sendfile(int snum)
5329 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5330 if (Protocol < PROTOCOL_NT1) {
5333 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
5336 /*******************************************************************
5337 Turn off sendfile if we find the underlying OS doesn't support it.
5338 ********************************************************************/
5340 void set_use_sendfile(int snum, BOOL val)
5342 if (LP_SNUM_OK(snum))
5343 ServicePtrs[snum]->bUseSendfile = val;
5345 sDefault.bUseSendfile = val;
5348 /*******************************************************************
5349 Turn off storing DOS attributes if this share doesn't support it.
5350 ********************************************************************/
5352 void set_store_dos_attributes(int snum, BOOL val)
5354 if (!LP_SNUM_OK(snum))
5356 ServicePtrs[(snum)]->bStoreDosAttributes = val;
5359 void lp_set_mangling_method(const char *new_method)
5361 string_set(&Globals.szManglingMethod, new_method);
5364 /*******************************************************************
5365 Global state for POSIX pathname processing.
5366 ********************************************************************/
5368 static BOOL posix_pathnames;
5370 BOOL lp_posix_pathnames(void)
5372 return posix_pathnames;
5375 /*******************************************************************
5376 Change everything needed to ensure POSIX pathname processing (currently
5378 ********************************************************************/
5380 void lp_set_posix_pathnames(void)
5382 posix_pathnames = True;