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
12 Copyright (C) Michael Adam 2008
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 3 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
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
55 #include "libnet/libnet.h"
59 extern enum protocol_types Protocol;
60 extern userdom_struct current_user_info;
63 #define GLOBAL_NAME "global"
67 #define PRINTERS_NAME "printers"
71 #define HOMES_NAME "homes"
74 static bool in_client = False; /* Not in the client by default */
75 static uint64_t conf_last_seqnum = 0;
76 static struct libnet_conf_ctx *conf_ctx = NULL;
78 #define CONFIG_BACKEND_FILE 0
79 #define CONFIG_BACKEND_REGISTRY 1
81 static int config_backend = CONFIG_BACKEND_FILE;
83 /* some helpful bits */
84 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
85 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
87 #define USERSHARE_VALID 1
88 #define USERSHARE_PENDING_DELETE 2
90 extern int extra_time_offset;
92 static bool defaults_saved = False;
94 typedef struct _param_opt_struct param_opt_struct;
95 struct _param_opt_struct {
96 param_opt_struct *prev, *next;
103 * This structure describes global (ie., server-wide) parameters.
110 char *display_charset;
111 char *szPrintcapname;
112 char *szAddPortCommand;
113 char *szEnumPortsCommand;
114 char *szAddPrinterCommand;
115 char *szDeletePrinterCommand;
116 char *szOs2DriverMap;
120 char *szDefaultService;
124 char *szServerString;
125 char *szAutoServices;
126 char *szPasswdProgram;
130 char *szSMBPasswdFile;
132 char *szPassdbBackend;
133 char **szPreloadModules;
134 char *szPasswordServer;
135 char *szSocketOptions;
137 char *szAfsUsernameMap;
138 int iAfsTokenLifetime;
139 char *szLogNtTokenCommand;
145 char **szWINSservers;
147 char *szRemoteAnnounce;
148 char *szRemoteBrowseSync;
149 char *szSocketAddress;
150 char *szNISHomeMapName;
151 char *szAnnounceVersion; /* This is initialised in init_globals */
154 char **szNetbiosAliases;
155 char *szNetbiosScope;
156 char *szNameResolveOrder;
158 char *szAddUserScript;
159 char *szRenameUserScript;
160 char *szDelUserScript;
161 char *szAddGroupScript;
162 char *szDelGroupScript;
163 char *szAddUserToGroupScript;
164 char *szDelUserFromGroupScript;
165 char *szSetPrimaryGroupScript;
166 char *szAddMachineScript;
167 char *szShutdownScript;
168 char *szAbortShutdownScript;
169 char *szUsernameMapScript;
170 char *szCheckPasswordScript;
177 bool bPassdbExpandExplicit;
178 int AlgorithmicRidBase;
179 char *szTemplateHomedir;
180 char *szTemplateShell;
181 char *szWinbindSeparator;
182 bool bWinbindEnumUsers;
183 bool bWinbindEnumGroups;
184 bool bWinbindUseDefaultDomain;
185 bool bWinbindTrustedDomainsOnly;
186 bool bWinbindNestedGroups;
187 int winbind_expand_groups;
188 bool bWinbindRefreshTickets;
189 bool bWinbindOfflineLogon;
190 bool bWinbindNormalizeNames;
191 bool bWinbindRpcOnly;
192 char **szIdmapDomains;
193 char **szIdmapBackend; /* deprecated */
194 char *szIdmapAllocBackend;
195 char *szAddShareCommand;
196 char *szChangeShareCommand;
197 char *szDeleteShareCommand;
199 char *szGuestaccount;
200 char *szManglingMethod;
201 char **szServicesList;
202 char *szUsersharePath;
203 char *szUsershareTemplateShare;
204 char **szUsersharePrefixAllowList;
205 char **szUsersharePrefixDenyList;
212 int open_files_db_hash_size;
221 bool paranoid_server_security;
224 int iMaxSmbdProcesses;
225 bool bDisableSpoolss;
228 bool enhanced_browsing;
234 int announce_as; /* This is initialised in init_globals */
235 int machine_password_timeout;
237 int oplock_break_wait_time;
238 int winbind_cache_time;
239 int winbind_max_idle_children;
240 char **szWinbindNssInfo;
242 char *szLdapMachineSuffix;
243 char *szLdapUserSuffix;
244 char *szLdapIdmapSuffix;
245 char *szLdapGroupSuffix;
249 int ldap_debug_level;
250 int ldap_debug_threshold;
253 char *szIPrintServer;
255 char **szClusterAddresses;
257 int ldap_passwd_sync;
258 int ldap_replication_sleep;
259 int ldap_timeout; /* This is initialised in init_globals */
262 bool bMsAddPrinterWizard;
267 int iPreferredMaster;
270 bool bEncryptPasswords;
275 bool bObeyPamRestrictions;
277 int PrintcapCacheTime;
278 bool bLargeReadwrite;
285 bool bBindInterfacesOnly;
286 bool bPamPasswordChange;
287 bool bUnixPasswdSync;
288 bool bPasswdChatDebug;
289 int iPasswdChatTimeout;
293 bool bNTStatusSupport;
295 int iMaxStatCacheSize;
297 bool bAllowTrustedDomains;
301 bool bClientLanManAuth;
302 bool bClientNTLMv2Auth;
303 bool bClientPlaintextAuth;
304 bool bClientUseSpnego;
305 bool bDebugPrefixTimestamp;
306 bool bDebugHiresTimestamp;
310 bool bEnableCoreFiles;
313 bool bHostnameLookups;
314 bool bUnixExtensions;
315 bool bDisableNetbios;
316 bool bUseKerberosKeytab;
317 bool bDeferSharingViolations;
318 bool bEnablePrivileges;
320 bool bUsershareOwnerOnly;
321 bool bUsershareAllowGuests;
322 bool bRegistryShares;
323 int restrict_anonymous;
324 int name_cache_timeout;
327 int client_ldap_sasl_wrapping;
328 int iUsershareMaxShares;
330 int iIdmapNegativeCacheTime;
334 param_opt_struct *param_opt;
337 static struct global Globals;
340 * This structure describes a single service.
346 time_t usershare_last_mod;
350 char **szInvalidUsers;
358 char *szRootPostExec;
360 char *szPrintcommand;
363 char *szLppausecommand;
364 char *szLpresumecommand;
365 char *szQueuepausecommand;
366 char *szQueueresumecommand;
368 char *szPrintjobUsername;
376 char *szVetoOplockFiles;
382 char **printer_admin;
387 char *szAioWriteBehind;
391 int iMaxReportedPrintJobs;
394 int iCreate_force_mode;
396 int iSecurity_force_mode;
399 int iDir_Security_mask;
400 int iDir_Security_force_mode;
404 int iOplockContentionLimit;
409 bool bRootpreexecClose;
412 bool bShortCasePreserve;
414 bool bHideSpecialFiles;
415 bool bHideUnReadable;
416 bool bHideUnWriteableFiles;
422 bool bAdministrative_share;
428 bool bStoreDosAttributes;
441 bool bStrictAllocate;
444 struct bitmap *copymap;
445 bool bDeleteReadonly;
447 bool bDeleteVetoFiles;
450 bool bDosFiletimeResolution;
451 bool bFakeDirCreateTimes;
457 bool bUseClientDriver;
458 bool bDefaultDevmode;
459 bool bForcePrintername;
461 bool bForceUnknownAclUser;
464 bool bMap_acl_inherit;
467 bool bAclCheckPermissions;
468 bool bAclMapFullControl;
469 bool bAclGroupControl;
471 bool bKernelChangeNotify;
472 int iallocation_roundup_size;
476 int iDirectoryNameCacheSize;
478 param_opt_struct *param_opt;
480 char dummy[3]; /* for alignment */
484 /* This is a default service used to prime a services structure */
485 static struct service sDefault = {
487 False, /* not autoloaded */
488 0, /* not a usershare */
489 (time_t)0, /* No last mod time */
490 NULL, /* szService */
492 NULL, /* szUsername */
493 NULL, /* szInvalidUsers */
494 NULL, /* szValidUsers */
495 NULL, /* szAdminUsers */
497 NULL, /* szInclude */
498 NULL, /* szPreExec */
499 NULL, /* szPostExec */
500 NULL, /* szRootPreExec */
501 NULL, /* szRootPostExec */
502 NULL, /* szCupsOptions */
503 NULL, /* szPrintcommand */
504 NULL, /* szLpqcommand */
505 NULL, /* szLprmcommand */
506 NULL, /* szLppausecommand */
507 NULL, /* szLpresumecommand */
508 NULL, /* szQueuepausecommand */
509 NULL, /* szQueueresumecommand */
510 NULL, /* szPrintername */
511 NULL, /* szPrintjobUsername */
512 NULL, /* szDontdescend */
513 NULL, /* szHostsallow */
514 NULL, /* szHostsdeny */
515 NULL, /* szMagicScript */
516 NULL, /* szMagicOutput */
517 NULL, /* szVetoFiles */
518 NULL, /* szHideFiles */
519 NULL, /* szVetoOplockFiles */
521 NULL, /* force user */
522 NULL, /* force group */
524 NULL, /* writelist */
525 NULL, /* printer admin */
528 NULL, /* vfs objects */
529 NULL, /* szMSDfsProxy */
530 NULL, /* szAioWriteBehind */
532 0, /* iMinPrintSpace */
533 1000, /* iMaxPrintJobs */
534 0, /* iMaxReportedPrintJobs */
535 0, /* iWriteCacheSize */
536 0744, /* iCreate_mask */
537 0000, /* iCreate_force_mode */
538 0777, /* iSecurity_mask */
539 0, /* iSecurity_force_mode */
540 0755, /* iDir_mask */
541 0000, /* iDir_force_mode */
542 0777, /* iDir_Security_mask */
543 0, /* iDir_Security_force_mode */
544 0, /* iMaxConnections */
545 CASE_LOWER, /* iDefaultCase */
546 DEFAULT_PRINTING, /* iPrinting */
547 2, /* iOplockContentionLimit */
549 1024, /* iBlock_size */
550 0, /* iDfreeCacheTime */
551 False, /* bPreexecClose */
552 False, /* bRootpreexecClose */
553 Auto, /* case sensitive */
554 True, /* case preserve */
555 True, /* short case preserve */
556 True, /* bHideDotFiles */
557 False, /* bHideSpecialFiles */
558 False, /* bHideUnReadable */
559 False, /* bHideUnWriteableFiles */
560 True, /* bBrowseable */
561 True, /* bAvailable */
562 True, /* bRead_only */
563 True, /* bNo_set_dir */
564 False, /* bGuest_only */
565 False, /* bAdministrative_share */
566 False, /* bGuest_ok */
567 False, /* bPrint_ok */
568 False, /* bMap_system */
569 False, /* bMap_hidden */
570 True, /* bMap_archive */
571 False, /* bStoreDosAttributes */
572 False, /* bDmapiSupport */
574 Auto, /* iStrictLocking */
575 True, /* bPosixLocking */
576 True, /* bShareModes */
578 True, /* bLevel2OpLocks */
579 False, /* bOnlyUser */
580 True, /* bMangledNames */
581 True, /* bWidelinks */
582 True, /* bSymlinks */
583 False, /* bSyncAlways */
584 False, /* bStrictAllocate */
585 False, /* bStrictSync */
586 '~', /* magic char */
588 False, /* bDeleteReadonly */
589 False, /* bFakeOplocks */
590 False, /* bDeleteVetoFiles */
591 False, /* bDosFilemode */
592 True, /* bDosFiletimes */
593 False, /* bDosFiletimeResolution */
594 False, /* bFakeDirCreateTimes */
595 True, /* bBlockingLocks */
596 False, /* bInheritPerms */
597 False, /* bInheritACLS */
598 False, /* bInheritOwner */
599 False, /* bMSDfsRoot */
600 False, /* bUseClientDriver */
601 True, /* bDefaultDevmode */
602 False, /* bForcePrintername */
603 True, /* bNTAclSupport */
604 False, /* bForceUnknownAclUser */
605 False, /* bUseSendfile */
606 False, /* bProfileAcls */
607 False, /* bMap_acl_inherit */
608 False, /* bAfs_Share */
609 False, /* bEASupport */
610 True, /* bAclCheckPermissions */
611 True, /* bAclMapFullControl */
612 False, /* bAclGroupControl */
613 True, /* bChangeNotify */
614 True, /* bKernelChangeNotify */
615 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
616 0, /* iAioReadSize */
617 0, /* iAioWriteSize */
618 MAP_READONLY_YES, /* iMap_readonly */
619 #ifdef BROKEN_DIRECTORY_HANDLING
620 0, /* iDirectoryNameCacheSize */
622 100, /* iDirectoryNameCacheSize */
624 Auto, /* ismb_encrypt */
625 NULL, /* Parametric options */
630 /* local variables */
631 static struct service **ServicePtrs = NULL;
632 static int iNumServices = 0;
633 static int iServiceIndex = 0;
634 static struct db_context *ServiceHash;
635 static int *invalid_services = NULL;
636 static int num_invalid_services = 0;
637 static bool bInGlobalSection = True;
638 static bool bGlobalOnly = False;
639 static int server_role;
640 static int default_server_announce;
642 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
644 /* prototypes for the special type handlers */
645 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
646 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
647 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
648 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
649 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
650 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
651 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
652 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
653 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
654 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
655 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
656 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
658 static void set_server_role(void);
659 static void set_default_server_announce_type(void);
660 static void set_allowed_client_auth(void);
662 static const struct enum_list enum_protocol[] = {
663 {PROTOCOL_NT1, "NT1"},
664 {PROTOCOL_LANMAN2, "LANMAN2"},
665 {PROTOCOL_LANMAN1, "LANMAN1"},
666 {PROTOCOL_CORE, "CORE"},
667 {PROTOCOL_COREPLUS, "COREPLUS"},
668 {PROTOCOL_COREPLUS, "CORE+"},
672 static const struct enum_list enum_security[] = {
673 {SEC_SHARE, "SHARE"},
675 {SEC_SERVER, "SERVER"},
676 {SEC_DOMAIN, "DOMAIN"},
683 static const struct enum_list enum_printing[] = {
684 {PRINT_SYSV, "sysv"},
686 {PRINT_HPUX, "hpux"},
690 {PRINT_LPRNG, "lprng"},
691 {PRINT_CUPS, "cups"},
692 {PRINT_IPRINT, "iprint"},
694 {PRINT_LPROS2, "os2"},
696 {PRINT_TEST, "test"},
698 #endif /* DEVELOPER */
702 static const struct enum_list enum_ldap_sasl_wrapping[] = {
704 {ADS_AUTH_SASL_SIGN, "sign"},
705 {ADS_AUTH_SASL_SEAL, "seal"},
709 static const struct enum_list enum_ldap_ssl[] = {
710 {LDAP_SSL_OFF, "no"},
711 {LDAP_SSL_OFF, "No"},
712 {LDAP_SSL_OFF, "off"},
713 {LDAP_SSL_OFF, "Off"},
714 {LDAP_SSL_START_TLS, "start tls"},
715 {LDAP_SSL_START_TLS, "Start_tls"},
719 static const struct enum_list enum_ldap_passwd_sync[] = {
720 {LDAP_PASSWD_SYNC_OFF, "no"},
721 {LDAP_PASSWD_SYNC_OFF, "No"},
722 {LDAP_PASSWD_SYNC_OFF, "off"},
723 {LDAP_PASSWD_SYNC_OFF, "Off"},
724 {LDAP_PASSWD_SYNC_ON, "Yes"},
725 {LDAP_PASSWD_SYNC_ON, "yes"},
726 {LDAP_PASSWD_SYNC_ON, "on"},
727 {LDAP_PASSWD_SYNC_ON, "On"},
728 {LDAP_PASSWD_SYNC_ONLY, "Only"},
729 {LDAP_PASSWD_SYNC_ONLY, "only"},
733 /* Types of machine we can announce as. */
734 #define ANNOUNCE_AS_NT_SERVER 1
735 #define ANNOUNCE_AS_WIN95 2
736 #define ANNOUNCE_AS_WFW 3
737 #define ANNOUNCE_AS_NT_WORKSTATION 4
739 static const struct enum_list enum_announce_as[] = {
740 {ANNOUNCE_AS_NT_SERVER, "NT"},
741 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
742 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
743 {ANNOUNCE_AS_WIN95, "win95"},
744 {ANNOUNCE_AS_WFW, "WfW"},
748 static const struct enum_list enum_map_readonly[] = {
749 {MAP_READONLY_NO, "no"},
750 {MAP_READONLY_NO, "false"},
751 {MAP_READONLY_NO, "0"},
752 {MAP_READONLY_YES, "yes"},
753 {MAP_READONLY_YES, "true"},
754 {MAP_READONLY_YES, "1"},
755 {MAP_READONLY_PERMISSIONS, "permissions"},
756 {MAP_READONLY_PERMISSIONS, "perms"},
760 static const struct enum_list enum_case[] = {
761 {CASE_LOWER, "lower"},
762 {CASE_UPPER, "upper"},
766 static const struct enum_list enum_bool_auto[] = {
777 /* Client-side offline caching policy types */
778 #define CSC_POLICY_MANUAL 0
779 #define CSC_POLICY_DOCUMENTS 1
780 #define CSC_POLICY_PROGRAMS 2
781 #define CSC_POLICY_DISABLE 3
783 static const struct enum_list enum_csc_policy[] = {
784 {CSC_POLICY_MANUAL, "manual"},
785 {CSC_POLICY_DOCUMENTS, "documents"},
786 {CSC_POLICY_PROGRAMS, "programs"},
787 {CSC_POLICY_DISABLE, "disable"},
791 /* SMB signing types. */
792 static const struct enum_list enum_smb_signing_vals[] = {
804 {Required, "required"},
805 {Required, "mandatory"},
807 {Required, "forced"},
808 {Required, "enforced"},
812 /* ACL compatibility options. */
813 static const struct enum_list enum_acl_compat_vals[] = {
814 { ACL_COMPAT_AUTO, "auto" },
815 { ACL_COMPAT_WINNT, "winnt" },
816 { ACL_COMPAT_WIN2K, "win2k" },
821 Do you want session setups at user level security with a invalid
822 password to be rejected or allowed in as guest? WinNT rejects them
823 but it can be a pain as it means "net view" needs to use a password
825 You have 3 choices in the setting of map_to_guest:
827 "Never" means session setups with an invalid password
828 are rejected. This is the default.
830 "Bad User" means session setups with an invalid password
831 are rejected, unless the username does not exist, in which case it
832 is treated as a guest login
834 "Bad Password" means session setups with an invalid password
835 are treated as a guest login
837 Note that map_to_guest only has an effect in user or server
841 static const struct enum_list enum_map_to_guest[] = {
842 {NEVER_MAP_TO_GUEST, "Never"},
843 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
844 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
845 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
849 /* Config backend options */
851 static const struct enum_list enum_config_backend[] = {
852 {CONFIG_BACKEND_FILE, "file"},
853 {CONFIG_BACKEND_REGISTRY, "registry"},
857 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
859 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
860 * screen in SWAT. This is used to exclude parameters as well as to squash all
861 * parameters that have been duplicated by pseudonyms.
863 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
864 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
865 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
868 * NOTE2: Handling of duplicated (synonym) paramters:
869 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
870 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
871 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
872 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
875 static struct parm_struct parm_table[] = {
876 {N_("Base Options"), P_SEP, P_SEPARATOR},
879 .label = "dos charset",
882 .ptr = &Globals.dos_charset,
883 .special = handle_charset,
885 .flags = FLAG_ADVANCED
888 .label = "unix charset",
891 .ptr = &Globals.unix_charset,
892 .special = handle_charset,
894 .flags = FLAG_ADVANCED
897 .label = "display charset",
900 .ptr = &Globals.display_charset,
901 .special = handle_charset,
903 .flags = FLAG_ADVANCED
909 .ptr = &sDefault.comment,
912 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
918 .ptr = &sDefault.szPath,
921 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
924 .label = "directory",
927 .ptr = &sDefault.szPath,
933 .label = "workgroup",
936 .ptr = &Globals.szWorkgroup,
937 .special = handle_workgroup,
939 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
946 .ptr = &Globals.szRealm,
949 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
953 .label = "netbios name",
956 .ptr = &Globals.szNetbiosName,
957 .special = handle_netbios_name,
959 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
962 .label = "netbios aliases",
965 .ptr = &Globals.szNetbiosAliases,
966 .special = handle_netbios_aliases,
968 .flags = FLAG_ADVANCED,
971 .label = "netbios scope",
974 .ptr = &Globals.szNetbiosScope,
975 .special = handle_netbios_scope,
977 .flags = FLAG_ADVANCED,
980 .label = "server string",
983 .ptr = &Globals.szServerString,
986 .flags = FLAG_BASIC | FLAG_ADVANCED,
989 .label = "interfaces",
992 .ptr = &Globals.szInterfaces,
995 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
998 .label = "bind interfaces only",
1000 .p_class = P_GLOBAL,
1001 .ptr = &Globals.bBindInterfacesOnly,
1004 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1007 .label = "config backend",
1009 .p_class = P_GLOBAL,
1010 .ptr = &Globals.ConfigBackend,
1012 .enum_list = enum_config_backend,
1013 .flags = FLAG_ADVANCED,
1016 {N_("Security Options"), P_SEP, P_SEPARATOR},
1019 .label = "security",
1021 .p_class = P_GLOBAL,
1022 .ptr = &Globals.security,
1024 .enum_list = enum_security,
1025 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1028 .label = "auth methods",
1030 .p_class = P_GLOBAL,
1031 .ptr = &Globals.AuthMethods,
1034 .flags = FLAG_ADVANCED,
1037 .label = "encrypt passwords",
1039 .p_class = P_GLOBAL,
1040 .ptr = &Globals.bEncryptPasswords,
1043 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1046 .label = "update encrypted",
1048 .p_class = P_GLOBAL,
1049 .ptr = &Globals.bUpdateEncrypt,
1052 .flags = FLAG_ADVANCED,
1055 .label = "client schannel",
1057 .p_class = P_GLOBAL,
1058 .ptr = &Globals.clientSchannel,
1060 .enum_list = enum_bool_auto,
1061 .flags = FLAG_BASIC | FLAG_ADVANCED,
1064 .label = "server schannel",
1066 .p_class = P_GLOBAL,
1067 .ptr = &Globals.serverSchannel,
1069 .enum_list = enum_bool_auto,
1070 .flags = FLAG_BASIC | FLAG_ADVANCED,
1073 .label = "allow trusted domains",
1075 .p_class = P_GLOBAL,
1076 .ptr = &Globals.bAllowTrustedDomains,
1079 .flags = FLAG_ADVANCED,
1082 .label = "map to guest",
1084 .p_class = P_GLOBAL,
1085 .ptr = &Globals.map_to_guest,
1087 .enum_list = enum_map_to_guest,
1088 .flags = FLAG_ADVANCED,
1091 .label = "null passwords",
1093 .p_class = P_GLOBAL,
1094 .ptr = &Globals.bNullPasswords,
1097 .flags = FLAG_ADVANCED,
1100 .label = "obey pam restrictions",
1102 .p_class = P_GLOBAL,
1103 .ptr = &Globals.bObeyPamRestrictions,
1106 .flags = FLAG_ADVANCED,
1109 .label = "password server",
1111 .p_class = P_GLOBAL,
1112 .ptr = &Globals.szPasswordServer,
1115 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1118 .label = "smb passwd file",
1120 .p_class = P_GLOBAL,
1121 .ptr = &Globals.szSMBPasswdFile,
1124 .flags = FLAG_ADVANCED,
1127 .label = "private dir",
1129 .p_class = P_GLOBAL,
1130 .ptr = &Globals.szPrivateDir,
1133 .flags = FLAG_ADVANCED,
1136 .label = "passdb backend",
1138 .p_class = P_GLOBAL,
1139 .ptr = &Globals.szPassdbBackend,
1142 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1145 .label = "algorithmic rid base",
1147 .p_class = P_GLOBAL,
1148 .ptr = &Globals.AlgorithmicRidBase,
1151 .flags = FLAG_ADVANCED,
1154 .label = "root directory",
1156 .p_class = P_GLOBAL,
1157 .ptr = &Globals.szRootdir,
1160 .flags = FLAG_ADVANCED,
1163 .label = "root dir",
1165 .p_class = P_GLOBAL,
1166 .ptr = &Globals.szRootdir,
1174 .p_class = P_GLOBAL,
1175 .ptr = &Globals.szRootdir,
1181 .label = "guest account",
1183 .p_class = P_GLOBAL,
1184 .ptr = &Globals.szGuestaccount,
1187 .flags = FLAG_BASIC | FLAG_ADVANCED,
1190 .label = "enable privileges",
1192 .p_class = P_GLOBAL,
1193 .ptr = &Globals.bEnablePrivileges,
1196 .flags = FLAG_ADVANCED,
1200 .label = "pam password change",
1202 .p_class = P_GLOBAL,
1203 .ptr = &Globals.bPamPasswordChange,
1206 .flags = FLAG_ADVANCED,
1209 .label = "passwd program",
1211 .p_class = P_GLOBAL,
1212 .ptr = &Globals.szPasswdProgram,
1215 .flags = FLAG_ADVANCED,
1218 .label = "passwd chat",
1220 .p_class = P_GLOBAL,
1221 .ptr = &Globals.szPasswdChat,
1224 .flags = FLAG_ADVANCED,
1227 .label = "passwd chat debug",
1229 .p_class = P_GLOBAL,
1230 .ptr = &Globals.bPasswdChatDebug,
1233 .flags = FLAG_ADVANCED,
1236 .label = "passwd chat timeout",
1238 .p_class = P_GLOBAL,
1239 .ptr = &Globals.iPasswdChatTimeout,
1242 .flags = FLAG_ADVANCED,
1245 .label = "check password script",
1247 .p_class = P_GLOBAL,
1248 .ptr = &Globals.szCheckPasswordScript,
1251 .flags = FLAG_ADVANCED,
1254 .label = "username map",
1256 .p_class = P_GLOBAL,
1257 .ptr = &Globals.szUsernameMap,
1260 .flags = FLAG_ADVANCED,
1263 .label = "password level",
1265 .p_class = P_GLOBAL,
1266 .ptr = &Globals.pwordlevel,
1269 .flags = FLAG_ADVANCED,
1272 .label = "username level",
1274 .p_class = P_GLOBAL,
1275 .ptr = &Globals.unamelevel,
1278 .flags = FLAG_ADVANCED,
1281 .label = "unix password sync",
1283 .p_class = P_GLOBAL,
1284 .ptr = &Globals.bUnixPasswdSync,
1287 .flags = FLAG_ADVANCED,
1290 .label = "restrict anonymous",
1292 .p_class = P_GLOBAL,
1293 .ptr = &Globals.restrict_anonymous,
1296 .flags = FLAG_ADVANCED,
1299 .label = "lanman auth",
1301 .p_class = P_GLOBAL,
1302 .ptr = &Globals.bLanmanAuth,
1305 .flags = FLAG_ADVANCED,
1308 .label = "ntlm auth",
1310 .p_class = P_GLOBAL,
1311 .ptr = &Globals.bNTLMAuth,
1314 .flags = FLAG_ADVANCED,
1317 .label = "client NTLMv2 auth",
1319 .p_class = P_GLOBAL,
1320 .ptr = &Globals.bClientNTLMv2Auth,
1323 .flags = FLAG_ADVANCED,
1326 .label = "client lanman auth",
1328 .p_class = P_GLOBAL,
1329 .ptr = &Globals.bClientLanManAuth,
1332 .flags = FLAG_ADVANCED,
1335 .label = "client plaintext auth",
1337 .p_class = P_GLOBAL,
1338 .ptr = &Globals.bClientPlaintextAuth,
1341 .flags = FLAG_ADVANCED,
1344 .label = "username",
1347 .ptr = &sDefault.szUsername,
1350 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1356 .ptr = &sDefault.szUsername,
1365 .ptr = &sDefault.szUsername,
1371 .label = "invalid users",
1374 .ptr = &sDefault.szInvalidUsers,
1377 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1380 .label = "valid users",
1383 .ptr = &sDefault.szValidUsers,
1386 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1389 .label = "admin users",
1392 .ptr = &sDefault.szAdminUsers,
1395 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1398 .label = "read list",
1401 .ptr = &sDefault.readlist,
1404 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1407 .label = "write list",
1410 .ptr = &sDefault.writelist,
1413 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1416 .label = "printer admin",
1419 .ptr = &sDefault.printer_admin,
1422 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1425 .label = "force user",
1428 .ptr = &sDefault.force_user,
1431 .flags = FLAG_ADVANCED | FLAG_SHARE,
1434 .label = "force group",
1437 .ptr = &sDefault.force_group,
1440 .flags = FLAG_ADVANCED | FLAG_SHARE,
1446 .ptr = &sDefault.force_group,
1449 .flags = FLAG_ADVANCED,
1452 .label = "read only",
1455 .ptr = &sDefault.bRead_only,
1458 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1461 .label = "write ok",
1464 .ptr = &sDefault.bRead_only,
1470 .label = "writeable",
1473 .ptr = &sDefault.bRead_only,
1479 .label = "writable",
1482 .ptr = &sDefault.bRead_only,
1488 .label = "acl check permissions",
1491 .ptr = &sDefault.bAclCheckPermissions,
1494 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1497 .label = "acl group control",
1500 .ptr = &sDefault.bAclGroupControl,
1503 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1506 .label = "acl map full control",
1509 .ptr = &sDefault.bAclMapFullControl,
1512 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1515 .label = "create mask",
1518 .ptr = &sDefault.iCreate_mask,
1521 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1524 .label = "create mode",
1527 .ptr = &sDefault.iCreate_mask,
1533 .label = "force create mode",
1536 .ptr = &sDefault.iCreate_force_mode,
1539 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1542 .label = "security mask",
1545 .ptr = &sDefault.iSecurity_mask,
1548 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1551 .label = "force security mode",
1554 .ptr = &sDefault.iSecurity_force_mode,
1557 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1560 .label = "directory mask",
1563 .ptr = &sDefault.iDir_mask,
1566 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1569 .label = "directory mode",
1572 .ptr = &sDefault.iDir_mask,
1575 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1578 .label = "force directory mode",
1581 .ptr = &sDefault.iDir_force_mode,
1584 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1587 .label = "directory security mask",
1590 .ptr = &sDefault.iDir_Security_mask,
1593 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1596 .label = "force directory security mode",
1599 .ptr = &sDefault.iDir_Security_force_mode,
1602 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1605 .label = "force unknown acl user",
1608 .ptr = &sDefault.bForceUnknownAclUser,
1611 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1614 .label = "inherit permissions",
1617 .ptr = &sDefault.bInheritPerms,
1620 .flags = FLAG_ADVANCED | FLAG_SHARE,
1623 .label = "inherit acls",
1626 .ptr = &sDefault.bInheritACLS,
1629 .flags = FLAG_ADVANCED | FLAG_SHARE,
1632 .label = "inherit owner",
1635 .ptr = &sDefault.bInheritOwner,
1638 .flags = FLAG_ADVANCED | FLAG_SHARE,
1641 .label = "guest only",
1644 .ptr = &sDefault.bGuest_only,
1647 .flags = FLAG_ADVANCED | FLAG_SHARE,
1650 .label = "only guest",
1653 .ptr = &sDefault.bGuest_only,
1659 .label = "administrative share",
1662 .ptr = &sDefault.bAdministrative_share,
1665 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1669 .label = "guest ok",
1672 .ptr = &sDefault.bGuest_ok,
1675 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1681 .ptr = &sDefault.bGuest_ok,
1687 .label = "only user",
1690 .ptr = &sDefault.bOnlyUser,
1693 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1696 .label = "hosts allow",
1699 .ptr = &sDefault.szHostsallow,
1702 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1705 .label = "allow hosts",
1708 .ptr = &sDefault.szHostsallow,
1714 .label = "hosts deny",
1717 .ptr = &sDefault.szHostsdeny,
1720 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1723 .label = "deny hosts",
1726 .ptr = &sDefault.szHostsdeny,
1732 .label = "preload modules",
1734 .p_class = P_GLOBAL,
1735 .ptr = &Globals.szPreloadModules,
1738 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1741 .label = "use kerberos keytab",
1743 .p_class = P_GLOBAL,
1744 .ptr = &Globals.bUseKerberosKeytab,
1747 .flags = FLAG_ADVANCED,
1750 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1753 .label = "log level",
1755 .p_class = P_GLOBAL,
1756 .ptr = &Globals.szLogLevel,
1757 .special = handle_debug_list,
1759 .flags = FLAG_ADVANCED,
1762 .label = "debuglevel",
1764 .p_class = P_GLOBAL,
1765 .ptr = &Globals.szLogLevel,
1766 .special = handle_debug_list,
1773 .p_class = P_GLOBAL,
1774 .ptr = &Globals.syslog,
1777 .flags = FLAG_ADVANCED,
1780 .label = "syslog only",
1782 .p_class = P_GLOBAL,
1783 .ptr = &Globals.bSyslogOnly,
1786 .flags = FLAG_ADVANCED,
1789 .label = "log file",
1791 .p_class = P_GLOBAL,
1792 .ptr = &Globals.szLogFile,
1795 .flags = FLAG_ADVANCED,
1798 .label = "max log size",
1800 .p_class = P_GLOBAL,
1801 .ptr = &Globals.max_log_size,
1804 .flags = FLAG_ADVANCED,
1807 .label = "debug timestamp",
1809 .p_class = P_GLOBAL,
1810 .ptr = &Globals.bTimestampLogs,
1813 .flags = FLAG_ADVANCED,
1816 .label = "timestamp logs",
1818 .p_class = P_GLOBAL,
1819 .ptr = &Globals.bTimestampLogs,
1822 .flags = FLAG_ADVANCED,
1825 .label = "debug prefix timestamp",
1827 .p_class = P_GLOBAL,
1828 .ptr = &Globals.bDebugPrefixTimestamp,
1831 .flags = FLAG_ADVANCED,
1834 .label = "debug hires timestamp",
1836 .p_class = P_GLOBAL,
1837 .ptr = &Globals.bDebugHiresTimestamp,
1840 .flags = FLAG_ADVANCED,
1843 .label = "debug pid",
1845 .p_class = P_GLOBAL,
1846 .ptr = &Globals.bDebugPid,
1849 .flags = FLAG_ADVANCED,
1852 .label = "debug uid",
1854 .p_class = P_GLOBAL,
1855 .ptr = &Globals.bDebugUid,
1858 .flags = FLAG_ADVANCED,
1861 .label = "debug class",
1863 .p_class = P_GLOBAL,
1864 .ptr = &Globals.bDebugClass,
1867 .flags = FLAG_ADVANCED,
1870 .label = "enable core files",
1872 .p_class = P_GLOBAL,
1873 .ptr = &Globals.bEnableCoreFiles,
1876 .flags = FLAG_ADVANCED,
1879 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1882 .label = "allocation roundup size",
1885 .ptr = &sDefault.iallocation_roundup_size,
1888 .flags = FLAG_ADVANCED,
1891 .label = "aio read size",
1894 .ptr = &sDefault.iAioReadSize,
1897 .flags = FLAG_ADVANCED,
1900 .label = "aio write size",
1903 .ptr = &sDefault.iAioWriteSize,
1906 .flags = FLAG_ADVANCED,
1909 .label = "aio write behind",
1912 .ptr = &sDefault.szAioWriteBehind,
1915 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1918 .label = "smb ports",
1920 .p_class = P_GLOBAL,
1921 .ptr = &Globals.smb_ports,
1924 .flags = FLAG_ADVANCED,
1927 .label = "large readwrite",
1929 .p_class = P_GLOBAL,
1930 .ptr = &Globals.bLargeReadwrite,
1933 .flags = FLAG_ADVANCED,
1936 .label = "max protocol",
1938 .p_class = P_GLOBAL,
1939 .ptr = &Globals.maxprotocol,
1941 .enum_list = enum_protocol,
1942 .flags = FLAG_ADVANCED,
1945 .label = "protocol",
1947 .p_class = P_GLOBAL,
1948 .ptr = &Globals.maxprotocol,
1950 .enum_list = enum_protocol,
1951 .flags = FLAG_ADVANCED,
1954 .label = "min protocol",
1956 .p_class = P_GLOBAL,
1957 .ptr = &Globals.minprotocol,
1959 .enum_list = enum_protocol,
1960 .flags = FLAG_ADVANCED,
1963 .label = "min receivefile size",
1965 .p_class = P_GLOBAL,
1966 .ptr = &Globals.iminreceivefile,
1969 .flags = FLAG_ADVANCED,
1972 .label = "read raw",
1974 .p_class = P_GLOBAL,
1975 .ptr = &Globals.bReadRaw,
1978 .flags = FLAG_ADVANCED,
1981 .label = "write raw",
1983 .p_class = P_GLOBAL,
1984 .ptr = &Globals.bWriteRaw,
1987 .flags = FLAG_ADVANCED,
1990 .label = "disable netbios",
1992 .p_class = P_GLOBAL,
1993 .ptr = &Globals.bDisableNetbios,
1996 .flags = FLAG_ADVANCED,
1999 .label = "reset on zero vc",
2001 .p_class = P_GLOBAL,
2002 .ptr = &Globals.bResetOnZeroVC,
2005 .flags = FLAG_ADVANCED,
2008 .label = "acl compatibility",
2010 .p_class = P_GLOBAL,
2011 .ptr = &Globals.iAclCompat,
2013 .enum_list = enum_acl_compat_vals,
2014 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2017 .label = "defer sharing violations",
2019 .p_class = P_GLOBAL,
2020 .ptr = &Globals.bDeferSharingViolations,
2023 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2026 .label = "ea support",
2029 .ptr = &sDefault.bEASupport,
2032 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2035 .label = "nt acl support",
2038 .ptr = &sDefault.bNTAclSupport,
2041 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2044 .label = "nt pipe support",
2046 .p_class = P_GLOBAL,
2047 .ptr = &Globals.bNTPipeSupport,
2050 .flags = FLAG_ADVANCED,
2053 .label = "nt status support",
2055 .p_class = P_GLOBAL,
2056 .ptr = &Globals.bNTStatusSupport,
2059 .flags = FLAG_ADVANCED,
2062 .label = "profile acls",
2065 .ptr = &sDefault.bProfileAcls,
2068 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2071 .label = "announce version",
2073 .p_class = P_GLOBAL,
2074 .ptr = &Globals.szAnnounceVersion,
2077 .flags = FLAG_ADVANCED,
2080 .label = "announce as",
2082 .p_class = P_GLOBAL,
2083 .ptr = &Globals.announce_as,
2085 .enum_list = enum_announce_as,
2086 .flags = FLAG_ADVANCED,
2089 .label = "map acl inherit",
2092 .ptr = &sDefault.bMap_acl_inherit,
2095 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2098 .label = "afs share",
2101 .ptr = &sDefault.bAfs_Share,
2104 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2109 .p_class = P_GLOBAL,
2110 .ptr = &Globals.max_mux,
2113 .flags = FLAG_ADVANCED,
2116 .label = "max xmit",
2118 .p_class = P_GLOBAL,
2119 .ptr = &Globals.max_xmit,
2122 .flags = FLAG_ADVANCED,
2125 .label = "name resolve order",
2127 .p_class = P_GLOBAL,
2128 .ptr = &Globals.szNameResolveOrder,
2131 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2136 .p_class = P_GLOBAL,
2137 .ptr = &Globals.max_ttl,
2140 .flags = FLAG_ADVANCED,
2143 .label = "max wins ttl",
2145 .p_class = P_GLOBAL,
2146 .ptr = &Globals.max_wins_ttl,
2149 .flags = FLAG_ADVANCED,
2152 .label = "min wins ttl",
2154 .p_class = P_GLOBAL,
2155 .ptr = &Globals.min_wins_ttl,
2158 .flags = FLAG_ADVANCED,
2161 .label = "time server",
2163 .p_class = P_GLOBAL,
2164 .ptr = &Globals.bTimeServer,
2167 .flags = FLAG_ADVANCED,
2170 .label = "unix extensions",
2172 .p_class = P_GLOBAL,
2173 .ptr = &Globals.bUnixExtensions,
2176 .flags = FLAG_ADVANCED,
2179 .label = "use spnego",
2181 .p_class = P_GLOBAL,
2182 .ptr = &Globals.bUseSpnego,
2185 .flags = FLAG_ADVANCED,
2188 .label = "client signing",
2190 .p_class = P_GLOBAL,
2191 .ptr = &Globals.client_signing,
2193 .enum_list = enum_smb_signing_vals,
2194 .flags = FLAG_ADVANCED,
2197 .label = "server signing",
2199 .p_class = P_GLOBAL,
2200 .ptr = &Globals.server_signing,
2202 .enum_list = enum_smb_signing_vals,
2203 .flags = FLAG_ADVANCED,
2206 .label = "smb encrypt",
2209 .ptr = &sDefault.ismb_encrypt,
2211 .enum_list = enum_smb_signing_vals,
2212 .flags = FLAG_ADVANCED,
2215 .label = "client use spnego",
2217 .p_class = P_GLOBAL,
2218 .ptr = &Globals.bClientUseSpnego,
2221 .flags = FLAG_ADVANCED,
2224 .label = "client ldap sasl wrapping",
2226 .p_class = P_GLOBAL,
2227 .ptr = &Globals.client_ldap_sasl_wrapping,
2229 .enum_list = enum_ldap_sasl_wrapping,
2230 .flags = FLAG_ADVANCED,
2233 .label = "enable asu support",
2235 .p_class = P_GLOBAL,
2236 .ptr = &Globals.bASUSupport,
2239 .flags = FLAG_ADVANCED,
2242 .label = "svcctl list",
2244 .p_class = P_GLOBAL,
2245 .ptr = &Globals.szServicesList,
2248 .flags = FLAG_ADVANCED,
2251 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2254 .label = "block size",
2257 .ptr = &sDefault.iBlock_size,
2260 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2263 .label = "deadtime",
2265 .p_class = P_GLOBAL,
2266 .ptr = &Globals.deadtime,
2269 .flags = FLAG_ADVANCED,
2272 .label = "getwd cache",
2274 .p_class = P_GLOBAL,
2275 .ptr = &Globals.getwd_cache,
2278 .flags = FLAG_ADVANCED,
2281 .label = "keepalive",
2283 .p_class = P_GLOBAL,
2284 .ptr = &Globals.iKeepalive,
2287 .flags = FLAG_ADVANCED,
2290 .label = "change notify",
2293 .ptr = &sDefault.bChangeNotify,
2296 .flags = FLAG_ADVANCED | FLAG_SHARE,
2299 .label = "directory name cache size",
2302 .ptr = &sDefault.iDirectoryNameCacheSize,
2305 .flags = FLAG_ADVANCED | FLAG_SHARE,
2308 .label = "kernel change notify",
2311 .ptr = &sDefault.bKernelChangeNotify,
2314 .flags = FLAG_ADVANCED | FLAG_SHARE,
2317 .label = "lpq cache time",
2319 .p_class = P_GLOBAL,
2320 .ptr = &Globals.lpqcachetime,
2323 .flags = FLAG_ADVANCED,
2326 .label = "max smbd processes",
2328 .p_class = P_GLOBAL,
2329 .ptr = &Globals.iMaxSmbdProcesses,
2332 .flags = FLAG_ADVANCED,
2335 .label = "max connections",
2338 .ptr = &sDefault.iMaxConnections,
2341 .flags = FLAG_ADVANCED | FLAG_SHARE,
2344 .label = "paranoid server security",
2346 .p_class = P_GLOBAL,
2347 .ptr = &Globals.paranoid_server_security,
2350 .flags = FLAG_ADVANCED,
2353 .label = "max disk size",
2355 .p_class = P_GLOBAL,
2356 .ptr = &Globals.maxdisksize,
2359 .flags = FLAG_ADVANCED,
2362 .label = "max open files",
2364 .p_class = P_GLOBAL,
2365 .ptr = &Globals.max_open_files,
2368 .flags = FLAG_ADVANCED,
2371 .label = "min print space",
2374 .ptr = &sDefault.iMinPrintSpace,
2377 .flags = FLAG_ADVANCED | FLAG_PRINT,
2380 .label = "socket options",
2382 .p_class = P_GLOBAL,
2383 .ptr = &Globals.szSocketOptions,
2386 .flags = FLAG_ADVANCED,
2389 .label = "strict allocate",
2392 .ptr = &sDefault.bStrictAllocate,
2395 .flags = FLAG_ADVANCED | FLAG_SHARE,
2398 .label = "strict sync",
2401 .ptr = &sDefault.bStrictSync,
2404 .flags = FLAG_ADVANCED | FLAG_SHARE,
2407 .label = "sync always",
2410 .ptr = &sDefault.bSyncAlways,
2413 .flags = FLAG_ADVANCED | FLAG_SHARE,
2416 .label = "use mmap",
2418 .p_class = P_GLOBAL,
2419 .ptr = &Globals.bUseMmap,
2422 .flags = FLAG_ADVANCED,
2425 .label = "use sendfile",
2428 .ptr = &sDefault.bUseSendfile,
2431 .flags = FLAG_ADVANCED | FLAG_SHARE,
2434 .label = "hostname lookups",
2436 .p_class = P_GLOBAL,
2437 .ptr = &Globals.bHostnameLookups,
2440 .flags = FLAG_ADVANCED,
2443 .label = "write cache size",
2446 .ptr = &sDefault.iWriteCacheSize,
2449 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2452 .label = "name cache timeout",
2454 .p_class = P_GLOBAL,
2455 .ptr = &Globals.name_cache_timeout,
2458 .flags = FLAG_ADVANCED,
2461 .label = "ctdbd socket",
2463 .p_class = P_GLOBAL,
2464 .ptr = &Globals.ctdbdSocket,
2467 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2470 .label = "cluster addresses",
2472 .p_class = P_GLOBAL,
2473 .ptr = &Globals.szClusterAddresses,
2476 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2479 .label = "clustering",
2481 .p_class = P_GLOBAL,
2482 .ptr = &Globals.clustering,
2485 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2488 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2491 .label = "max reported print jobs",
2494 .ptr = &sDefault.iMaxReportedPrintJobs,
2497 .flags = FLAG_ADVANCED | FLAG_PRINT,
2500 .label = "max print jobs",
2503 .ptr = &sDefault.iMaxPrintJobs,
2506 .flags = FLAG_ADVANCED | FLAG_PRINT,
2509 .label = "load printers",
2511 .p_class = P_GLOBAL,
2512 .ptr = &Globals.bLoadPrinters,
2515 .flags = FLAG_ADVANCED | FLAG_PRINT,
2518 .label = "printcap cache time",
2520 .p_class = P_GLOBAL,
2521 .ptr = &Globals.PrintcapCacheTime,
2524 .flags = FLAG_ADVANCED | FLAG_PRINT,
2527 .label = "printcap name",
2529 .p_class = P_GLOBAL,
2530 .ptr = &Globals.szPrintcapname,
2533 .flags = FLAG_ADVANCED | FLAG_PRINT,
2536 .label = "printcap",
2538 .p_class = P_GLOBAL,
2539 .ptr = &Globals.szPrintcapname,
2545 .label = "printable",
2548 .ptr = &sDefault.bPrint_ok,
2551 .flags = FLAG_ADVANCED | FLAG_PRINT,
2554 .label = "print ok",
2557 .ptr = &sDefault.bPrint_ok,
2563 .label = "printing",
2566 .ptr = &sDefault.iPrinting,
2567 .special = handle_printing,
2568 .enum_list = enum_printing,
2569 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2572 .label = "cups options",
2575 .ptr = &sDefault.szCupsOptions,
2578 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2581 .label = "cups server",
2583 .p_class = P_GLOBAL,
2584 .ptr = &Globals.szCupsServer,
2587 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2590 .label = "iprint server",
2592 .p_class = P_GLOBAL,
2593 .ptr = &Globals.szIPrintServer,
2596 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2599 .label = "print command",
2602 .ptr = &sDefault.szPrintcommand,
2605 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2608 .label = "disable spoolss",
2610 .p_class = P_GLOBAL,
2611 .ptr = &Globals.bDisableSpoolss,
2614 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2617 .label = "enable spoolss",
2619 .p_class = P_GLOBAL,
2620 .ptr = &Globals.bDisableSpoolss,
2626 .label = "lpq command",
2629 .ptr = &sDefault.szLpqcommand,
2632 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2635 .label = "lprm command",
2638 .ptr = &sDefault.szLprmcommand,
2641 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2644 .label = "lppause command",
2647 .ptr = &sDefault.szLppausecommand,
2650 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2653 .label = "lpresume command",
2656 .ptr = &sDefault.szLpresumecommand,
2659 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2662 .label = "queuepause command",
2665 .ptr = &sDefault.szQueuepausecommand,
2668 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2671 .label = "queueresume command",
2674 .ptr = &sDefault.szQueueresumecommand,
2677 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2680 .label = "addport command",
2682 .p_class = P_GLOBAL,
2683 .ptr = &Globals.szAddPortCommand,
2686 .flags = FLAG_ADVANCED,
2689 .label = "enumports command",
2691 .p_class = P_GLOBAL,
2692 .ptr = &Globals.szEnumPortsCommand,
2695 .flags = FLAG_ADVANCED,
2698 .label = "addprinter command",
2700 .p_class = P_GLOBAL,
2701 .ptr = &Globals.szAddPrinterCommand,
2704 .flags = FLAG_ADVANCED,
2707 .label = "deleteprinter command",
2709 .p_class = P_GLOBAL,
2710 .ptr = &Globals.szDeletePrinterCommand,
2713 .flags = FLAG_ADVANCED,
2716 .label = "show add printer wizard",
2718 .p_class = P_GLOBAL,
2719 .ptr = &Globals.bMsAddPrinterWizard,
2722 .flags = FLAG_ADVANCED,
2725 .label = "os2 driver map",
2727 .p_class = P_GLOBAL,
2728 .ptr = &Globals.szOs2DriverMap,
2731 .flags = FLAG_ADVANCED,
2735 .label = "printer name",
2738 .ptr = &sDefault.szPrintername,
2741 .flags = FLAG_ADVANCED | FLAG_PRINT,
2747 .ptr = &sDefault.szPrintername,
2753 .label = "use client driver",
2756 .ptr = &sDefault.bUseClientDriver,
2759 .flags = FLAG_ADVANCED | FLAG_PRINT,
2762 .label = "default devmode",
2765 .ptr = &sDefault.bDefaultDevmode,
2768 .flags = FLAG_ADVANCED | FLAG_PRINT,
2771 .label = "force printername",
2774 .ptr = &sDefault.bForcePrintername,
2777 .flags = FLAG_ADVANCED | FLAG_PRINT,
2780 .label = "printjob username",
2783 .ptr = &sDefault.szPrintjobUsername,
2786 .flags = FLAG_ADVANCED | FLAG_PRINT,
2789 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2792 .label = "mangling method",
2794 .p_class = P_GLOBAL,
2795 .ptr = &Globals.szManglingMethod,
2798 .flags = FLAG_ADVANCED,
2801 .label = "mangle prefix",
2803 .p_class = P_GLOBAL,
2804 .ptr = &Globals.mangle_prefix,
2807 .flags = FLAG_ADVANCED,
2811 .label = "default case",
2814 .ptr = &sDefault.iDefaultCase,
2816 .enum_list = enum_case,
2817 .flags = FLAG_ADVANCED | FLAG_SHARE,
2820 .label = "case sensitive",
2823 .ptr = &sDefault.iCaseSensitive,
2825 .enum_list = enum_bool_auto,
2826 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2829 .label = "casesignames",
2832 .ptr = &sDefault.iCaseSensitive,
2834 .enum_list = enum_bool_auto,
2835 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2838 .label = "preserve case",
2841 .ptr = &sDefault.bCasePreserve,
2844 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2847 .label = "short preserve case",
2850 .ptr = &sDefault.bShortCasePreserve,
2853 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2856 .label = "mangling char",
2859 .ptr = &sDefault.magic_char,
2862 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2865 .label = "hide dot files",
2868 .ptr = &sDefault.bHideDotFiles,
2871 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2874 .label = "hide special files",
2877 .ptr = &sDefault.bHideSpecialFiles,
2880 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2883 .label = "hide unreadable",
2886 .ptr = &sDefault.bHideUnReadable,
2889 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2892 .label = "hide unwriteable files",
2895 .ptr = &sDefault.bHideUnWriteableFiles,
2898 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2901 .label = "delete veto files",
2904 .ptr = &sDefault.bDeleteVetoFiles,
2907 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2910 .label = "veto files",
2913 .ptr = &sDefault.szVetoFiles,
2916 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2919 .label = "hide files",
2922 .ptr = &sDefault.szHideFiles,
2925 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2928 .label = "veto oplock files",
2931 .ptr = &sDefault.szVetoOplockFiles,
2934 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2937 .label = "map archive",
2940 .ptr = &sDefault.bMap_archive,
2943 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2946 .label = "map hidden",
2949 .ptr = &sDefault.bMap_hidden,
2952 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2955 .label = "map system",
2958 .ptr = &sDefault.bMap_system,
2961 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2964 .label = "map readonly",
2967 .ptr = &sDefault.iMap_readonly,
2969 .enum_list = enum_map_readonly,
2970 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2973 .label = "mangled names",
2976 .ptr = &sDefault.bMangledNames,
2979 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2982 .label = "max stat cache size",
2984 .p_class = P_GLOBAL,
2985 .ptr = &Globals.iMaxStatCacheSize,
2988 .flags = FLAG_ADVANCED,
2991 .label = "stat cache",
2993 .p_class = P_GLOBAL,
2994 .ptr = &Globals.bStatCache,
2997 .flags = FLAG_ADVANCED,
3000 .label = "store dos attributes",
3003 .ptr = &sDefault.bStoreDosAttributes,
3006 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3009 .label = "dmapi support",
3012 .ptr = &sDefault.bDmapiSupport,
3015 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3019 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3022 .label = "machine password timeout",
3024 .p_class = P_GLOBAL,
3025 .ptr = &Globals.machine_password_timeout,
3028 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3031 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3034 .label = "add user script",
3036 .p_class = P_GLOBAL,
3037 .ptr = &Globals.szAddUserScript,
3040 .flags = FLAG_ADVANCED,
3043 .label = "rename user script",
3045 .p_class = P_GLOBAL,
3046 .ptr = &Globals.szRenameUserScript,
3049 .flags = FLAG_ADVANCED,
3052 .label = "delete user script",
3054 .p_class = P_GLOBAL,
3055 .ptr = &Globals.szDelUserScript,
3058 .flags = FLAG_ADVANCED,
3061 .label = "add group script",
3063 .p_class = P_GLOBAL,
3064 .ptr = &Globals.szAddGroupScript,
3067 .flags = FLAG_ADVANCED,
3070 .label = "delete group script",
3072 .p_class = P_GLOBAL,
3073 .ptr = &Globals.szDelGroupScript,
3076 .flags = FLAG_ADVANCED,
3079 .label = "add user to group script",
3081 .p_class = P_GLOBAL,
3082 .ptr = &Globals.szAddUserToGroupScript,
3085 .flags = FLAG_ADVANCED,
3088 .label = "delete user from group script",
3090 .p_class = P_GLOBAL,
3091 .ptr = &Globals.szDelUserFromGroupScript,
3094 .flags = FLAG_ADVANCED,
3097 .label = "set primary group script",
3099 .p_class = P_GLOBAL,
3100 .ptr = &Globals.szSetPrimaryGroupScript,
3103 .flags = FLAG_ADVANCED,
3106 .label = "add machine script",
3108 .p_class = P_GLOBAL,
3109 .ptr = &Globals.szAddMachineScript,
3112 .flags = FLAG_ADVANCED,
3115 .label = "shutdown script",
3117 .p_class = P_GLOBAL,
3118 .ptr = &Globals.szShutdownScript,
3121 .flags = FLAG_ADVANCED,
3124 .label = "abort shutdown script",
3126 .p_class = P_GLOBAL,
3127 .ptr = &Globals.szAbortShutdownScript,
3130 .flags = FLAG_ADVANCED,
3133 .label = "username map script",
3135 .p_class = P_GLOBAL,
3136 .ptr = &Globals.szUsernameMapScript,
3139 .flags = FLAG_ADVANCED,
3142 .label = "logon script",
3144 .p_class = P_GLOBAL,
3145 .ptr = &Globals.szLogonScript,
3148 .flags = FLAG_ADVANCED,
3151 .label = "logon path",
3153 .p_class = P_GLOBAL,
3154 .ptr = &Globals.szLogonPath,
3157 .flags = FLAG_ADVANCED,
3160 .label = "logon drive",
3162 .p_class = P_GLOBAL,
3163 .ptr = &Globals.szLogonDrive,
3166 .flags = FLAG_ADVANCED,
3169 .label = "logon home",
3171 .p_class = P_GLOBAL,
3172 .ptr = &Globals.szLogonHome,
3175 .flags = FLAG_ADVANCED,
3178 .label = "domain logons",
3180 .p_class = P_GLOBAL,
3181 .ptr = &Globals.bDomainLogons,
3184 .flags = FLAG_ADVANCED,
3187 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3190 .label = "os level",
3192 .p_class = P_GLOBAL,
3193 .ptr = &Globals.os_level,
3196 .flags = FLAG_BASIC | FLAG_ADVANCED,
3199 .label = "lm announce",
3201 .p_class = P_GLOBAL,
3202 .ptr = &Globals.lm_announce,
3204 .enum_list = enum_bool_auto,
3205 .flags = FLAG_ADVANCED,
3208 .label = "lm interval",
3210 .p_class = P_GLOBAL,
3211 .ptr = &Globals.lm_interval,
3214 .flags = FLAG_ADVANCED,
3217 .label = "preferred master",
3219 .p_class = P_GLOBAL,
3220 .ptr = &Globals.iPreferredMaster,
3222 .enum_list = enum_bool_auto,
3223 .flags = FLAG_BASIC | FLAG_ADVANCED,
3226 .label = "prefered master",
3228 .p_class = P_GLOBAL,
3229 .ptr = &Globals.iPreferredMaster,
3231 .enum_list = enum_bool_auto,
3235 .label = "local master",
3237 .p_class = P_GLOBAL,
3238 .ptr = &Globals.bLocalMaster,
3241 .flags = FLAG_BASIC | FLAG_ADVANCED,
3244 .label = "domain master",
3246 .p_class = P_GLOBAL,
3247 .ptr = &Globals.iDomainMaster,
3249 .enum_list = enum_bool_auto,
3250 .flags = FLAG_BASIC | FLAG_ADVANCED,
3253 .label = "browse list",
3255 .p_class = P_GLOBAL,
3256 .ptr = &Globals.bBrowseList,
3259 .flags = FLAG_ADVANCED,
3262 .label = "browseable",
3265 .ptr = &sDefault.bBrowseable,
3268 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3271 .label = "browsable",
3274 .ptr = &sDefault.bBrowseable,
3280 .label = "enhanced browsing",
3282 .p_class = P_GLOBAL,
3283 .ptr = &Globals.enhanced_browsing,
3286 .flags = FLAG_ADVANCED,
3289 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3292 .label = "dns proxy",
3294 .p_class = P_GLOBAL,
3295 .ptr = &Globals.bDNSproxy,
3298 .flags = FLAG_ADVANCED,
3301 .label = "wins proxy",
3303 .p_class = P_GLOBAL,
3304 .ptr = &Globals.bWINSproxy,
3307 .flags = FLAG_ADVANCED,
3310 .label = "wins server",
3312 .p_class = P_GLOBAL,
3313 .ptr = &Globals.szWINSservers,
3316 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3319 .label = "wins support",
3321 .p_class = P_GLOBAL,
3322 .ptr = &Globals.bWINSsupport,
3325 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3328 .label = "wins hook",
3330 .p_class = P_GLOBAL,
3331 .ptr = &Globals.szWINSHook,
3334 .flags = FLAG_ADVANCED,
3337 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3340 .label = "blocking locks",
3343 .ptr = &sDefault.bBlockingLocks,
3346 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3349 .label = "csc policy",
3352 .ptr = &sDefault.iCSCPolicy,
3354 .enum_list = enum_csc_policy,
3355 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3358 .label = "fake oplocks",
3361 .ptr = &sDefault.bFakeOplocks,
3364 .flags = FLAG_ADVANCED | FLAG_SHARE,
3367 .label = "kernel oplocks",
3369 .p_class = P_GLOBAL,
3370 .ptr = &Globals.bKernelOplocks,
3373 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3379 .ptr = &sDefault.bLocking,
3382 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3385 .label = "lock spin time",
3387 .p_class = P_GLOBAL,
3388 .ptr = &Globals.iLockSpinTime,
3391 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3397 .ptr = &sDefault.bOpLocks,
3400 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3403 .label = "level2 oplocks",
3406 .ptr = &sDefault.bLevel2OpLocks,
3409 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3412 .label = "oplock break wait time",
3414 .p_class = P_GLOBAL,
3415 .ptr = &Globals.oplock_break_wait_time,
3418 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3421 .label = "oplock contention limit",
3424 .ptr = &sDefault.iOplockContentionLimit,
3427 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3430 .label = "posix locking",
3433 .ptr = &sDefault.bPosixLocking,
3436 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3439 .label = "strict locking",
3442 .ptr = &sDefault.iStrictLocking,
3444 .enum_list = enum_bool_auto,
3445 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3448 .label = "share modes",
3451 .ptr = &sDefault.bShareModes,
3454 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3457 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3460 .label = "ldap admin dn",
3462 .p_class = P_GLOBAL,
3463 .ptr = &Globals.szLdapAdminDn,
3466 .flags = FLAG_ADVANCED,
3469 .label = "ldap delete dn",
3471 .p_class = P_GLOBAL,
3472 .ptr = &Globals.ldap_delete_dn,
3475 .flags = FLAG_ADVANCED,
3478 .label = "ldap group suffix",
3480 .p_class = P_GLOBAL,
3481 .ptr = &Globals.szLdapGroupSuffix,
3484 .flags = FLAG_ADVANCED,
3487 .label = "ldap idmap suffix",
3489 .p_class = P_GLOBAL,
3490 .ptr = &Globals.szLdapIdmapSuffix,
3493 .flags = FLAG_ADVANCED,
3496 .label = "ldap machine suffix",
3498 .p_class = P_GLOBAL,
3499 .ptr = &Globals.szLdapMachineSuffix,
3502 .flags = FLAG_ADVANCED,
3505 .label = "ldap passwd sync",
3507 .p_class = P_GLOBAL,
3508 .ptr = &Globals.ldap_passwd_sync,
3510 .enum_list = enum_ldap_passwd_sync,
3511 .flags = FLAG_ADVANCED,
3514 .label = "ldap password sync",
3516 .p_class = P_GLOBAL,
3517 .ptr = &Globals.ldap_passwd_sync,
3519 .enum_list = enum_ldap_passwd_sync,
3523 .label = "ldap replication sleep",
3525 .p_class = P_GLOBAL,
3526 .ptr = &Globals.ldap_replication_sleep,
3529 .flags = FLAG_ADVANCED,
3532 .label = "ldap suffix",
3534 .p_class = P_GLOBAL,
3535 .ptr = &Globals.szLdapSuffix,
3538 .flags = FLAG_ADVANCED,
3541 .label = "ldap ssl",
3543 .p_class = P_GLOBAL,
3544 .ptr = &Globals.ldap_ssl,
3546 .enum_list = enum_ldap_ssl,
3547 .flags = FLAG_ADVANCED,
3550 .label = "ldap timeout",
3552 .p_class = P_GLOBAL,
3553 .ptr = &Globals.ldap_timeout,
3556 .flags = FLAG_ADVANCED,
3559 .label = "ldap page size",
3561 .p_class = P_GLOBAL,
3562 .ptr = &Globals.ldap_page_size,
3565 .flags = FLAG_ADVANCED,
3568 .label = "ldap user suffix",
3570 .p_class = P_GLOBAL,
3571 .ptr = &Globals.szLdapUserSuffix,
3574 .flags = FLAG_ADVANCED,
3577 .label = "ldap debug level",
3579 .p_class = P_GLOBAL,
3580 .ptr = &Globals.ldap_debug_level,
3581 .special = handle_ldap_debug_level,
3583 .flags = FLAG_ADVANCED,
3586 .label = "ldap debug threshold",
3588 .p_class = P_GLOBAL,
3589 .ptr = &Globals.ldap_debug_threshold,
3592 .flags = FLAG_ADVANCED,
3595 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3598 .label = "eventlog list",
3600 .p_class = P_GLOBAL,
3601 .ptr = &Globals.szEventLogs,
3604 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3607 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3610 .label = "add share command",
3612 .p_class = P_GLOBAL,
3613 .ptr = &Globals.szAddShareCommand,
3616 .flags = FLAG_ADVANCED,
3619 .label = "change share command",
3621 .p_class = P_GLOBAL,
3622 .ptr = &Globals.szChangeShareCommand,
3625 .flags = FLAG_ADVANCED,
3628 .label = "delete share command",
3630 .p_class = P_GLOBAL,
3631 .ptr = &Globals.szDeleteShareCommand,
3634 .flags = FLAG_ADVANCED,
3637 .label = "config file",
3639 .p_class = P_GLOBAL,
3640 .ptr = &Globals.szConfigFile,
3648 .p_class = P_GLOBAL,
3649 .ptr = &Globals.szAutoServices,
3652 .flags = FLAG_ADVANCED,
3655 .label = "auto services",
3657 .p_class = P_GLOBAL,
3658 .ptr = &Globals.szAutoServices,
3661 .flags = FLAG_ADVANCED,
3664 .label = "lock directory",
3666 .p_class = P_GLOBAL,
3667 .ptr = &Globals.szLockDir,
3670 .flags = FLAG_ADVANCED,
3673 .label = "lock dir",
3675 .p_class = P_GLOBAL,
3676 .ptr = &Globals.szLockDir,
3682 .label = "pid directory",
3684 .p_class = P_GLOBAL,
3685 .ptr = &Globals.szPidDir,
3688 .flags = FLAG_ADVANCED,
3692 .label = "utmp directory",
3694 .p_class = P_GLOBAL,
3695 .ptr = &Globals.szUtmpDir,
3698 .flags = FLAG_ADVANCED,
3701 .label = "wtmp directory",
3703 .p_class = P_GLOBAL,
3704 .ptr = &Globals.szWtmpDir,
3707 .flags = FLAG_ADVANCED,
3712 .p_class = P_GLOBAL,
3713 .ptr = &Globals.bUtmp,
3716 .flags = FLAG_ADVANCED,
3720 .label = "default service",
3722 .p_class = P_GLOBAL,
3723 .ptr = &Globals.szDefaultService,
3726 .flags = FLAG_ADVANCED,
3731 .p_class = P_GLOBAL,
3732 .ptr = &Globals.szDefaultService,
3735 .flags = FLAG_ADVANCED,
3738 .label = "message command",
3740 .p_class = P_GLOBAL,
3741 .ptr = &Globals.szMsgCommand,
3744 .flags = FLAG_ADVANCED,
3747 .label = "dfree cache time",
3750 .ptr = &sDefault.iDfreeCacheTime,
3753 .flags = FLAG_ADVANCED,
3756 .label = "dfree command",
3759 .ptr = &sDefault.szDfree,
3762 .flags = FLAG_ADVANCED,
3765 .label = "get quota command",
3767 .p_class = P_GLOBAL,
3768 .ptr = &Globals.szGetQuota,
3771 .flags = FLAG_ADVANCED,
3774 .label = "set quota command",
3776 .p_class = P_GLOBAL,
3777 .ptr = &Globals.szSetQuota,
3780 .flags = FLAG_ADVANCED,
3783 .label = "remote announce",
3785 .p_class = P_GLOBAL,
3786 .ptr = &Globals.szRemoteAnnounce,
3789 .flags = FLAG_ADVANCED,
3792 .label = "remote browse sync",
3794 .p_class = P_GLOBAL,
3795 .ptr = &Globals.szRemoteBrowseSync,
3798 .flags = FLAG_ADVANCED,
3801 .label = "socket address",
3803 .p_class = P_GLOBAL,
3804 .ptr = &Globals.szSocketAddress,
3807 .flags = FLAG_ADVANCED,
3810 .label = "homedir map",
3812 .p_class = P_GLOBAL,
3813 .ptr = &Globals.szNISHomeMapName,
3816 .flags = FLAG_ADVANCED,
3819 .label = "afs username map",
3821 .p_class = P_GLOBAL,
3822 .ptr = &Globals.szAfsUsernameMap,
3825 .flags = FLAG_ADVANCED,
3828 .label = "afs token lifetime",
3830 .p_class = P_GLOBAL,
3831 .ptr = &Globals.iAfsTokenLifetime,
3834 .flags = FLAG_ADVANCED,
3837 .label = "log nt token command",
3839 .p_class = P_GLOBAL,
3840 .ptr = &Globals.szLogNtTokenCommand,
3843 .flags = FLAG_ADVANCED,
3846 .label = "time offset",
3848 .p_class = P_GLOBAL,
3849 .ptr = &extra_time_offset,
3852 .flags = FLAG_ADVANCED,
3855 .label = "NIS homedir",
3857 .p_class = P_GLOBAL,
3858 .ptr = &Globals.bNISHomeMap,
3861 .flags = FLAG_ADVANCED,
3867 .ptr = &sDefault.valid,
3876 .ptr = &sDefault.szCopy,
3877 .special = handle_copy,
3885 .ptr = &sDefault.szInclude,
3886 .special = handle_include,
3894 .ptr = &sDefault.szPreExec,
3897 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3903 .ptr = &sDefault.szPreExec,
3906 .flags = FLAG_ADVANCED,
3909 .label = "preexec close",
3912 .ptr = &sDefault.bPreexecClose,
3915 .flags = FLAG_ADVANCED | FLAG_SHARE,
3918 .label = "postexec",
3921 .ptr = &sDefault.szPostExec,
3924 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3927 .label = "root preexec",
3930 .ptr = &sDefault.szRootPreExec,
3933 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3936 .label = "root preexec close",
3939 .ptr = &sDefault.bRootpreexecClose,
3942 .flags = FLAG_ADVANCED | FLAG_SHARE,
3945 .label = "root postexec",
3948 .ptr = &sDefault.szRootPostExec,
3951 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3954 .label = "available",
3957 .ptr = &sDefault.bAvailable,
3960 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3963 .label = "registry shares",
3965 .p_class = P_GLOBAL,
3966 .ptr = &Globals.bRegistryShares,
3969 .flags = FLAG_ADVANCED,
3972 .label = "usershare allow guests",
3974 .p_class = P_GLOBAL,
3975 .ptr = &Globals.bUsershareAllowGuests,
3978 .flags = FLAG_ADVANCED,
3981 .label = "usershare max shares",
3983 .p_class = P_GLOBAL,
3984 .ptr = &Globals.iUsershareMaxShares,
3987 .flags = FLAG_ADVANCED,
3990 .label = "usershare owner only",
3992 .p_class = P_GLOBAL,
3993 .ptr = &Globals.bUsershareOwnerOnly,
3996 .flags = FLAG_ADVANCED,
3999 .label = "usershare path",
4001 .p_class = P_GLOBAL,
4002 .ptr = &Globals.szUsersharePath,
4005 .flags = FLAG_ADVANCED,
4008 .label = "usershare prefix allow list",
4010 .p_class = P_GLOBAL,
4011 .ptr = &Globals.szUsersharePrefixAllowList,
4014 .flags = FLAG_ADVANCED,
4017 .label = "usershare prefix deny list",
4019 .p_class = P_GLOBAL,
4020 .ptr = &Globals.szUsersharePrefixDenyList,
4023 .flags = FLAG_ADVANCED,
4026 .label = "usershare template share",
4028 .p_class = P_GLOBAL,
4029 .ptr = &Globals.szUsershareTemplateShare,
4032 .flags = FLAG_ADVANCED,
4038 .ptr = &sDefault.volume,
4041 .flags = FLAG_ADVANCED | FLAG_SHARE,
4047 .ptr = &sDefault.fstype,
4050 .flags = FLAG_ADVANCED | FLAG_SHARE,
4053 .label = "set directory",
4056 .ptr = &sDefault.bNo_set_dir,
4059 .flags = FLAG_ADVANCED | FLAG_SHARE,
4062 .label = "wide links",
4065 .ptr = &sDefault.bWidelinks,
4068 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4071 .label = "follow symlinks",
4074 .ptr = &sDefault.bSymlinks,
4077 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4080 .label = "dont descend",
4083 .ptr = &sDefault.szDontdescend,
4086 .flags = FLAG_ADVANCED | FLAG_SHARE,
4089 .label = "magic script",
4092 .ptr = &sDefault.szMagicScript,
4095 .flags = FLAG_ADVANCED | FLAG_SHARE,
4098 .label = "magic output",
4101 .ptr = &sDefault.szMagicOutput,
4104 .flags = FLAG_ADVANCED | FLAG_SHARE,
4107 .label = "delete readonly",
4110 .ptr = &sDefault.bDeleteReadonly,
4113 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4116 .label = "dos filemode",
4119 .ptr = &sDefault.bDosFilemode,
4122 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4125 .label = "dos filetimes",
4128 .ptr = &sDefault.bDosFiletimes,
4131 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4134 .label = "dos filetime resolution",
4137 .ptr = &sDefault.bDosFiletimeResolution,
4140 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4143 .label = "fake directory create times",
4146 .ptr = &sDefault.bFakeDirCreateTimes,
4149 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4152 .label = "panic action",
4154 .p_class = P_GLOBAL,
4155 .ptr = &Globals.szPanicAction,
4158 .flags = FLAG_ADVANCED,
4161 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4164 .label = "vfs objects",
4167 .ptr = &sDefault.szVfsObjects,
4170 .flags = FLAG_ADVANCED | FLAG_SHARE,
4173 .label = "vfs object",
4176 .ptr = &sDefault.szVfsObjects,
4183 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4186 .label = "msdfs root",
4189 .ptr = &sDefault.bMSDfsRoot,
4192 .flags = FLAG_ADVANCED | FLAG_SHARE,
4195 .label = "msdfs proxy",
4198 .ptr = &sDefault.szMSDfsProxy,
4201 .flags = FLAG_ADVANCED | FLAG_SHARE,
4204 .label = "host msdfs",
4206 .p_class = P_GLOBAL,
4207 .ptr = &Globals.bHostMSDfs,
4210 .flags = FLAG_ADVANCED,
4213 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4216 .label = "passdb expand explicit",
4218 .p_class = P_GLOBAL,
4219 .ptr = &Globals.bPassdbExpandExplicit,
4222 .flags = FLAG_ADVANCED,
4225 .label = "idmap domains",
4227 .p_class = P_GLOBAL,
4228 .ptr = &Globals.szIdmapDomains,
4231 .flags = FLAG_ADVANCED,
4234 .label = "idmap backend",
4236 .p_class = P_GLOBAL,
4237 .ptr = &Globals.szIdmapBackend,
4240 .flags = FLAG_ADVANCED,
4243 .label = "idmap alloc backend",
4245 .p_class = P_GLOBAL,
4246 .ptr = &Globals.szIdmapAllocBackend,
4249 .flags = FLAG_ADVANCED,
4252 .label = "idmap cache time",
4254 .p_class = P_GLOBAL,
4255 .ptr = &Globals.iIdmapCacheTime,
4258 .flags = FLAG_ADVANCED,
4261 .label = "idmap negative cache time",
4263 .p_class = P_GLOBAL,
4264 .ptr = &Globals.iIdmapNegativeCacheTime,
4267 .flags = FLAG_ADVANCED,
4270 .label = "idmap uid",
4272 .p_class = P_GLOBAL,
4273 .ptr = &Globals.szIdmapUID,
4274 .special = handle_idmap_uid,
4276 .flags = FLAG_ADVANCED,
4279 .label = "winbind uid",
4281 .p_class = P_GLOBAL,
4282 .ptr = &Globals.szIdmapUID,
4283 .special = handle_idmap_uid,
4288 .label = "idmap gid",
4290 .p_class = P_GLOBAL,
4291 .ptr = &Globals.szIdmapGID,
4292 .special = handle_idmap_gid,
4294 .flags = FLAG_ADVANCED,
4297 .label = "winbind gid",
4299 .p_class = P_GLOBAL,
4300 .ptr = &Globals.szIdmapGID,
4301 .special = handle_idmap_gid,
4306 .label = "template homedir",
4308 .p_class = P_GLOBAL,
4309 .ptr = &Globals.szTemplateHomedir,
4312 .flags = FLAG_ADVANCED,
4315 .label = "template shell",
4317 .p_class = P_GLOBAL,
4318 .ptr = &Globals.szTemplateShell,
4321 .flags = FLAG_ADVANCED,
4324 .label = "winbind separator",
4326 .p_class = P_GLOBAL,
4327 .ptr = &Globals.szWinbindSeparator,
4330 .flags = FLAG_ADVANCED,
4333 .label = "winbind cache time",
4335 .p_class = P_GLOBAL,
4336 .ptr = &Globals.winbind_cache_time,
4339 .flags = FLAG_ADVANCED,
4342 .label = "winbind enum users",
4344 .p_class = P_GLOBAL,
4345 .ptr = &Globals.bWinbindEnumUsers,
4348 .flags = FLAG_ADVANCED,
4351 .label = "winbind enum groups",
4353 .p_class = P_GLOBAL,
4354 .ptr = &Globals.bWinbindEnumGroups,
4357 .flags = FLAG_ADVANCED,
4360 .label = "winbind use default domain",
4362 .p_class = P_GLOBAL,
4363 .ptr = &Globals.bWinbindUseDefaultDomain,
4366 .flags = FLAG_ADVANCED,
4369 .label = "winbind trusted domains only",
4371 .p_class = P_GLOBAL,
4372 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4375 .flags = FLAG_ADVANCED,
4378 .label = "winbind nested groups",
4380 .p_class = P_GLOBAL,
4381 .ptr = &Globals.bWinbindNestedGroups,
4384 .flags = FLAG_ADVANCED,
4387 .label = "winbind expand groups",
4389 .p_class = P_GLOBAL,
4390 .ptr = &Globals.winbind_expand_groups,
4393 .flags = FLAG_ADVANCED,
4396 .label = "winbind nss info",
4398 .p_class = P_GLOBAL,
4399 .ptr = &Globals.szWinbindNssInfo,
4402 .flags = FLAG_ADVANCED,
4405 .label = "winbind refresh tickets",
4407 .p_class = P_GLOBAL,
4408 .ptr = &Globals.bWinbindRefreshTickets,
4411 .flags = FLAG_ADVANCED,
4414 .label = "winbind offline logon",
4416 .p_class = P_GLOBAL,
4417 .ptr = &Globals.bWinbindOfflineLogon,
4420 .flags = FLAG_ADVANCED,
4423 .label = "winbind normalize names",
4425 .p_class = P_GLOBAL,
4426 .ptr = &Globals.bWinbindNormalizeNames,
4429 .flags = FLAG_ADVANCED,
4432 .label = "winbind rpc only",
4434 .p_class = P_GLOBAL,
4435 .ptr = &Globals.bWinbindRpcOnly,
4438 .flags = FLAG_ADVANCED,
4441 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4444 /***************************************************************************
4445 Initialise the sDefault parameter structure for the printer values.
4446 ***************************************************************************/
4448 static void init_printer_values(struct service *pService)
4450 /* choose defaults depending on the type of printing */
4451 switch (pService->iPrinting) {
4456 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4457 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4458 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4463 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4464 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4465 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4466 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4467 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4468 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4469 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4475 /* set the lpq command to contain the destination printer
4476 name only. This is used by cups_queue_get() */
4477 string_set(&pService->szLpqcommand, "%p");
4478 string_set(&pService->szLprmcommand, "");
4479 string_set(&pService->szPrintcommand, "");
4480 string_set(&pService->szLppausecommand, "");
4481 string_set(&pService->szLpresumecommand, "");
4482 string_set(&pService->szQueuepausecommand, "");
4483 string_set(&pService->szQueueresumecommand, "");
4485 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4486 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4487 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4488 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4489 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4490 string_set(&pService->szQueuepausecommand, "disable '%p'");
4491 string_set(&pService->szQueueresumecommand, "enable '%p'");
4492 #endif /* HAVE_CUPS */
4497 string_set(&pService->szLpqcommand, "lpstat -o%p");
4498 string_set(&pService->szLprmcommand, "cancel %p-%j");
4499 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4500 string_set(&pService->szQueuepausecommand, "disable %p");
4501 string_set(&pService->szQueueresumecommand, "enable %p");
4503 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4504 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4509 string_set(&pService->szLpqcommand, "lpq -P%p");
4510 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4511 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4517 string_set(&pService->szPrintcommand, "vlp print %p %s");
4518 string_set(&pService->szLpqcommand, "vlp lpq %p");
4519 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4520 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4521 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4522 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4523 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4525 #endif /* DEVELOPER */
4530 /***************************************************************************
4531 Initialise the global parameter structure.
4532 ***************************************************************************/
4534 static void init_globals(bool first_time_only)
4536 static bool done_init = False;
4540 /* If requested to initialize only once and we've already done it... */
4541 if (first_time_only && done_init) {
4542 /* ... then we have nothing more to do */
4547 /* The logfile can be set before this is invoked. Free it if so. */
4548 if (Globals.szLogFile != NULL) {
4549 string_free(&Globals.szLogFile);
4550 Globals.szLogFile = NULL;
4554 for (i = 0; parm_table[i].label; i++) {
4555 if ((parm_table[i].type == P_STRING ||
4556 parm_table[i].type == P_USTRING) &&
4559 string_free((char **)parm_table[i].ptr);
4564 memset((void *)&Globals, '\0', sizeof(Globals));
4566 for (i = 0; parm_table[i].label; i++) {
4567 if ((parm_table[i].type == P_STRING ||
4568 parm_table[i].type == P_USTRING) &&
4571 string_set((char **)parm_table[i].ptr, "");
4575 string_set(&sDefault.fstype, FSTYPE_STRING);
4576 string_set(&sDefault.szPrintjobUsername, "%U");
4578 init_printer_values(&sDefault);
4581 DEBUG(3, ("Initialising global parameters\n"));
4583 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4584 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4586 /* use the new 'hash2' method by default, with a prefix of 1 */
4587 string_set(&Globals.szManglingMethod, "hash2");
4588 Globals.mangle_prefix = 1;
4590 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4592 /* using UTF8 by default allows us to support all chars */
4593 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4595 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4596 /* If the system supports nl_langinfo(), try to grab the value
4597 from the user's locale */
4598 string_set(&Globals.display_charset, "LOCALE");
4600 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4603 /* Use codepage 850 as a default for the dos character set */
4604 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4607 * Allow the default PASSWD_CHAT to be overridden in local.h.
4609 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4611 set_global_myname(myhostname());
4612 string_set(&Globals.szNetbiosName,global_myname());
4614 set_global_myworkgroup(WORKGROUP);
4615 string_set(&Globals.szWorkgroup, lp_workgroup());
4617 string_set(&Globals.szPasswdProgram, "");
4618 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4619 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4620 string_set(&Globals.szSocketAddress, "0.0.0.0");
4622 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4623 smb_panic("init_globals: ENOMEM");
4625 string_set(&Globals.szServerString, s);
4627 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4628 DEFAULT_MINOR_VERSION) < 0) {
4629 smb_panic("init_globals: ENOMEM");
4631 string_set(&Globals.szAnnounceVersion, s);
4634 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4637 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4639 string_set(&Globals.szLogonDrive, "");
4640 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4641 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4642 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4644 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4645 string_set(&Globals.szPasswordServer, "*");
4647 Globals.AlgorithmicRidBase = BASE_RID;
4649 Globals.bLoadPrinters = True;
4650 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4652 Globals.ConfigBackend = config_backend;
4654 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4655 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4656 Globals.max_xmit = 0x4104;
4657 Globals.max_mux = 50; /* This is *needed* for profile support. */
4658 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4659 Globals.bDisableSpoolss = False;
4660 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4661 Globals.pwordlevel = 0;
4662 Globals.unamelevel = 0;
4663 Globals.deadtime = 0;
4664 Globals.getwd_cache = true;
4665 Globals.bLargeReadwrite = True;
4666 Globals.max_log_size = 5000;
4667 Globals.max_open_files = MAX_OPEN_FILES;
4668 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4669 Globals.maxprotocol = PROTOCOL_NT1;
4670 Globals.minprotocol = PROTOCOL_CORE;
4671 Globals.security = SEC_USER;
4672 Globals.paranoid_server_security = True;
4673 Globals.bEncryptPasswords = True;
4674 Globals.bUpdateEncrypt = False;
4675 Globals.clientSchannel = Auto;
4676 Globals.serverSchannel = Auto;
4677 Globals.bReadRaw = True;
4678 Globals.bWriteRaw = True;
4679 Globals.bNullPasswords = False;
4680 Globals.bObeyPamRestrictions = False;
4682 Globals.bSyslogOnly = False;
4683 Globals.bTimestampLogs = True;
4684 string_set(&Globals.szLogLevel, "0");
4685 Globals.bDebugPrefixTimestamp = False;
4686 Globals.bDebugHiresTimestamp = False;
4687 Globals.bDebugPid = False;
4688 Globals.bDebugUid = False;
4689 Globals.bDebugClass = False;
4690 Globals.bEnableCoreFiles = True;
4691 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4692 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4693 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4694 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4695 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4696 Globals.lm_interval = 60;
4697 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4698 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4699 Globals.bNISHomeMap = False;
4700 #ifdef WITH_NISPLUS_HOME
4701 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4703 string_set(&Globals.szNISHomeMapName, "auto.home");
4706 Globals.bTimeServer = False;
4707 Globals.bBindInterfacesOnly = False;
4708 Globals.bUnixPasswdSync = False;
4709 Globals.bPamPasswordChange = False;
4710 Globals.bPasswdChatDebug = False;
4711 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4712 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4713 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4714 Globals.bStatCache = True; /* use stat cache by default */
4715 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4716 Globals.restrict_anonymous = 0;
4717 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4718 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4719 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4720 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4721 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4722 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4724 Globals.map_to_guest = 0; /* By Default, "Never" */
4725 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4726 Globals.enhanced_browsing = true;
4727 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4728 #ifdef MMAP_BLACKLIST
4729 Globals.bUseMmap = False;
4731 Globals.bUseMmap = True;
4733 Globals.bUnixExtensions = True;
4734 Globals.bResetOnZeroVC = False;
4736 /* hostname lookups can be very expensive and are broken on
4737 a large number of sites (tridge) */
4738 Globals.bHostnameLookups = False;
4740 string_set(&Globals.szPassdbBackend, "smbpasswd");
4741 string_set(&Globals.szLdapSuffix, "");
4742 string_set(&Globals.szLdapMachineSuffix, "");
4743 string_set(&Globals.szLdapUserSuffix, "");
4744 string_set(&Globals.szLdapGroupSuffix, "");
4745 string_set(&Globals.szLdapIdmapSuffix, "");
4747 string_set(&Globals.szLdapAdminDn, "");
4748 Globals.ldap_ssl = LDAP_SSL_ON;
4749 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4750 Globals.ldap_delete_dn = False;
4751 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4752 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
4753 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4755 Globals.ldap_debug_level = 0;
4756 Globals.ldap_debug_threshold = 10;
4758 /* This is what we tell the afs client. in reality we set the token
4759 * to never expire, though, when this runs out the afs client will
4760 * forget the token. Set to 0 to get NEVERDATE.*/
4761 Globals.iAfsTokenLifetime = 604800;
4763 /* these parameters are set to defaults that are more appropriate
4764 for the increasing samba install base:
4766 as a member of the workgroup, that will possibly become a
4767 _local_ master browser (lm = True). this is opposed to a forced
4768 local master browser startup (pm = True).
4770 doesn't provide WINS server service by default (wsupp = False),
4771 and doesn't provide domain master browser services by default, either.
4775 Globals.bMsAddPrinterWizard = True;
4776 Globals.os_level = 20;
4777 Globals.bLocalMaster = True;
4778 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4779 Globals.bDomainLogons = False;
4780 Globals.bBrowseList = True;
4781 Globals.bWINSsupport = False;
4782 Globals.bWINSproxy = False;
4784 Globals.bDNSproxy = True;
4786 /* this just means to use them if they exist */
4787 Globals.bKernelOplocks = True;
4789 Globals.bAllowTrustedDomains = True;
4791 string_set(&Globals.szTemplateShell, "/bin/false");
4792 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4793 string_set(&Globals.szWinbindSeparator, "\\");
4795 string_set(&Globals.szCupsServer, "");
4796 string_set(&Globals.szIPrintServer, "");
4798 string_set(&Globals.ctdbdSocket, "");
4799 Globals.szClusterAddresses = NULL;
4800 Globals.clustering = False;
4802 Globals.winbind_cache_time = 300; /* 5 minutes */
4803 Globals.bWinbindEnumUsers = False;
4804 Globals.bWinbindEnumGroups = False;
4805 Globals.bWinbindUseDefaultDomain = False;
4806 Globals.bWinbindTrustedDomainsOnly = False;
4807 Globals.bWinbindNestedGroups = True;
4808 Globals.winbind_expand_groups = 1;
4809 Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4810 Globals.bWinbindRefreshTickets = False;
4811 Globals.bWinbindOfflineLogon = False;
4813 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
4814 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4816 Globals.bPassdbExpandExplicit = False;
4818 Globals.name_cache_timeout = 660; /* In seconds */
4820 Globals.bUseSpnego = True;
4821 Globals.bClientUseSpnego = True;
4823 Globals.client_signing = Auto;
4824 Globals.server_signing = False;
4826 Globals.bDeferSharingViolations = True;
4827 string_set(&Globals.smb_ports, SMB_PORTS);
4829 Globals.bEnablePrivileges = True;
4830 Globals.bHostMSDfs = True;
4831 Globals.bASUSupport = False;
4833 /* User defined shares. */
4834 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4835 smb_panic("init_globals: ENOMEM");
4837 string_set(&Globals.szUsersharePath, s);
4839 string_set(&Globals.szUsershareTemplateShare, "");
4840 Globals.iUsershareMaxShares = 0;
4841 /* By default disallow sharing of directories not owned by the sharer. */
4842 Globals.bUsershareOwnerOnly = True;
4843 /* By default disallow guest access to usershares. */
4844 Globals.bUsershareAllowGuests = False;
4846 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4848 /* By default no shares out of the registry */
4849 Globals.bRegistryShares = False;
4851 Globals.iminreceivefile = 0;
4854 /*******************************************************************
4855 Convenience routine to grab string parameters into temporary memory
4856 and run standard_sub_basic on them. The buffers can be written to by
4857 callers without affecting the source string.
4858 ********************************************************************/
4860 static char *lp_string(const char *s)
4863 TALLOC_CTX *ctx = talloc_tos();
4865 /* The follow debug is useful for tracking down memory problems
4866 especially if you have an inner loop that is calling a lp_*()
4867 function that returns a string. Perhaps this debug should be
4868 present all the time? */
4871 DEBUG(10, ("lp_string(%s)\n", s));
4874 ret = talloc_sub_basic(ctx,
4875 get_current_username(),
4876 current_user_info.domain,
4878 if (trim_char(ret, '\"', '\"')) {
4879 if (strchr(ret,'\"') != NULL) {
4881 ret = talloc_sub_basic(ctx,
4882 get_current_username(),
4883 current_user_info.domain,
4891 In this section all the functions that are used to access the
4892 parameters from the rest of the program are defined
4895 #define FN_GLOBAL_STRING(fn_name,ptr) \
4896 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4897 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4898 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4899 #define FN_GLOBAL_LIST(fn_name,ptr) \
4900 const char **fn_name(void) {return(*(const char ***)(ptr));}
4901 #define FN_GLOBAL_BOOL(fn_name,ptr) \
4902 bool fn_name(void) {return(*(bool *)(ptr));}
4903 #define FN_GLOBAL_CHAR(fn_name,ptr) \
4904 char fn_name(void) {return(*(char *)(ptr));}
4905 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
4906 int fn_name(void) {return(*(int *)(ptr));}
4908 #define FN_LOCAL_STRING(fn_name,val) \
4909 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4910 #define FN_LOCAL_CONST_STRING(fn_name,val) \
4911 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4912 #define FN_LOCAL_LIST(fn_name,val) \
4913 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4914 #define FN_LOCAL_BOOL(fn_name,val) \
4915 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4916 #define FN_LOCAL_INTEGER(fn_name,val) \
4917 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4919 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
4920 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4921 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4922 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4923 #define FN_LOCAL_PARM_STRING(fn_name,val) \
4924 char *fn_name(const struct share_params *p) {return(lp_string((LP_SNUM_OK(p->service) && ServicePtrs[(p->service)]->val) ? ServicePtrs[(p->service)]->val : sDefault.val));}
4925 #define FN_LOCAL_CHAR(fn_name,val) \
4926 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4928 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4929 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4930 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4931 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4932 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4933 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4934 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4935 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4936 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4937 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4938 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4939 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4940 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4941 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4942 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4943 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4944 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4945 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4946 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4947 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4948 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4949 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4950 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4951 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4952 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4953 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4954 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
4955 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
4956 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
4957 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
4958 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
4959 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
4960 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
4961 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
4962 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
4963 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
4964 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
4965 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
4966 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
4967 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
4968 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
4969 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
4970 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
4971 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
4972 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
4973 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
4974 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
4975 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
4976 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
4977 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
4978 * lp_passdb_backend() should be replace by the this macro again after
4981 const char *lp_passdb_backend(void)
4983 char *delim, *quote;
4985 delim = strchr( Globals.szPassdbBackend, ' ');
4986 /* no space at all */
4987 if (delim == NULL) {
4991 quote = strchr(Globals.szPassdbBackend, '"');
4992 /* no quote char or non in the first part */
4993 if (quote == NULL || quote > delim) {
4998 quote = strchr(quote+1, '"');
4999 if (quote == NULL) {
5000 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5002 } else if (*(quote+1) == '\0') {
5003 /* space, fitting quote char, and one backend only */
5006 /* terminate string after the fitting quote char */
5011 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5012 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5013 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5014 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5017 return Globals.szPassdbBackend;
5019 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5020 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5021 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5022 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5023 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5025 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5026 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5027 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5028 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5029 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5030 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5032 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5034 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5035 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5036 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5038 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5040 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5041 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5042 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5043 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5044 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5045 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5046 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5047 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5048 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5049 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5050 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5051 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5052 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5053 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5054 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5056 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
5057 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
5058 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5059 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5060 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5061 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5062 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5064 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5065 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5066 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5067 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5068 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5069 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5070 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5071 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5072 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5073 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5074 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5075 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5076 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5077 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5078 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5079 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5081 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5083 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5084 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5085 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5086 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5087 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5088 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5089 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5090 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5091 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5092 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5093 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5094 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5095 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5096 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5097 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5098 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5099 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5100 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5101 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5102 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5103 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5104 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5105 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5106 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5107 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5108 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5109 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5110 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5111 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5112 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5113 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5114 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5115 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5116 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5117 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5118 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5119 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5120 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5121 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5122 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5123 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5124 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5125 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5126 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5127 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5128 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5129 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5130 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5131 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5132 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5133 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5134 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5135 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5136 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5137 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5138 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5139 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5140 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5141 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5142 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5143 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5144 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5145 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5146 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5147 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5148 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5149 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5150 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5151 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5152 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5153 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5154 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5155 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5156 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5157 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5158 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5159 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5160 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5161 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5162 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5163 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5164 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5165 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5166 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5167 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5168 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5169 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5170 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5171 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5172 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5173 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5174 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5175 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5176 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5177 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5178 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend);
5180 FN_LOCAL_STRING(lp_preexec, szPreExec)
5181 FN_LOCAL_STRING(lp_postexec, szPostExec)
5182 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5183 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5184 FN_LOCAL_STRING(lp_servicename, szService)
5185 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5186 FN_LOCAL_STRING(lp_pathname, szPath)
5187 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5188 FN_LOCAL_STRING(lp_username, szUsername)
5189 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5190 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5191 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5192 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5193 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5194 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5195 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5196 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5197 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5198 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering);
5199 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5200 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5201 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5202 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5203 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5204 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5205 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5206 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5207 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5208 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5209 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5210 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5211 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5212 FN_LOCAL_STRING(lp_comment, comment)
5213 FN_LOCAL_STRING(lp_force_user, force_user)
5214 FN_LOCAL_STRING(lp_force_group, force_group)
5215 FN_LOCAL_LIST(lp_readlist, readlist)
5216 FN_LOCAL_LIST(lp_writelist, writelist)
5217 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5218 FN_LOCAL_STRING(lp_fstype, fstype)
5219 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5220 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5221 static FN_LOCAL_STRING(lp_volume, volume)
5222 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5223 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5224 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5225 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5226 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5227 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5228 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5229 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5230 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5231 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5232 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5233 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5234 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5235 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5236 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5237 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5238 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5239 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5240 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5241 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5242 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5243 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5244 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5245 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5246 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5247 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5248 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5249 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5250 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5251 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5252 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5253 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5254 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5255 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5256 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5257 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5258 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5259 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5260 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5261 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5262 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5263 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5264 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5265 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5266 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5267 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5268 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5269 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5270 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5271 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5272 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5273 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5274 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5275 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5276 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5277 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5278 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5279 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5280 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5281 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5282 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5283 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5284 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5285 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5286 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5287 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5288 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5289 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5290 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5291 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5292 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5293 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5294 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5295 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5296 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5297 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5298 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5299 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5300 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5301 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5302 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5303 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5304 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5305 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5306 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5307 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5308 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5309 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5310 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5311 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5312 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5313 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5314 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5315 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5316 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5317 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5318 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5320 /* local prototypes */
5322 static int map_parameter(const char *pszParmName);
5323 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5324 static bool set_boolean(bool *pb, const char *pszParmValue);
5325 static const char *get_boolean(bool bool_value);
5326 static int getservicebyname(const char *pszServiceName,
5327 struct service *pserviceDest);
5328 static void copy_service(struct service *pserviceDest,
5329 struct service *pserviceSource,
5330 struct bitmap *pcopymapDest);
5331 static bool do_parameter(const char *pszParmName, const char *pszParmValue);
5332 static bool do_section(const char *pszSectionName);
5333 static void init_copymap(struct service *pservice);
5334 static bool hash_a_service(const char *name, int number);
5335 static void free_service_byindex(int iService);
5336 static char * canonicalize_servicename(const char *name);
5337 static void show_parameter(int parmIndex);
5338 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5340 /* This is a helper function for parametrical options support. */
5341 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
5342 /* Actual parametrical functions are quite simple */
5343 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
5345 bool global_section = False;
5347 param_opt_struct *data;
5349 if (snum >= iNumServices) return NULL;
5352 data = Globals.param_opt;
5353 global_section = True;
5355 data = ServicePtrs[snum]->param_opt;
5358 if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
5359 DEBUG(0,("asprintf failed!\n"));
5364 if (strcmp(data->key, param_key) == 0) {
5365 string_free(¶m_key);
5371 if (!global_section) {
5372 /* Try to fetch the same option but from globals */
5373 /* but only if we are not already working with Globals */
5374 data = Globals.param_opt;
5376 if (strcmp(data->key, param_key) == 0) {
5377 string_free(¶m_key);
5384 string_free(¶m_key);
5390 #define MISSING_PARAMETER(name) \
5391 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5393 /*******************************************************************
5394 convenience routine to return int parameters.
5395 ********************************************************************/
5396 static int lp_int(const char *s)
5400 MISSING_PARAMETER(lp_int);
5404 return (int)strtol(s, NULL, 0);
5407 /*******************************************************************
5408 convenience routine to return unsigned long parameters.
5409 ********************************************************************/
5410 static unsigned long lp_ulong(const char *s)
5414 MISSING_PARAMETER(lp_ulong);
5418 return strtoul(s, NULL, 0);
5421 /*******************************************************************
5422 convenience routine to return boolean parameters.
5423 ********************************************************************/
5424 static bool lp_bool(const char *s)
5429 MISSING_PARAMETER(lp_bool);
5433 if (!set_boolean(&ret,s)) {
5434 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5441 /*******************************************************************
5442 convenience routine to return enum parameters.
5443 ********************************************************************/
5444 static int lp_enum(const char *s,const struct enum_list *_enum)
5448 if (!s || !*s || !_enum) {
5449 MISSING_PARAMETER(lp_enum);
5453 for (i=0; _enum[i].name; i++) {
5454 if (strequal(_enum[i].name,s))
5455 return _enum[i].value;
5458 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5462 #undef MISSING_PARAMETER
5464 /* DO NOT USE lp_parm_string ANYMORE!!!!
5465 * use lp_parm_const_string or lp_parm_talloc_string
5467 * lp_parm_string is only used to let old modules find this symbol
5469 #undef lp_parm_string
5470 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5471 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5473 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5476 /* Return parametric option from a given service. Type is a part of option before ':' */
5477 /* Parametric option has following syntax: 'Type: option = value' */
5478 /* the returned value is talloced on the talloc_tos() */
5479 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5481 param_opt_struct *data = get_parametrics(snum, type, option);
5483 if (data == NULL||data->value==NULL) {
5485 return lp_string(def);
5491 return lp_string(data->value);
5494 /* Return parametric option from a given service. Type is a part of option before ':' */
5495 /* Parametric option has following syntax: 'Type: option = value' */
5496 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5498 param_opt_struct *data = get_parametrics(snum, type, option);
5500 if (data == NULL||data->value==NULL)
5506 /* Return parametric option from a given service. Type is a part of option before ':' */
5507 /* Parametric option has following syntax: 'Type: option = value' */
5509 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5511 param_opt_struct *data = get_parametrics(snum, type, option);
5513 if (data == NULL||data->value==NULL)
5514 return (const char **)def;
5516 if (data->list==NULL) {
5517 data->list = str_list_make(NULL, data->value, NULL);
5520 return (const char **)data->list;
5523 /* Return parametric option from a given service. Type is a part of option before ':' */
5524 /* Parametric option has following syntax: 'Type: option = value' */
5526 int lp_parm_int(int snum, const char *type, const char *option, int def)
5528 param_opt_struct *data = get_parametrics(snum, type, option);
5530 if (data && data->value && *data->value)
5531 return lp_int(data->value);
5536 /* Return parametric option from a given service. Type is a part of option before ':' */
5537 /* Parametric option has following syntax: 'Type: option = value' */
5539 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5541 param_opt_struct *data = get_parametrics(snum, type, option);
5543 if (data && data->value && *data->value)
5544 return lp_ulong(data->value);
5549 /* Return parametric option from a given service. Type is a part of option before ':' */
5550 /* Parametric option has following syntax: 'Type: option = value' */
5552 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5554 param_opt_struct *data = get_parametrics(snum, type, option);
5556 if (data && data->value && *data->value)
5557 return lp_bool(data->value);
5562 /* Return parametric option from a given service. Type is a part of option before ':' */
5563 /* Parametric option has following syntax: 'Type: option = value' */
5565 int lp_parm_enum(int snum, const char *type, const char *option,
5566 const struct enum_list *_enum, int def)
5568 param_opt_struct *data = get_parametrics(snum, type, option);
5570 if (data && data->value && *data->value && _enum)
5571 return lp_enum(data->value, _enum);
5577 /***************************************************************************
5578 Initialise a service to the defaults.
5579 ***************************************************************************/
5581 static void init_service(struct service *pservice)
5583 memset((char *)pservice, '\0', sizeof(struct service));
5584 copy_service(pservice, &sDefault, NULL);
5587 /***************************************************************************
5588 Free the dynamically allocated parts of a service struct.
5589 ***************************************************************************/
5591 static void free_service(struct service *pservice)
5594 param_opt_struct *data, *pdata;
5598 if (pservice->szService)
5599 DEBUG(5, ("free_service: Freeing service %s\n",
5600 pservice->szService));
5602 string_free(&pservice->szService);
5603 bitmap_free(pservice->copymap);
5605 for (i = 0; parm_table[i].label; i++) {
5606 if ((parm_table[i].type == P_STRING ||
5607 parm_table[i].type == P_USTRING) &&
5608 parm_table[i].p_class == P_LOCAL)
5609 string_free((char **)
5610 (((char *)pservice) +
5611 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5612 else if (parm_table[i].type == P_LIST &&
5613 parm_table[i].p_class == P_LOCAL)
5614 TALLOC_FREE(*((char ***)
5615 (((char *)pservice) +
5616 PTR_DIFF(parm_table[i].ptr,
5620 data = pservice->param_opt;
5622 DEBUG(5,("Freeing parametrics:\n"));
5624 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5625 string_free(&data->key);
5626 string_free(&data->value);
5627 TALLOC_FREE(data->list);
5633 ZERO_STRUCTP(pservice);
5637 /***************************************************************************
5638 remove a service indexed in the ServicePtrs array from the ServiceHash
5639 and free the dynamically allocated parts
5640 ***************************************************************************/
5642 static void free_service_byindex(int idx)
5644 if ( !LP_SNUM_OK(idx) )
5647 ServicePtrs[idx]->valid = False;
5648 invalid_services[num_invalid_services++] = idx;
5650 /* we have to cleanup the hash record */
5652 if (ServicePtrs[idx]->szService) {
5653 char *canon_name = canonicalize_servicename(
5654 ServicePtrs[idx]->szService );
5656 dbwrap_delete_bystring(ServiceHash, canon_name );
5657 TALLOC_FREE(canon_name);
5660 free_service(ServicePtrs[idx]);
5663 /***************************************************************************
5664 Add a new service to the services array initialising it with the given
5666 ***************************************************************************/
5668 static int add_a_service(const struct service *pservice, const char *name)
5671 struct service tservice;
5672 int num_to_alloc = iNumServices + 1;
5673 param_opt_struct *data, *pdata;
5675 tservice = *pservice;
5677 /* it might already exist */
5679 i = getservicebyname(name, NULL);
5681 /* Clean all parametric options for service */
5682 /* They will be added during parsing again */
5683 data = ServicePtrs[i]->param_opt;
5685 string_free(&data->key);
5686 string_free(&data->value);
5687 TALLOC_FREE(data->list);
5692 ServicePtrs[i]->param_opt = NULL;
5697 /* find an invalid one */
5699 if (num_invalid_services > 0) {
5700 i = invalid_services[--num_invalid_services];
5703 /* if not, then create one */
5704 if (i == iNumServices) {
5705 struct service **tsp;
5708 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5710 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5714 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5715 if (!ServicePtrs[iNumServices]) {
5716 DEBUG(0,("add_a_service: out of memory!\n"));
5721 /* enlarge invalid_services here for now... */
5722 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5724 if (tinvalid == NULL) {
5725 DEBUG(0,("add_a_service: failed to enlarge "
5726 "invalid_services!\n"));
5729 invalid_services = tinvalid;
5731 free_service_byindex(i);
5734 ServicePtrs[i]->valid = True;
5736 init_service(ServicePtrs[i]);
5737 copy_service(ServicePtrs[i], &tservice, NULL);
5739 string_set(&ServicePtrs[i]->szService, name);
5741 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5742 i, ServicePtrs[i]->szService));
5744 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5751 /***************************************************************************
5752 Convert a string to uppercase and remove whitespaces.
5753 ***************************************************************************/
5755 static char *canonicalize_servicename(const char *src)
5760 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5764 result = talloc_strdup(talloc_tos(), src);
5765 SMB_ASSERT(result != NULL);
5771 /***************************************************************************
5772 Add a name/index pair for the services array to the hash table.
5773 ***************************************************************************/
5775 static bool hash_a_service(const char *name, int idx)
5779 if ( !ServiceHash ) {
5780 DEBUG(10,("hash_a_service: creating servicehash\n"));
5781 ServiceHash = db_open_rbt(NULL);
5782 if ( !ServiceHash ) {
5783 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5788 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5791 canon_name = canonicalize_servicename( name );
5793 dbwrap_store_bystring(ServiceHash, canon_name,
5794 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5797 TALLOC_FREE(canon_name);
5802 /***************************************************************************
5803 Add a new home service, with the specified home directory, defaults coming
5805 ***************************************************************************/
5807 bool lp_add_home(const char *pszHomename, int iDefaultService,
5808 const char *user, const char *pszHomedir)
5812 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5817 if (!(*(ServicePtrs[iDefaultService]->szPath))
5818 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5819 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5822 if (!(*(ServicePtrs[i]->comment))) {
5823 char *comment = NULL;
5824 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5827 string_set(&ServicePtrs[i]->comment, comment);
5831 /* set the browseable flag from the global default */
5833 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5835 ServicePtrs[i]->autoloaded = True;
5837 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5838 user, ServicePtrs[i]->szPath ));
5843 /***************************************************************************
5844 Add a new service, based on an old one.
5845 ***************************************************************************/
5847 int lp_add_service(const char *pszService, int iDefaultService)
5849 if (iDefaultService < 0) {
5850 return add_a_service(&sDefault, pszService);
5853 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5856 /***************************************************************************
5857 Add the IPC service.
5858 ***************************************************************************/
5860 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5862 char *comment = NULL;
5863 int i = add_a_service(&sDefault, ipc_name);
5868 if (asprintf(&comment, "IPC Service (%s)",
5869 Globals.szServerString) < 0) {
5873 string_set(&ServicePtrs[i]->szPath, tmpdir());
5874 string_set(&ServicePtrs[i]->szUsername, "");
5875 string_set(&ServicePtrs[i]->comment, comment);
5876 string_set(&ServicePtrs[i]->fstype, "IPC");
5877 ServicePtrs[i]->iMaxConnections = 0;
5878 ServicePtrs[i]->bAvailable = True;
5879 ServicePtrs[i]->bRead_only = True;
5880 ServicePtrs[i]->bGuest_only = False;
5881 ServicePtrs[i]->bAdministrative_share = True;
5882 ServicePtrs[i]->bGuest_ok = guest_ok;
5883 ServicePtrs[i]->bPrint_ok = False;
5884 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5886 DEBUG(3, ("adding IPC service\n"));
5892 /***************************************************************************
5893 Add a new printer service, with defaults coming from service iFrom.
5894 ***************************************************************************/
5896 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5898 const char *comment = "From Printcap";
5899 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5904 /* note that we do NOT default the availability flag to True - */
5905 /* we take it from the default service passed. This allows all */
5906 /* dynamic printers to be disabled by disabling the [printers] */
5907 /* entry (if/when the 'available' keyword is implemented!). */
5909 /* the printer name is set to the service name. */
5910 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5911 string_set(&ServicePtrs[i]->comment, comment);
5913 /* set the browseable flag from the gloabl default */
5914 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5916 /* Printers cannot be read_only. */
5917 ServicePtrs[i]->bRead_only = False;
5918 /* No share modes on printer services. */
5919 ServicePtrs[i]->bShareModes = False;
5920 /* No oplocks on printer services. */
5921 ServicePtrs[i]->bOpLocks = False;
5922 /* Printer services must be printable. */
5923 ServicePtrs[i]->bPrint_ok = True;
5925 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5931 /***************************************************************************
5932 Check whether the given parameter name is valid.
5933 Parametric options (names containing a colon) are considered valid.
5934 ***************************************************************************/
5936 bool lp_parameter_is_valid(const char *pszParmName)
5938 return ((map_parameter(pszParmName) != -1) ||
5939 (strchr(pszParmName, ':') != NULL));
5942 /***************************************************************************
5943 Check whether the given name is the name of a global parameter.
5944 Returns True for strings belonging to parameters of class
5945 P_GLOBAL, False for all other strings, also for parametric options
5946 and strings not belonging to any option.
5947 ***************************************************************************/
5949 bool lp_parameter_is_global(const char *pszParmName)
5951 int num = map_parameter(pszParmName);
5954 return (parm_table[num].p_class == P_GLOBAL);
5960 /**************************************************************************
5961 Check whether the given name is the canonical name of a parameter.
5962 Returns False if it is not a valid parameter Name.
5963 For parametric options, True is returned.
5964 **************************************************************************/
5966 bool lp_parameter_is_canonical(const char *parm_name)
5968 if (!lp_parameter_is_valid(parm_name)) {
5972 return (map_parameter(parm_name) ==
5973 map_parameter_canonical(parm_name, NULL));
5976 /**************************************************************************
5977 Determine the canonical name for a parameter.
5978 Indicate when it is an inverse (boolean) synonym instead of a
5980 **************************************************************************/
5982 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
5987 if (!lp_parameter_is_valid(parm_name)) {
5992 num = map_parameter_canonical(parm_name, inverse);
5994 /* parametric option */
5995 *canon_parm = parm_name;
5997 *canon_parm = parm_table[num].label;
6004 /**************************************************************************
6005 Determine the canonical name for a parameter.
6006 Turn the value given into the inverse boolean expression when
6007 the synonym is an invers boolean synonym.
6009 Return True if parm_name is a valid parameter name and
6010 in case it is an invers boolean synonym, if the val string could
6011 successfully be converted to the reverse bool.
6012 Return false in all other cases.
6013 **************************************************************************/
6015 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6017 const char **canon_parm,
6018 const char **canon_val)
6023 if (!lp_parameter_is_valid(parm_name)) {
6029 num = map_parameter_canonical(parm_name, &inverse);
6031 /* parametric option */
6032 *canon_parm = parm_name;
6035 *canon_parm = parm_table[num].label;
6037 if (!lp_invert_boolean(val, canon_val)) {
6049 /***************************************************************************
6050 Map a parameter's string representation to something we can use.
6051 Returns False if the parameter string is not recognised, else TRUE.
6052 ***************************************************************************/
6054 static int map_parameter(const char *pszParmName)
6058 if (*pszParmName == '-')
6061 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6062 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6065 /* Warn only if it isn't parametric option */
6066 if (strchr(pszParmName, ':') == NULL)
6067 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6068 /* We do return 'fail' for parametric options as well because they are
6069 stored in different storage
6074 /***************************************************************************
6075 Map a parameter's string representation to the index of the canonical
6076 form of the parameter (it might be a synonym).
6077 Returns -1 if the parameter string is not recognised.
6078 ***************************************************************************/
6080 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6082 int parm_num, canon_num;
6083 bool loc_inverse = False;
6085 parm_num = map_parameter(pszParmName);
6086 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6087 /* invalid, parametric or no canidate for synonyms ... */
6091 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6092 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6093 parm_num = canon_num;
6099 if (inverse != NULL) {
6100 *inverse = loc_inverse;
6105 /***************************************************************************
6106 return true if parameter number parm1 is a synonym of parameter
6107 number parm2 (parm2 being the principal name).
6108 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6110 ***************************************************************************/
6112 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6114 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6115 (parm_table[parm1].flags & FLAG_HIDE) &&
6116 !(parm_table[parm2].flags & FLAG_HIDE))
6118 if (inverse != NULL) {
6119 if ((parm_table[parm1].type == P_BOOLREV) &&
6120 (parm_table[parm2].type == P_BOOL))
6132 /***************************************************************************
6133 Show one parameter's name, type, [values,] and flags.
6134 (helper functions for show_parameter_list)
6135 ***************************************************************************/
6137 static void show_parameter(int parmIndex)
6139 int enumIndex, flagIndex;
6144 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6145 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6147 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6148 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6149 FLAG_HIDE, FLAG_DOS_STRING};
6150 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6151 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6152 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6154 printf("%s=%s", parm_table[parmIndex].label,
6155 type[parm_table[parmIndex].type]);
6156 if (parm_table[parmIndex].type == P_ENUM) {
6159 parm_table[parmIndex].enum_list[enumIndex].name;
6163 enumIndex ? "|" : "",
6164 parm_table[parmIndex].enum_list[enumIndex].name);
6169 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6170 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6173 flag_names[flagIndex]);
6178 /* output synonyms */
6180 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6181 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6182 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6183 parm_table[parmIndex2].label);
6184 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6186 printf(" (synonyms: ");
6191 printf("%s%s", parm_table[parmIndex2].label,
6192 inverse ? "[i]" : "");
6202 /***************************************************************************
6203 Show all parameter's name, type, [values,] and flags.
6204 ***************************************************************************/
6206 void show_parameter_list(void)
6208 int classIndex, parmIndex;
6209 const char *section_names[] = { "local", "global", NULL};
6211 for (classIndex=0; section_names[classIndex]; classIndex++) {
6212 printf("[%s]\n", section_names[classIndex]);
6213 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6214 if (parm_table[parmIndex].p_class == classIndex) {
6215 show_parameter(parmIndex);
6221 /***************************************************************************
6222 Set a boolean variable from the text value stored in the passed string.
6223 Returns True in success, False if the passed string does not correctly
6224 represent a boolean.
6225 ***************************************************************************/
6227 static bool set_boolean(bool *pb, const char *pszParmValue)
6234 if (strwicmp(pszParmValue, "yes") == 0 ||
6235 strwicmp(pszParmValue, "true") == 0 ||
6236 strwicmp(pszParmValue, "1") == 0)
6238 else if (strwicmp(pszParmValue, "no") == 0 ||
6239 strwicmp(pszParmValue, "False") == 0 ||
6240 strwicmp(pszParmValue, "0") == 0)
6244 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6249 if ((pb != NULL) && (bRetval != False)) {
6257 /***************************************************************************
6258 Check if a given string correctly represents a boolean value.
6259 ***************************************************************************/
6261 bool lp_string_is_valid_boolean(const char *parm_value)
6263 return set_boolean(NULL, parm_value);
6266 /***************************************************************************
6267 Get the standard string representation of a boolean value ("yes" or "no")
6268 ***************************************************************************/
6270 static const char *get_boolean(bool bool_value)
6272 static const char *yes_str = "yes";
6273 static const char *no_str = "no";
6275 return (bool_value ? yes_str : no_str);
6278 /***************************************************************************
6279 Provide the string of the negated boolean value associated to the boolean
6280 given as a string. Returns False if the passed string does not correctly
6281 represent a boolean.
6282 ***************************************************************************/
6284 bool lp_invert_boolean(const char *str, const char **inverse_str)
6288 if (!set_boolean(&val, str)) {
6292 *inverse_str = get_boolean(!val);
6296 /***************************************************************************
6297 Provide the canonical string representation of a boolean value given
6298 as a string. Return True on success, False if the string given does
6299 not correctly represent a boolean.
6300 ***************************************************************************/
6302 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6306 if (!set_boolean(&val, str)) {
6310 *canon_str = get_boolean(val);
6314 /***************************************************************************
6315 Find a service by name. Otherwise works like get_service.
6316 ***************************************************************************/
6318 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6324 if (ServiceHash == NULL) {
6328 canon_name = canonicalize_servicename(pszServiceName);
6330 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6332 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6333 iService = *(int *)data.dptr;
6336 TALLOC_FREE(canon_name);
6338 if ((iService != -1) && (LP_SNUM_OK(iService))
6339 && (pserviceDest != NULL)) {
6340 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6346 /***************************************************************************
6347 Copy a service structure to another.
6348 If pcopymapDest is NULL then copy all fields
6349 ***************************************************************************/
6351 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6352 struct bitmap *pcopymapDest)
6355 bool bcopyall = (pcopymapDest == NULL);
6356 param_opt_struct *data, *pdata, *paramo;
6359 for (i = 0; parm_table[i].label; i++)
6360 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6361 (bcopyall || bitmap_query(pcopymapDest,i))) {
6362 void *def_ptr = parm_table[i].ptr;
6364 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6367 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6370 switch (parm_table[i].type) {
6373 *(bool *)dest_ptr = *(bool *)src_ptr;
6379 *(int *)dest_ptr = *(int *)src_ptr;
6383 *(char *)dest_ptr = *(char *)src_ptr;
6387 string_set((char **)dest_ptr,
6392 string_set((char **)dest_ptr,
6394 strupper_m(*(char **)dest_ptr);
6397 TALLOC_FREE(*((char ***)dest_ptr));
6398 str_list_copy(NULL, (char ***)dest_ptr,
6399 *(const char ***)src_ptr);
6407 init_copymap(pserviceDest);
6408 if (pserviceSource->copymap)
6409 bitmap_copy(pserviceDest->copymap,
6410 pserviceSource->copymap);
6413 data = pserviceSource->param_opt;
6416 pdata = pserviceDest->param_opt;
6417 /* Traverse destination */
6419 /* If we already have same option, override it */
6420 if (strcmp(pdata->key, data->key) == 0) {
6421 string_free(&pdata->value);
6422 TALLOC_FREE(data->list);
6423 pdata->value = SMB_STRDUP(data->value);
6427 pdata = pdata->next;
6430 paramo = SMB_XMALLOC_P(param_opt_struct);
6431 paramo->key = SMB_STRDUP(data->key);
6432 paramo->value = SMB_STRDUP(data->value);
6433 paramo->list = NULL;
6434 DLIST_ADD(pserviceDest->param_opt, paramo);
6440 /***************************************************************************
6441 Check a service for consistency. Return False if the service is in any way
6442 incomplete or faulty, else True.
6443 ***************************************************************************/
6445 bool service_ok(int iService)
6450 if (ServicePtrs[iService]->szService[0] == '\0') {
6451 DEBUG(0, ("The following message indicates an internal error:\n"));
6452 DEBUG(0, ("No service name in service entry.\n"));
6456 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6457 /* I can't see why you'd want a non-printable printer service... */
6458 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6459 if (!ServicePtrs[iService]->bPrint_ok) {
6460 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6461 ServicePtrs[iService]->szService));
6462 ServicePtrs[iService]->bPrint_ok = True;
6464 /* [printers] service must also be non-browsable. */
6465 if (ServicePtrs[iService]->bBrowseable)
6466 ServicePtrs[iService]->bBrowseable = False;
6469 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6470 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6471 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6473 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6474 ServicePtrs[iService]->szService));
6475 ServicePtrs[iService]->bAvailable = False;
6478 /* If a service is flagged unavailable, log the fact at level 1. */
6479 if (!ServicePtrs[iService]->bAvailable)
6480 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6481 ServicePtrs[iService]->szService));
6487 * process_registry_globals
6489 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
6493 char **param_values;
6494 uint32_t num_params;
6496 TALLOC_CTX *mem_ctx = talloc_stackframe();
6499 if (conf_ctx == NULL) {
6501 werr = libnet_conf_open(NULL, &conf_ctx);
6502 if (!W_ERROR_IS_OK(werr)) {
6507 if (!libnet_conf_share_exists(conf_ctx, GLOBAL_NAME)) {
6508 /* nothing to read from the registry yet but make sure lp_load
6509 * doesn't return false */
6514 werr = libnet_conf_get_share(mem_ctx, conf_ctx, GLOBAL_NAME,
6515 &num_params, ¶m_names, ¶m_values);
6516 if (!W_ERROR_IS_OK(werr)) {
6520 for (count = 0; count < num_params; count++) {
6521 ret = pfunc(param_names[count], param_values[count]);
6527 ret = pfunc("registry shares", "yes");
6528 conf_last_seqnum = libnet_conf_get_seqnum(conf_ctx, NULL, NULL);
6531 TALLOC_FREE(mem_ctx);
6535 static struct file_lists {
6536 struct file_lists *next;
6540 } *file_lists = NULL;
6542 /*******************************************************************
6543 Keep a linked list of all config files so we know when one has changed
6544 it's date and needs to be reloaded.
6545 ********************************************************************/
6547 static void add_to_file_list(const char *fname, const char *subfname)
6549 struct file_lists *f = file_lists;
6552 if (f->name && !strcmp(f->name, fname))
6558 f = SMB_MALLOC_P(struct file_lists);
6561 f->next = file_lists;
6562 f->name = SMB_STRDUP(fname);
6567 f->subfname = SMB_STRDUP(subfname);
6573 f->modtime = file_modtime(subfname);
6575 time_t t = file_modtime(subfname);
6582 * Utility function for outsiders to check if we're running on registry.
6584 bool lp_config_backend_is_registry(void)
6586 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6590 * Utility function to check if the config backend is FILE.
6592 bool lp_config_backend_is_file(void)
6594 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6597 /*******************************************************************
6598 Check if a config file has changed date.
6599 ********************************************************************/
6601 bool lp_file_list_changed(void)
6603 struct file_lists *f = file_lists;
6605 DEBUG(6, ("lp_file_list_changed()\n"));
6607 if (lp_config_backend_is_registry()) {
6608 uint64_t conf_cur_seqnum;
6609 if (conf_ctx == NULL) {
6611 werr = libnet_conf_open(NULL, &conf_ctx);
6612 if (!W_ERROR_IS_OK(werr)) {
6613 DEBUG(0, ("error opening configuration: %s\n",
6618 conf_cur_seqnum = libnet_conf_get_seqnum(conf_ctx, NULL, NULL);
6619 if (conf_last_seqnum != conf_cur_seqnum) {
6620 DEBUGADD(6, ("regdb seqnum changed: old = %llu, "
6622 (unsigned long long)conf_last_seqnum,
6623 (unsigned long long)conf_cur_seqnum));
6627 * Don't check files when config_backend is registry.
6628 * Remove this to obtain checking of files even with
6629 * registry config backend. That would enable switching
6630 * off registry configuration by changing smb.conf even
6631 * without restarting smbd.
6641 n2 = alloc_sub_basic(get_current_username(),
6642 current_user_info.domain,
6647 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6648 f->name, n2, ctime(&f->modtime)));
6650 mod_time = file_modtime(n2);
6652 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6654 ("file %s modified: %s\n", n2,
6656 f->modtime = mod_time;
6657 SAFE_FREE(f->subfname);
6658 f->subfname = n2; /* Passing ownership of
6659 return from alloc_sub_basic
6670 /***************************************************************************
6671 Run standard_sub_basic on netbios name... needed because global_myname
6672 is not accessed through any lp_ macro.
6673 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6674 ***************************************************************************/
6676 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6679 char *netbios_name = alloc_sub_basic(get_current_username(),
6680 current_user_info.domain,
6683 ret = set_global_myname(netbios_name);
6684 SAFE_FREE(netbios_name);
6685 string_set(&Globals.szNetbiosName,global_myname());
6687 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6693 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6695 if (strcmp(*ptr, pszParmValue) != 0) {
6696 string_set(ptr, pszParmValue);
6704 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6708 ret = set_global_myworkgroup(pszParmValue);
6709 string_set(&Globals.szWorkgroup,lp_workgroup());
6714 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6718 ret = set_global_scope(pszParmValue);
6719 string_set(&Globals.szNetbiosScope,global_scope());
6724 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6726 TALLOC_FREE(Globals.szNetbiosAliases);
6727 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6728 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6731 /***************************************************************************
6732 Handle the include operation.
6733 ***************************************************************************/
6735 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6739 fname = alloc_sub_basic(get_current_username(),
6740 current_user_info.domain,
6743 add_to_file_list(pszParmValue, fname);
6745 string_set(ptr, fname);
6747 if (file_exist(fname, NULL)) {
6748 bool ret = pm_process(fname, do_section, do_parameter);
6753 DEBUG(2, ("Can't find include file %s\n", fname));
6758 /***************************************************************************
6759 Handle the interpretation of the copy parameter.
6760 ***************************************************************************/
6762 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6766 struct service serviceTemp;
6768 string_set(ptr, pszParmValue);
6770 init_service(&serviceTemp);
6774 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6776 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6777 if (iTemp == iServiceIndex) {
6778 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6780 copy_service(ServicePtrs[iServiceIndex],
6782 ServicePtrs[iServiceIndex]->copymap);
6786 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6790 free_service(&serviceTemp);
6794 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6796 Globals.ldap_debug_level = lp_int(pszParmValue);
6797 init_ldap_debugging();
6801 /***************************************************************************
6802 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6807 idmap uid = 1000-1999
6810 We only do simple parsing checks here. The strings are parsed into useful
6811 structures in the idmap daemon code.
6813 ***************************************************************************/
6815 /* Some lp_ routines to return idmap [ug]id information */
6817 static uid_t idmap_uid_low, idmap_uid_high;
6818 static gid_t idmap_gid_low, idmap_gid_high;
6820 bool lp_idmap_uid(uid_t *low, uid_t *high)
6822 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6826 *low = idmap_uid_low;
6829 *high = idmap_uid_high;
6834 bool lp_idmap_gid(gid_t *low, gid_t *high)
6836 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6840 *low = idmap_gid_low;
6843 *high = idmap_gid_high;
6848 /* Do some simple checks on "idmap [ug]id" parameter values */
6850 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6854 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6859 string_set(ptr, pszParmValue);
6861 idmap_uid_low = low;
6862 idmap_uid_high = high;
6867 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6871 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6876 string_set(ptr, pszParmValue);
6878 idmap_gid_low = low;
6879 idmap_gid_high = high;
6884 /***************************************************************************
6885 Handle the DEBUG level list.
6886 ***************************************************************************/
6888 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
6890 string_set(ptr, pszParmValueIn);
6891 return debug_parse_levels(pszParmValueIn);
6894 /***************************************************************************
6895 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
6896 ***************************************************************************/
6898 static const char *append_ldap_suffix( const char *str )
6900 const char *suffix_string;
6903 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
6904 Globals.szLdapSuffix );
6905 if ( !suffix_string ) {
6906 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
6910 return suffix_string;
6913 const char *lp_ldap_machine_suffix(void)
6915 if (Globals.szLdapMachineSuffix[0])
6916 return append_ldap_suffix(Globals.szLdapMachineSuffix);
6918 return lp_string(Globals.szLdapSuffix);
6921 const char *lp_ldap_user_suffix(void)
6923 if (Globals.szLdapUserSuffix[0])
6924 return append_ldap_suffix(Globals.szLdapUserSuffix);
6926 return lp_string(Globals.szLdapSuffix);
6929 const char *lp_ldap_group_suffix(void)
6931 if (Globals.szLdapGroupSuffix[0])
6932 return append_ldap_suffix(Globals.szLdapGroupSuffix);
6934 return lp_string(Globals.szLdapSuffix);
6937 const char *lp_ldap_idmap_suffix(void)
6939 if (Globals.szLdapIdmapSuffix[0])
6940 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
6942 return lp_string(Globals.szLdapSuffix);
6945 /****************************************************************************
6946 set the value for a P_ENUM
6947 ***************************************************************************/
6949 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
6954 for (i = 0; parm->enum_list[i].name; i++) {
6955 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
6956 *ptr = parm->enum_list[i].value;
6962 /***************************************************************************
6963 ***************************************************************************/
6965 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
6967 static int parm_num = -1;
6970 if ( parm_num == -1 )
6971 parm_num = map_parameter( "printing" );
6973 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
6978 s = ServicePtrs[snum];
6980 init_printer_values( s );
6986 /***************************************************************************
6987 Initialise a copymap.
6988 ***************************************************************************/
6990 static void init_copymap(struct service *pservice)
6993 if (pservice->copymap) {
6994 bitmap_free(pservice->copymap);
6996 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
6997 if (!pservice->copymap)
6999 ("Couldn't allocate copymap!! (size %d)\n",
7000 (int)NUMPARAMETERS));
7002 for (i = 0; i < NUMPARAMETERS; i++)
7003 bitmap_set(pservice->copymap, i);
7006 /***************************************************************************
7007 Return the local pointer to a parameter given the service number and the
7008 pointer into the default structure.
7009 ***************************************************************************/
7011 void *lp_local_ptr(int snum, void *ptr)
7013 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7016 /***************************************************************************
7017 Process a parameter for a particular service number. If snum < 0
7018 then assume we are in the globals.
7019 ***************************************************************************/
7021 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7023 int parmnum, i, slen;
7024 void *parm_ptr = NULL; /* where we are going to store the result */
7025 void *def_ptr = NULL;
7026 char *param_key = NULL;
7028 param_opt_struct *paramo, *data;
7031 parmnum = map_parameter(pszParmName);
7034 if ((sep=strchr(pszParmName, ':')) != NULL) {
7035 TALLOC_CTX *frame = talloc_stackframe();
7038 param_key = talloc_asprintf(frame, "%s:", pszParmName);
7043 slen = strlen(param_key);
7044 param_key = talloc_asprintf_append(param_key, sep+1);
7049 trim_char(param_key+slen, ' ', ' ');
7051 data = (snum < 0) ? Globals.param_opt :
7052 ServicePtrs[snum]->param_opt;
7053 /* Traverse destination */
7055 /* If we already have same option, override it */
7056 if (strcmp(data->key, param_key) == 0) {
7057 string_free(&data->value);
7058 TALLOC_FREE(data->list);
7059 data->value = SMB_STRDUP(pszParmValue);
7066 paramo = SMB_XMALLOC_P(param_opt_struct);
7067 paramo->key = SMB_STRDUP(param_key);
7068 paramo->value = SMB_STRDUP(pszParmValue);
7069 paramo->list = NULL;
7071 DLIST_ADD(Globals.param_opt, paramo);
7073 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
7081 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7085 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7086 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7090 def_ptr = parm_table[parmnum].ptr;
7092 /* we might point at a service, the default service or a global */
7096 if (parm_table[parmnum].p_class == P_GLOBAL) {
7098 ("Global parameter %s found in service section!\n",
7103 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7108 if (!ServicePtrs[snum]->copymap)
7109 init_copymap(ServicePtrs[snum]);
7111 /* this handles the aliases - set the copymap for other entries with
7112 the same data pointer */
7113 for (i = 0; parm_table[i].label; i++)
7114 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7115 bitmap_clear(ServicePtrs[snum]->copymap, i);
7118 /* if it is a special case then go ahead */
7119 if (parm_table[parmnum].special) {
7120 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
7124 /* now switch on the type of variable it is */
7125 switch (parm_table[parmnum].type)
7128 *(bool *)parm_ptr = lp_bool(pszParmValue);
7132 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7136 *(int *)parm_ptr = lp_int(pszParmValue);
7140 *(char *)parm_ptr = *pszParmValue;
7144 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7146 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7151 TALLOC_FREE(*((char ***)parm_ptr));
7152 *(char ***)parm_ptr = str_list_make(
7153 NULL, pszParmValue, NULL);
7157 string_set((char **)parm_ptr, pszParmValue);
7161 string_set((char **)parm_ptr, pszParmValue);
7162 strupper_m(*(char **)parm_ptr);
7166 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7175 /***************************************************************************
7176 Process a parameter.
7177 ***************************************************************************/
7179 static bool do_parameter(const char *pszParmName, const char *pszParmValue)
7181 if (!bInGlobalSection && bGlobalOnly)
7184 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7186 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7187 pszParmName, pszParmValue));
7190 /***************************************************************************
7191 Print a parameter of the specified type.
7192 ***************************************************************************/
7194 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7200 for (i = 0; p->enum_list[i].name; i++) {
7201 if (*(int *)ptr == p->enum_list[i].value) {
7203 p->enum_list[i].name);
7210 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7214 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7218 fprintf(f, "%d", *(int *)ptr);
7222 fprintf(f, "%c", *(char *)ptr);
7226 char *o = octal_string(*(int *)ptr);
7227 fprintf(f, "%s", o);
7233 if ((char ***)ptr && *(char ***)ptr) {
7234 char **list = *(char ***)ptr;
7235 for (; *list; list++) {
7236 /* surround strings with whitespace in double quotes */
7237 if ( strchr_m( *list, ' ' ) )
7238 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7240 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7247 if (*(char **)ptr) {
7248 fprintf(f, "%s", *(char **)ptr);
7256 /***************************************************************************
7257 Check if two parameters are equal.
7258 ***************************************************************************/
7260 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7265 return (*((bool *)ptr1) == *((bool *)ptr2));
7270 return (*((int *)ptr1) == *((int *)ptr2));
7273 return (*((char *)ptr1) == *((char *)ptr2));
7276 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7281 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7286 return (p1 == p2 || strequal(p1, p2));
7294 /***************************************************************************
7295 Initialize any local varients in the sDefault table.
7296 ***************************************************************************/
7298 void init_locals(void)
7303 /***************************************************************************
7304 Process a new section (service). At this stage all sections are services.
7305 Later we'll have special sections that permit server parameters to be set.
7306 Returns True on success, False on failure.
7307 ***************************************************************************/
7309 static bool do_section(const char *pszSectionName)
7312 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7313 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7316 /* if we were in a global section then do the local inits */
7317 if (bInGlobalSection && !isglobal)
7320 /* if we've just struck a global section, note the fact. */
7321 bInGlobalSection = isglobal;
7323 /* check for multiple global sections */
7324 if (bInGlobalSection) {
7325 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7329 if (!bInGlobalSection && bGlobalOnly)
7332 /* if we have a current service, tidy it up before moving on */
7335 if (iServiceIndex >= 0)
7336 bRetval = service_ok(iServiceIndex);
7338 /* if all is still well, move to the next record in the services array */
7340 /* We put this here to avoid an odd message order if messages are */
7341 /* issued by the post-processing of a previous section. */
7342 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7344 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7346 DEBUG(0, ("Failed to add a new service\n"));
7355 /***************************************************************************
7356 Determine if a partcular base parameter is currentl set to the default value.
7357 ***************************************************************************/
7359 static bool is_default(int i)
7361 if (!defaults_saved)
7363 switch (parm_table[i].type) {
7365 return str_list_compare (parm_table[i].def.lvalue,
7366 *(char ***)parm_table[i].ptr);
7369 return strequal(parm_table[i].def.svalue,
7370 *(char **)parm_table[i].ptr);
7373 return parm_table[i].def.bvalue ==
7374 *(bool *)parm_table[i].ptr;
7376 return parm_table[i].def.cvalue ==
7377 *(char *)parm_table[i].ptr;
7381 return parm_table[i].def.ivalue ==
7382 *(int *)parm_table[i].ptr;
7389 /***************************************************************************
7390 Display the contents of the global structure.
7391 ***************************************************************************/
7393 static void dump_globals(FILE *f)
7396 param_opt_struct *data;
7398 fprintf(f, "[global]\n");
7400 for (i = 0; parm_table[i].label; i++)
7401 if (parm_table[i].p_class == P_GLOBAL &&
7402 parm_table[i].ptr &&
7403 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7404 if (defaults_saved && is_default(i))
7406 fprintf(f, "\t%s = ", parm_table[i].label);
7407 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7410 if (Globals.param_opt != NULL) {
7411 data = Globals.param_opt;
7413 fprintf(f, "\t%s = %s\n", data->key, data->value);
7420 /***************************************************************************
7421 Return True if a local parameter is currently set to the global default.
7422 ***************************************************************************/
7424 bool lp_is_default(int snum, struct parm_struct *parm)
7426 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7428 return equal_parameter(parm->type,
7429 ((char *)ServicePtrs[snum]) + pdiff,
7430 ((char *)&sDefault) + pdiff);
7433 /***************************************************************************
7434 Display the contents of a single services record.
7435 ***************************************************************************/
7437 static void dump_a_service(struct service *pService, FILE * f)
7440 param_opt_struct *data;
7442 if (pService != &sDefault)
7443 fprintf(f, "[%s]\n", pService->szService);
7445 for (i = 0; parm_table[i].label; i++) {
7447 if (parm_table[i].p_class == P_LOCAL &&
7448 parm_table[i].ptr &&
7449 (*parm_table[i].label != '-') &&
7450 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7453 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7455 if (pService == &sDefault) {
7456 if (defaults_saved && is_default(i))
7459 if (equal_parameter(parm_table[i].type,
7460 ((char *)pService) +
7462 ((char *)&sDefault) +
7467 fprintf(f, "\t%s = ", parm_table[i].label);
7468 print_parameter(&parm_table[i],
7469 ((char *)pService) + pdiff, f);
7474 if (pService->param_opt != NULL) {
7475 data = pService->param_opt;
7477 fprintf(f, "\t%s = %s\n", data->key, data->value);
7483 /***************************************************************************
7484 Display the contents of a parameter of a single services record.
7485 ***************************************************************************/
7487 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7490 bool result = False;
7493 fstring local_parm_name;
7495 const char *parm_opt_value;
7497 /* check for parametrical option */
7498 fstrcpy( local_parm_name, parm_name);
7499 parm_opt = strchr( local_parm_name, ':');
7504 if (strlen(parm_opt)) {
7505 parm_opt_value = lp_parm_const_string( snum,
7506 local_parm_name, parm_opt, NULL);
7507 if (parm_opt_value) {
7508 printf( "%s\n", parm_opt_value);
7515 /* check for a key and print the value */
7522 for (i = 0; parm_table[i].label; i++) {
7523 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7524 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7525 parm_table[i].ptr &&
7526 (*parm_table[i].label != '-') &&
7527 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7532 ptr = parm_table[i].ptr;
7534 struct service *pService = ServicePtrs[snum];
7535 ptr = ((char *)pService) +
7536 PTR_DIFF(parm_table[i].ptr, &sDefault);
7539 print_parameter(&parm_table[i],
7550 /***************************************************************************
7551 Return info about the requested parameter (given as a string).
7552 Return NULL when the string is not a valid parameter name.
7553 ***************************************************************************/
7555 struct parm_struct *lp_get_parameter(const char *param_name)
7557 int num = map_parameter(param_name);
7563 return &parm_table[num];
7566 /***************************************************************************
7567 Return info about the next parameter in a service.
7568 snum==GLOBAL_SECTION_SNUM gives the globals.
7569 Return NULL when out of parameters.
7570 ***************************************************************************/
7572 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7575 /* do the globals */
7576 for (; parm_table[*i].label; (*i)++) {
7577 if (parm_table[*i].p_class == P_SEPARATOR)
7578 return &parm_table[(*i)++];
7580 if (!parm_table[*i].ptr
7581 || (*parm_table[*i].label == '-'))
7585 && (parm_table[*i].ptr ==
7586 parm_table[(*i) - 1].ptr))
7589 if (is_default(*i) && !allparameters)
7592 return &parm_table[(*i)++];
7595 struct service *pService = ServicePtrs[snum];
7597 for (; parm_table[*i].label; (*i)++) {
7598 if (parm_table[*i].p_class == P_SEPARATOR)
7599 return &parm_table[(*i)++];
7601 if (parm_table[*i].p_class == P_LOCAL &&
7602 parm_table[*i].ptr &&
7603 (*parm_table[*i].label != '-') &&
7605 (parm_table[*i].ptr !=
7606 parm_table[(*i) - 1].ptr)))
7609 PTR_DIFF(parm_table[*i].ptr,
7612 if (allparameters ||
7613 !equal_parameter(parm_table[*i].type,
7614 ((char *)pService) +
7616 ((char *)&sDefault) +
7619 return &parm_table[(*i)++];
7630 /***************************************************************************
7631 Display the contents of a single copy structure.
7632 ***************************************************************************/
7633 static void dump_copy_map(bool *pcopymap)
7639 printf("\n\tNon-Copied parameters:\n");
7641 for (i = 0; parm_table[i].label; i++)
7642 if (parm_table[i].p_class == P_LOCAL &&
7643 parm_table[i].ptr && !pcopymap[i] &&
7644 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7646 printf("\t\t%s\n", parm_table[i].label);
7651 /***************************************************************************
7652 Return TRUE if the passed service number is within range.
7653 ***************************************************************************/
7655 bool lp_snum_ok(int iService)
7657 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7660 /***************************************************************************
7661 Auto-load some home services.
7662 ***************************************************************************/
7664 static void lp_add_auto_services(char *str)
7674 s = SMB_STRDUP(str);
7678 homes = lp_servicenumber(HOMES_NAME);
7680 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7681 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7684 if (lp_servicenumber(p) >= 0)
7687 home = get_user_home_dir(talloc_tos(), p);
7689 if (home && homes >= 0)
7690 lp_add_home(p, homes, p, home);
7697 /***************************************************************************
7698 Auto-load one printer.
7699 ***************************************************************************/
7701 void lp_add_one_printer(char *name, char *comment)
7703 int printers = lp_servicenumber(PRINTERS_NAME);
7706 if (lp_servicenumber(name) < 0) {
7707 lp_add_printer(name, printers);
7708 if ((i = lp_servicenumber(name)) >= 0) {
7709 string_set(&ServicePtrs[i]->comment, comment);
7710 ServicePtrs[i]->autoloaded = True;
7715 /***************************************************************************
7716 Have we loaded a services file yet?
7717 ***************************************************************************/
7719 bool lp_loaded(void)
7724 /***************************************************************************
7725 Unload unused services.
7726 ***************************************************************************/
7728 void lp_killunused(bool (*snumused) (int))
7731 for (i = 0; i < iNumServices; i++) {
7735 /* don't kill autoloaded or usershare services */
7736 if ( ServicePtrs[i]->autoloaded ||
7737 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7741 if (!snumused || !snumused(i)) {
7742 free_service_byindex(i);
7748 * Kill all except autoloaded and usershare services - convenience wrapper
7750 void lp_kill_all_services(void)
7752 lp_killunused(NULL);
7755 /***************************************************************************
7757 ***************************************************************************/
7759 void lp_killservice(int iServiceIn)
7761 if (VALID(iServiceIn)) {
7762 free_service_byindex(iServiceIn);
7766 /***************************************************************************
7767 Save the curent values of all global and sDefault parameters into the
7768 defaults union. This allows swat and testparm to show only the
7769 changed (ie. non-default) parameters.
7770 ***************************************************************************/
7772 static void lp_save_defaults(void)
7775 for (i = 0; parm_table[i].label; i++) {
7776 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7778 switch (parm_table[i].type) {
7781 NULL, &(parm_table[i].def.lvalue),
7782 *(const char ***)parm_table[i].ptr);
7786 if (parm_table[i].ptr) {
7787 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7789 parm_table[i].def.svalue = NULL;
7794 parm_table[i].def.bvalue =
7795 *(bool *)parm_table[i].ptr;
7798 parm_table[i].def.cvalue =
7799 *(char *)parm_table[i].ptr;
7804 parm_table[i].def.ivalue =
7805 *(int *)parm_table[i].ptr;
7811 defaults_saved = True;
7814 /*******************************************************************
7815 Set the server type we will announce as via nmbd.
7816 ********************************************************************/
7818 static const struct srv_role_tab {
7820 const char *role_str;
7821 } srv_role_tab [] = {
7822 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7823 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7824 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7825 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7829 const char* server_role_str(uint32 role)
7832 for (i=0; srv_role_tab[i].role_str; i++) {
7833 if (role == srv_role_tab[i].role) {
7834 return srv_role_tab[i].role_str;
7840 static void set_server_role(void)
7842 server_role = ROLE_STANDALONE;
7844 switch (lp_security()) {
7846 if (lp_domain_logons())
7847 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7850 if (lp_domain_logons())
7851 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7852 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7853 server_role = ROLE_STANDALONE;
7856 if (lp_domain_logons()) {
7857 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7858 server_role = ROLE_DOMAIN_BDC;
7861 server_role = ROLE_DOMAIN_MEMBER;
7864 if (lp_domain_logons()) {
7865 server_role = ROLE_DOMAIN_PDC;
7868 server_role = ROLE_DOMAIN_MEMBER;
7871 if (lp_domain_logons()) {
7873 if (Globals.iDomainMaster) /* auto or yes */
7874 server_role = ROLE_DOMAIN_PDC;
7876 server_role = ROLE_DOMAIN_BDC;
7880 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7884 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7887 /***********************************************************
7888 If we should send plaintext/LANMAN passwords in the clinet
7889 ************************************************************/
7891 static void set_allowed_client_auth(void)
7893 if (Globals.bClientNTLMv2Auth) {
7894 Globals.bClientLanManAuth = False;
7896 if (!Globals.bClientLanManAuth) {
7897 Globals.bClientPlaintextAuth = False;
7901 /***************************************************************************
7903 The following code allows smbd to read a user defined share file.
7904 Yes, this is my intent. Yes, I'm comfortable with that...
7906 THE FOLLOWING IS SECURITY CRITICAL CODE.
7908 It washes your clothes, it cleans your house, it guards you while you sleep...
7909 Do not f%^k with it....
7910 ***************************************************************************/
7912 #define MAX_USERSHARE_FILE_SIZE (10*1024)
7914 /***************************************************************************
7915 Check allowed stat state of a usershare file.
7916 Ensure we print out who is dicking with us so the admin can
7917 get their sorry ass fired.
7918 ***************************************************************************/
7920 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
7922 if (!S_ISREG(psbuf->st_mode)) {
7923 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
7924 "not a regular file\n",
7925 fname, (unsigned int)psbuf->st_uid ));
7929 /* Ensure this doesn't have the other write bit set. */
7930 if (psbuf->st_mode & S_IWOTH) {
7931 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
7932 "public write. Refusing to allow as a usershare file.\n",
7933 fname, (unsigned int)psbuf->st_uid ));
7937 /* Should be 10k or less. */
7938 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
7939 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
7940 "too large (%u) to be a user share file.\n",
7941 fname, (unsigned int)psbuf->st_uid,
7942 (unsigned int)psbuf->st_size ));
7949 /***************************************************************************
7950 Parse the contents of a usershare file.
7951 ***************************************************************************/
7953 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
7954 SMB_STRUCT_STAT *psbuf,
7955 const char *servicename,
7959 char **pp_sharepath,
7964 const char **prefixallowlist = lp_usershare_prefix_allow_list();
7965 const char **prefixdenylist = lp_usershare_prefix_deny_list();
7968 SMB_STRUCT_STAT sbuf;
7969 char *sharepath = NULL;
7970 char *comment = NULL;
7972 *pp_sharepath = NULL;
7975 *pallow_guest = False;
7978 return USERSHARE_MALFORMED_FILE;
7981 if (strcmp(lines[0], "#VERSION 1") == 0) {
7983 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
7986 return USERSHARE_MALFORMED_FILE;
7989 return USERSHARE_BAD_VERSION;
7992 if (strncmp(lines[1], "path=", 5) != 0) {
7993 return USERSHARE_MALFORMED_PATH;
7996 sharepath = talloc_strdup(ctx, &lines[1][5]);
7998 return USERSHARE_POSIX_ERR;
8000 trim_string(sharepath, " ", " ");
8002 if (strncmp(lines[2], "comment=", 8) != 0) {
8003 return USERSHARE_MALFORMED_COMMENT_DEF;
8006 comment = talloc_strdup(ctx, &lines[2][8]);
8008 return USERSHARE_POSIX_ERR;
8010 trim_string(comment, " ", " ");
8011 trim_char(comment, '"', '"');
8013 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8014 return USERSHARE_MALFORMED_ACL_DEF;
8017 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8018 return USERSHARE_ACL_ERR;
8022 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8023 return USERSHARE_MALFORMED_ACL_DEF;
8025 if (lines[4][9] == 'y') {
8026 *pallow_guest = True;
8030 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8031 /* Path didn't change, no checks needed. */
8032 *pp_sharepath = sharepath;
8033 *pp_comment = comment;
8034 return USERSHARE_OK;
8037 /* The path *must* be absolute. */
8038 if (sharepath[0] != '/') {
8039 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8040 servicename, sharepath));
8041 return USERSHARE_PATH_NOT_ABSOLUTE;
8044 /* If there is a usershare prefix deny list ensure one of these paths
8045 doesn't match the start of the user given path. */
8046 if (prefixdenylist) {
8048 for ( i=0; prefixdenylist[i]; i++ ) {
8049 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8050 servicename, i, prefixdenylist[i], sharepath ));
8051 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8052 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8053 "usershare prefix deny list entries.\n",
8054 servicename, sharepath));
8055 return USERSHARE_PATH_IS_DENIED;
8060 /* If there is a usershare prefix allow list ensure one of these paths
8061 does match the start of the user given path. */
8063 if (prefixallowlist) {
8065 for ( i=0; prefixallowlist[i]; i++ ) {
8066 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8067 servicename, i, prefixallowlist[i], sharepath ));
8068 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8072 if (prefixallowlist[i] == NULL) {
8073 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8074 "usershare prefix allow list entries.\n",
8075 servicename, sharepath));
8076 return USERSHARE_PATH_NOT_ALLOWED;
8080 /* Ensure this is pointing to a directory. */
8081 dp = sys_opendir(sharepath);
8084 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8085 servicename, sharepath));
8086 return USERSHARE_PATH_NOT_DIRECTORY;
8089 /* Ensure the owner of the usershare file has permission to share
8092 if (sys_stat(sharepath, &sbuf) == -1) {
8093 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8094 servicename, sharepath, strerror(errno) ));
8096 return USERSHARE_POSIX_ERR;
8101 if (!S_ISDIR(sbuf.st_mode)) {
8102 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8103 servicename, sharepath ));
8104 return USERSHARE_PATH_NOT_DIRECTORY;
8107 /* Check if sharing is restricted to owner-only. */
8108 /* psbuf is the stat of the usershare definition file,
8109 sbuf is the stat of the target directory to be shared. */
8111 if (lp_usershare_owner_only()) {
8112 /* root can share anything. */
8113 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8114 return USERSHARE_PATH_NOT_ALLOWED;
8118 *pp_sharepath = sharepath;
8119 *pp_comment = comment;
8120 return USERSHARE_OK;
8123 /***************************************************************************
8124 Deal with a usershare file.
8127 -1 - Bad name, invalid contents.
8128 - service name already existed and not a usershare, problem
8129 with permissions to share directory etc.
8130 ***************************************************************************/
8132 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8134 SMB_STRUCT_STAT sbuf;
8135 SMB_STRUCT_STAT lsbuf;
8137 char *sharepath = NULL;
8138 char *comment = NULL;
8139 fstring service_name;
8140 char **lines = NULL;
8144 TALLOC_CTX *ctx = NULL;
8145 SEC_DESC *psd = NULL;
8146 bool guest_ok = False;
8148 /* Ensure share name doesn't contain invalid characters. */
8149 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8150 DEBUG(0,("process_usershare_file: share name %s contains "
8151 "invalid characters (any of %s)\n",
8152 file_name, INVALID_SHARENAME_CHARS ));
8156 fstrcpy(service_name, file_name);
8158 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8161 /* Minimize the race condition by doing an lstat before we
8162 open and fstat. Ensure this isn't a symlink link. */
8164 if (sys_lstat(fname, &lsbuf) != 0) {
8165 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8166 fname, strerror(errno) ));
8171 /* This must be a regular file, not a symlink, directory or
8172 other strange filetype. */
8173 if (!check_usershare_stat(fname, &lsbuf)) {
8179 char *canon_name = canonicalize_servicename(service_name);
8180 TDB_DATA data = dbwrap_fetch_bystring(
8181 ServiceHash, canon_name, canon_name);
8185 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8186 iService = *(int *)data.dptr;
8188 TALLOC_FREE(canon_name);
8191 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8192 /* Nothing changed - Mark valid and return. */
8193 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8195 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8200 /* Try and open the file read only - no symlinks allowed. */
8202 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8204 fd = sys_open(fname, O_RDONLY, 0);
8208 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8209 fname, strerror(errno) ));
8214 /* Now fstat to be *SURE* it's a regular file. */
8215 if (sys_fstat(fd, &sbuf) != 0) {
8217 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8218 fname, strerror(errno) ));
8223 /* Is it the same dev/inode as was lstated ? */
8224 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8226 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8227 "Symlink spoofing going on ?\n", fname ));
8232 /* This must be a regular file, not a symlink, directory or
8233 other strange filetype. */
8234 if (!check_usershare_stat(fname, &sbuf)) {
8239 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8242 if (lines == NULL) {
8243 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8244 fname, (unsigned int)sbuf.st_uid ));
8251 /* Should we allow printers to be shared... ? */
8252 ctx = talloc_init("usershare_sd_xctx");
8254 file_lines_free(lines);
8258 if (parse_usershare_file(ctx, &sbuf, service_name,
8259 iService, lines, numlines, &sharepath,
8260 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8261 talloc_destroy(ctx);
8262 file_lines_free(lines);
8266 file_lines_free(lines);
8268 /* Everything ok - add the service possibly using a template. */
8270 const struct service *sp = &sDefault;
8271 if (snum_template != -1) {
8272 sp = ServicePtrs[snum_template];
8275 if ((iService = add_a_service(sp, service_name)) < 0) {
8276 DEBUG(0, ("process_usershare_file: Failed to add "
8277 "new service %s\n", service_name));
8278 talloc_destroy(ctx);
8282 /* Read only is controlled by usershare ACL below. */
8283 ServicePtrs[iService]->bRead_only = False;
8286 /* Write the ACL of the new/modified share. */
8287 if (!set_share_security(service_name, psd)) {
8288 DEBUG(0, ("process_usershare_file: Failed to set share "
8289 "security for user share %s\n",
8291 lp_remove_service(iService);
8292 talloc_destroy(ctx);
8296 /* If from a template it may be marked invalid. */
8297 ServicePtrs[iService]->valid = True;
8299 /* Set the service as a valid usershare. */
8300 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8302 /* Set guest access. */
8303 if (lp_usershare_allow_guests()) {
8304 ServicePtrs[iService]->bGuest_ok = guest_ok;
8307 /* And note when it was loaded. */
8308 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8309 string_set(&ServicePtrs[iService]->szPath, sharepath);
8310 string_set(&ServicePtrs[iService]->comment, comment);
8312 talloc_destroy(ctx);
8317 /***************************************************************************
8318 Checks if a usershare entry has been modified since last load.
8319 ***************************************************************************/
8321 static bool usershare_exists(int iService, time_t *last_mod)
8323 SMB_STRUCT_STAT lsbuf;
8324 const char *usersharepath = Globals.szUsersharePath;
8327 if (asprintf(&fname, "%s/%s",
8329 ServicePtrs[iService]->szService) < 0) {
8333 if (sys_lstat(fname, &lsbuf) != 0) {
8338 if (!S_ISREG(lsbuf.st_mode)) {
8344 *last_mod = lsbuf.st_mtime;
8348 /***************************************************************************
8349 Load a usershare service by name. Returns a valid servicenumber or -1.
8350 ***************************************************************************/
8352 int load_usershare_service(const char *servicename)
8354 SMB_STRUCT_STAT sbuf;
8355 const char *usersharepath = Globals.szUsersharePath;
8356 int max_user_shares = Globals.iUsershareMaxShares;
8357 int snum_template = -1;
8359 if (*usersharepath == 0 || max_user_shares == 0) {
8363 if (sys_stat(usersharepath, &sbuf) != 0) {
8364 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8365 usersharepath, strerror(errno) ));
8369 if (!S_ISDIR(sbuf.st_mode)) {
8370 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8376 * This directory must be owned by root, and have the 't' bit set.
8377 * It also must not be writable by "other".
8381 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8383 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8385 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8386 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8391 /* Ensure the template share exists if it's set. */
8392 if (Globals.szUsershareTemplateShare[0]) {
8393 /* We can't use lp_servicenumber here as we are recommending that
8394 template shares have -valid=False set. */
8395 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8396 if (ServicePtrs[snum_template]->szService &&
8397 strequal(ServicePtrs[snum_template]->szService,
8398 Globals.szUsershareTemplateShare)) {
8403 if (snum_template == -1) {
8404 DEBUG(0,("load_usershare_service: usershare template share %s "
8405 "does not exist.\n",
8406 Globals.szUsershareTemplateShare ));
8411 return process_usershare_file(usersharepath, servicename, snum_template);
8414 /***************************************************************************
8415 Load all user defined shares from the user share directory.
8416 We only do this if we're enumerating the share list.
8417 This is the function that can delete usershares that have
8419 ***************************************************************************/
8421 int load_usershare_shares(void)
8424 SMB_STRUCT_STAT sbuf;
8425 SMB_STRUCT_DIRENT *de;
8426 int num_usershares = 0;
8427 int max_user_shares = Globals.iUsershareMaxShares;
8428 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8429 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8430 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8432 int snum_template = -1;
8433 const char *usersharepath = Globals.szUsersharePath;
8434 int ret = lp_numservices();
8436 if (max_user_shares == 0 || *usersharepath == '\0') {
8437 return lp_numservices();
8440 if (sys_stat(usersharepath, &sbuf) != 0) {
8441 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8442 usersharepath, strerror(errno) ));
8447 * This directory must be owned by root, and have the 't' bit set.
8448 * It also must not be writable by "other".
8452 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8454 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8456 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8457 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8462 /* Ensure the template share exists if it's set. */
8463 if (Globals.szUsershareTemplateShare[0]) {
8464 /* We can't use lp_servicenumber here as we are recommending that
8465 template shares have -valid=False set. */
8466 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8467 if (ServicePtrs[snum_template]->szService &&
8468 strequal(ServicePtrs[snum_template]->szService,
8469 Globals.szUsershareTemplateShare)) {
8474 if (snum_template == -1) {
8475 DEBUG(0,("load_usershare_shares: usershare template share %s "
8476 "does not exist.\n",
8477 Globals.szUsershareTemplateShare ));
8482 /* Mark all existing usershares as pending delete. */
8483 for (iService = iNumServices - 1; iService >= 0; iService--) {
8484 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8485 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8489 dp = sys_opendir(usersharepath);
8491 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8492 usersharepath, strerror(errno) ));
8496 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8497 (de = sys_readdir(dp));
8498 num_dir_entries++ ) {
8500 const char *n = de->d_name;
8502 /* Ignore . and .. */
8504 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8510 /* Temporary file used when creating a share. */
8511 num_tmp_dir_entries++;
8514 /* Allow 20% tmp entries. */
8515 if (num_tmp_dir_entries > allowed_tmp_entries) {
8516 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8517 "in directory %s\n",
8518 num_tmp_dir_entries, usersharepath));
8522 r = process_usershare_file(usersharepath, n, snum_template);
8524 /* Update the services count. */
8526 if (num_usershares >= max_user_shares) {
8527 DEBUG(0,("load_usershare_shares: max user shares reached "
8528 "on file %s in directory %s\n",
8529 n, usersharepath ));
8532 } else if (r == -1) {
8533 num_bad_dir_entries++;
8536 /* Allow 20% bad entries. */
8537 if (num_bad_dir_entries > allowed_bad_entries) {
8538 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8539 "in directory %s\n",
8540 num_bad_dir_entries, usersharepath));
8544 /* Allow 20% bad entries. */
8545 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8546 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8547 "in directory %s\n",
8548 num_dir_entries, usersharepath));
8555 /* Sweep through and delete any non-refreshed usershares that are
8556 not currently in use. */
8557 for (iService = iNumServices - 1; iService >= 0; iService--) {
8558 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8559 if (conn_snum_used(iService)) {
8562 /* Remove from the share ACL db. */
8563 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8564 lp_servicename(iService) ));
8565 delete_share_security(lp_servicename(iService));
8566 free_service_byindex(iService);
8570 return lp_numservices();
8573 /********************************************************
8574 Destroy global resources allocated in this file
8575 ********************************************************/
8577 void gfree_loadparm(void)
8579 struct file_lists *f;
8580 struct file_lists *next;
8583 /* Free the file lists */
8588 SAFE_FREE( f->name );
8589 SAFE_FREE( f->subfname );
8594 /* Free resources allocated to services */
8596 for ( i = 0; i < iNumServices; i++ ) {
8598 free_service_byindex(i);
8602 SAFE_FREE( ServicePtrs );
8605 /* Now release all resources allocated to global
8606 parameters and the default service */
8608 for (i = 0; parm_table[i].label; i++)
8610 if ( parm_table[i].type == P_STRING
8611 || parm_table[i].type == P_USTRING )
8613 string_free( (char**)parm_table[i].ptr );
8615 else if (parm_table[i].type == P_LIST) {
8616 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8622 /***************************************************************************
8623 Allow client apps to specify that they are a client
8624 ***************************************************************************/
8625 void lp_set_in_client(bool b)
8631 /***************************************************************************
8632 Determine if we're running in a client app
8633 ***************************************************************************/
8634 bool lp_is_in_client(void)
8642 /***************************************************************************
8643 Load the services array from the services file. Return True on success,
8645 ***************************************************************************/
8647 bool lp_load(const char *pszFname,
8651 bool initialize_globals)
8655 param_opt_struct *data, *pdata;
8659 DEBUG(3, ("lp_load: refreshing parameters\n"));
8661 bInGlobalSection = True;
8662 bGlobalOnly = global_only;
8664 init_globals(! initialize_globals);
8667 if (save_defaults) {
8672 if (Globals.param_opt != NULL) {
8673 data = Globals.param_opt;
8675 string_free(&data->key);
8676 string_free(&data->value);
8677 TALLOC_FREE(data->list);
8682 Globals.param_opt = NULL;
8685 if (lp_config_backend_is_file()) {
8686 n2 = alloc_sub_basic(get_current_username(),
8687 current_user_info.domain,
8690 smb_panic("lp_load: out of memory");
8693 add_to_file_list(pszFname, n2);
8695 /* We get sections first, so have to start 'behind' to make up */
8697 bRetval = pm_process(n2, do_section, do_parameter);
8700 /* finish up the last section */
8701 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8703 if (iServiceIndex >= 0) {
8704 bRetval = service_ok(iServiceIndex);
8708 if (lp_config_backend_is_registry()) {
8709 /* config backend changed to registry in config file */
8711 * We need to use this extra global variable here to
8712 * survive restart: init_globals uses this as a default
8713 * for ConfigBackend. Otherwise, init_globals would
8714 * send us into an endless loop here.
8716 config_backend = CONFIG_BACKEND_REGISTRY;
8718 init_globals(false);
8719 return lp_load(pszFname, global_only, save_defaults,
8720 add_ipc, initialize_globals);
8722 } else if (lp_config_backend_is_registry()) {
8723 bRetval = process_registry_globals(do_parameter);
8725 DEBUG(0, ("Illegal config backend given: %d\n",
8726 lp_config_backend()));
8730 lp_add_auto_services(lp_auto_services());
8733 /* When 'restrict anonymous = 2' guest connections to ipc$
8735 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8736 if ( lp_enable_asu_support() ) {
8737 lp_add_ipc("ADMIN$", false);
8742 set_default_server_announce_type();
8743 set_allowed_client_auth();
8747 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8748 /* if bWINSsupport is true and we are in the client */
8749 if (lp_is_in_client() && Globals.bWINSsupport) {
8750 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8758 /***************************************************************************
8759 Reset the max number of services.
8760 ***************************************************************************/
8762 void lp_resetnumservices(void)
8767 /***************************************************************************
8768 Return the max number of services.
8769 ***************************************************************************/
8771 int lp_numservices(void)
8773 return (iNumServices);
8776 /***************************************************************************
8777 Display the contents of the services array in human-readable form.
8778 ***************************************************************************/
8780 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8785 defaults_saved = False;
8789 dump_a_service(&sDefault, f);
8791 for (iService = 0; iService < maxtoprint; iService++) {
8793 lp_dump_one(f, show_defaults, iService);
8797 /***************************************************************************
8798 Display the contents of one service in human-readable form.
8799 ***************************************************************************/
8801 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8804 if (ServicePtrs[snum]->szService[0] == '\0')
8806 dump_a_service(ServicePtrs[snum], f);
8810 /***************************************************************************
8811 Return the number of the service with the given name, or -1 if it doesn't
8812 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8813 getservicebyname()! This works ONLY if all services have been loaded, and
8814 does not copy the found service.
8815 ***************************************************************************/
8817 int lp_servicenumber(const char *pszServiceName)
8820 fstring serviceName;
8822 if (!pszServiceName) {
8823 return GLOBAL_SECTION_SNUM;
8826 for (iService = iNumServices - 1; iService >= 0; iService--) {
8827 if (VALID(iService) && ServicePtrs[iService]->szService) {
8829 * The substitution here is used to support %U is
8832 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8833 standard_sub_basic(get_current_username(),
8834 current_user_info.domain,
8835 serviceName,sizeof(serviceName));
8836 if (strequal(serviceName, pszServiceName)) {
8842 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8845 if (!usershare_exists(iService, &last_mod)) {
8846 /* Remove the share security tdb entry for it. */
8847 delete_share_security(lp_servicename(iService));
8848 /* Remove it from the array. */
8849 free_service_byindex(iService);
8850 /* Doesn't exist anymore. */
8851 return GLOBAL_SECTION_SNUM;
8854 /* Has it been modified ? If so delete and reload. */
8855 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
8856 /* Remove it from the array. */
8857 free_service_byindex(iService);
8858 /* and now reload it. */
8859 iService = load_usershare_service(pszServiceName);
8864 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
8865 return GLOBAL_SECTION_SNUM;
8871 bool share_defined(const char *service_name)
8873 return (lp_servicenumber(service_name) != -1);
8876 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
8877 const char *sharename)
8879 struct share_params *result;
8883 if (!(sname = SMB_STRDUP(sharename))) {
8887 snum = find_service(sname);
8894 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
8895 DEBUG(0, ("talloc failed\n"));
8899 result->service = snum;
8903 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
8905 struct share_iterator *result;
8907 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
8908 DEBUG(0, ("talloc failed\n"));
8912 result->next_id = 0;
8916 struct share_params *next_share(struct share_iterator *list)
8918 struct share_params *result;
8920 while (!lp_snum_ok(list->next_id) &&
8921 (list->next_id < lp_numservices())) {
8925 if (list->next_id >= lp_numservices()) {
8929 if (!(result = TALLOC_P(list, struct share_params))) {
8930 DEBUG(0, ("talloc failed\n"));
8934 result->service = list->next_id;
8939 struct share_params *next_printer(struct share_iterator *list)
8941 struct share_params *result;
8943 while ((result = next_share(list)) != NULL) {
8944 if (lp_print_ok(result->service)) {
8952 * This is a hack for a transition period until we transformed all code from
8953 * service numbers to struct share_params.
8956 struct share_params *snum2params_static(int snum)
8958 static struct share_params result;
8959 result.service = snum;
8963 /*******************************************************************
8964 A useful volume label function.
8965 ********************************************************************/
8967 const char *volume_label(int snum)
8970 const char *label = lp_volume(snum);
8972 label = lp_servicename(snum);
8975 /* This returns a 33 byte guarenteed null terminated string. */
8976 ret = talloc_strndup(talloc_tos(), label, 32);
8983 /*******************************************************************
8984 Set the server type we will announce as via nmbd.
8985 ********************************************************************/
8987 static void set_default_server_announce_type(void)
8989 default_server_announce = 0;
8990 default_server_announce |= SV_TYPE_WORKSTATION;
8991 default_server_announce |= SV_TYPE_SERVER;
8992 default_server_announce |= SV_TYPE_SERVER_UNIX;
8994 /* note that the flag should be set only if we have a
8995 printer service but nmbd doesn't actually load the
8996 services so we can't tell --jerry */
8998 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9000 switch (lp_announce_as()) {
9001 case ANNOUNCE_AS_NT_SERVER:
9002 default_server_announce |= SV_TYPE_SERVER_NT;
9003 /* fall through... */
9004 case ANNOUNCE_AS_NT_WORKSTATION:
9005 default_server_announce |= SV_TYPE_NT;
9007 case ANNOUNCE_AS_WIN95:
9008 default_server_announce |= SV_TYPE_WIN95_PLUS;
9010 case ANNOUNCE_AS_WFW:
9011 default_server_announce |= SV_TYPE_WFW;
9017 switch (lp_server_role()) {
9018 case ROLE_DOMAIN_MEMBER:
9019 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9021 case ROLE_DOMAIN_PDC:
9022 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9024 case ROLE_DOMAIN_BDC:
9025 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9027 case ROLE_STANDALONE:
9031 if (lp_time_server())
9032 default_server_announce |= SV_TYPE_TIME_SOURCE;
9034 if (lp_host_msdfs())
9035 default_server_announce |= SV_TYPE_DFS_SERVER;
9038 /***********************************************************
9039 returns role of Samba server
9040 ************************************************************/
9042 int lp_server_role(void)
9047 /***********************************************************
9048 If we are PDC then prefer us as DMB
9049 ************************************************************/
9051 bool lp_domain_master(void)
9053 if (Globals.iDomainMaster == Auto)
9054 return (lp_server_role() == ROLE_DOMAIN_PDC);
9056 return (bool)Globals.iDomainMaster;
9059 /***********************************************************
9060 If we are DMB then prefer us as LMB
9061 ************************************************************/
9063 bool lp_preferred_master(void)
9065 if (Globals.iPreferredMaster == Auto)
9066 return (lp_local_master() && lp_domain_master());
9068 return (bool)Globals.iPreferredMaster;
9071 /*******************************************************************
9073 ********************************************************************/
9075 void lp_remove_service(int snum)
9077 ServicePtrs[snum]->valid = False;
9078 invalid_services[num_invalid_services++] = snum;
9081 /*******************************************************************
9083 ********************************************************************/
9085 void lp_copy_service(int snum, const char *new_name)
9087 do_section(new_name);
9089 snum = lp_servicenumber(new_name);
9091 lp_do_parameter(snum, "copy", lp_servicename(snum));
9096 /*******************************************************************
9097 Get the default server type we will announce as via nmbd.
9098 ********************************************************************/
9100 int lp_default_server_announce(void)
9102 return default_server_announce;
9105 /*******************************************************************
9106 Split the announce version into major and minor numbers.
9107 ********************************************************************/
9109 int lp_major_announce_version(void)
9111 static bool got_major = False;
9112 static int major_version = DEFAULT_MAJOR_VERSION;
9117 return major_version;
9120 if ((vers = lp_announce_version()) == NULL)
9121 return major_version;
9123 if ((p = strchr_m(vers, '.')) == 0)
9124 return major_version;
9127 major_version = atoi(vers);
9128 return major_version;
9131 int lp_minor_announce_version(void)
9133 static bool got_minor = False;
9134 static int minor_version = DEFAULT_MINOR_VERSION;
9139 return minor_version;
9142 if ((vers = lp_announce_version()) == NULL)
9143 return minor_version;
9145 if ((p = strchr_m(vers, '.')) == 0)
9146 return minor_version;
9149 minor_version = atoi(p);
9150 return minor_version;
9153 /***********************************************************
9154 Set the global name resolution order (used in smbclient).
9155 ************************************************************/
9157 void lp_set_name_resolve_order(const char *new_order)
9159 string_set(&Globals.szNameResolveOrder, new_order);
9162 const char *lp_printername(int snum)
9164 const char *ret = _lp_printername(snum);
9165 if (ret == NULL || (ret != NULL && *ret == '\0'))
9166 ret = lp_const_servicename(snum);
9172 /***********************************************************
9173 Allow daemons such as winbindd to fix their logfile name.
9174 ************************************************************/
9176 void lp_set_logfile(const char *name)
9178 string_set(&Globals.szLogFile, name);
9179 debug_set_logfile(name);
9182 /*******************************************************************
9183 Return the max print jobs per queue.
9184 ********************************************************************/
9186 int lp_maxprintjobs(int snum)
9188 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9189 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9190 maxjobs = PRINT_MAX_JOBID - 1;
9195 const char *lp_printcapname(void)
9197 if ((Globals.szPrintcapname != NULL) &&
9198 (Globals.szPrintcapname[0] != '\0'))
9199 return Globals.szPrintcapname;
9201 if (sDefault.iPrinting == PRINT_CUPS) {
9209 if (sDefault.iPrinting == PRINT_BSD)
9210 return "/etc/printcap";
9212 return PRINTCAP_NAME;
9215 /*******************************************************************
9216 Ensure we don't use sendfile if server smb signing is active.
9217 ********************************************************************/
9219 static uint32 spoolss_state;
9221 bool lp_disable_spoolss( void )
9223 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9224 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9226 return spoolss_state == SVCCTL_STOPPED ? True : False;
9229 void lp_set_spoolss_state( uint32 state )
9231 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9233 spoolss_state = state;
9236 uint32 lp_get_spoolss_state( void )
9238 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9241 /*******************************************************************
9242 Ensure we don't use sendfile if server smb signing is active.
9243 ********************************************************************/
9245 bool lp_use_sendfile(int snum)
9247 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9248 if (Protocol < PROTOCOL_NT1) {
9251 return (_lp_use_sendfile(snum) &&
9252 (get_remote_arch() != RA_WIN95) &&
9253 !srv_is_signing_active());
9256 /*******************************************************************
9257 Turn off sendfile if we find the underlying OS doesn't support it.
9258 ********************************************************************/
9260 void set_use_sendfile(int snum, bool val)
9262 if (LP_SNUM_OK(snum))
9263 ServicePtrs[snum]->bUseSendfile = val;
9265 sDefault.bUseSendfile = val;
9268 /*******************************************************************
9269 Turn off storing DOS attributes if this share doesn't support it.
9270 ********************************************************************/
9272 void set_store_dos_attributes(int snum, bool val)
9274 if (!LP_SNUM_OK(snum))
9276 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9279 void lp_set_mangling_method(const char *new_method)
9281 string_set(&Globals.szManglingMethod, new_method);
9284 /*******************************************************************
9285 Global state for POSIX pathname processing.
9286 ********************************************************************/
9288 static bool posix_pathnames;
9290 bool lp_posix_pathnames(void)
9292 return posix_pathnames;
9295 /*******************************************************************
9296 Change everything needed to ensure POSIX pathname processing (currently
9298 ********************************************************************/
9300 void lp_set_posix_pathnames(void)
9302 posix_pathnames = True;
9305 /*******************************************************************
9306 Global state for POSIX lock processing - CIFS unix extensions.
9307 ********************************************************************/
9309 bool posix_default_lock_was_set;
9310 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9312 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9314 if (posix_default_lock_was_set) {
9315 return posix_cifsx_locktype;
9317 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9321 /*******************************************************************
9322 ********************************************************************/
9324 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9326 posix_default_lock_was_set = True;
9327 posix_cifsx_locktype = val;
9330 int lp_min_receive_file_size(void)
9332 if (Globals.iminreceivefile < 0) {
9335 return MIN(Globals.iminreceivefile, BUFFER_SIZE);