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
13 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14 Copyright (C) Andrew Bartlett 2011
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 3 of the License, or
19 (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
33 * This module provides suitable callback functions for the params
34 * module. It builds the internal table of service details which is
35 * then used by the rest of the server.
39 * 1) add it to the global or service structure definition
40 * 2) add it to the parm_table
41 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42 * 4) If it's a global then initialise it in init_globals. If a local
43 * (ie. service) parameter then initialise it in the sDefault structure
47 * The configuration file is processed sequentially for speed. It is NOT
48 * accessed randomly as happens in 'real' Windows. For this reason, there
49 * is a fair bit of sequence-dependent code here - ie., code which assumes
50 * that certain things happen before others. In particular, the code which
51 * happens at the boundary between sections is delicately poised, so be
57 #include "system/filesys.h"
59 #include "lib/param/loadparm.h"
61 #include "lib/smbconf/smbconf.h"
62 #include "lib/smbconf/smbconf_init.h"
65 #include "../librpc/gen_ndr/svcctl.h"
67 #include "../libcli/smb/smb_signing.h"
68 #include "dbwrap/dbwrap.h"
69 #include "dbwrap/dbwrap_rbt.h"
70 #include "../lib/util/bitmap.h"
71 #include "../source4/dns_server/dns_update.h"
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
81 #ifdef CLUSTER_SUPPORT
82 #include "ctdb_private.h"
87 extern userdom_struct current_user_info
;
89 /* the special value for the include parameter
90 * to be interpreted not as a file name but to
91 * trigger loading of the global smb.conf options
93 #ifndef INCLUDE_REGISTRY_NAME
94 #define INCLUDE_REGISTRY_NAME "registry"
97 static bool in_client
= false; /* Not in the client by default */
98 static struct smbconf_csn conf_last_csn
;
100 static int config_backend
= CONFIG_BACKEND_FILE
;
102 /* some helpful bits */
103 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
104 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
106 #define USERSHARE_VALID 1
107 #define USERSHARE_PENDING_DELETE 2
109 static bool defaults_saved
= false;
111 #define LOADPARM_EXTRA_GLOBALS \
112 struct parmlist_entry *param_opt; \
115 int iminreceivefile; \
116 char *szPrintcapname; \
118 int iPreferredMaster; \
119 char *szLdapMachineSuffix; \
120 char *szLdapUserSuffix; \
121 char *szLdapIdmapSuffix; \
122 char *szLdapGroupSuffix; \
125 char *szSocketAddress; \
126 char *szUsershareTemplateShare; \
129 int winbindMaxDomainConnections; \
130 int ismb2_max_credits; \
132 char *tls_certfile; \
136 char *panic_action; \
137 int bPreferredMaster;
139 #include "param/param_global.h"
141 static struct loadparm_global Globals
;
143 /* This is a default service used to prime a services structure */
144 static struct loadparm_service sDefault
=
149 .usershare_last_mod
= {0, 0},
153 .szInvalidUsers
= NULL
,
154 .szValidUsers
= NULL
,
155 .szAdminUsers
= NULL
,
160 .szRootPreExec
= NULL
,
161 .szRootPostExec
= NULL
,
162 .szCupsOptions
= NULL
,
163 .szPrintcommand
= NULL
,
164 .szLpqcommand
= NULL
,
165 .szLprmcommand
= NULL
,
166 .szLppausecommand
= NULL
,
167 .szLpresumecommand
= NULL
,
168 .szQueuepausecommand
= NULL
,
169 .szQueueresumecommand
= NULL
,
170 .szPrintername
= NULL
,
171 .szPrintjobUsername
= NULL
,
172 .szDontdescend
= NULL
,
173 .szHostsallow
= NULL
,
175 .szMagicScript
= NULL
,
176 .szMagicOutput
= NULL
,
179 .szVetoOplockFiles
= NULL
,
187 .szVfsObjects
= NULL
,
188 .szMSDfsProxy
= NULL
,
189 .szAioWriteBehind
= NULL
,
192 .iMaxPrintJobs
= 1000,
193 .iMaxReportedPrintJobs
= 0,
194 .iWriteCacheSize
= 0,
195 .iCreate_mask
= 0744,
196 .iCreate_force_mode
= 0,
197 .iSecurity_mask
= 0777,
198 .iSecurity_force_mode
= 0,
200 .iDir_force_mode
= 0,
201 .iDir_Security_mask
= 0777,
202 .iDir_Security_force_mode
= 0,
203 .iMaxConnections
= 0,
204 .iDefaultCase
= CASE_LOWER
,
205 .iPrinting
= DEFAULT_PRINTING
,
206 .iOplockContentionLimit
= 2,
209 .iDfreeCacheTime
= 0,
210 .bPreexecClose
= false,
211 .bRootpreexecClose
= false,
212 .iCaseSensitive
= Auto
,
213 .bCasePreserve
= true,
214 .bShortCasePreserve
= true,
215 .bHideDotFiles
= true,
216 .bHideSpecialFiles
= false,
217 .bHideUnReadable
= false,
218 .bHideUnWriteableFiles
= false,
220 .bAccessBasedShareEnum
= false,
224 .bGuest_only
= false,
225 .bAdministrative_share
= false,
228 .bPrintNotifyBackchannel
= true,
229 .bMap_system
= false,
230 .bMap_hidden
= false,
231 .bMap_archive
= true,
232 .bStoreDosAttributes
= false,
233 .bDmapiSupport
= false,
235 .iStrictLocking
= Auto
,
236 .bPosixLocking
= true,
239 .bKernelOplocks
= false,
240 .bLevel2OpLocks
= true,
242 .bMangledNames
= true,
245 .bSyncAlways
= false,
246 .bStrictAllocate
= false,
247 .bStrictSync
= false,
250 .bDeleteReadonly
= false,
251 .bFakeOplocks
= false,
252 .bDeleteVetoFiles
= false,
253 .bDosFilemode
= false,
254 .bDosFiletimes
= true,
255 .bDosFiletimeResolution
= false,
256 .bFakeDirCreateTimes
= false,
257 .bBlockingLocks
= true,
258 .bInheritPerms
= false,
259 .bInheritACLS
= false,
260 .bInheritOwner
= false,
262 .bUseClientDriver
= false,
263 .bDefaultDevmode
= true,
264 .bForcePrintername
= false,
265 .bNTAclSupport
= true,
266 .bForceUnknownAclUser
= false,
267 .bUseSendfile
= false,
268 .bProfileAcls
= false,
269 .bMap_acl_inherit
= false,
272 .bAclCheckPermissions
= true,
273 .bAclMapFullControl
= true,
274 .bAclGroupControl
= false,
275 .bChangeNotify
= true,
276 .bKernelChangeNotify
= true,
277 .iallocation_roundup_size
= SMB_ROUNDUP_ALLOCATION_SIZE
,
280 .iMap_readonly
= MAP_READONLY_YES
,
281 #ifdef BROKEN_DIRECTORY_HANDLING
282 .iDirectoryNameCacheSize
= 0,
284 .iDirectoryNameCacheSize
= 100,
286 .ismb_encrypt
= Auto
,
291 /* local variables */
292 static struct loadparm_service
**ServicePtrs
= NULL
;
293 static int iNumServices
= 0;
294 static int iServiceIndex
= 0;
295 static struct db_context
*ServiceHash
;
296 static int *invalid_services
= NULL
;
297 static int num_invalid_services
= 0;
298 static bool bInGlobalSection
= true;
299 static bool bGlobalOnly
= false;
301 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
303 /* prototypes for the special type handlers */
304 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
305 static bool handle_copy(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
306 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
307 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
308 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
309 static bool handle_debug_list(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
310 static bool handle_realm(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
311 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
312 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
313 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
314 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
315 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
317 /* these are parameter handlers which are not needed in the
321 #define handle_logfile NULL
323 static void set_allowed_client_auth(void);
325 static void add_to_file_list(const char *fname
, const char *subfname
);
326 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
);
327 static void free_param_opts(struct parmlist_entry
**popts
);
329 #include "lib/param/param_table.c"
331 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
333 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
334 * screen in SWAT. This is used to exclude parameters as well as to squash all
335 * parameters that have been duplicated by pseudonyms.
337 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
338 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
339 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
342 * NOTE2: Handling of duplicated (synonym) parameters:
343 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
344 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
345 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
346 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
349 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
350 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
353 static struct parm_struct parm_table
[] = {
354 {N_("Base Options"), P_SEP
, P_SEPARATOR
},
357 .label
= "dos charset",
360 .offset
= GLOBAL_VAR(dos_charset
),
361 .special
= handle_dos_charset
,
363 .flags
= FLAG_ADVANCED
366 .label
= "unix charset",
369 .offset
= GLOBAL_VAR(unix_charset
),
370 .special
= handle_charset
,
372 .flags
= FLAG_ADVANCED
378 .offset
= LOCAL_VAR(comment
),
381 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
387 .offset
= LOCAL_VAR(szPath
),
390 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
393 .label
= "directory",
396 .offset
= LOCAL_VAR(szPath
),
402 .label
= "workgroup",
405 .offset
= GLOBAL_VAR(szWorkgroup
),
408 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
414 .offset
= GLOBAL_VAR(szRealm
),
415 .special
= handle_realm
,
417 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
420 .label
= "netbios name",
423 .offset
= GLOBAL_VAR(szNetbiosName
),
426 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
429 .label
= "netbios aliases",
432 .offset
= GLOBAL_VAR(szNetbiosAliases
),
433 .special
= handle_netbios_aliases
,
435 .flags
= FLAG_ADVANCED
,
438 .label
= "netbios scope",
441 .offset
= GLOBAL_VAR(szNetbiosScope
),
444 .flags
= FLAG_ADVANCED
,
447 .label
= "server string",
450 .offset
= GLOBAL_VAR(szServerString
),
453 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
456 .label
= "interfaces",
459 .offset
= GLOBAL_VAR(szInterfaces
),
462 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
465 .label
= "bind interfaces only",
468 .offset
= GLOBAL_VAR(bBindInterfacesOnly
),
471 .flags
= FLAG_ADVANCED
| FLAG_WIZARD
,
474 .label
= "config backend",
477 .offset
= GLOBAL_VAR(ConfigBackend
),
479 .enum_list
= enum_config_backend
,
480 .flags
= FLAG_HIDE
|FLAG_ADVANCED
|FLAG_META
,
483 .label
= "server role",
486 .offset
= GLOBAL_VAR(server_role
),
488 .enum_list
= enum_server_role
,
489 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
492 {N_("Security Options"), P_SEP
, P_SEPARATOR
},
498 .offset
= GLOBAL_VAR(security
),
500 .enum_list
= enum_security
,
501 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
504 .label
= "auth methods",
507 .offset
= GLOBAL_VAR(AuthMethods
),
510 .flags
= FLAG_ADVANCED
,
513 .label
= "encrypt passwords",
516 .offset
= GLOBAL_VAR(bEncryptPasswords
),
519 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
522 .label
= "client schannel",
525 .offset
= GLOBAL_VAR(clientSchannel
),
527 .enum_list
= enum_bool_auto
,
528 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
531 .label
= "server schannel",
534 .offset
= GLOBAL_VAR(serverSchannel
),
536 .enum_list
= enum_bool_auto
,
537 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
540 .label
= "allow trusted domains",
543 .offset
= GLOBAL_VAR(bAllowTrustedDomains
),
546 .flags
= FLAG_ADVANCED
,
549 .label
= "map to guest",
552 .offset
= GLOBAL_VAR(map_to_guest
),
554 .enum_list
= enum_map_to_guest
,
555 .flags
= FLAG_ADVANCED
,
558 .label
= "null passwords",
561 .offset
= GLOBAL_VAR(bNullPasswords
),
564 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
567 .label
= "obey pam restrictions",
570 .offset
= GLOBAL_VAR(bObeyPamRestrictions
),
573 .flags
= FLAG_ADVANCED
,
576 .label
= "password server",
579 .offset
= GLOBAL_VAR(szPasswordServer
),
582 .flags
= FLAG_ADVANCED
| FLAG_WIZARD
,
585 .label
= "smb passwd file",
588 .offset
= GLOBAL_VAR(szSMBPasswdFile
),
591 .flags
= FLAG_ADVANCED
,
594 .label
= "private dir",
597 .offset
= GLOBAL_VAR(szPrivateDir
),
600 .flags
= FLAG_ADVANCED
,
603 .label
= "private directory",
606 .offset
= GLOBAL_VAR(szPrivateDir
),
612 .label
= "passdb backend",
615 .offset
= GLOBAL_VAR(passdb_backend
),
618 .flags
= FLAG_ADVANCED
| FLAG_WIZARD
,
621 .label
= "algorithmic rid base",
624 .offset
= GLOBAL_VAR(AlgorithmicRidBase
),
627 .flags
= FLAG_ADVANCED
,
630 .label
= "root directory",
633 .offset
= GLOBAL_VAR(szRootdir
),
636 .flags
= FLAG_ADVANCED
,
642 .offset
= GLOBAL_VAR(szRootdir
),
651 .offset
= GLOBAL_VAR(szRootdir
),
657 .label
= "guest account",
660 .offset
= GLOBAL_VAR(szGuestaccount
),
663 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
666 .label
= "enable privileges",
669 .offset
= GLOBAL_VAR(bEnablePrivileges
),
672 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
676 .label
= "pam password change",
679 .offset
= GLOBAL_VAR(bPamPasswordChange
),
682 .flags
= FLAG_ADVANCED
,
685 .label
= "passwd program",
688 .offset
= GLOBAL_VAR(szPasswdProgram
),
691 .flags
= FLAG_ADVANCED
,
694 .label
= "passwd chat",
697 .offset
= GLOBAL_VAR(szPasswdChat
),
700 .flags
= FLAG_ADVANCED
,
703 .label
= "passwd chat debug",
706 .offset
= GLOBAL_VAR(bPasswdChatDebug
),
709 .flags
= FLAG_ADVANCED
,
712 .label
= "passwd chat timeout",
715 .offset
= GLOBAL_VAR(iPasswdChatTimeout
),
718 .flags
= FLAG_ADVANCED
,
721 .label
= "check password script",
724 .offset
= GLOBAL_VAR(szCheckPasswordScript
),
727 .flags
= FLAG_ADVANCED
,
730 .label
= "username map",
733 .offset
= GLOBAL_VAR(szUsernameMap
),
736 .flags
= FLAG_ADVANCED
,
739 .label
= "password level",
742 .offset
= GLOBAL_VAR(pwordlevel
),
745 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
748 .label
= "username level",
751 .offset
= GLOBAL_VAR(unamelevel
),
754 .flags
= FLAG_ADVANCED
,
757 .label
= "unix password sync",
760 .offset
= GLOBAL_VAR(bUnixPasswdSync
),
763 .flags
= FLAG_ADVANCED
,
766 .label
= "restrict anonymous",
769 .offset
= GLOBAL_VAR(restrict_anonymous
),
772 .flags
= FLAG_ADVANCED
,
775 .label
= "lanman auth",
778 .offset
= GLOBAL_VAR(bLanmanAuth
),
781 .flags
= FLAG_ADVANCED
,
784 .label
= "ntlm auth",
787 .offset
= GLOBAL_VAR(bNTLMAuth
),
790 .flags
= FLAG_ADVANCED
,
793 .label
= "client NTLMv2 auth",
796 .offset
= GLOBAL_VAR(bClientNTLMv2Auth
),
799 .flags
= FLAG_ADVANCED
,
802 .label
= "client lanman auth",
805 .offset
= GLOBAL_VAR(bClientLanManAuth
),
808 .flags
= FLAG_ADVANCED
,
811 .label
= "client plaintext auth",
814 .offset
= GLOBAL_VAR(bClientPlaintextAuth
),
817 .flags
= FLAG_ADVANCED
,
820 .label
= "client use spnego principal",
823 .offset
= GLOBAL_VAR(client_use_spnego_principal
),
826 .flags
= FLAG_ADVANCED
,
832 .offset
= LOCAL_VAR(szUsername
),
835 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
| FLAG_DEPRECATED
,
841 .offset
= LOCAL_VAR(szUsername
),
850 .offset
= LOCAL_VAR(szUsername
),
856 .label
= "invalid users",
859 .offset
= LOCAL_VAR(szInvalidUsers
),
862 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
865 .label
= "valid users",
868 .offset
= LOCAL_VAR(szValidUsers
),
871 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
874 .label
= "admin users",
877 .offset
= LOCAL_VAR(szAdminUsers
),
880 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
883 .label
= "read list",
886 .offset
= LOCAL_VAR(readlist
),
889 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
892 .label
= "write list",
895 .offset
= LOCAL_VAR(writelist
),
898 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
901 .label
= "force user",
904 .offset
= LOCAL_VAR(force_user
),
907 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
910 .label
= "force group",
913 .offset
= LOCAL_VAR(force_group
),
916 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
922 .offset
= LOCAL_VAR(force_group
),
925 .flags
= FLAG_ADVANCED
,
928 .label
= "read only",
931 .offset
= LOCAL_VAR(bRead_only
),
934 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
,
940 .offset
= LOCAL_VAR(bRead_only
),
946 .label
= "writeable",
949 .offset
= LOCAL_VAR(bRead_only
),
958 .offset
= LOCAL_VAR(bRead_only
),
964 .label
= "acl check permissions",
967 .offset
= LOCAL_VAR(bAclCheckPermissions
),
970 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
| FLAG_DEPRECATED
,
973 .label
= "acl group control",
976 .offset
= LOCAL_VAR(bAclGroupControl
),
979 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
982 .label
= "acl map full control",
985 .offset
= LOCAL_VAR(bAclMapFullControl
),
988 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
991 .label
= "create mask",
994 .offset
= LOCAL_VAR(iCreate_mask
),
997 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1000 .label
= "create mode",
1003 .offset
= LOCAL_VAR(iCreate_mask
),
1009 .label
= "force create mode",
1012 .offset
= LOCAL_VAR(iCreate_force_mode
),
1015 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1018 .label
= "security mask",
1021 .offset
= LOCAL_VAR(iSecurity_mask
),
1024 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1027 .label
= "force security mode",
1030 .offset
= LOCAL_VAR(iSecurity_force_mode
),
1033 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1036 .label
= "directory mask",
1039 .offset
= LOCAL_VAR(iDir_mask
),
1042 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1045 .label
= "directory mode",
1048 .offset
= LOCAL_VAR(iDir_mask
),
1051 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
1054 .label
= "force directory mode",
1057 .offset
= LOCAL_VAR(iDir_force_mode
),
1060 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1063 .label
= "directory security mask",
1066 .offset
= LOCAL_VAR(iDir_Security_mask
),
1069 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1072 .label
= "force directory security mode",
1075 .offset
= LOCAL_VAR(iDir_Security_force_mode
),
1078 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1081 .label
= "force unknown acl user",
1084 .offset
= LOCAL_VAR(bForceUnknownAclUser
),
1087 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1090 .label
= "inherit permissions",
1093 .offset
= LOCAL_VAR(bInheritPerms
),
1096 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1099 .label
= "inherit acls",
1102 .offset
= LOCAL_VAR(bInheritACLS
),
1105 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1108 .label
= "inherit owner",
1111 .offset
= LOCAL_VAR(bInheritOwner
),
1114 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1117 .label
= "guest only",
1120 .offset
= LOCAL_VAR(bGuest_only
),
1123 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1126 .label
= "only guest",
1129 .offset
= LOCAL_VAR(bGuest_only
),
1135 .label
= "administrative share",
1138 .offset
= LOCAL_VAR(bAdministrative_share
),
1141 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
1145 .label
= "guest ok",
1148 .offset
= LOCAL_VAR(bGuest_ok
),
1151 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
1157 .offset
= LOCAL_VAR(bGuest_ok
),
1163 .label
= "only user",
1166 .offset
= LOCAL_VAR(bOnlyUser
),
1169 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_DEPRECATED
,
1172 .label
= "hosts allow",
1175 .offset
= LOCAL_VAR(szHostsallow
),
1178 .flags
= FLAG_GLOBAL
| FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
1181 .label
= "allow hosts",
1184 .offset
= LOCAL_VAR(szHostsallow
),
1190 .label
= "hosts deny",
1193 .offset
= LOCAL_VAR(szHostsdeny
),
1196 .flags
= FLAG_GLOBAL
| FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
1199 .label
= "deny hosts",
1202 .offset
= LOCAL_VAR(szHostsdeny
),
1208 .label
= "preload modules",
1210 .p_class
= P_GLOBAL
,
1211 .offset
= GLOBAL_VAR(szPreloadModules
),
1214 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
1217 .label
= "dedicated keytab file",
1219 .p_class
= P_GLOBAL
,
1220 .offset
= GLOBAL_VAR(szDedicatedKeytabFile
),
1223 .flags
= FLAG_ADVANCED
,
1226 .label
= "kerberos method",
1228 .p_class
= P_GLOBAL
,
1229 .offset
= GLOBAL_VAR(iKerberosMethod
),
1231 .enum_list
= enum_kerberos_method
,
1232 .flags
= FLAG_ADVANCED
,
1235 .label
= "map untrusted to domain",
1237 .p_class
= P_GLOBAL
,
1238 .offset
= GLOBAL_VAR(bMapUntrustedToDomain
),
1241 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
1245 {N_("Logging Options"), P_SEP
, P_SEPARATOR
},
1248 .label
= "log level",
1250 .p_class
= P_GLOBAL
,
1251 .offset
= GLOBAL_VAR(loglevel
),
1252 .special
= handle_debug_list
,
1254 .flags
= FLAG_ADVANCED
,
1257 .label
= "debuglevel",
1259 .p_class
= P_GLOBAL
,
1260 .offset
= GLOBAL_VAR(loglevel
),
1261 .special
= handle_debug_list
,
1268 .p_class
= P_GLOBAL
,
1269 .offset
= GLOBAL_VAR(syslog
),
1272 .flags
= FLAG_ADVANCED
,
1275 .label
= "syslog only",
1277 .p_class
= P_GLOBAL
,
1278 .offset
= GLOBAL_VAR(bSyslogOnly
),
1281 .flags
= FLAG_ADVANCED
,
1284 .label
= "log file",
1286 .p_class
= P_GLOBAL
,
1287 .offset
= GLOBAL_VAR(logfile
),
1288 .special
= handle_logfile
,
1290 .flags
= FLAG_ADVANCED
,
1293 .label
= "max log size",
1295 .p_class
= P_GLOBAL
,
1296 .offset
= GLOBAL_VAR(max_log_size
),
1299 .flags
= FLAG_ADVANCED
,
1302 .label
= "debug timestamp",
1304 .p_class
= P_GLOBAL
,
1305 .offset
= GLOBAL_VAR(bTimestampLogs
),
1308 .flags
= FLAG_ADVANCED
,
1311 .label
= "timestamp logs",
1313 .p_class
= P_GLOBAL
,
1314 .offset
= GLOBAL_VAR(bTimestampLogs
),
1317 .flags
= FLAG_ADVANCED
,
1320 .label
= "debug prefix timestamp",
1322 .p_class
= P_GLOBAL
,
1323 .offset
= GLOBAL_VAR(bDebugPrefixTimestamp
),
1326 .flags
= FLAG_ADVANCED
,
1329 .label
= "debug hires timestamp",
1331 .p_class
= P_GLOBAL
,
1332 .offset
= GLOBAL_VAR(bDebugHiresTimestamp
),
1335 .flags
= FLAG_ADVANCED
,
1338 .label
= "debug pid",
1340 .p_class
= P_GLOBAL
,
1341 .offset
= GLOBAL_VAR(bDebugPid
),
1344 .flags
= FLAG_ADVANCED
,
1347 .label
= "debug uid",
1349 .p_class
= P_GLOBAL
,
1350 .offset
= GLOBAL_VAR(bDebugUid
),
1353 .flags
= FLAG_ADVANCED
,
1356 .label
= "debug class",
1358 .p_class
= P_GLOBAL
,
1359 .offset
= GLOBAL_VAR(bDebugClass
),
1362 .flags
= FLAG_ADVANCED
,
1365 .label
= "enable core files",
1367 .p_class
= P_GLOBAL
,
1368 .offset
= GLOBAL_VAR(bEnableCoreFiles
),
1371 .flags
= FLAG_ADVANCED
,
1374 {N_("Protocol Options"), P_SEP
, P_SEPARATOR
},
1377 .label
= "allocation roundup size",
1380 .offset
= LOCAL_VAR(iallocation_roundup_size
),
1383 .flags
= FLAG_ADVANCED
,
1386 .label
= "aio read size",
1389 .offset
= LOCAL_VAR(iAioReadSize
),
1392 .flags
= FLAG_ADVANCED
,
1395 .label
= "aio write size",
1398 .offset
= LOCAL_VAR(iAioWriteSize
),
1401 .flags
= FLAG_ADVANCED
,
1404 .label
= "aio write behind",
1407 .offset
= LOCAL_VAR(szAioWriteBehind
),
1410 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1413 .label
= "smb ports",
1415 .p_class
= P_GLOBAL
,
1416 .offset
= GLOBAL_VAR(smb_ports
),
1419 .flags
= FLAG_ADVANCED
,
1422 .label
= "large readwrite",
1424 .p_class
= P_GLOBAL
,
1425 .offset
= GLOBAL_VAR(bLargeReadwrite
),
1428 .flags
= FLAG_ADVANCED
,
1431 .label
= "server max protocol",
1433 .p_class
= P_GLOBAL
,
1434 .offset
= GLOBAL_VAR(srv_maxprotocol
),
1436 .enum_list
= enum_protocol
,
1437 .flags
= FLAG_ADVANCED
,
1440 .label
= "max protocol",
1442 .p_class
= P_GLOBAL
,
1443 .offset
= GLOBAL_VAR(srv_maxprotocol
),
1445 .enum_list
= enum_protocol
,
1446 .flags
= FLAG_ADVANCED
,
1449 .label
= "protocol",
1451 .p_class
= P_GLOBAL
,
1452 .offset
= GLOBAL_VAR(srv_maxprotocol
),
1454 .enum_list
= enum_protocol
,
1455 .flags
= FLAG_ADVANCED
,
1458 .label
= "server min protocol",
1460 .p_class
= P_GLOBAL
,
1461 .offset
= GLOBAL_VAR(srv_minprotocol
),
1463 .enum_list
= enum_protocol
,
1464 .flags
= FLAG_ADVANCED
,
1467 .label
= "min protocol",
1469 .p_class
= P_GLOBAL
,
1470 .offset
= GLOBAL_VAR(srv_minprotocol
),
1472 .enum_list
= enum_protocol
,
1473 .flags
= FLAG_ADVANCED
,
1476 .label
= "client max protocol",
1478 .p_class
= P_GLOBAL
,
1479 .offset
= GLOBAL_VAR(cli_maxprotocol
),
1481 .enum_list
= enum_protocol
,
1482 .flags
= FLAG_ADVANCED
,
1485 .label
= "client min protocol",
1487 .p_class
= P_GLOBAL
,
1488 .offset
= GLOBAL_VAR(cli_minprotocol
),
1490 .enum_list
= enum_protocol
,
1491 .flags
= FLAG_ADVANCED
,
1496 .p_class
= P_GLOBAL
,
1497 .offset
= GLOBAL_VAR(bUnicode
),
1502 .label
= "min receivefile size",
1504 .p_class
= P_GLOBAL
,
1505 .offset
= GLOBAL_VAR(iminreceivefile
),
1508 .flags
= FLAG_ADVANCED
,
1511 .label
= "read raw",
1513 .p_class
= P_GLOBAL
,
1514 .offset
= GLOBAL_VAR(bReadRaw
),
1517 .flags
= FLAG_ADVANCED
,
1520 .label
= "write raw",
1522 .p_class
= P_GLOBAL
,
1523 .offset
= GLOBAL_VAR(bWriteRaw
),
1526 .flags
= FLAG_ADVANCED
,
1529 .label
= "disable netbios",
1531 .p_class
= P_GLOBAL
,
1532 .offset
= GLOBAL_VAR(bDisableNetbios
),
1535 .flags
= FLAG_ADVANCED
,
1538 .label
= "reset on zero vc",
1540 .p_class
= P_GLOBAL
,
1541 .offset
= GLOBAL_VAR(bResetOnZeroVC
),
1544 .flags
= FLAG_ADVANCED
,
1547 .label
= "log writeable files on exit",
1549 .p_class
= P_GLOBAL
,
1550 .offset
= GLOBAL_VAR(bLogWriteableFilesOnExit
),
1553 .flags
= FLAG_ADVANCED
,
1556 .label
= "acl compatibility",
1558 .p_class
= P_GLOBAL
,
1559 .offset
= GLOBAL_VAR(iAclCompat
),
1561 .enum_list
= enum_acl_compat_vals
,
1562 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1565 .label
= "defer sharing violations",
1567 .p_class
= P_GLOBAL
,
1568 .offset
= GLOBAL_VAR(bDeferSharingViolations
),
1571 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
1574 .label
= "ea support",
1577 .offset
= LOCAL_VAR(bEASupport
),
1580 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1583 .label
= "nt acl support",
1586 .offset
= LOCAL_VAR(bNTAclSupport
),
1589 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1592 .label
= "nt pipe support",
1594 .p_class
= P_GLOBAL
,
1595 .offset
= GLOBAL_VAR(bNTPipeSupport
),
1598 .flags
= FLAG_ADVANCED
,
1601 .label
= "nt status support",
1603 .p_class
= P_GLOBAL
,
1604 .offset
= GLOBAL_VAR(bNTStatusSupport
),
1607 .flags
= FLAG_ADVANCED
,
1610 .label
= "profile acls",
1613 .offset
= LOCAL_VAR(bProfileAcls
),
1616 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1619 .label
= "map acl inherit",
1622 .offset
= LOCAL_VAR(bMap_acl_inherit
),
1625 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1628 .label
= "afs share",
1631 .offset
= LOCAL_VAR(bAfs_Share
),
1634 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1639 .p_class
= P_GLOBAL
,
1640 .offset
= GLOBAL_VAR(max_mux
),
1643 .flags
= FLAG_ADVANCED
,
1646 .label
= "max xmit",
1648 .p_class
= P_GLOBAL
,
1649 .offset
= GLOBAL_VAR(max_xmit
),
1652 .flags
= FLAG_ADVANCED
,
1655 .label
= "name resolve order",
1657 .p_class
= P_GLOBAL
,
1658 .offset
= GLOBAL_VAR(szNameResolveOrder
),
1661 .flags
= FLAG_ADVANCED
| FLAG_WIZARD
,
1666 .p_class
= P_GLOBAL
,
1667 .offset
= GLOBAL_VAR(max_ttl
),
1670 .flags
= FLAG_ADVANCED
,
1673 .label
= "max wins ttl",
1675 .p_class
= P_GLOBAL
,
1676 .offset
= GLOBAL_VAR(max_wins_ttl
),
1679 .flags
= FLAG_ADVANCED
,
1682 .label
= "min wins ttl",
1684 .p_class
= P_GLOBAL
,
1685 .offset
= GLOBAL_VAR(min_wins_ttl
),
1688 .flags
= FLAG_ADVANCED
,
1691 .label
= "time server",
1693 .p_class
= P_GLOBAL
,
1694 .offset
= GLOBAL_VAR(bTimeServer
),
1697 .flags
= FLAG_ADVANCED
,
1700 .label
= "unix extensions",
1702 .p_class
= P_GLOBAL
,
1703 .offset
= GLOBAL_VAR(bUnixExtensions
),
1706 .flags
= FLAG_ADVANCED
,
1709 .label
= "use spnego",
1711 .p_class
= P_GLOBAL
,
1712 .offset
= GLOBAL_VAR(bUseSpnego
),
1715 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
1718 .label
= "client signing",
1720 .p_class
= P_GLOBAL
,
1721 .offset
= GLOBAL_VAR(client_signing
),
1723 .enum_list
= enum_smb_signing_vals
,
1724 .flags
= FLAG_ADVANCED
,
1727 .label
= "server signing",
1729 .p_class
= P_GLOBAL
,
1730 .offset
= GLOBAL_VAR(server_signing
),
1732 .enum_list
= enum_smb_signing_vals
,
1733 .flags
= FLAG_ADVANCED
,
1736 .label
= "smb encrypt",
1739 .offset
= LOCAL_VAR(ismb_encrypt
),
1741 .enum_list
= enum_smb_signing_vals
,
1742 .flags
= FLAG_ADVANCED
,
1745 .label
= "client use spnego",
1747 .p_class
= P_GLOBAL
,
1748 .offset
= GLOBAL_VAR(bClientUseSpnego
),
1751 .flags
= FLAG_ADVANCED
,
1754 .label
= "client ldap sasl wrapping",
1756 .p_class
= P_GLOBAL
,
1757 .offset
= GLOBAL_VAR(client_ldap_sasl_wrapping
),
1759 .enum_list
= enum_ldap_sasl_wrapping
,
1760 .flags
= FLAG_ADVANCED
,
1763 .label
= "enable asu support",
1765 .p_class
= P_GLOBAL
,
1766 .offset
= GLOBAL_VAR(bASUSupport
),
1769 .flags
= FLAG_ADVANCED
,
1772 .label
= "svcctl list",
1774 .p_class
= P_GLOBAL
,
1775 .offset
= GLOBAL_VAR(szServicesList
),
1778 .flags
= FLAG_ADVANCED
,
1781 .label
= "cldap port",
1783 .p_class
= P_GLOBAL
,
1784 .offset
= GLOBAL_VAR(cldap_port
),
1789 .label
= "dgram port",
1791 .p_class
= P_GLOBAL
,
1792 .offset
= GLOBAL_VAR(dgram_port
),
1797 .label
= "nbt port",
1799 .p_class
= P_GLOBAL
,
1800 .offset
= GLOBAL_VAR(nbt_port
),
1805 .label
= "krb5 port",
1807 .p_class
= P_GLOBAL
,
1808 .offset
= GLOBAL_VAR(krb5_port
),
1813 .label
= "kpasswd port",
1815 .p_class
= P_GLOBAL
,
1816 .offset
= GLOBAL_VAR(kpasswd_port
),
1821 .label
= "web port",
1823 .p_class
= P_GLOBAL
,
1824 .offset
= GLOBAL_VAR(web_port
),
1829 .label
= "rpc big endian",
1831 .p_class
= P_GLOBAL
,
1832 .offset
= GLOBAL_VAR(bRpcBigEndian
),
1837 {N_("Tuning Options"), P_SEP
, P_SEPARATOR
},
1840 .label
= "block size",
1843 .offset
= LOCAL_VAR(iBlock_size
),
1846 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1849 .label
= "deadtime",
1851 .p_class
= P_GLOBAL
,
1852 .offset
= GLOBAL_VAR(deadtime
),
1855 .flags
= FLAG_ADVANCED
,
1858 .label
= "getwd cache",
1860 .p_class
= P_GLOBAL
,
1861 .offset
= GLOBAL_VAR(getwd_cache
),
1864 .flags
= FLAG_ADVANCED
,
1867 .label
= "keepalive",
1869 .p_class
= P_GLOBAL
,
1870 .offset
= GLOBAL_VAR(iKeepalive
),
1873 .flags
= FLAG_ADVANCED
,
1876 .label
= "change notify",
1879 .offset
= LOCAL_VAR(bChangeNotify
),
1882 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1885 .label
= "directory name cache size",
1888 .offset
= LOCAL_VAR(iDirectoryNameCacheSize
),
1891 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1894 .label
= "kernel change notify",
1897 .offset
= LOCAL_VAR(bKernelChangeNotify
),
1900 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1903 .label
= "lpq cache time",
1905 .p_class
= P_GLOBAL
,
1906 .offset
= GLOBAL_VAR(lpqcachetime
),
1909 .flags
= FLAG_ADVANCED
,
1912 .label
= "max smbd processes",
1914 .p_class
= P_GLOBAL
,
1915 .offset
= GLOBAL_VAR(iMaxSmbdProcesses
),
1918 .flags
= FLAG_ADVANCED
,
1921 .label
= "max connections",
1924 .offset
= LOCAL_VAR(iMaxConnections
),
1927 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1930 .label
= "paranoid server security",
1932 .p_class
= P_GLOBAL
,
1933 .offset
= GLOBAL_VAR(paranoid_server_security
),
1936 .flags
= FLAG_ADVANCED
,
1939 .label
= "max disk size",
1941 .p_class
= P_GLOBAL
,
1942 .offset
= GLOBAL_VAR(maxdisksize
),
1945 .flags
= FLAG_ADVANCED
,
1948 .label
= "max open files",
1950 .p_class
= P_GLOBAL
,
1951 .offset
= GLOBAL_VAR(max_open_files
),
1954 .flags
= FLAG_ADVANCED
,
1957 .label
= "min print space",
1960 .offset
= LOCAL_VAR(iMinPrintSpace
),
1963 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
1966 .label
= "socket options",
1968 .p_class
= P_GLOBAL
,
1969 .offset
= GLOBAL_VAR(socket_options
),
1972 .flags
= FLAG_ADVANCED
,
1975 .label
= "strict allocate",
1978 .offset
= LOCAL_VAR(bStrictAllocate
),
1981 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1984 .label
= "strict sync",
1987 .offset
= LOCAL_VAR(bStrictSync
),
1990 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1993 .label
= "sync always",
1996 .offset
= LOCAL_VAR(bSyncAlways
),
1999 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2002 .label
= "use mmap",
2004 .p_class
= P_GLOBAL
,
2005 .offset
= GLOBAL_VAR(bUseMmap
),
2008 .flags
= FLAG_ADVANCED
,
2011 .label
= "use sendfile",
2014 .offset
= LOCAL_VAR(bUseSendfile
),
2017 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2020 .label
= "hostname lookups",
2022 .p_class
= P_GLOBAL
,
2023 .offset
= GLOBAL_VAR(bHostnameLookups
),
2026 .flags
= FLAG_ADVANCED
,
2029 .label
= "write cache size",
2032 .offset
= LOCAL_VAR(iWriteCacheSize
),
2035 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2038 .label
= "name cache timeout",
2040 .p_class
= P_GLOBAL
,
2041 .offset
= GLOBAL_VAR(name_cache_timeout
),
2044 .flags
= FLAG_ADVANCED
,
2047 .label
= "ctdbd socket",
2049 .p_class
= P_GLOBAL
,
2050 .offset
= GLOBAL_VAR(ctdbdSocket
),
2053 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
2056 .label
= "cluster addresses",
2058 .p_class
= P_GLOBAL
,
2059 .offset
= GLOBAL_VAR(szClusterAddresses
),
2062 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
2065 .label
= "clustering",
2067 .p_class
= P_GLOBAL
,
2068 .offset
= GLOBAL_VAR(clustering
),
2071 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
2074 .label
= "ctdb timeout",
2076 .p_class
= P_GLOBAL
,
2077 .offset
= GLOBAL_VAR(ctdb_timeout
),
2080 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
2083 .label
= "ctdb locktime warn threshold",
2085 .p_class
= P_GLOBAL
,
2086 .offset
= GLOBAL_VAR(ctdb_locktime_warn_threshold
),
2089 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
2092 .label
= "smb2 max read",
2094 .p_class
= P_GLOBAL
,
2095 .offset
= GLOBAL_VAR(ismb2_max_read
),
2098 .flags
= FLAG_ADVANCED
,
2101 .label
= "smb2 max write",
2103 .p_class
= P_GLOBAL
,
2104 .offset
= GLOBAL_VAR(ismb2_max_write
),
2107 .flags
= FLAG_ADVANCED
,
2110 .label
= "smb2 max trans",
2112 .p_class
= P_GLOBAL
,
2113 .offset
= GLOBAL_VAR(ismb2_max_trans
),
2116 .flags
= FLAG_ADVANCED
,
2119 .label
= "smb2 max credits",
2121 .p_class
= P_GLOBAL
,
2122 .offset
= GLOBAL_VAR(ismb2_max_credits
),
2125 .flags
= FLAG_ADVANCED
,
2128 {N_("Printing Options"), P_SEP
, P_SEPARATOR
},
2131 .label
= "max reported print jobs",
2134 .offset
= LOCAL_VAR(iMaxReportedPrintJobs
),
2137 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2140 .label
= "max print jobs",
2143 .offset
= LOCAL_VAR(iMaxPrintJobs
),
2146 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2149 .label
= "load printers",
2151 .p_class
= P_GLOBAL
,
2152 .offset
= GLOBAL_VAR(bLoadPrinters
),
2155 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2158 .label
= "printcap cache time",
2160 .p_class
= P_GLOBAL
,
2161 .offset
= GLOBAL_VAR(PrintcapCacheTime
),
2164 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2167 .label
= "printcap name",
2169 .p_class
= P_GLOBAL
,
2170 .offset
= GLOBAL_VAR(szPrintcapname
),
2173 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2176 .label
= "printcap",
2178 .p_class
= P_GLOBAL
,
2179 .offset
= GLOBAL_VAR(szPrintcapname
),
2185 .label
= "printable",
2188 .offset
= LOCAL_VAR(bPrint_ok
),
2191 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2194 .label
= "print notify backchannel",
2197 .offset
= LOCAL_VAR(bPrintNotifyBackchannel
),
2200 .flags
= FLAG_ADVANCED
,
2203 .label
= "print ok",
2206 .offset
= LOCAL_VAR(bPrint_ok
),
2212 .label
= "printing",
2215 .offset
= LOCAL_VAR(iPrinting
),
2216 .special
= handle_printing
,
2217 .enum_list
= enum_printing
,
2218 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2221 .label
= "cups options",
2224 .offset
= LOCAL_VAR(szCupsOptions
),
2227 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2230 .label
= "cups server",
2232 .p_class
= P_GLOBAL
,
2233 .offset
= GLOBAL_VAR(szCupsServer
),
2236 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2239 .label
= "cups encrypt",
2241 .p_class
= P_GLOBAL
,
2242 .offset
= GLOBAL_VAR(CupsEncrypt
),
2244 .enum_list
= enum_bool_auto
,
2245 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2249 .label
= "cups connection timeout",
2251 .p_class
= P_GLOBAL
,
2252 .offset
= GLOBAL_VAR(cups_connection_timeout
),
2255 .flags
= FLAG_ADVANCED
,
2258 .label
= "iprint server",
2260 .p_class
= P_GLOBAL
,
2261 .offset
= GLOBAL_VAR(szIPrintServer
),
2264 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2267 .label
= "print command",
2270 .offset
= LOCAL_VAR(szPrintcommand
),
2273 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2276 .label
= "disable spoolss",
2278 .p_class
= P_GLOBAL
,
2279 .offset
= GLOBAL_VAR(bDisableSpoolss
),
2282 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2285 .label
= "enable spoolss",
2287 .p_class
= P_GLOBAL
,
2288 .offset
= GLOBAL_VAR(bDisableSpoolss
),
2294 .label
= "lpq command",
2297 .offset
= LOCAL_VAR(szLpqcommand
),
2300 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2303 .label
= "lprm command",
2306 .offset
= LOCAL_VAR(szLprmcommand
),
2309 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2312 .label
= "lppause command",
2315 .offset
= LOCAL_VAR(szLppausecommand
),
2318 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2321 .label
= "lpresume command",
2324 .offset
= LOCAL_VAR(szLpresumecommand
),
2327 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2330 .label
= "queuepause command",
2333 .offset
= LOCAL_VAR(szQueuepausecommand
),
2336 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2339 .label
= "queueresume command",
2342 .offset
= LOCAL_VAR(szQueueresumecommand
),
2345 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2348 .label
= "addport command",
2350 .p_class
= P_GLOBAL
,
2351 .offset
= GLOBAL_VAR(szAddPortCommand
),
2354 .flags
= FLAG_ADVANCED
,
2357 .label
= "enumports command",
2359 .p_class
= P_GLOBAL
,
2360 .offset
= GLOBAL_VAR(szEnumPortsCommand
),
2363 .flags
= FLAG_ADVANCED
,
2366 .label
= "addprinter command",
2368 .p_class
= P_GLOBAL
,
2369 .offset
= GLOBAL_VAR(szAddPrinterCommand
),
2372 .flags
= FLAG_ADVANCED
,
2375 .label
= "deleteprinter command",
2377 .p_class
= P_GLOBAL
,
2378 .offset
= GLOBAL_VAR(szDeletePrinterCommand
),
2381 .flags
= FLAG_ADVANCED
,
2384 .label
= "show add printer wizard",
2386 .p_class
= P_GLOBAL
,
2387 .offset
= GLOBAL_VAR(bMsAddPrinterWizard
),
2390 .flags
= FLAG_ADVANCED
,
2393 .label
= "os2 driver map",
2395 .p_class
= P_GLOBAL
,
2396 .offset
= GLOBAL_VAR(szOs2DriverMap
),
2399 .flags
= FLAG_ADVANCED
,
2403 .label
= "printer name",
2406 .offset
= LOCAL_VAR(szPrintername
),
2409 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2415 .offset
= LOCAL_VAR(szPrintername
),
2421 .label
= "use client driver",
2424 .offset
= LOCAL_VAR(bUseClientDriver
),
2427 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2430 .label
= "default devmode",
2433 .offset
= LOCAL_VAR(bDefaultDevmode
),
2436 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2439 .label
= "force printername",
2442 .offset
= LOCAL_VAR(bForcePrintername
),
2445 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2448 .label
= "printjob username",
2451 .offset
= LOCAL_VAR(szPrintjobUsername
),
2454 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2457 {N_("Filename Handling"), P_SEP
, P_SEPARATOR
},
2460 .label
= "mangling method",
2462 .p_class
= P_GLOBAL
,
2463 .offset
= GLOBAL_VAR(szManglingMethod
),
2466 .flags
= FLAG_ADVANCED
,
2469 .label
= "mangle prefix",
2471 .p_class
= P_GLOBAL
,
2472 .offset
= GLOBAL_VAR(mangle_prefix
),
2475 .flags
= FLAG_ADVANCED
,
2479 .label
= "default case",
2482 .offset
= LOCAL_VAR(iDefaultCase
),
2484 .enum_list
= enum_case
,
2485 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2488 .label
= "case sensitive",
2491 .offset
= LOCAL_VAR(iCaseSensitive
),
2493 .enum_list
= enum_bool_auto
,
2494 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2497 .label
= "casesignames",
2500 .offset
= LOCAL_VAR(iCaseSensitive
),
2502 .enum_list
= enum_bool_auto
,
2503 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
| FLAG_HIDE
,
2506 .label
= "preserve case",
2509 .offset
= LOCAL_VAR(bCasePreserve
),
2512 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2515 .label
= "short preserve case",
2518 .offset
= LOCAL_VAR(bShortCasePreserve
),
2521 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2524 .label
= "mangling char",
2527 .offset
= LOCAL_VAR(magic_char
),
2530 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2533 .label
= "hide dot files",
2536 .offset
= LOCAL_VAR(bHideDotFiles
),
2539 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2542 .label
= "hide special files",
2545 .offset
= LOCAL_VAR(bHideSpecialFiles
),
2548 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2551 .label
= "hide unreadable",
2554 .offset
= LOCAL_VAR(bHideUnReadable
),
2557 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2560 .label
= "hide unwriteable files",
2563 .offset
= LOCAL_VAR(bHideUnWriteableFiles
),
2566 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2569 .label
= "delete veto files",
2572 .offset
= LOCAL_VAR(bDeleteVetoFiles
),
2575 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2578 .label
= "veto files",
2581 .offset
= LOCAL_VAR(szVetoFiles
),
2584 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2587 .label
= "hide files",
2590 .offset
= LOCAL_VAR(szHideFiles
),
2593 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2596 .label
= "veto oplock files",
2599 .offset
= LOCAL_VAR(szVetoOplockFiles
),
2602 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2605 .label
= "map archive",
2608 .offset
= LOCAL_VAR(bMap_archive
),
2611 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2614 .label
= "map hidden",
2617 .offset
= LOCAL_VAR(bMap_hidden
),
2620 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2623 .label
= "map system",
2626 .offset
= LOCAL_VAR(bMap_system
),
2629 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2632 .label
= "map readonly",
2635 .offset
= LOCAL_VAR(iMap_readonly
),
2637 .enum_list
= enum_map_readonly
,
2638 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2641 .label
= "mangled names",
2644 .offset
= LOCAL_VAR(bMangledNames
),
2647 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2650 .label
= "max stat cache size",
2652 .p_class
= P_GLOBAL
,
2653 .offset
= GLOBAL_VAR(iMaxStatCacheSize
),
2656 .flags
= FLAG_ADVANCED
,
2659 .label
= "stat cache",
2661 .p_class
= P_GLOBAL
,
2662 .offset
= GLOBAL_VAR(bStatCache
),
2665 .flags
= FLAG_ADVANCED
,
2668 .label
= "store dos attributes",
2671 .offset
= LOCAL_VAR(bStoreDosAttributes
),
2674 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2677 .label
= "dmapi support",
2680 .offset
= LOCAL_VAR(bDmapiSupport
),
2683 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2687 {N_("Domain Options"), P_SEP
, P_SEPARATOR
},
2690 .label
= "machine password timeout",
2692 .p_class
= P_GLOBAL
,
2693 .offset
= GLOBAL_VAR(machine_password_timeout
),
2696 .flags
= FLAG_ADVANCED
| FLAG_WIZARD
,
2699 {N_("Logon Options"), P_SEP
, P_SEPARATOR
},
2702 .label
= "add user script",
2704 .p_class
= P_GLOBAL
,
2705 .offset
= GLOBAL_VAR(szAddUserScript
),
2708 .flags
= FLAG_ADVANCED
,
2711 .label
= "rename user script",
2713 .p_class
= P_GLOBAL
,
2714 .offset
= GLOBAL_VAR(szRenameUserScript
),
2717 .flags
= FLAG_ADVANCED
,
2720 .label
= "delete user script",
2722 .p_class
= P_GLOBAL
,
2723 .offset
= GLOBAL_VAR(szDelUserScript
),
2726 .flags
= FLAG_ADVANCED
,
2729 .label
= "add group script",
2731 .p_class
= P_GLOBAL
,
2732 .offset
= GLOBAL_VAR(szAddGroupScript
),
2735 .flags
= FLAG_ADVANCED
,
2738 .label
= "delete group script",
2740 .p_class
= P_GLOBAL
,
2741 .offset
= GLOBAL_VAR(szDelGroupScript
),
2744 .flags
= FLAG_ADVANCED
,
2747 .label
= "add user to group script",
2749 .p_class
= P_GLOBAL
,
2750 .offset
= GLOBAL_VAR(szAddUserToGroupScript
),
2753 .flags
= FLAG_ADVANCED
,
2756 .label
= "delete user from group script",
2758 .p_class
= P_GLOBAL
,
2759 .offset
= GLOBAL_VAR(szDelUserFromGroupScript
),
2762 .flags
= FLAG_ADVANCED
,
2765 .label
= "set primary group script",
2767 .p_class
= P_GLOBAL
,
2768 .offset
= GLOBAL_VAR(szSetPrimaryGroupScript
),
2771 .flags
= FLAG_ADVANCED
,
2774 .label
= "add machine script",
2776 .p_class
= P_GLOBAL
,
2777 .offset
= GLOBAL_VAR(szAddMachineScript
),
2780 .flags
= FLAG_ADVANCED
,
2783 .label
= "shutdown script",
2785 .p_class
= P_GLOBAL
,
2786 .offset
= GLOBAL_VAR(szShutdownScript
),
2789 .flags
= FLAG_ADVANCED
,
2792 .label
= "abort shutdown script",
2794 .p_class
= P_GLOBAL
,
2795 .offset
= GLOBAL_VAR(szAbortShutdownScript
),
2798 .flags
= FLAG_ADVANCED
,
2801 .label
= "username map script",
2803 .p_class
= P_GLOBAL
,
2804 .offset
= GLOBAL_VAR(szUsernameMapScript
),
2807 .flags
= FLAG_ADVANCED
,
2810 .label
= "username map cache time",
2812 .p_class
= P_GLOBAL
,
2813 .offset
= GLOBAL_VAR(iUsernameMapCacheTime
),
2816 .flags
= FLAG_ADVANCED
,
2819 .label
= "logon script",
2821 .p_class
= P_GLOBAL
,
2822 .offset
= GLOBAL_VAR(szLogonScript
),
2825 .flags
= FLAG_ADVANCED
,
2828 .label
= "logon path",
2830 .p_class
= P_GLOBAL
,
2831 .offset
= GLOBAL_VAR(szLogonPath
),
2834 .flags
= FLAG_ADVANCED
,
2837 .label
= "logon drive",
2839 .p_class
= P_GLOBAL
,
2840 .offset
= GLOBAL_VAR(szLogonDrive
),
2843 .flags
= FLAG_ADVANCED
,
2846 .label
= "logon home",
2848 .p_class
= P_GLOBAL
,
2849 .offset
= GLOBAL_VAR(szLogonHome
),
2852 .flags
= FLAG_ADVANCED
,
2855 .label
= "domain logons",
2857 .p_class
= P_GLOBAL
,
2858 .offset
= GLOBAL_VAR(bDomainLogons
),
2861 .flags
= FLAG_ADVANCED
,
2865 .label
= "init logon delayed hosts",
2867 .p_class
= P_GLOBAL
,
2868 .offset
= GLOBAL_VAR(szInitLogonDelayedHosts
),
2871 .flags
= FLAG_ADVANCED
,
2875 .label
= "init logon delay",
2877 .p_class
= P_GLOBAL
,
2878 .offset
= GLOBAL_VAR(InitLogonDelay
),
2881 .flags
= FLAG_ADVANCED
,
2885 {N_("Browse Options"), P_SEP
, P_SEPARATOR
},
2888 .label
= "os level",
2890 .p_class
= P_GLOBAL
,
2891 .offset
= GLOBAL_VAR(os_level
),
2894 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
2897 .label
= "lm announce",
2899 .p_class
= P_GLOBAL
,
2900 .offset
= GLOBAL_VAR(lm_announce
),
2902 .enum_list
= enum_bool_auto
,
2903 .flags
= FLAG_ADVANCED
,
2906 .label
= "lm interval",
2908 .p_class
= P_GLOBAL
,
2909 .offset
= GLOBAL_VAR(lm_interval
),
2912 .flags
= FLAG_ADVANCED
,
2915 .label
= "preferred master",
2917 .p_class
= P_GLOBAL
,
2918 .offset
= GLOBAL_VAR(iPreferredMaster
),
2920 .enum_list
= enum_bool_auto
,
2921 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
2924 .label
= "prefered master",
2926 .p_class
= P_GLOBAL
,
2927 .offset
= GLOBAL_VAR(iPreferredMaster
),
2929 .enum_list
= enum_bool_auto
,
2933 .label
= "local master",
2935 .p_class
= P_GLOBAL
,
2936 .offset
= GLOBAL_VAR(bLocalMaster
),
2939 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
2942 .label
= "domain master",
2944 .p_class
= P_GLOBAL
,
2945 .offset
= GLOBAL_VAR(domain_master
),
2947 .enum_list
= enum_bool_auto
,
2948 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
2951 .label
= "browse list",
2953 .p_class
= P_GLOBAL
,
2954 .offset
= GLOBAL_VAR(bBrowseList
),
2957 .flags
= FLAG_ADVANCED
,
2960 .label
= "browseable",
2963 .offset
= LOCAL_VAR(bBrowseable
),
2966 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
2969 .label
= "browsable",
2972 .offset
= LOCAL_VAR(bBrowseable
),
2978 .label
= "access based share enum",
2981 .offset
= LOCAL_VAR(bAccessBasedShareEnum
),
2984 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
2987 .label
= "enhanced browsing",
2989 .p_class
= P_GLOBAL
,
2990 .offset
= GLOBAL_VAR(enhanced_browsing
),
2993 .flags
= FLAG_ADVANCED
,
2996 {N_("WINS Options"), P_SEP
, P_SEPARATOR
},
2999 .label
= "dns proxy",
3001 .p_class
= P_GLOBAL
,
3002 .offset
= GLOBAL_VAR(bWINSdnsProxy
),
3005 .flags
= FLAG_ADVANCED
,
3008 .label
= "wins proxy",
3010 .p_class
= P_GLOBAL
,
3011 .offset
= GLOBAL_VAR(bWINSproxy
),
3014 .flags
= FLAG_ADVANCED
,
3017 .label
= "wins server",
3019 .p_class
= P_GLOBAL
,
3020 .offset
= GLOBAL_VAR(szWINSservers
),
3023 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
3026 .label
= "wins support",
3028 .p_class
= P_GLOBAL
,
3029 .offset
= GLOBAL_VAR(bWINSsupport
),
3032 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
3035 .label
= "wins hook",
3037 .p_class
= P_GLOBAL
,
3038 .offset
= GLOBAL_VAR(szWINSHook
),
3041 .flags
= FLAG_ADVANCED
,
3044 {N_("Locking Options"), P_SEP
, P_SEPARATOR
},
3047 .label
= "blocking locks",
3050 .offset
= LOCAL_VAR(bBlockingLocks
),
3053 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3056 .label
= "csc policy",
3059 .offset
= LOCAL_VAR(iCSCPolicy
),
3061 .enum_list
= enum_csc_policy
,
3062 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3065 .label
= "fake oplocks",
3068 .offset
= LOCAL_VAR(bFakeOplocks
),
3071 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3074 .label
= "kernel oplocks",
3077 .offset
= LOCAL_VAR(bKernelOplocks
),
3080 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3086 .offset
= LOCAL_VAR(bLocking
),
3089 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3092 .label
= "lock spin time",
3094 .p_class
= P_GLOBAL
,
3095 .offset
= GLOBAL_VAR(iLockSpinTime
),
3098 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
3104 .offset
= LOCAL_VAR(bOpLocks
),
3107 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3110 .label
= "level2 oplocks",
3113 .offset
= LOCAL_VAR(bLevel2OpLocks
),
3116 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3119 .label
= "oplock break wait time",
3121 .p_class
= P_GLOBAL
,
3122 .offset
= GLOBAL_VAR(oplock_break_wait_time
),
3125 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
3128 .label
= "oplock contention limit",
3131 .offset
= LOCAL_VAR(iOplockContentionLimit
),
3134 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3137 .label
= "posix locking",
3140 .offset
= LOCAL_VAR(bPosixLocking
),
3143 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3146 .label
= "strict locking",
3149 .offset
= LOCAL_VAR(iStrictLocking
),
3151 .enum_list
= enum_bool_auto
,
3152 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3155 {N_("Ldap Options"), P_SEP
, P_SEPARATOR
},
3158 .label
= "ldap admin dn",
3160 .p_class
= P_GLOBAL
,
3161 .offset
= GLOBAL_VAR(szLdapAdminDn
),
3164 .flags
= FLAG_ADVANCED
,
3167 .label
= "ldap delete dn",
3169 .p_class
= P_GLOBAL
,
3170 .offset
= GLOBAL_VAR(ldap_delete_dn
),
3173 .flags
= FLAG_ADVANCED
,
3176 .label
= "ldap group suffix",
3178 .p_class
= P_GLOBAL
,
3179 .offset
= GLOBAL_VAR(szLdapGroupSuffix
),
3182 .flags
= FLAG_ADVANCED
,
3185 .label
= "ldap idmap suffix",
3187 .p_class
= P_GLOBAL
,
3188 .offset
= GLOBAL_VAR(szLdapIdmapSuffix
),
3191 .flags
= FLAG_ADVANCED
,
3194 .label
= "ldap machine suffix",
3196 .p_class
= P_GLOBAL
,
3197 .offset
= GLOBAL_VAR(szLdapMachineSuffix
),
3200 .flags
= FLAG_ADVANCED
,
3203 .label
= "ldap passwd sync",
3205 .p_class
= P_GLOBAL
,
3206 .offset
= GLOBAL_VAR(ldap_passwd_sync
),
3208 .enum_list
= enum_ldap_passwd_sync
,
3209 .flags
= FLAG_ADVANCED
,
3212 .label
= "ldap password sync",
3214 .p_class
= P_GLOBAL
,
3215 .offset
= GLOBAL_VAR(ldap_passwd_sync
),
3217 .enum_list
= enum_ldap_passwd_sync
,
3221 .label
= "ldap replication sleep",
3223 .p_class
= P_GLOBAL
,
3224 .offset
= GLOBAL_VAR(ldap_replication_sleep
),
3227 .flags
= FLAG_ADVANCED
,
3230 .label
= "ldap suffix",
3232 .p_class
= P_GLOBAL
,
3233 .offset
= GLOBAL_VAR(szLdapSuffix
),
3236 .flags
= FLAG_ADVANCED
,
3239 .label
= "ldap ssl",
3241 .p_class
= P_GLOBAL
,
3242 .offset
= GLOBAL_VAR(ldap_ssl
),
3244 .enum_list
= enum_ldap_ssl
,
3245 .flags
= FLAG_ADVANCED
,
3248 .label
= "ldap ssl ads",
3250 .p_class
= P_GLOBAL
,
3251 .offset
= GLOBAL_VAR(ldap_ssl_ads
),
3254 .flags
= FLAG_ADVANCED
,
3257 .label
= "ldap deref",
3259 .p_class
= P_GLOBAL
,
3260 .offset
= GLOBAL_VAR(ldap_deref
),
3262 .enum_list
= enum_ldap_deref
,
3263 .flags
= FLAG_ADVANCED
,
3266 .label
= "ldap follow referral",
3268 .p_class
= P_GLOBAL
,
3269 .offset
= GLOBAL_VAR(ldap_follow_referral
),
3271 .enum_list
= enum_bool_auto
,
3272 .flags
= FLAG_ADVANCED
,
3275 .label
= "ldap timeout",
3277 .p_class
= P_GLOBAL
,
3278 .offset
= GLOBAL_VAR(ldap_timeout
),
3281 .flags
= FLAG_ADVANCED
,
3284 .label
= "ldap connection timeout",
3286 .p_class
= P_GLOBAL
,
3287 .offset
= GLOBAL_VAR(ldap_connection_timeout
),
3290 .flags
= FLAG_ADVANCED
,
3293 .label
= "ldap page size",
3295 .p_class
= P_GLOBAL
,
3296 .offset
= GLOBAL_VAR(ldap_page_size
),
3299 .flags
= FLAG_ADVANCED
,
3302 .label
= "ldap user suffix",
3304 .p_class
= P_GLOBAL
,
3305 .offset
= GLOBAL_VAR(szLdapUserSuffix
),
3308 .flags
= FLAG_ADVANCED
,
3311 .label
= "ldap debug level",
3313 .p_class
= P_GLOBAL
,
3314 .offset
= GLOBAL_VAR(ldap_debug_level
),
3315 .special
= handle_ldap_debug_level
,
3317 .flags
= FLAG_ADVANCED
,
3320 .label
= "ldap debug threshold",
3322 .p_class
= P_GLOBAL
,
3323 .offset
= GLOBAL_VAR(ldap_debug_threshold
),
3326 .flags
= FLAG_ADVANCED
,
3329 {N_("EventLog Options"), P_SEP
, P_SEPARATOR
},
3332 .label
= "eventlog list",
3334 .p_class
= P_GLOBAL
,
3335 .offset
= GLOBAL_VAR(szEventLogs
),
3338 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
3341 {N_("Miscellaneous Options"), P_SEP
, P_SEPARATOR
},
3344 .label
= "add share command",
3346 .p_class
= P_GLOBAL
,
3347 .offset
= GLOBAL_VAR(szAddShareCommand
),
3350 .flags
= FLAG_ADVANCED
,
3353 .label
= "change share command",
3355 .p_class
= P_GLOBAL
,
3356 .offset
= GLOBAL_VAR(szChangeShareCommand
),
3359 .flags
= FLAG_ADVANCED
,
3362 .label
= "delete share command",
3364 .p_class
= P_GLOBAL
,
3365 .offset
= GLOBAL_VAR(szDeleteShareCommand
),
3368 .flags
= FLAG_ADVANCED
,
3371 .label
= "config file",
3373 .p_class
= P_GLOBAL
,
3374 .offset
= GLOBAL_VAR(szConfigFile
),
3377 .flags
= FLAG_HIDE
|FLAG_META
,
3382 .p_class
= P_GLOBAL
,
3383 .offset
= GLOBAL_VAR(szAutoServices
),
3386 .flags
= FLAG_ADVANCED
,
3389 .label
= "auto services",
3391 .p_class
= P_GLOBAL
,
3392 .offset
= GLOBAL_VAR(szAutoServices
),
3395 .flags
= FLAG_ADVANCED
,
3398 .label
= "lock directory",
3400 .p_class
= P_GLOBAL
,
3401 .offset
= GLOBAL_VAR(szLockDir
),
3404 .flags
= FLAG_ADVANCED
,
3407 .label
= "lock dir",
3409 .p_class
= P_GLOBAL
,
3410 .offset
= GLOBAL_VAR(szLockDir
),
3416 .label
= "state directory",
3418 .p_class
= P_GLOBAL
,
3419 .offset
= GLOBAL_VAR(szStateDir
),
3422 .flags
= FLAG_ADVANCED
,
3425 .label
= "cache directory",
3427 .p_class
= P_GLOBAL
,
3428 .offset
= GLOBAL_VAR(szCacheDir
),
3431 .flags
= FLAG_ADVANCED
,
3434 .label
= "pid directory",
3436 .p_class
= P_GLOBAL
,
3437 .offset
= GLOBAL_VAR(szPidDir
),
3440 .flags
= FLAG_ADVANCED
,
3443 .label
= "ntp signd socket directory",
3445 .p_class
= P_GLOBAL
,
3446 .offset
= GLOBAL_VAR(szNTPSignDSocketDirectory
),
3449 .flags
= FLAG_ADVANCED
,
3454 .label
= "utmp directory",
3456 .p_class
= P_GLOBAL
,
3457 .offset
= GLOBAL_VAR(szUtmpDir
),
3460 .flags
= FLAG_ADVANCED
,
3463 .label
= "wtmp directory",
3465 .p_class
= P_GLOBAL
,
3466 .offset
= GLOBAL_VAR(szWtmpDir
),
3469 .flags
= FLAG_ADVANCED
,
3474 .p_class
= P_GLOBAL
,
3475 .offset
= GLOBAL_VAR(bUtmp
),
3478 .flags
= FLAG_ADVANCED
,
3482 .label
= "default service",
3484 .p_class
= P_GLOBAL
,
3485 .offset
= GLOBAL_VAR(szDefaultService
),
3488 .flags
= FLAG_ADVANCED
,
3493 .p_class
= P_GLOBAL
,
3494 .offset
= GLOBAL_VAR(szDefaultService
),
3497 .flags
= FLAG_ADVANCED
,
3500 .label
= "message command",
3502 .p_class
= P_GLOBAL
,
3503 .offset
= GLOBAL_VAR(szMsgCommand
),
3506 .flags
= FLAG_ADVANCED
,
3509 .label
= "dfree cache time",
3512 .offset
= LOCAL_VAR(iDfreeCacheTime
),
3515 .flags
= FLAG_ADVANCED
,
3518 .label
= "dfree command",
3521 .offset
= LOCAL_VAR(szDfree
),
3524 .flags
= FLAG_ADVANCED
,
3527 .label
= "get quota command",
3529 .p_class
= P_GLOBAL
,
3530 .offset
= GLOBAL_VAR(szGetQuota
),
3533 .flags
= FLAG_ADVANCED
,
3536 .label
= "set quota command",
3538 .p_class
= P_GLOBAL
,
3539 .offset
= GLOBAL_VAR(szSetQuota
),
3542 .flags
= FLAG_ADVANCED
,
3545 .label
= "remote announce",
3547 .p_class
= P_GLOBAL
,
3548 .offset
= GLOBAL_VAR(szRemoteAnnounce
),
3551 .flags
= FLAG_ADVANCED
,
3554 .label
= "remote browse sync",
3556 .p_class
= P_GLOBAL
,
3557 .offset
= GLOBAL_VAR(szRemoteBrowseSync
),
3560 .flags
= FLAG_ADVANCED
,
3563 .label
= "socket address",
3565 .p_class
= P_GLOBAL
,
3566 .offset
= GLOBAL_VAR(szSocketAddress
),
3569 .flags
= FLAG_ADVANCED
,
3572 .label
= "nmbd bind explicit broadcast",
3574 .p_class
= P_GLOBAL
,
3575 .offset
= GLOBAL_VAR(bNmbdBindExplicitBroadcast
),
3578 .flags
= FLAG_ADVANCED
,
3581 .label
= "homedir map",
3583 .p_class
= P_GLOBAL
,
3584 .offset
= GLOBAL_VAR(szNISHomeMapName
),
3587 .flags
= FLAG_ADVANCED
,
3590 .label
= "afs username map",
3592 .p_class
= P_GLOBAL
,
3593 .offset
= GLOBAL_VAR(szAfsUsernameMap
),
3596 .flags
= FLAG_ADVANCED
,
3599 .label
= "afs token lifetime",
3601 .p_class
= P_GLOBAL
,
3602 .offset
= GLOBAL_VAR(iAfsTokenLifetime
),
3605 .flags
= FLAG_ADVANCED
,
3608 .label
= "log nt token command",
3610 .p_class
= P_GLOBAL
,
3611 .offset
= GLOBAL_VAR(szLogNtTokenCommand
),
3614 .flags
= FLAG_ADVANCED
,
3617 .label
= "NIS homedir",
3619 .p_class
= P_GLOBAL
,
3620 .offset
= GLOBAL_VAR(bNISHomeMap
),
3623 .flags
= FLAG_ADVANCED
,
3629 .offset
= LOCAL_VAR(valid
),
3638 .offset
= LOCAL_VAR(szCopy
),
3639 .special
= handle_copy
,
3647 .offset
= LOCAL_VAR(szInclude
),
3648 .special
= handle_include
,
3650 .flags
= FLAG_HIDE
|FLAG_META
,
3656 .offset
= LOCAL_VAR(szPreExec
),
3659 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
3665 .offset
= LOCAL_VAR(szPreExec
),
3668 .flags
= FLAG_ADVANCED
,
3671 .label
= "preexec close",
3674 .offset
= LOCAL_VAR(bPreexecClose
),
3677 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3680 .label
= "postexec",
3683 .offset
= LOCAL_VAR(szPostExec
),
3686 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
3689 .label
= "root preexec",
3692 .offset
= LOCAL_VAR(szRootPreExec
),
3695 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
3698 .label
= "root preexec close",
3701 .offset
= LOCAL_VAR(bRootpreexecClose
),
3704 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3707 .label
= "root postexec",
3710 .offset
= LOCAL_VAR(szRootPostExec
),
3713 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
3716 .label
= "available",
3719 .offset
= LOCAL_VAR(bAvailable
),
3722 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
3725 .label
= "registry shares",
3727 .p_class
= P_GLOBAL
,
3728 .offset
= GLOBAL_VAR(bRegistryShares
),
3731 .flags
= FLAG_ADVANCED
,
3734 .label
= "usershare allow guests",
3736 .p_class
= P_GLOBAL
,
3737 .offset
= GLOBAL_VAR(bUsershareAllowGuests
),
3740 .flags
= FLAG_ADVANCED
,
3743 .label
= "usershare max shares",
3745 .p_class
= P_GLOBAL
,
3746 .offset
= GLOBAL_VAR(iUsershareMaxShares
),
3749 .flags
= FLAG_ADVANCED
,
3752 .label
= "usershare owner only",
3754 .p_class
= P_GLOBAL
,
3755 .offset
= GLOBAL_VAR(bUsershareOwnerOnly
),
3758 .flags
= FLAG_ADVANCED
,
3761 .label
= "usershare path",
3763 .p_class
= P_GLOBAL
,
3764 .offset
= GLOBAL_VAR(szUsersharePath
),
3767 .flags
= FLAG_ADVANCED
,
3770 .label
= "usershare prefix allow list",
3772 .p_class
= P_GLOBAL
,
3773 .offset
= GLOBAL_VAR(szUsersharePrefixAllowList
),
3776 .flags
= FLAG_ADVANCED
,
3779 .label
= "usershare prefix deny list",
3781 .p_class
= P_GLOBAL
,
3782 .offset
= GLOBAL_VAR(szUsersharePrefixDenyList
),
3785 .flags
= FLAG_ADVANCED
,
3788 .label
= "usershare template share",
3790 .p_class
= P_GLOBAL
,
3791 .offset
= GLOBAL_VAR(szUsershareTemplateShare
),
3794 .flags
= FLAG_ADVANCED
,
3800 .offset
= LOCAL_VAR(volume
),
3803 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3809 .offset
= LOCAL_VAR(fstype
),
3812 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3815 .label
= "set directory",
3818 .offset
= LOCAL_VAR(bNo_set_dir
),
3821 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3824 .label
= "allow insecure wide links",
3826 .p_class
= P_GLOBAL
,
3827 .offset
= GLOBAL_VAR(bAllowInsecureWidelinks
),
3830 .flags
= FLAG_ADVANCED
,
3833 .label
= "wide links",
3836 .offset
= LOCAL_VAR(bWidelinks
),
3839 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3842 .label
= "follow symlinks",
3845 .offset
= LOCAL_VAR(bSymlinks
),
3848 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3851 .label
= "dont descend",
3854 .offset
= LOCAL_VAR(szDontdescend
),
3857 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3860 .label
= "magic script",
3863 .offset
= LOCAL_VAR(szMagicScript
),
3866 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3869 .label
= "magic output",
3872 .offset
= LOCAL_VAR(szMagicOutput
),
3875 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3878 .label
= "delete readonly",
3881 .offset
= LOCAL_VAR(bDeleteReadonly
),
3884 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3887 .label
= "dos filemode",
3890 .offset
= LOCAL_VAR(bDosFilemode
),
3893 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3896 .label
= "dos filetimes",
3899 .offset
= LOCAL_VAR(bDosFiletimes
),
3902 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3905 .label
= "dos filetime resolution",
3908 .offset
= LOCAL_VAR(bDosFiletimeResolution
),
3911 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3914 .label
= "fake directory create times",
3917 .offset
= LOCAL_VAR(bFakeDirCreateTimes
),
3920 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
3923 .label
= "async smb echo handler",
3925 .p_class
= P_GLOBAL
,
3926 .offset
= GLOBAL_VAR(bAsyncSMBEchoHandler
),
3929 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
3932 .label
= "panic action",
3934 .p_class
= P_GLOBAL
,
3935 .offset
= GLOBAL_VAR(szPanicAction
),
3938 .flags
= FLAG_ADVANCED
,
3941 .label
= "perfcount module",
3943 .p_class
= P_GLOBAL
,
3944 .offset
= GLOBAL_VAR(szSMBPerfcountModule
),
3947 .flags
= FLAG_ADVANCED
,
3950 {N_("VFS module options"), P_SEP
, P_SEPARATOR
},
3953 .label
= "vfs objects",
3956 .offset
= LOCAL_VAR(szVfsObjects
),
3959 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3962 .label
= "vfs object",
3965 .offset
= LOCAL_VAR(szVfsObjects
),
3972 {N_("MSDFS options"), P_SEP
, P_SEPARATOR
},
3975 .label
= "msdfs root",
3978 .offset
= LOCAL_VAR(bMSDfsRoot
),
3981 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3984 .label
= "msdfs proxy",
3987 .offset
= LOCAL_VAR(szMSDfsProxy
),
3990 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3993 .label
= "host msdfs",
3995 .p_class
= P_GLOBAL
,
3996 .offset
= GLOBAL_VAR(bHostMSDfs
),
3999 .flags
= FLAG_ADVANCED
,
4002 {N_("Winbind options"), P_SEP
, P_SEPARATOR
},
4005 .label
= "passdb expand explicit",
4007 .p_class
= P_GLOBAL
,
4008 .offset
= GLOBAL_VAR(bPassdbExpandExplicit
),
4011 .flags
= FLAG_ADVANCED
,
4014 .label
= "idmap backend",
4016 .p_class
= P_GLOBAL
,
4017 .offset
= GLOBAL_VAR(szIdmapBackend
),
4018 .special
= handle_idmap_backend
,
4020 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
4023 .label
= "idmap cache time",
4025 .p_class
= P_GLOBAL
,
4026 .offset
= GLOBAL_VAR(iIdmapCacheTime
),
4029 .flags
= FLAG_ADVANCED
,
4032 .label
= "idmap negative cache time",
4034 .p_class
= P_GLOBAL
,
4035 .offset
= GLOBAL_VAR(iIdmapNegativeCacheTime
),
4038 .flags
= FLAG_ADVANCED
,
4041 .label
= "idmap uid",
4043 .p_class
= P_GLOBAL
,
4044 .offset
= GLOBAL_VAR(szIdmapUID
),
4045 .special
= handle_idmap_uid
,
4047 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
4050 .label
= "winbind uid",
4052 .p_class
= P_GLOBAL
,
4053 .offset
= GLOBAL_VAR(szIdmapUID
),
4054 .special
= handle_idmap_uid
,
4059 .label
= "idmap gid",
4061 .p_class
= P_GLOBAL
,
4062 .offset
= GLOBAL_VAR(szIdmapGID
),
4063 .special
= handle_idmap_gid
,
4065 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
4068 .label
= "winbind gid",
4070 .p_class
= P_GLOBAL
,
4071 .offset
= GLOBAL_VAR(szIdmapGID
),
4072 .special
= handle_idmap_gid
,
4077 .label
= "template homedir",
4079 .p_class
= P_GLOBAL
,
4080 .offset
= GLOBAL_VAR(szTemplateHomedir
),
4083 .flags
= FLAG_ADVANCED
,
4086 .label
= "template shell",
4088 .p_class
= P_GLOBAL
,
4089 .offset
= GLOBAL_VAR(szTemplateShell
),
4092 .flags
= FLAG_ADVANCED
,
4095 .label
= "winbind separator",
4097 .p_class
= P_GLOBAL
,
4098 .offset
= GLOBAL_VAR(szWinbindSeparator
),
4101 .flags
= FLAG_ADVANCED
,
4104 .label
= "winbind cache time",
4106 .p_class
= P_GLOBAL
,
4107 .offset
= GLOBAL_VAR(winbind_cache_time
),
4110 .flags
= FLAG_ADVANCED
,
4113 .label
= "winbind reconnect delay",
4115 .p_class
= P_GLOBAL
,
4116 .offset
= GLOBAL_VAR(winbind_reconnect_delay
),
4119 .flags
= FLAG_ADVANCED
,
4122 .label
= "winbind max clients",
4124 .p_class
= P_GLOBAL
,
4125 .offset
= GLOBAL_VAR(winbind_max_clients
),
4128 .flags
= FLAG_ADVANCED
,
4131 .label
= "winbind enum users",
4133 .p_class
= P_GLOBAL
,
4134 .offset
= GLOBAL_VAR(bWinbindEnumUsers
),
4137 .flags
= FLAG_ADVANCED
,
4140 .label
= "winbind enum groups",
4142 .p_class
= P_GLOBAL
,
4143 .offset
= GLOBAL_VAR(bWinbindEnumGroups
),
4146 .flags
= FLAG_ADVANCED
,
4149 .label
= "winbind use default domain",
4151 .p_class
= P_GLOBAL
,
4152 .offset
= GLOBAL_VAR(bWinbindUseDefaultDomain
),
4155 .flags
= FLAG_ADVANCED
,
4158 .label
= "winbind trusted domains only",
4160 .p_class
= P_GLOBAL
,
4161 .offset
= GLOBAL_VAR(bWinbindTrustedDomainsOnly
),
4164 .flags
= FLAG_ADVANCED
,
4167 .label
= "winbind nested groups",
4169 .p_class
= P_GLOBAL
,
4170 .offset
= GLOBAL_VAR(bWinbindNestedGroups
),
4173 .flags
= FLAG_ADVANCED
,
4176 .label
= "winbind expand groups",
4178 .p_class
= P_GLOBAL
,
4179 .offset
= GLOBAL_VAR(winbind_expand_groups
),
4182 .flags
= FLAG_ADVANCED
,
4185 .label
= "winbind nss info",
4187 .p_class
= P_GLOBAL
,
4188 .offset
= GLOBAL_VAR(szWinbindNssInfo
),
4191 .flags
= FLAG_ADVANCED
,
4194 .label
= "winbind refresh tickets",
4196 .p_class
= P_GLOBAL
,
4197 .offset
= GLOBAL_VAR(bWinbindRefreshTickets
),
4200 .flags
= FLAG_ADVANCED
,
4203 .label
= "winbind offline logon",
4205 .p_class
= P_GLOBAL
,
4206 .offset
= GLOBAL_VAR(bWinbindOfflineLogon
),
4209 .flags
= FLAG_ADVANCED
,
4212 .label
= "winbind normalize names",
4214 .p_class
= P_GLOBAL
,
4215 .offset
= GLOBAL_VAR(bWinbindNormalizeNames
),
4218 .flags
= FLAG_ADVANCED
,
4221 .label
= "winbind rpc only",
4223 .p_class
= P_GLOBAL
,
4224 .offset
= GLOBAL_VAR(bWinbindRpcOnly
),
4227 .flags
= FLAG_ADVANCED
,
4230 .label
= "create krb5 conf",
4232 .p_class
= P_GLOBAL
,
4233 .offset
= GLOBAL_VAR(bCreateKrb5Conf
),
4236 .flags
= FLAG_ADVANCED
,
4239 .label
= "ncalrpc dir",
4241 .p_class
= P_GLOBAL
,
4242 .offset
= GLOBAL_VAR(ncalrpc_dir
),
4245 .flags
= FLAG_ADVANCED
,
4248 .label
= "winbind max domain connections",
4250 .p_class
= P_GLOBAL
,
4251 .offset
= GLOBAL_VAR(winbindMaxDomainConnections
),
4254 .flags
= FLAG_ADVANCED
,
4257 .label
= "winbindd socket directory",
4259 .p_class
= P_GLOBAL
,
4260 .offset
= GLOBAL_VAR(szWinbinddSocketDirectory
),
4263 .flags
= FLAG_ADVANCED
,
4266 .label
= "winbindd privileged socket directory",
4268 .p_class
= P_GLOBAL
,
4269 .offset
= GLOBAL_VAR(szWinbinddPrivilegedSocketDirectory
),
4272 .flags
= FLAG_ADVANCED
,
4275 .label
= "winbind sealed pipes",
4277 .p_class
= P_GLOBAL
,
4278 .offset
= GLOBAL_VAR(bWinbindSealedPipes
),
4281 .flags
= FLAG_ADVANCED
,
4284 {N_("DNS options"), P_SEP
, P_SEPARATOR
},
4286 .label
= "allow dns updates",
4288 .p_class
= P_GLOBAL
,
4289 .offset
= GLOBAL_VAR(allow_dns_updates
),
4291 .enum_list
= enum_dns_update_settings
,
4292 .flags
= FLAG_ADVANCED
,
4295 .label
= "dns forwarder",
4297 .p_class
= P_GLOBAL
,
4298 .offset
= GLOBAL_VAR(dns_forwarder
),
4301 .flags
= FLAG_ADVANCED
,
4304 .label
= "dns recursive queries",
4306 .p_class
= P_GLOBAL
,
4307 .offset
= GLOBAL_VAR(dns_recursive_queries
),
4312 .label
= "dns update command",
4314 .p_class
= P_GLOBAL
,
4315 .offset
= GLOBAL_VAR(szDNSUpdateCommand
),
4318 .flags
= FLAG_ADVANCED
,
4321 .label
= "nsupdate command",
4323 .p_class
= P_GLOBAL
,
4324 .offset
= GLOBAL_VAR(szNSUpdateCommand
),
4327 .flags
= FLAG_ADVANCED
,
4330 .label
= "rndc command",
4332 .p_class
= P_GLOBAL
,
4333 .offset
= GLOBAL_VAR(szRNDCCommand
),
4336 .flags
= FLAG_ADVANCED
,
4339 .label
= "multicast dns register",
4341 .p_class
= P_GLOBAL
,
4342 .offset
= GLOBAL_VAR(bMulticastDnsRegister
),
4345 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
4348 {N_("AD DC options"), P_SEP
, P_SEPARATOR
},
4351 .label
= "samba kcc command",
4353 .p_class
= P_GLOBAL
,
4354 .offset
= GLOBAL_VAR(szSambaKCCCommand
),
4357 .flags
= FLAG_ADVANCED
,
4360 .label
= "server services",
4362 .p_class
= P_GLOBAL
,
4363 .offset
= GLOBAL_VAR(server_services
),
4368 .label
= "dcerpc endpoint servers",
4370 .p_class
= P_GLOBAL
,
4371 .offset
= GLOBAL_VAR(dcerpc_ep_servers
),
4376 .label
= "spn update command",
4378 .p_class
= P_GLOBAL
,
4379 .offset
= GLOBAL_VAR(szSPNUpdateCommand
),
4382 .flags
= FLAG_ADVANCED
,
4385 .label
= "share backend",
4387 .p_class
= P_GLOBAL
,
4388 .offset
= GLOBAL_VAR(szShareBackend
),
4393 .label
= "ntvfs handler",
4396 .offset
= LOCAL_VAR(ntvfs_handler
),
4401 {N_("TLS options"), P_SEP
, P_SEPARATOR
},
4404 .label
= "tls enabled",
4406 .p_class
= P_GLOBAL
,
4407 .offset
= GLOBAL_VAR(tls_enabled
),
4412 .label
= "tls keyfile",
4414 .p_class
= P_GLOBAL
,
4415 .offset
= GLOBAL_VAR(tls_keyfile
),
4420 .label
= "tls certfile",
4422 .p_class
= P_GLOBAL
,
4423 .offset
= GLOBAL_VAR(tls_certfile
),
4428 .label
= "tls cafile",
4430 .p_class
= P_GLOBAL
,
4431 .offset
= GLOBAL_VAR(tls_cafile
),
4436 .label
= "tls crlfile",
4438 .p_class
= P_GLOBAL
,
4439 .offset
= GLOBAL_VAR(tls_crlfile
),
4444 .label
= "tls dh params file",
4446 .p_class
= P_GLOBAL
,
4447 .offset
= GLOBAL_VAR(tls_dhpfile
),
4452 {NULL
, P_BOOL
, P_NONE
, 0, NULL
, NULL
, 0}
4455 /***************************************************************************
4456 Initialise the sDefault parameter structure for the printer values.
4457 ***************************************************************************/
4459 static void init_printer_values(struct loadparm_service
*pService
)
4461 /* choose defaults depending on the type of printing */
4462 switch (pService
->iPrinting
) {
4467 string_set(&pService
->szLpqcommand
, "lpq -P'%p'");
4468 string_set(&pService
->szLprmcommand
, "lprm -P'%p' %j");
4469 string_set(&pService
->szPrintcommand
, "lpr -r -P'%p' %s");
4474 string_set(&pService
->szLpqcommand
, "lpq -P'%p'");
4475 string_set(&pService
->szLprmcommand
, "lprm -P'%p' %j");
4476 string_set(&pService
->szPrintcommand
, "lpr -r -P'%p' %s");
4477 string_set(&pService
->szQueuepausecommand
, "lpc stop '%p'");
4478 string_set(&pService
->szQueueresumecommand
, "lpc start '%p'");
4479 string_set(&pService
->szLppausecommand
, "lpc hold '%p' %j");
4480 string_set(&pService
->szLpresumecommand
, "lpc release '%p' %j");
4486 /* set the lpq command to contain the destination printer
4487 name only. This is used by cups_queue_get() */
4488 string_set(&pService
->szLpqcommand
, "%p");
4489 string_set(&pService
->szLprmcommand
, "");
4490 string_set(&pService
->szPrintcommand
, "");
4491 string_set(&pService
->szLppausecommand
, "");
4492 string_set(&pService
->szLpresumecommand
, "");
4493 string_set(&pService
->szQueuepausecommand
, "");
4494 string_set(&pService
->szQueueresumecommand
, "");
4496 string_set(&pService
->szLpqcommand
, "lpq -P'%p'");
4497 string_set(&pService
->szLprmcommand
, "lprm -P'%p' %j");
4498 string_set(&pService
->szPrintcommand
, "lpr -P'%p' %s; rm %s");
4499 string_set(&pService
->szLppausecommand
, "lp -i '%p-%j' -H hold");
4500 string_set(&pService
->szLpresumecommand
, "lp -i '%p-%j' -H resume");
4501 string_set(&pService
->szQueuepausecommand
, "disable '%p'");
4502 string_set(&pService
->szQueueresumecommand
, "enable '%p'");
4503 #endif /* HAVE_CUPS */
4508 string_set(&pService
->szLpqcommand
, "lpstat -o%p");
4509 string_set(&pService
->szLprmcommand
, "cancel %p-%j");
4510 string_set(&pService
->szPrintcommand
, "lp -c -d%p %s; rm %s");
4511 string_set(&pService
->szQueuepausecommand
, "disable %p");
4512 string_set(&pService
->szQueueresumecommand
, "enable %p");
4514 string_set(&pService
->szLppausecommand
, "lp -i %p-%j -H hold");
4515 string_set(&pService
->szLpresumecommand
, "lp -i %p-%j -H resume");
4520 string_set(&pService
->szLpqcommand
, "lpq -P%p");
4521 string_set(&pService
->szLprmcommand
, "lprm -P%p %j");
4522 string_set(&pService
->szPrintcommand
, "lp -r -P%p %s");
4525 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4529 const char *tdbfile
;
4530 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
4533 tdbfile
= talloc_asprintf(
4534 tmp_ctx
, "tdbfile=%s",
4535 lp_parm_const_string(-1, "vlp", "tdbfile",
4537 if (tdbfile
== NULL
) {
4538 tdbfile
="tdbfile=/tmp/vlp.tdb";
4541 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s print %%p %%s",
4543 string_set(&pService
->szPrintcommand
,
4544 tmp
? tmp
: "vlp print %p %s");
4546 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpq %%p",
4548 string_set(&pService
->szLpqcommand
,
4549 tmp
? tmp
: "vlp lpq %p");
4551 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lprm %%p %%j",
4553 string_set(&pService
->szLprmcommand
,
4554 tmp
? tmp
: "vlp lprm %p %j");
4556 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lppause %%p %%j",
4558 string_set(&pService
->szLppausecommand
,
4559 tmp
? tmp
: "vlp lppause %p %j");
4561 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpresume %%p %%j",
4563 string_set(&pService
->szLpresumecommand
,
4564 tmp
? tmp
: "vlp lpresume %p %j");
4566 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queuepause %%p",
4568 string_set(&pService
->szQueuepausecommand
,
4569 tmp
? tmp
: "vlp queuepause %p");
4571 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queueresume %%p",
4573 string_set(&pService
->szQueueresumecommand
,
4574 tmp
? tmp
: "vlp queueresume %p");
4575 TALLOC_FREE(tmp_ctx
);
4579 #endif /* DEVELOPER */
4584 * Function to return the default value for the maximum number of open
4585 * file descriptors permitted. This function tries to consult the
4586 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4587 * the smaller of those.
4589 static int max_open_files(void)
4591 int sysctl_max
= MAX_OPEN_FILES
;
4592 int rlimit_max
= MAX_OPEN_FILES
;
4594 #ifdef HAVE_SYSCTLBYNAME
4596 size_t size
= sizeof(sysctl_max
);
4597 sysctlbyname("kern.maxfilesperproc", &sysctl_max
, &size
, NULL
,
4602 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4608 if (getrlimit(RLIMIT_NOFILE
, &rl
) == 0)
4609 rlimit_max
= rl
.rlim_cur
;
4611 #if defined(RLIM_INFINITY)
4612 if(rl
.rlim_cur
== RLIM_INFINITY
)
4613 rlimit_max
= MAX_OPEN_FILES
;
4618 if (sysctl_max
< MIN_OPEN_FILES_WINDOWS
) {
4619 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4620 "minimum Windows limit (%d)\n",
4622 MIN_OPEN_FILES_WINDOWS
));
4623 sysctl_max
= MIN_OPEN_FILES_WINDOWS
;
4626 if (rlimit_max
< MIN_OPEN_FILES_WINDOWS
) {
4627 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4628 "minimum Windows limit (%d)\n",
4630 MIN_OPEN_FILES_WINDOWS
));
4631 rlimit_max
= MIN_OPEN_FILES_WINDOWS
;
4634 return MIN(sysctl_max
, rlimit_max
);
4638 * Common part of freeing allocated data for one parameter.
4640 static void free_one_parameter_common(void *parm_ptr
,
4641 struct parm_struct parm
)
4643 if ((parm
.type
== P_STRING
) ||
4644 (parm
.type
== P_USTRING
))
4646 string_free((char**)parm_ptr
);
4647 } else if (parm
.type
== P_LIST
) {
4648 TALLOC_FREE(*((char***)parm_ptr
));
4653 * Free the allocated data for one parameter for a share
4654 * given as a service struct.
4656 static void free_one_parameter(struct loadparm_service
*service
,
4657 struct parm_struct parm
)
4661 if (parm
.p_class
!= P_LOCAL
) {
4665 parm_ptr
= lp_parm_ptr(service
, &parm
);
4667 free_one_parameter_common(parm_ptr
, parm
);
4671 * Free the allocated parameter data of a share given
4672 * as a service struct.
4674 static void free_parameters(struct loadparm_service
*service
)
4678 for (i
=0; parm_table
[i
].label
; i
++) {
4679 free_one_parameter(service
, parm_table
[i
]);
4684 * Free the allocated data for one parameter for a given share
4685 * specified by an snum.
4687 static void free_one_parameter_by_snum(int snum
, struct parm_struct parm
)
4692 parm_ptr
= lp_parm_ptr(NULL
, &parm
);
4693 } else if (parm
.p_class
!= P_LOCAL
) {
4696 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm
);
4699 free_one_parameter_common(parm_ptr
, parm
);
4703 * Free the allocated parameter data for a share specified
4706 static void free_parameters_by_snum(int snum
)
4710 for (i
=0; parm_table
[i
].label
; i
++) {
4711 free_one_parameter_by_snum(snum
, parm_table
[i
]);
4716 * Free the allocated global parameters.
4718 static void free_global_parameters(void)
4720 free_param_opts(&Globals
.param_opt
);
4721 free_parameters_by_snum(GLOBAL_SECTION_SNUM
);
4724 static int map_parameter(const char *pszParmName
);
4726 struct lp_stored_option
{
4727 struct lp_stored_option
*prev
, *next
;
4732 static struct lp_stored_option
*stored_options
;
4735 save options set by lp_set_cmdline() into a list. This list is
4736 re-applied when we do a globals reset, so that cmdline set options
4737 are sticky across reloads of smb.conf
4739 static bool store_lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
4741 struct lp_stored_option
*entry
, *entry_next
;
4742 for (entry
= stored_options
; entry
!= NULL
; entry
= entry_next
) {
4743 entry_next
= entry
->next
;
4744 if (strcmp(pszParmName
, entry
->label
) == 0) {
4745 DLIST_REMOVE(stored_options
, entry
);
4751 entry
= talloc(NULL
, struct lp_stored_option
);
4756 entry
->label
= talloc_strdup(entry
, pszParmName
);
4757 if (!entry
->label
) {
4762 entry
->value
= talloc_strdup(entry
, pszParmValue
);
4763 if (!entry
->value
) {
4768 DLIST_ADD_END(stored_options
, entry
, struct lp_stored_option
);
4773 static bool apply_lp_set_cmdline(void)
4775 struct lp_stored_option
*entry
= NULL
;
4776 for (entry
= stored_options
; entry
!= NULL
; entry
= entry
->next
) {
4777 if (!lp_set_cmdline_helper(entry
->label
, entry
->value
, false)) {
4778 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
4779 entry
->label
, entry
->value
));
4786 /***************************************************************************
4787 Initialise the global parameter structure.
4788 ***************************************************************************/
4790 static void init_globals(bool reinit_globals
)
4792 static bool done_init
= false;
4796 /* If requested to initialize only once and we've already done it... */
4797 if (!reinit_globals
&& done_init
) {
4798 /* ... then we have nothing more to do */
4803 /* The logfile can be set before this is invoked. Free it if so. */
4804 if (Globals
.logfile
!= NULL
) {
4805 string_free(&Globals
.logfile
);
4806 Globals
.logfile
= NULL
;
4810 free_global_parameters();
4813 /* This memset and the free_global_parameters() above will
4814 * wipe out smb.conf options set with lp_set_cmdline(). The
4815 * apply_lp_set_cmdline() call puts these values back in the
4816 * table once the defaults are set */
4817 ZERO_STRUCT(Globals
);
4819 for (i
= 0; parm_table
[i
].label
; i
++) {
4820 if ((parm_table
[i
].type
== P_STRING
||
4821 parm_table
[i
].type
== P_USTRING
))
4823 string_set((char **)lp_parm_ptr(NULL
, &parm_table
[i
]), "");
4828 string_set(&sDefault
.fstype
, FSTYPE_STRING
);
4829 string_set(&sDefault
.szPrintjobUsername
, "%U");
4831 init_printer_values(&sDefault
);
4834 DEBUG(3, ("Initialising global parameters\n"));
4836 /* Must manually force to upper case here, as this does not go via the handler */
4837 string_set(&Globals
.szNetbiosName
, myhostname_upper());
4839 string_set(&Globals
.szSMBPasswdFile
, get_dyn_SMB_PASSWD_FILE());
4840 string_set(&Globals
.szPrivateDir
, get_dyn_PRIVATE_DIR());
4842 /* use the new 'hash2' method by default, with a prefix of 1 */
4843 string_set(&Globals
.szManglingMethod
, "hash2");
4844 Globals
.mangle_prefix
= 1;
4846 string_set(&Globals
.szGuestaccount
, GUEST_ACCOUNT
);
4848 /* using UTF8 by default allows us to support all chars */
4849 string_set(&Globals
.unix_charset
, DEFAULT_UNIX_CHARSET
);
4851 /* Use codepage 850 as a default for the dos character set */
4852 string_set(&Globals
.dos_charset
, DEFAULT_DOS_CHARSET
);
4855 * Allow the default PASSWD_CHAT to be overridden in local.h.
4857 string_set(&Globals
.szPasswdChat
, DEFAULT_PASSWD_CHAT
);
4859 string_set(&Globals
.szWorkgroup
, DEFAULT_WORKGROUP
);
4861 string_set(&Globals
.szPasswdProgram
, "");
4862 string_set(&Globals
.szLockDir
, get_dyn_LOCKDIR());
4863 string_set(&Globals
.szStateDir
, get_dyn_STATEDIR());
4864 string_set(&Globals
.szCacheDir
, get_dyn_CACHEDIR());
4865 string_set(&Globals
.szPidDir
, get_dyn_PIDDIR());
4866 string_set(&Globals
.szSocketAddress
, "0.0.0.0");
4868 * By default support explicit binding to broadcast
4871 Globals
.bNmbdBindExplicitBroadcast
= true;
4873 if (asprintf(&s
, "Samba %s", samba_version_string()) < 0) {
4874 smb_panic("init_globals: ENOMEM");
4876 string_set(&Globals
.szServerString
, s
);
4879 string_set(&Globals
.szPanicAction
, "/bin/sleep 999999999");
4882 string_set(&Globals
.socket_options
, DEFAULT_SOCKET_OPTIONS
);
4884 string_set(&Globals
.szLogonDrive
, "");
4885 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4886 string_set(&Globals
.szLogonHome
, "\\\\%N\\%U");
4887 string_set(&Globals
.szLogonPath
, "\\\\%N\\%U\\profile");
4889 Globals
.szNameResolveOrder
= (const char **)str_list_make_v3(NULL
, "lmhosts wins host bcast", NULL
);
4890 string_set(&Globals
.szPasswordServer
, "*");
4892 Globals
.AlgorithmicRidBase
= BASE_RID
;
4894 Globals
.bLoadPrinters
= true;
4895 Globals
.PrintcapCacheTime
= 750; /* 12.5 minutes */
4897 Globals
.ConfigBackend
= config_backend
;
4898 Globals
.server_role
= ROLE_AUTO
;
4900 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4901 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4902 Globals
.max_xmit
= 0x4104;
4903 Globals
.max_mux
= 50; /* This is *needed* for profile support. */
4904 Globals
.lpqcachetime
= 30; /* changed to handle large print servers better -- jerry */
4905 Globals
.bDisableSpoolss
= false;
4906 Globals
.iMaxSmbdProcesses
= 0;/* no limit specified */
4907 Globals
.pwordlevel
= 0;
4908 Globals
.unamelevel
= 0;
4909 Globals
.deadtime
= 0;
4910 Globals
.getwd_cache
= true;
4911 Globals
.bLargeReadwrite
= true;
4912 Globals
.max_log_size
= 5000;
4913 Globals
.max_open_files
= max_open_files();
4914 Globals
.open_files_db_hash_size
= SMB_OPEN_DATABASE_TDB_HASH_SIZE
;
4915 Globals
.srv_maxprotocol
= PROTOCOL_SMB2_10
;
4916 Globals
.srv_minprotocol
= PROTOCOL_LANMAN1
;
4917 Globals
.security
= SEC_USER
;
4918 Globals
.paranoid_server_security
= true;
4919 Globals
.bEncryptPasswords
= true;
4920 Globals
.clientSchannel
= Auto
;
4921 Globals
.serverSchannel
= Auto
;
4922 Globals
.bReadRaw
= true;
4923 Globals
.bWriteRaw
= true;
4924 Globals
.bNullPasswords
= false;
4925 Globals
.bObeyPamRestrictions
= false;
4927 Globals
.bSyslogOnly
= false;
4928 Globals
.bTimestampLogs
= true;
4929 string_set(&Globals
.loglevel
, "0");
4930 Globals
.bDebugPrefixTimestamp
= false;
4931 Globals
.bDebugHiresTimestamp
= true;
4932 Globals
.bDebugPid
= false;
4933 Globals
.bDebugUid
= false;
4934 Globals
.bDebugClass
= false;
4935 Globals
.bEnableCoreFiles
= true;
4936 Globals
.max_ttl
= 60 * 60 * 24 * 3; /* 3 days default. */
4937 Globals
.max_wins_ttl
= 60 * 60 * 24 * 6; /* 6 days default. */
4938 Globals
.min_wins_ttl
= 60 * 60 * 6; /* 6 hours default. */
4939 Globals
.machine_password_timeout
= 60 * 60 * 24 * 7; /* 7 days default. */
4940 Globals
.lm_announce
= Auto
; /* = Auto: send only if LM clients found */
4941 Globals
.lm_interval
= 60;
4942 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4943 Globals
.bNISHomeMap
= false;
4944 #ifdef WITH_NISPLUS_HOME
4945 string_set(&Globals
.szNISHomeMapName
, "auto_home.org_dir");
4947 string_set(&Globals
.szNISHomeMapName
, "auto.home");
4950 Globals
.bTimeServer
= false;
4951 Globals
.bBindInterfacesOnly
= false;
4952 Globals
.bUnixPasswdSync
= false;
4953 Globals
.bPamPasswordChange
= false;
4954 Globals
.bPasswdChatDebug
= false;
4955 Globals
.iPasswdChatTimeout
= 2; /* 2 second default. */
4956 Globals
.bNTPipeSupport
= true; /* Do NT pipes by default. */
4957 Globals
.bNTStatusSupport
= true; /* Use NT status by default. */
4958 Globals
.bStatCache
= true; /* use stat cache by default */
4959 Globals
.iMaxStatCacheSize
= 256; /* 256k by default */
4960 Globals
.restrict_anonymous
= 0;
4961 Globals
.bClientLanManAuth
= false; /* Do NOT use the LanMan hash if it is available */
4962 Globals
.bClientPlaintextAuth
= false; /* Do NOT use a plaintext password even if is requested by the server */
4963 Globals
.bLanmanAuth
= false; /* Do NOT use the LanMan hash, even if it is supplied */
4964 Globals
.bNTLMAuth
= true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4965 Globals
.bClientNTLMv2Auth
= true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
4966 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
4968 Globals
.map_to_guest
= 0; /* By Default, "Never" */
4969 Globals
.oplock_break_wait_time
= 0; /* By Default, 0 msecs. */
4970 Globals
.enhanced_browsing
= true;
4971 Globals
.iLockSpinTime
= WINDOWS_MINIMUM_LOCK_TIMEOUT_MS
; /* msec. */
4972 #ifdef MMAP_BLACKLIST
4973 Globals
.bUseMmap
= false;
4975 Globals
.bUseMmap
= true;
4977 Globals
.bUnicode
= true;
4978 Globals
.bUnixExtensions
= true;
4979 Globals
.bResetOnZeroVC
= false;
4980 Globals
.bLogWriteableFilesOnExit
= false;
4981 Globals
.bCreateKrb5Conf
= true;
4982 Globals
.winbindMaxDomainConnections
= 1;
4984 /* hostname lookups can be very expensive and are broken on
4985 a large number of sites (tridge) */
4986 Globals
.bHostnameLookups
= false;
4988 string_set(&Globals
.passdb_backend
, "tdbsam");
4989 string_set(&Globals
.szLdapSuffix
, "");
4990 string_set(&Globals
.szLdapMachineSuffix
, "");
4991 string_set(&Globals
.szLdapUserSuffix
, "");
4992 string_set(&Globals
.szLdapGroupSuffix
, "");
4993 string_set(&Globals
.szLdapIdmapSuffix
, "");
4995 string_set(&Globals
.szLdapAdminDn
, "");
4996 Globals
.ldap_ssl
= LDAP_SSL_START_TLS
;
4997 Globals
.ldap_ssl_ads
= false;
4998 Globals
.ldap_deref
= -1;
4999 Globals
.ldap_passwd_sync
= LDAP_PASSWD_SYNC_OFF
;
5000 Globals
.ldap_delete_dn
= false;
5001 Globals
.ldap_replication_sleep
= 1000; /* wait 1 sec for replication */
5002 Globals
.ldap_follow_referral
= Auto
;
5003 Globals
.ldap_timeout
= LDAP_DEFAULT_TIMEOUT
;
5004 Globals
.ldap_connection_timeout
= LDAP_CONNECTION_DEFAULT_TIMEOUT
;
5005 Globals
.ldap_page_size
= LDAP_PAGE_SIZE
;
5007 Globals
.ldap_debug_level
= 0;
5008 Globals
.ldap_debug_threshold
= 10;
5010 /* This is what we tell the afs client. in reality we set the token
5011 * to never expire, though, when this runs out the afs client will
5012 * forget the token. Set to 0 to get NEVERDATE.*/
5013 Globals
.iAfsTokenLifetime
= 604800;
5014 Globals
.cups_connection_timeout
= CUPS_DEFAULT_CONNECTION_TIMEOUT
;
5016 /* these parameters are set to defaults that are more appropriate
5017 for the increasing samba install base:
5019 as a member of the workgroup, that will possibly become a
5020 _local_ master browser (lm = true). this is opposed to a forced
5021 local master browser startup (pm = true).
5023 doesn't provide WINS server service by default (wsupp = false),
5024 and doesn't provide domain master browser services by default, either.
5028 Globals
.bMsAddPrinterWizard
= true;
5029 Globals
.os_level
= 20;
5030 Globals
.bLocalMaster
= true;
5031 Globals
.domain_master
= Auto
; /* depending on bDomainLogons */
5032 Globals
.bDomainLogons
= false;
5033 Globals
.bBrowseList
= true;
5034 Globals
.bWINSsupport
= false;
5035 Globals
.bWINSproxy
= false;
5037 TALLOC_FREE(Globals
.szInitLogonDelayedHosts
);
5038 Globals
.InitLogonDelay
= 100; /* 100 ms default delay */
5040 Globals
.bWINSdnsProxy
= true;
5042 Globals
.bAllowTrustedDomains
= true;
5043 string_set(&Globals
.szIdmapBackend
, "tdb");
5045 string_set(&Globals
.szTemplateShell
, "/bin/false");
5046 string_set(&Globals
.szTemplateHomedir
, "/home/%D/%U");
5047 string_set(&Globals
.szWinbindSeparator
, "\\");
5049 string_set(&Globals
.szCupsServer
, "");
5050 string_set(&Globals
.szIPrintServer
, "");
5052 #ifdef CLUSTER_SUPPORT
5053 string_set(&Globals
.ctdbdSocket
, CTDB_PATH
);
5055 string_set(&Globals
.ctdbdSocket
, "");
5058 Globals
.szClusterAddresses
= NULL
;
5059 Globals
.clustering
= false;
5060 Globals
.ctdb_timeout
= 0;
5061 Globals
.ctdb_locktime_warn_threshold
= 0;
5063 Globals
.winbind_cache_time
= 300; /* 5 minutes */
5064 Globals
.winbind_reconnect_delay
= 30; /* 30 seconds */
5065 Globals
.winbind_max_clients
= 200;
5066 Globals
.bWinbindEnumUsers
= false;
5067 Globals
.bWinbindEnumGroups
= false;
5068 Globals
.bWinbindUseDefaultDomain
= false;
5069 Globals
.bWinbindTrustedDomainsOnly
= false;
5070 Globals
.bWinbindNestedGroups
= true;
5071 Globals
.winbind_expand_groups
= 1;
5072 Globals
.szWinbindNssInfo
= (const char **)str_list_make_v3(NULL
, "template", NULL
);
5073 Globals
.bWinbindRefreshTickets
= false;
5074 Globals
.bWinbindOfflineLogon
= false;
5076 Globals
.iIdmapCacheTime
= 86400 * 7; /* a week by default */
5077 Globals
.iIdmapNegativeCacheTime
= 120; /* 2 minutes by default */
5079 Globals
.bPassdbExpandExplicit
= false;
5081 Globals
.name_cache_timeout
= 660; /* In seconds */
5083 Globals
.bUseSpnego
= true;
5084 Globals
.bClientUseSpnego
= true;
5086 Globals
.client_signing
= SMB_SIGNING_DEFAULT
;
5087 Globals
.server_signing
= SMB_SIGNING_DEFAULT
;
5089 Globals
.bDeferSharingViolations
= true;
5090 Globals
.smb_ports
= (const char **)str_list_make_v3(NULL
, SMB_PORTS
, NULL
);
5092 Globals
.bEnablePrivileges
= true;
5093 Globals
.bHostMSDfs
= true;
5094 Globals
.bASUSupport
= false;
5096 /* User defined shares. */
5097 if (asprintf(&s
, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5098 smb_panic("init_globals: ENOMEM");
5100 string_set(&Globals
.szUsersharePath
, s
);
5102 string_set(&Globals
.szUsershareTemplateShare
, "");
5103 Globals
.iUsershareMaxShares
= 0;
5104 /* By default disallow sharing of directories not owned by the sharer. */
5105 Globals
.bUsershareOwnerOnly
= true;
5106 /* By default disallow guest access to usershares. */
5107 Globals
.bUsershareAllowGuests
= false;
5109 Globals
.iKeepalive
= DEFAULT_KEEPALIVE
;
5111 /* By default no shares out of the registry */
5112 Globals
.bRegistryShares
= false;
5114 Globals
.iminreceivefile
= 0;
5116 Globals
.bMapUntrustedToDomain
= false;
5117 Globals
.bMulticastDnsRegister
= true;
5119 Globals
.ismb2_max_read
= DEFAULT_SMB2_MAX_READ
;
5120 Globals
.ismb2_max_write
= DEFAULT_SMB2_MAX_WRITE
;
5121 Globals
.ismb2_max_trans
= DEFAULT_SMB2_MAX_TRANSACT
;
5122 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
5124 string_set(&Globals
.ncalrpc_dir
, get_dyn_NCALRPCDIR());
5126 /* Now put back the settings that were set with lp_set_cmdline() */
5127 apply_lp_set_cmdline();
5130 /*******************************************************************
5131 Convenience routine to grab string parameters into talloced memory
5132 and run standard_sub_basic on them. The buffers can be written to by
5133 callers without affecting the source string.
5134 ********************************************************************/
5136 static char *lp_string(TALLOC_CTX
*ctx
, const char *s
)
5140 /* The follow debug is useful for tracking down memory problems
5141 especially if you have an inner loop that is calling a lp_*()
5142 function that returns a string. Perhaps this debug should be
5143 present all the time? */
5146 DEBUG(10, ("lp_string(%s)\n", s
));
5152 ret
= talloc_sub_basic(ctx
,
5153 get_current_username(),
5154 current_user_info
.domain
,
5156 if (trim_char(ret
, '\"', '\"')) {
5157 if (strchr(ret
,'\"') != NULL
) {
5159 ret
= talloc_sub_basic(ctx
,
5160 get_current_username(),
5161 current_user_info
.domain
,
5169 In this section all the functions that are used to access the
5170 parameters from the rest of the program are defined
5173 #define FN_GLOBAL_STRING(fn_name,ptr) \
5174 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5175 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5176 const char *lp_ ## fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5177 #define FN_GLOBAL_LIST(fn_name,ptr) \
5178 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5179 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5180 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
5181 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5182 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
5183 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5184 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
5186 #define FN_LOCAL_STRING(fn_name,val) \
5187 char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5188 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5189 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5190 #define FN_LOCAL_LIST(fn_name,val) \
5191 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5192 #define FN_LOCAL_BOOL(fn_name,val) \
5193 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5194 #define FN_LOCAL_INTEGER(fn_name,val) \
5195 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5197 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5198 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5199 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5200 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5201 #define FN_LOCAL_CHAR(fn_name,val) \
5202 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5205 static FN_GLOBAL_BOOL(_readraw
, bReadRaw
)
5206 static FN_GLOBAL_BOOL(_writeraw
, bWriteRaw
)
5208 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5209 * build process or in smb.conf, we use that value. Otherwise they
5210 * default to the value of lp_lockdir(). */
5211 const char *lp_statedir(void) {
5212 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5213 (strcmp(get_dyn_STATEDIR(), Globals
.szStateDir
) != 0))
5214 return(*(char **)(&Globals
.szStateDir
) ?
5215 *(char **)(&Globals
.szStateDir
) : "");
5217 return(*(char **)(&Globals
.szLockDir
) ?
5218 *(char **)(&Globals
.szLockDir
) : "");
5220 const char *lp_cachedir(void) {
5221 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5222 (strcmp(get_dyn_CACHEDIR(), Globals
.szCacheDir
) != 0))
5223 return(*(char **)(&Globals
.szCacheDir
) ?
5224 *(char **)(&Globals
.szCacheDir
) : "");
5226 return(*(char **)(&Globals
.szLockDir
) ?
5227 *(char **)(&Globals
.szLockDir
) : "");
5229 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int
,
5230 winbindMaxDomainConnections
)
5232 int lp_winbind_max_domain_connections(void)
5234 if (lp_winbind_offline_logon() &&
5235 lp_winbind_max_domain_connections_int() > 1) {
5236 DEBUG(1, ("offline logons active, restricting max domain "
5237 "connections to 1\n"));
5240 return MAX(1, lp_winbind_max_domain_connections_int());
5243 int lp_smb2_max_credits(void)
5245 if (Globals
.ismb2_max_credits
== 0) {
5246 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
5248 return Globals
.ismb2_max_credits
;
5250 int lp_cups_encrypt(void)
5253 #ifdef HAVE_HTTPCONNECTENCRYPT
5254 switch (Globals
.CupsEncrypt
) {
5256 result
= HTTP_ENCRYPT_REQUIRED
;
5259 result
= HTTP_ENCRYPT_ALWAYS
;
5262 result
= HTTP_ENCRYPT_NEVER
;
5269 /* These functions remain in source3/param for now */
5271 FN_GLOBAL_STRING(configfile
, szConfigFile
)
5273 #include "lib/param/param_functions.c"
5275 FN_LOCAL_STRING(servicename
, szService
)
5276 FN_LOCAL_CONST_STRING(const_servicename
, szService
)
5278 /* local prototypes */
5280 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
);
5281 static const char *get_boolean(bool bool_value
);
5282 static int getservicebyname(const char *pszServiceName
,
5283 struct loadparm_service
*pserviceDest
);
5284 static void copy_service(struct loadparm_service
*pserviceDest
,
5285 struct loadparm_service
*pserviceSource
,
5286 struct bitmap
*pcopymapDest
);
5287 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
5289 static bool do_section(const char *pszSectionName
, void *userdata
);
5290 static void init_copymap(struct loadparm_service
*pservice
);
5291 static bool hash_a_service(const char *name
, int number
);
5292 static void free_service_byindex(int iService
);
5293 static void show_parameter(int parmIndex
);
5294 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
);
5297 * This is a helper function for parametrical options support. It returns a
5298 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5299 * parametrical functions are quite simple
5301 static struct parmlist_entry
*get_parametrics_by_service(struct loadparm_service
*service
, const char *type
,
5304 bool global_section
= false;
5306 struct parmlist_entry
*data
;
5308 if (service
== NULL
) {
5309 data
= Globals
.param_opt
;
5310 global_section
= true;
5312 data
= service
->param_opt
;
5315 if (asprintf(¶m_key
, "%s:%s", type
, option
) == -1) {
5316 DEBUG(0,("asprintf failed!\n"));
5321 if (strwicmp(data
->key
, param_key
) == 0) {
5322 string_free(¶m_key
);
5328 if (!global_section
) {
5329 /* Try to fetch the same option but from globals */
5330 /* but only if we are not already working with Globals */
5331 data
= Globals
.param_opt
;
5333 if (strwicmp(data
->key
, param_key
) == 0) {
5334 string_free(¶m_key
);
5341 string_free(¶m_key
);
5347 * This is a helper function for parametrical options support. It returns a
5348 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5349 * parametrical functions are quite simple
5351 static struct parmlist_entry
*get_parametrics(int snum
, const char *type
,
5354 if (snum
>= iNumServices
) return NULL
;
5357 return get_parametrics_by_service(NULL
, type
, option
);
5359 return get_parametrics_by_service(ServicePtrs
[snum
], type
, option
);
5364 #define MISSING_PARAMETER(name) \
5365 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5367 /*******************************************************************
5368 convenience routine to return int parameters.
5369 ********************************************************************/
5370 static int lp_int(const char *s
)
5374 MISSING_PARAMETER(lp_int
);
5378 return (int)strtol(s
, NULL
, 0);
5381 /*******************************************************************
5382 convenience routine to return unsigned long parameters.
5383 ********************************************************************/
5384 static unsigned long lp_ulong(const char *s
)
5388 MISSING_PARAMETER(lp_ulong
);
5392 return strtoul(s
, NULL
, 0);
5395 /*******************************************************************
5396 convenience routine to return boolean parameters.
5397 ********************************************************************/
5398 static bool lp_bool(const char *s
)
5403 MISSING_PARAMETER(lp_bool
);
5407 if (!set_boolean(s
, &ret
)) {
5408 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s
));
5415 /*******************************************************************
5416 convenience routine to return enum parameters.
5417 ********************************************************************/
5418 static int lp_enum(const char *s
,const struct enum_list
*_enum
)
5422 if (!s
|| !*s
|| !_enum
) {
5423 MISSING_PARAMETER(lp_enum
);
5427 for (i
=0; _enum
[i
].name
; i
++) {
5428 if (strequal(_enum
[i
].name
,s
))
5429 return _enum
[i
].value
;
5432 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s
));
5436 #undef MISSING_PARAMETER
5438 /* Return parametric option from a given service. Type is a part of option before ':' */
5439 /* Parametric option has following syntax: 'Type: option = value' */
5440 char *lp_parm_talloc_string(TALLOC_CTX
*ctx
, int snum
, const char *type
, const char *option
, const char *def
)
5442 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5444 if (data
== NULL
||data
->value
==NULL
) {
5446 return lp_string(ctx
, def
);
5452 return lp_string(ctx
, data
->value
);
5455 /* Return parametric option from a given service. Type is a part of option before ':' */
5456 /* Parametric option has following syntax: 'Type: option = value' */
5457 const char *lp_parm_const_string(int snum
, const char *type
, const char *option
, const char *def
)
5459 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5461 if (data
== NULL
||data
->value
==NULL
)
5467 const char *lp_parm_const_string_service(struct loadparm_service
*service
, const char *type
, const char *option
)
5469 struct parmlist_entry
*data
= get_parametrics_by_service(service
, type
, option
);
5471 if (data
== NULL
||data
->value
==NULL
)
5478 /* Return parametric option from a given service. Type is a part of option before ':' */
5479 /* Parametric option has following syntax: 'Type: option = value' */
5481 const char **lp_parm_string_list(int snum
, const char *type
, const char *option
, const char **def
)
5483 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5485 if (data
== NULL
||data
->value
==NULL
)
5486 return (const char **)def
;
5488 if (data
->list
==NULL
) {
5489 data
->list
= str_list_make_v3(NULL
, data
->value
, NULL
);
5492 return (const char **)data
->list
;
5495 /* Return parametric option from a given service. Type is a part of option before ':' */
5496 /* Parametric option has following syntax: 'Type: option = value' */
5498 int lp_parm_int(int snum
, const char *type
, const char *option
, int def
)
5500 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5502 if (data
&& data
->value
&& *data
->value
)
5503 return lp_int(data
->value
);
5508 /* Return parametric option from a given service. Type is a part of option before ':' */
5509 /* Parametric option has following syntax: 'Type: option = value' */
5511 unsigned long lp_parm_ulong(int snum
, const char *type
, const char *option
, unsigned long def
)
5513 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5515 if (data
&& data
->value
&& *data
->value
)
5516 return lp_ulong(data
->value
);
5521 /* Return parametric option from a given service. Type is a part of option before ':' */
5522 /* Parametric option has following syntax: 'Type: option = value' */
5524 bool lp_parm_bool(int snum
, const char *type
, const char *option
, bool def
)
5526 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5528 if (data
&& data
->value
&& *data
->value
)
5529 return lp_bool(data
->value
);
5534 /* Return parametric option from a given service. Type is a part of option before ':' */
5535 /* Parametric option has following syntax: 'Type: option = value' */
5537 int lp_parm_enum(int snum
, const char *type
, const char *option
,
5538 const struct enum_list
*_enum
, int def
)
5540 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5542 if (data
&& data
->value
&& *data
->value
&& _enum
)
5543 return lp_enum(data
->value
, _enum
);
5549 /***************************************************************************
5550 Initialise a service to the defaults.
5551 ***************************************************************************/
5553 static void init_service(struct loadparm_service
*pservice
)
5555 memset((char *)pservice
, '\0', sizeof(struct loadparm_service
));
5556 copy_service(pservice
, &sDefault
, NULL
);
5561 * free a param_opts structure.
5562 * param_opts handling should be moved to talloc;
5563 * then this whole functions reduces to a TALLOC_FREE().
5566 static void free_param_opts(struct parmlist_entry
**popts
)
5568 struct parmlist_entry
*opt
, *next_opt
;
5570 if (popts
== NULL
) {
5574 if (*popts
!= NULL
) {
5575 DEBUG(5, ("Freeing parametrics:\n"));
5578 while (opt
!= NULL
) {
5579 string_free(&opt
->key
);
5580 string_free(&opt
->value
);
5581 TALLOC_FREE(opt
->list
);
5582 next_opt
= opt
->next
;
5589 /***************************************************************************
5590 Free the dynamically allocated parts of a service struct.
5591 ***************************************************************************/
5593 static void free_service(struct loadparm_service
*pservice
)
5598 if (pservice
->szService
)
5599 DEBUG(5, ("free_service: Freeing service %s\n",
5600 pservice
->szService
));
5602 free_parameters(pservice
);
5604 string_free(&pservice
->szService
);
5605 TALLOC_FREE(pservice
->copymap
);
5607 free_param_opts(&pservice
->param_opt
);
5609 ZERO_STRUCTP(pservice
);
5613 /***************************************************************************
5614 remove a service indexed in the ServicePtrs array from the ServiceHash
5615 and free the dynamically allocated parts
5616 ***************************************************************************/
5618 static void free_service_byindex(int idx
)
5620 if ( !LP_SNUM_OK(idx
) )
5623 ServicePtrs
[idx
]->valid
= false;
5624 invalid_services
[num_invalid_services
++] = idx
;
5626 /* we have to cleanup the hash record */
5628 if (ServicePtrs
[idx
]->szService
) {
5629 char *canon_name
= canonicalize_servicename(
5631 ServicePtrs
[idx
]->szService
);
5633 dbwrap_delete_bystring(ServiceHash
, canon_name
);
5634 TALLOC_FREE(canon_name
);
5637 free_service(ServicePtrs
[idx
]);
5640 /***************************************************************************
5641 Add a new service to the services array initialising it with the given
5643 ***************************************************************************/
5645 static int add_a_service(const struct loadparm_service
*pservice
, const char *name
)
5648 struct loadparm_service tservice
;
5649 int num_to_alloc
= iNumServices
+ 1;
5651 tservice
= *pservice
;
5653 /* it might already exist */
5655 i
= getservicebyname(name
, NULL
);
5661 /* find an invalid one */
5663 if (num_invalid_services
> 0) {
5664 i
= invalid_services
[--num_invalid_services
];
5667 /* if not, then create one */
5668 if (i
== iNumServices
) {
5669 struct loadparm_service
**tsp
;
5672 tsp
= SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs
, struct loadparm_service
*, num_to_alloc
);
5674 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5678 ServicePtrs
[iNumServices
] = SMB_MALLOC_P(struct loadparm_service
);
5679 if (!ServicePtrs
[iNumServices
]) {
5680 DEBUG(0,("add_a_service: out of memory!\n"));
5685 /* enlarge invalid_services here for now... */
5686 tinvalid
= SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services
, int,
5688 if (tinvalid
== NULL
) {
5689 DEBUG(0,("add_a_service: failed to enlarge "
5690 "invalid_services!\n"));
5693 invalid_services
= tinvalid
;
5695 free_service_byindex(i
);
5698 ServicePtrs
[i
]->valid
= true;
5700 init_service(ServicePtrs
[i
]);
5701 copy_service(ServicePtrs
[i
], &tservice
, NULL
);
5703 string_set(&ServicePtrs
[i
]->szService
, name
);
5705 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5706 i
, ServicePtrs
[i
]->szService
));
5708 if (!hash_a_service(ServicePtrs
[i
]->szService
, i
)) {
5715 /***************************************************************************
5716 Convert a string to uppercase and remove whitespaces.
5717 ***************************************************************************/
5719 char *canonicalize_servicename(TALLOC_CTX
*ctx
, const char *src
)
5724 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5728 result
= talloc_strdup(ctx
, src
);
5729 SMB_ASSERT(result
!= NULL
);
5735 /***************************************************************************
5736 Add a name/index pair for the services array to the hash table.
5737 ***************************************************************************/
5739 static bool hash_a_service(const char *name
, int idx
)
5743 if ( !ServiceHash
) {
5744 DEBUG(10,("hash_a_service: creating servicehash\n"));
5745 ServiceHash
= db_open_rbt(NULL
);
5746 if ( !ServiceHash
) {
5747 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5752 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5755 canon_name
= canonicalize_servicename(talloc_tos(), name
);
5757 dbwrap_store_bystring(ServiceHash
, canon_name
,
5758 make_tdb_data((uint8
*)&idx
, sizeof(idx
)),
5761 TALLOC_FREE(canon_name
);
5766 /***************************************************************************
5767 Add a new home service, with the specified home directory, defaults coming
5769 ***************************************************************************/
5771 bool lp_add_home(const char *pszHomename
, int iDefaultService
,
5772 const char *user
, const char *pszHomedir
)
5776 if (pszHomename
== NULL
|| user
== NULL
|| pszHomedir
== NULL
||
5777 pszHomedir
[0] == '\0') {
5781 i
= add_a_service(ServicePtrs
[iDefaultService
], pszHomename
);
5786 if (!(*(ServicePtrs
[iDefaultService
]->szPath
))
5787 || strequal(ServicePtrs
[iDefaultService
]->szPath
,
5788 lp_pathname(talloc_tos(), GLOBAL_SECTION_SNUM
))) {
5789 string_set(&ServicePtrs
[i
]->szPath
, pszHomedir
);
5792 if (!(*(ServicePtrs
[i
]->comment
))) {
5793 char *comment
= NULL
;
5794 if (asprintf(&comment
, "Home directory of %s", user
) < 0) {
5797 string_set(&ServicePtrs
[i
]->comment
, comment
);
5801 /* set the browseable flag from the global default */
5803 ServicePtrs
[i
]->bBrowseable
= sDefault
.bBrowseable
;
5804 ServicePtrs
[i
]->bAccessBasedShareEnum
= sDefault
.bAccessBasedShareEnum
;
5806 ServicePtrs
[i
]->autoloaded
= true;
5808 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename
,
5809 user
, ServicePtrs
[i
]->szPath
));
5814 /***************************************************************************
5815 Add a new service, based on an old one.
5816 ***************************************************************************/
5818 int lp_add_service(const char *pszService
, int iDefaultService
)
5820 if (iDefaultService
< 0) {
5821 return add_a_service(&sDefault
, pszService
);
5824 return (add_a_service(ServicePtrs
[iDefaultService
], pszService
));
5827 /***************************************************************************
5828 Add the IPC service.
5829 ***************************************************************************/
5831 static bool lp_add_ipc(const char *ipc_name
, bool guest_ok
)
5833 char *comment
= NULL
;
5834 int i
= add_a_service(&sDefault
, ipc_name
);
5839 if (asprintf(&comment
, "IPC Service (%s)",
5840 Globals
.szServerString
) < 0) {
5844 string_set(&ServicePtrs
[i
]->szPath
, tmpdir());
5845 string_set(&ServicePtrs
[i
]->szUsername
, "");
5846 string_set(&ServicePtrs
[i
]->comment
, comment
);
5847 string_set(&ServicePtrs
[i
]->fstype
, "IPC");
5848 ServicePtrs
[i
]->iMaxConnections
= 0;
5849 ServicePtrs
[i
]->bAvailable
= true;
5850 ServicePtrs
[i
]->bRead_only
= true;
5851 ServicePtrs
[i
]->bGuest_only
= false;
5852 ServicePtrs
[i
]->bAdministrative_share
= true;
5853 ServicePtrs
[i
]->bGuest_ok
= guest_ok
;
5854 ServicePtrs
[i
]->bPrint_ok
= false;
5855 ServicePtrs
[i
]->bBrowseable
= sDefault
.bBrowseable
;
5857 DEBUG(3, ("adding IPC service\n"));
5863 /***************************************************************************
5864 Add a new printer service, with defaults coming from service iFrom.
5865 ***************************************************************************/
5867 bool lp_add_printer(const char *pszPrintername
, int iDefaultService
)
5869 const char *comment
= "From Printcap";
5870 int i
= add_a_service(ServicePtrs
[iDefaultService
], pszPrintername
);
5875 /* note that we do NOT default the availability flag to true - */
5876 /* we take it from the default service passed. This allows all */
5877 /* dynamic printers to be disabled by disabling the [printers] */
5878 /* entry (if/when the 'available' keyword is implemented!). */
5880 /* the printer name is set to the service name. */
5881 string_set(&ServicePtrs
[i
]->szPrintername
, pszPrintername
);
5882 string_set(&ServicePtrs
[i
]->comment
, comment
);
5884 /* set the browseable flag from the gloabl default */
5885 ServicePtrs
[i
]->bBrowseable
= sDefault
.bBrowseable
;
5887 /* Printers cannot be read_only. */
5888 ServicePtrs
[i
]->bRead_only
= false;
5889 /* No share modes on printer services. */
5890 ServicePtrs
[i
]->bShareModes
= false;
5891 /* No oplocks on printer services. */
5892 ServicePtrs
[i
]->bOpLocks
= false;
5893 /* Printer services must be printable. */
5894 ServicePtrs
[i
]->bPrint_ok
= true;
5896 DEBUG(3, ("adding printer service %s\n", pszPrintername
));
5902 /***************************************************************************
5903 Check whether the given parameter name is valid.
5904 Parametric options (names containing a colon) are considered valid.
5905 ***************************************************************************/
5907 bool lp_parameter_is_valid(const char *pszParmName
)
5909 return ((map_parameter(pszParmName
) != -1) ||
5910 (strchr(pszParmName
, ':') != NULL
));
5913 /***************************************************************************
5914 Check whether the given name is the name of a global parameter.
5915 Returns true for strings belonging to parameters of class
5916 P_GLOBAL, false for all other strings, also for parametric options
5917 and strings not belonging to any option.
5918 ***************************************************************************/
5920 bool lp_parameter_is_global(const char *pszParmName
)
5922 int num
= map_parameter(pszParmName
);
5925 return (parm_table
[num
].p_class
== P_GLOBAL
);
5931 /**************************************************************************
5932 Check whether the given name is the canonical name of a parameter.
5933 Returns false if it is not a valid parameter Name.
5934 For parametric options, true is returned.
5935 **************************************************************************/
5937 bool lp_parameter_is_canonical(const char *parm_name
)
5939 if (!lp_parameter_is_valid(parm_name
)) {
5943 return (map_parameter(parm_name
) ==
5944 map_parameter_canonical(parm_name
, NULL
));
5947 /**************************************************************************
5948 Determine the canonical name for a parameter.
5949 Indicate when it is an inverse (boolean) synonym instead of a
5951 **************************************************************************/
5953 bool lp_canonicalize_parameter(const char *parm_name
, const char **canon_parm
,
5958 if (!lp_parameter_is_valid(parm_name
)) {
5963 num
= map_parameter_canonical(parm_name
, inverse
);
5965 /* parametric option */
5966 *canon_parm
= parm_name
;
5968 *canon_parm
= parm_table
[num
].label
;
5975 /**************************************************************************
5976 Determine the canonical name for a parameter.
5977 Turn the value given into the inverse boolean expression when
5978 the synonym is an invers boolean synonym.
5980 Return true if parm_name is a valid parameter name and
5981 in case it is an invers boolean synonym, if the val string could
5982 successfully be converted to the reverse bool.
5983 Return false in all other cases.
5984 **************************************************************************/
5986 bool lp_canonicalize_parameter_with_value(const char *parm_name
,
5988 const char **canon_parm
,
5989 const char **canon_val
)
5994 if (!lp_parameter_is_valid(parm_name
)) {
6000 num
= map_parameter_canonical(parm_name
, &inverse
);
6002 /* parametric option */
6003 *canon_parm
= parm_name
;
6006 *canon_parm
= parm_table
[num
].label
;
6008 if (!lp_invert_boolean(val
, canon_val
)) {
6020 /***************************************************************************
6021 Map a parameter's string representation to something we can use.
6022 Returns false if the parameter string is not recognised, else TRUE.
6023 ***************************************************************************/
6025 static int map_parameter(const char *pszParmName
)
6029 if (*pszParmName
== '-' && !strequal(pszParmName
, "-valid"))
6032 for (iIndex
= 0; parm_table
[iIndex
].label
; iIndex
++)
6033 if (strwicmp(parm_table
[iIndex
].label
, pszParmName
) == 0)
6036 /* Warn only if it isn't parametric option */
6037 if (strchr(pszParmName
, ':') == NULL
)
6038 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName
));
6039 /* We do return 'fail' for parametric options as well because they are
6040 stored in different storage
6045 /***************************************************************************
6046 Map a parameter's string representation to the index of the canonical
6047 form of the parameter (it might be a synonym).
6048 Returns -1 if the parameter string is not recognised.
6049 ***************************************************************************/
6051 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
)
6053 int parm_num
, canon_num
;
6054 bool loc_inverse
= false;
6056 parm_num
= map_parameter(pszParmName
);
6057 if ((parm_num
< 0) || !(parm_table
[parm_num
].flags
& FLAG_HIDE
)) {
6058 /* invalid, parametric or no canidate for synonyms ... */
6062 for (canon_num
= 0; parm_table
[canon_num
].label
; canon_num
++) {
6063 if (is_synonym_of(parm_num
, canon_num
, &loc_inverse
)) {
6064 parm_num
= canon_num
;
6070 if (inverse
!= NULL
) {
6071 *inverse
= loc_inverse
;
6076 /***************************************************************************
6077 return true if parameter number parm1 is a synonym of parameter
6078 number parm2 (parm2 being the principal name).
6079 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
6081 ***************************************************************************/
6083 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
)
6085 if ((parm_table
[parm1
].offset
== parm_table
[parm2
].offset
) &&
6086 (parm_table
[parm1
].p_class
== parm_table
[parm2
].p_class
) &&
6087 (parm_table
[parm1
].flags
& FLAG_HIDE
) &&
6088 !(parm_table
[parm2
].flags
& FLAG_HIDE
))
6090 if (inverse
!= NULL
) {
6091 if ((parm_table
[parm1
].type
== P_BOOLREV
) &&
6092 (parm_table
[parm2
].type
== P_BOOL
))
6104 /***************************************************************************
6105 Show one parameter's name, type, [values,] and flags.
6106 (helper functions for show_parameter_list)
6107 ***************************************************************************/
6109 static void show_parameter(int parmIndex
)
6111 int enumIndex
, flagIndex
;
6116 const char *type
[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6117 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6119 unsigned flags
[] = { FLAG_BASIC
, FLAG_SHARE
, FLAG_PRINT
, FLAG_GLOBAL
,
6120 FLAG_WIZARD
, FLAG_ADVANCED
, FLAG_DEVELOPER
, FLAG_DEPRECATED
,
6122 const char *flag_names
[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6123 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6124 "FLAG_DEPRECATED", "FLAG_HIDE", NULL
};
6126 printf("%s=%s", parm_table
[parmIndex
].label
,
6127 type
[parm_table
[parmIndex
].type
]);
6128 if (parm_table
[parmIndex
].type
== P_ENUM
) {
6131 parm_table
[parmIndex
].enum_list
[enumIndex
].name
;
6135 enumIndex
? "|" : "",
6136 parm_table
[parmIndex
].enum_list
[enumIndex
].name
);
6141 for (flagIndex
=0; flag_names
[flagIndex
]; flagIndex
++) {
6142 if (parm_table
[parmIndex
].flags
& flags
[flagIndex
]) {
6145 flag_names
[flagIndex
]);
6150 /* output synonyms */
6152 for (parmIndex2
=0; parm_table
[parmIndex2
].label
; parmIndex2
++) {
6153 if (is_synonym_of(parmIndex
, parmIndex2
, &inverse
)) {
6154 printf(" (%ssynonym of %s)", inverse
? "inverse " : "",
6155 parm_table
[parmIndex2
].label
);
6156 } else if (is_synonym_of(parmIndex2
, parmIndex
, &inverse
)) {
6158 printf(" (synonyms: ");
6163 printf("%s%s", parm_table
[parmIndex2
].label
,
6164 inverse
? "[i]" : "");
6174 /***************************************************************************
6175 Show all parameter's name, type, [values,] and flags.
6176 ***************************************************************************/
6178 void show_parameter_list(void)
6180 int classIndex
, parmIndex
;
6181 const char *section_names
[] = { "local", "global", NULL
};
6183 for (classIndex
=0; section_names
[classIndex
]; classIndex
++) {
6184 printf("[%s]\n", section_names
[classIndex
]);
6185 for (parmIndex
= 0; parm_table
[parmIndex
].label
; parmIndex
++) {
6186 if (parm_table
[parmIndex
].p_class
== classIndex
) {
6187 show_parameter(parmIndex
);
6193 /***************************************************************************
6194 Check if a given string correctly represents a boolean value.
6195 ***************************************************************************/
6197 bool lp_string_is_valid_boolean(const char *parm_value
)
6199 return set_boolean(parm_value
, NULL
);
6202 /***************************************************************************
6203 Get the standard string representation of a boolean value ("yes" or "no")
6204 ***************************************************************************/
6206 static const char *get_boolean(bool bool_value
)
6208 static const char *yes_str
= "yes";
6209 static const char *no_str
= "no";
6211 return (bool_value
? yes_str
: no_str
);
6214 /***************************************************************************
6215 Provide the string of the negated boolean value associated to the boolean
6216 given as a string. Returns false if the passed string does not correctly
6217 represent a boolean.
6218 ***************************************************************************/
6220 bool lp_invert_boolean(const char *str
, const char **inverse_str
)
6224 if (!set_boolean(str
, &val
)) {
6228 *inverse_str
= get_boolean(!val
);
6232 /***************************************************************************
6233 Provide the canonical string representation of a boolean value given
6234 as a string. Return true on success, false if the string given does
6235 not correctly represent a boolean.
6236 ***************************************************************************/
6238 bool lp_canonicalize_boolean(const char *str
, const char**canon_str
)
6242 if (!set_boolean(str
, &val
)) {
6246 *canon_str
= get_boolean(val
);
6250 /***************************************************************************
6251 Find a service by name. Otherwise works like get_service.
6252 ***************************************************************************/
6254 static int getservicebyname(const char *pszServiceName
, struct loadparm_service
*pserviceDest
)
6261 if (ServiceHash
== NULL
) {
6265 canon_name
= canonicalize_servicename(talloc_tos(), pszServiceName
);
6267 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
, canon_name
,
6270 if (NT_STATUS_IS_OK(status
) &&
6271 (data
.dptr
!= NULL
) &&
6272 (data
.dsize
== sizeof(iService
)))
6274 iService
= *(int *)data
.dptr
;
6277 TALLOC_FREE(canon_name
);
6279 if ((iService
!= -1) && (LP_SNUM_OK(iService
))
6280 && (pserviceDest
!= NULL
)) {
6281 copy_service(pserviceDest
, ServicePtrs
[iService
], NULL
);
6287 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
6288 struct loadparm_service
*lp_service(const char *pszServiceName
)
6290 int iService
= getservicebyname(pszServiceName
, NULL
);
6291 if (iService
== -1 || !LP_SNUM_OK(iService
)) {
6294 return ServicePtrs
[iService
];
6297 struct loadparm_service
*lp_servicebynum(int snum
)
6299 if ((snum
== -1) || !LP_SNUM_OK(snum
)) {
6302 return ServicePtrs
[snum
];
6305 struct loadparm_service
*lp_default_loadparm_service()
6311 /***************************************************************************
6312 Copy a service structure to another.
6313 If pcopymapDest is NULL then copy all fields
6314 ***************************************************************************/
6317 * Add a parametric option to a parmlist_entry,
6318 * replacing old value, if already present.
6320 static void set_param_opt(struct parmlist_entry
**opt_list
,
6321 const char *opt_name
,
6322 const char *opt_value
,
6325 struct parmlist_entry
*new_opt
, *opt
;
6328 if (opt_list
== NULL
) {
6335 /* Traverse destination */
6337 /* If we already have same option, override it */
6338 if (strwicmp(opt
->key
, opt_name
) == 0) {
6339 if ((opt
->priority
& FLAG_CMDLINE
) &&
6340 !(priority
& FLAG_CMDLINE
)) {
6341 /* it's been marked as not to be
6345 string_free(&opt
->value
);
6346 TALLOC_FREE(opt
->list
);
6347 opt
->value
= SMB_STRDUP(opt_value
);
6348 opt
->priority
= priority
;
6355 new_opt
= SMB_XMALLOC_P(struct parmlist_entry
);
6356 new_opt
->key
= SMB_STRDUP(opt_name
);
6357 new_opt
->value
= SMB_STRDUP(opt_value
);
6358 new_opt
->list
= NULL
;
6359 new_opt
->priority
= priority
;
6360 DLIST_ADD(*opt_list
, new_opt
);
6364 static void copy_service(struct loadparm_service
*pserviceDest
, struct loadparm_service
*pserviceSource
,
6365 struct bitmap
*pcopymapDest
)
6368 bool bcopyall
= (pcopymapDest
== NULL
);
6369 struct parmlist_entry
*data
;
6371 for (i
= 0; parm_table
[i
].label
; i
++)
6372 if (parm_table
[i
].p_class
== P_LOCAL
&&
6373 (bcopyall
|| bitmap_query(pcopymapDest
,i
))) {
6374 void *src_ptr
= lp_parm_ptr(pserviceSource
, &parm_table
[i
]);
6375 void *dest_ptr
= lp_parm_ptr(pserviceDest
, &parm_table
[i
]);
6377 switch (parm_table
[i
].type
) {
6380 *(bool *)dest_ptr
= *(bool *)src_ptr
;
6387 *(int *)dest_ptr
= *(int *)src_ptr
;
6391 *(char *)dest_ptr
= *(char *)src_ptr
;
6395 string_set((char **)dest_ptr
,
6401 char *upper_string
= strupper_talloc(talloc_tos(),
6403 string_set((char **)dest_ptr
,
6405 TALLOC_FREE(upper_string
);
6409 TALLOC_FREE(*((char ***)dest_ptr
));
6410 *((char ***)dest_ptr
) = str_list_copy(NULL
,
6411 *(const char ***)src_ptr
);
6419 init_copymap(pserviceDest
);
6420 if (pserviceSource
->copymap
)
6421 bitmap_copy(pserviceDest
->copymap
,
6422 pserviceSource
->copymap
);
6425 data
= pserviceSource
->param_opt
;
6427 set_param_opt(&pserviceDest
->param_opt
, data
->key
, data
->value
, data
->priority
);
6432 /***************************************************************************
6433 Check a service for consistency. Return false if the service is in any way
6434 incomplete or faulty, else true.
6435 ***************************************************************************/
6437 bool service_ok(int iService
)
6442 if (ServicePtrs
[iService
]->szService
[0] == '\0') {
6443 DEBUG(0, ("The following message indicates an internal error:\n"));
6444 DEBUG(0, ("No service name in service entry.\n"));
6448 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6449 /* I can't see why you'd want a non-printable printer service... */
6450 if (strwicmp(ServicePtrs
[iService
]->szService
, PRINTERS_NAME
) == 0) {
6451 if (!ServicePtrs
[iService
]->bPrint_ok
) {
6452 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6453 ServicePtrs
[iService
]->szService
));
6454 ServicePtrs
[iService
]->bPrint_ok
= true;
6456 /* [printers] service must also be non-browsable. */
6457 if (ServicePtrs
[iService
]->bBrowseable
)
6458 ServicePtrs
[iService
]->bBrowseable
= false;
6461 if (ServicePtrs
[iService
]->szPath
[0] == '\0' &&
6462 strwicmp(ServicePtrs
[iService
]->szService
, HOMES_NAME
) != 0 &&
6463 ServicePtrs
[iService
]->szMSDfsProxy
[0] == '\0'
6465 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6466 ServicePtrs
[iService
]->szService
));
6467 ServicePtrs
[iService
]->bAvailable
= false;
6470 /* If a service is flagged unavailable, log the fact at level 1. */
6471 if (!ServicePtrs
[iService
]->bAvailable
)
6472 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6473 ServicePtrs
[iService
]->szService
));
6478 static struct smbconf_ctx
*lp_smbconf_ctx(void)
6481 static struct smbconf_ctx
*conf_ctx
= NULL
;
6483 if (conf_ctx
== NULL
) {
6484 err
= smbconf_init(NULL
, &conf_ctx
, "registry:");
6485 if (!SBC_ERROR_IS_OK(err
)) {
6486 DEBUG(1, ("error initializing registry configuration: "
6487 "%s\n", sbcErrorString(err
)));
6495 static bool process_smbconf_service(struct smbconf_service
*service
)
6500 if (service
== NULL
) {
6504 ret
= do_section(service
->name
, NULL
);
6508 for (count
= 0; count
< service
->num_params
; count
++) {
6509 ret
= do_parameter(service
->param_names
[count
],
6510 service
->param_values
[count
],
6516 if (iServiceIndex
>= 0) {
6517 return service_ok(iServiceIndex
);
6523 * load a service from registry and activate it
6525 bool process_registry_service(const char *service_name
)
6528 struct smbconf_service
*service
= NULL
;
6529 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
6530 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
6533 if (conf_ctx
== NULL
) {
6537 DEBUG(5, ("process_registry_service: service name %s\n", service_name
));
6539 if (!smbconf_share_exists(conf_ctx
, service_name
)) {
6541 * Registry does not contain data for this service (yet),
6542 * but make sure lp_load doesn't return false.
6548 err
= smbconf_get_share(conf_ctx
, mem_ctx
, service_name
, &service
);
6549 if (!SBC_ERROR_IS_OK(err
)) {
6553 ret
= process_smbconf_service(service
);
6559 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
6562 TALLOC_FREE(mem_ctx
);
6567 * process_registry_globals
6569 static bool process_registry_globals(void)
6573 add_to_file_list(INCLUDE_REGISTRY_NAME
, INCLUDE_REGISTRY_NAME
);
6575 ret
= do_parameter("registry shares", "yes", NULL
);
6580 return process_registry_service(GLOBAL_NAME
);
6583 bool process_registry_shares(void)
6587 struct smbconf_service
**service
= NULL
;
6588 uint32_t num_shares
= 0;
6589 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
6590 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
6593 if (conf_ctx
== NULL
) {
6597 err
= smbconf_get_config(conf_ctx
, mem_ctx
, &num_shares
, &service
);
6598 if (!SBC_ERROR_IS_OK(err
)) {
6604 for (count
= 0; count
< num_shares
; count
++) {
6605 if (strequal(service
[count
]->name
, GLOBAL_NAME
)) {
6608 ret
= process_smbconf_service(service
[count
]);
6615 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
6618 TALLOC_FREE(mem_ctx
);
6623 * reload those shares from registry that are already
6624 * activated in the services array.
6626 static bool reload_registry_shares(void)
6631 for (i
= 0; i
< iNumServices
; i
++) {
6636 if (ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
6640 ret
= process_registry_service(ServicePtrs
[i
]->szService
);
6651 #define MAX_INCLUDE_DEPTH 100
6653 static uint8_t include_depth
;
6655 static struct file_lists
{
6656 struct file_lists
*next
;
6660 } *file_lists
= NULL
;
6662 /*******************************************************************
6663 Keep a linked list of all config files so we know when one has changed
6664 it's date and needs to be reloaded.
6665 ********************************************************************/
6667 static void add_to_file_list(const char *fname
, const char *subfname
)
6669 struct file_lists
*f
= file_lists
;
6672 if (f
->name
&& !strcmp(f
->name
, fname
))
6678 f
= SMB_MALLOC_P(struct file_lists
);
6681 f
->next
= file_lists
;
6682 f
->name
= SMB_STRDUP(fname
);
6687 f
->subfname
= SMB_STRDUP(subfname
);
6694 f
->modtime
= file_modtime(subfname
);
6696 time_t t
= file_modtime(subfname
);
6704 * Free the file lists
6706 static void free_file_list(void)
6708 struct file_lists
*f
;
6709 struct file_lists
*next
;
6714 SAFE_FREE( f
->name
);
6715 SAFE_FREE( f
->subfname
);
6724 * Utility function for outsiders to check if we're running on registry.
6726 bool lp_config_backend_is_registry(void)
6728 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY
);
6732 * Utility function to check if the config backend is FILE.
6734 bool lp_config_backend_is_file(void)
6736 return (lp_config_backend() == CONFIG_BACKEND_FILE
);
6739 /*******************************************************************
6740 Check if a config file has changed date.
6741 ********************************************************************/
6743 bool lp_file_list_changed(void)
6745 struct file_lists
*f
= file_lists
;
6747 DEBUG(6, ("lp_file_list_changed()\n"));
6752 if (strequal(f
->name
, INCLUDE_REGISTRY_NAME
)) {
6753 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
6755 if (conf_ctx
== NULL
) {
6758 if (smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
,
6761 DEBUGADD(6, ("registry config changed\n"));
6766 n2
= talloc_sub_basic(talloc_tos(),
6767 get_current_username(),
6768 current_user_info
.domain
,
6773 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6774 f
->name
, n2
, ctime(&f
->modtime
)));
6776 mod_time
= file_modtime(n2
);
6779 ((f
->modtime
!= mod_time
) ||
6780 (f
->subfname
== NULL
) ||
6781 (strcmp(n2
, f
->subfname
) != 0)))
6784 ("file %s modified: %s\n", n2
,
6786 f
->modtime
= mod_time
;
6787 SAFE_FREE(f
->subfname
);
6788 f
->subfname
= SMB_STRDUP(n2
);
6801 * Initialize iconv conversion descriptors.
6803 * This is called the first time it is needed, and also called again
6804 * every time the configuration is reloaded, because the charset or
6805 * codepage might have changed.
6807 static void init_iconv(void)
6809 global_iconv_handle
= smb_iconv_handle_reinit(NULL
, lp_dos_charset(),
6811 true, global_iconv_handle
);
6814 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
6816 if (strcmp(*ptr
, pszParmValue
) != 0) {
6817 string_set(ptr
, pszParmValue
);
6823 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
6825 bool is_utf8
= false;
6826 size_t len
= strlen(pszParmValue
);
6828 if (len
== 4 || len
== 5) {
6829 /* Don't use StrCaseCmp here as we don't want to
6830 initialize iconv. */
6831 if ((toupper_m(pszParmValue
[0]) == 'U') &&
6832 (toupper_m(pszParmValue
[1]) == 'T') &&
6833 (toupper_m(pszParmValue
[2]) == 'F')) {
6835 if (pszParmValue
[3] == '8') {
6839 if (pszParmValue
[3] == '-' &&
6840 pszParmValue
[4] == '8') {
6847 if (strcmp(*ptr
, pszParmValue
) != 0) {
6849 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
6850 "be UTF8, using (default value) %s instead.\n",
6851 DEFAULT_DOS_CHARSET
));
6852 pszParmValue
= DEFAULT_DOS_CHARSET
;
6854 string_set(ptr
, pszParmValue
);
6860 static bool handle_realm(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
6863 char *realm
= strupper_talloc(talloc_tos(), pszParmValue
);
6864 char *dnsdomain
= strlower_talloc(realm
, pszParmValue
);
6866 ret
&= string_set(&Globals
.szRealm
, pszParmValue
);
6867 ret
&= string_set(&Globals
.szRealm_upper
, realm
);
6868 ret
&= string_set(&Globals
.szRealm_lower
, dnsdomain
);
6874 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
6876 TALLOC_FREE(Globals
.szNetbiosAliases
);
6877 Globals
.szNetbiosAliases
= (const char **)str_list_make_v3(NULL
, pszParmValue
, NULL
);
6878 return set_netbios_aliases(Globals
.szNetbiosAliases
);
6881 /***************************************************************************
6882 Handle the include operation.
6883 ***************************************************************************/
6884 static bool bAllowIncludeRegistry
= true;
6886 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
6890 if (include_depth
>= MAX_INCLUDE_DEPTH
) {
6891 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
6896 if (strequal(pszParmValue
, INCLUDE_REGISTRY_NAME
)) {
6897 if (!bAllowIncludeRegistry
) {
6900 if (bInGlobalSection
) {
6903 ret
= process_registry_globals();
6907 DEBUG(1, ("\"include = registry\" only effective "
6908 "in %s section\n", GLOBAL_NAME
));
6913 fname
= talloc_sub_basic(talloc_tos(), get_current_username(),
6914 current_user_info
.domain
,
6917 add_to_file_list(pszParmValue
, fname
);
6919 string_set(ptr
, fname
);
6921 if (file_exist(fname
)) {
6924 ret
= pm_process(fname
, do_section
, do_parameter
, NULL
);
6930 DEBUG(2, ("Can't find include file %s\n", fname
));
6935 /***************************************************************************
6936 Handle the interpretation of the copy parameter.
6937 ***************************************************************************/
6939 static bool handle_copy(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
6943 struct loadparm_service serviceTemp
;
6945 string_set(ptr
, pszParmValue
);
6947 init_service(&serviceTemp
);
6951 DEBUG(3, ("Copying service from service %s\n", pszParmValue
));
6953 if ((iTemp
= getservicebyname(pszParmValue
, &serviceTemp
)) >= 0) {
6954 if (iTemp
== iServiceIndex
) {
6955 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue
));
6957 copy_service(ServicePtrs
[iServiceIndex
],
6959 ServicePtrs
[iServiceIndex
]->copymap
);
6963 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue
));
6967 free_service(&serviceTemp
);
6971 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
6973 Globals
.ldap_debug_level
= lp_int(pszParmValue
);
6974 init_ldap_debugging();
6978 /***************************************************************************
6979 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6984 idmap uid = 1000-1999
6987 We only do simple parsing checks here. The strings are parsed into useful
6988 structures in the idmap daemon code.
6990 ***************************************************************************/
6992 /* Some lp_ routines to return idmap [ug]id information */
6994 static uid_t idmap_uid_low
, idmap_uid_high
;
6995 static gid_t idmap_gid_low
, idmap_gid_high
;
6997 bool lp_idmap_uid(uid_t
*low
, uid_t
*high
)
6999 if (idmap_uid_low
== 0 || idmap_uid_high
== 0)
7003 *low
= idmap_uid_low
;
7006 *high
= idmap_uid_high
;
7011 bool lp_idmap_gid(gid_t
*low
, gid_t
*high
)
7013 if (idmap_gid_low
== 0 || idmap_gid_high
== 0)
7017 *low
= idmap_gid_low
;
7020 *high
= idmap_gid_high
;
7025 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7027 lp_do_parameter(snum
, "idmap config * : backend", pszParmValue
);
7032 /* Do some simple checks on "idmap [ug]id" parameter values */
7034 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7036 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
7041 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7043 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
7048 /***************************************************************************
7049 Handle the DEBUG level list.
7050 ***************************************************************************/
7052 static bool handle_debug_list(struct loadparm_context
*unused
, int snum
, const char *pszParmValueIn
, char **ptr
)
7054 string_set(ptr
, pszParmValueIn
);
7055 return debug_parse_levels(pszParmValueIn
);
7058 /***************************************************************************
7059 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7060 ***************************************************************************/
7062 static const char *append_ldap_suffix(TALLOC_CTX
*ctx
, const char *str
)
7064 const char *suffix_string
;
7066 suffix_string
= talloc_asprintf(ctx
, "%s,%s", str
,
7067 Globals
.szLdapSuffix
);
7068 if ( !suffix_string
) {
7069 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7073 return suffix_string
;
7076 const char *lp_ldap_machine_suffix(TALLOC_CTX
*ctx
)
7078 if (Globals
.szLdapMachineSuffix
[0])
7079 return append_ldap_suffix(ctx
, Globals
.szLdapMachineSuffix
);
7081 return lp_string(ctx
, Globals
.szLdapSuffix
);
7084 const char *lp_ldap_user_suffix(TALLOC_CTX
*ctx
)
7086 if (Globals
.szLdapUserSuffix
[0])
7087 return append_ldap_suffix(ctx
, Globals
.szLdapUserSuffix
);
7089 return lp_string(ctx
, Globals
.szLdapSuffix
);
7092 const char *lp_ldap_group_suffix(TALLOC_CTX
*ctx
)
7094 if (Globals
.szLdapGroupSuffix
[0])
7095 return append_ldap_suffix(ctx
, Globals
.szLdapGroupSuffix
);
7097 return lp_string(ctx
, Globals
.szLdapSuffix
);
7100 const char *lp_ldap_idmap_suffix(TALLOC_CTX
*ctx
)
7102 if (Globals
.szLdapIdmapSuffix
[0])
7103 return append_ldap_suffix(ctx
, Globals
.szLdapIdmapSuffix
);
7105 return lp_string(ctx
, Globals
.szLdapSuffix
);
7108 /****************************************************************************
7109 set the value for a P_ENUM
7110 ***************************************************************************/
7112 static void lp_set_enum_parm( struct parm_struct
*parm
, const char *pszParmValue
,
7117 for (i
= 0; parm
->enum_list
[i
].name
; i
++) {
7118 if ( strequal(pszParmValue
, parm
->enum_list
[i
].name
)) {
7119 *ptr
= parm
->enum_list
[i
].value
;
7123 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7124 pszParmValue
, parm
->label
));
7127 /***************************************************************************
7128 ***************************************************************************/
7130 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7132 static int parm_num
= -1;
7133 struct loadparm_service
*s
;
7135 if ( parm_num
== -1 )
7136 parm_num
= map_parameter( "printing" );
7138 lp_set_enum_parm( &parm_table
[parm_num
], pszParmValue
, (int*)ptr
);
7143 s
= ServicePtrs
[snum
];
7145 init_printer_values( s
);
7151 /***************************************************************************
7152 Initialise a copymap.
7153 ***************************************************************************/
7155 static void init_copymap(struct loadparm_service
*pservice
)
7159 TALLOC_FREE(pservice
->copymap
);
7161 pservice
->copymap
= bitmap_talloc(NULL
, NUMPARAMETERS
);
7162 if (!pservice
->copymap
)
7164 ("Couldn't allocate copymap!! (size %d)\n",
7165 (int)NUMPARAMETERS
));
7167 for (i
= 0; i
< NUMPARAMETERS
; i
++)
7168 bitmap_set(pservice
->copymap
, i
);
7172 return the parameter pointer for a parameter
7174 void *lp_parm_ptr(struct loadparm_service
*service
, struct parm_struct
*parm
)
7176 if (service
== NULL
) {
7177 if (parm
->p_class
== P_LOCAL
)
7178 return (void *)(((char *)&sDefault
)+parm
->offset
);
7179 else if (parm
->p_class
== P_GLOBAL
)
7180 return (void *)(((char *)&Globals
)+parm
->offset
);
7183 return (void *)(((char *)service
) + parm
->offset
);
7187 /***************************************************************************
7188 Return the local pointer to a parameter given the service number and parameter
7189 ***************************************************************************/
7191 void *lp_local_ptr_by_snum(int snum
, struct parm_struct
*parm
)
7193 return lp_parm_ptr(ServicePtrs
[snum
], parm
);
7196 /***************************************************************************
7197 Process a parameter for a particular service number. If snum < 0
7198 then assume we are in the globals.
7199 ***************************************************************************/
7201 bool lp_do_parameter(int snum
, const char *pszParmName
, const char *pszParmValue
)
7204 void *parm_ptr
= NULL
; /* where we are going to store the result */
7205 struct parmlist_entry
**opt_list
;
7207 parmnum
= map_parameter(pszParmName
);
7210 if (strchr(pszParmName
, ':') == NULL
) {
7211 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7217 * We've got a parametric option
7220 opt_list
= (snum
< 0)
7221 ? &Globals
.param_opt
: &ServicePtrs
[snum
]->param_opt
;
7222 set_param_opt(opt_list
, pszParmName
, pszParmValue
, 0);
7227 /* if it's already been set by the command line, then we don't
7229 if (parm_table
[parmnum
].flags
& FLAG_CMDLINE
) {
7233 if (parm_table
[parmnum
].flags
& FLAG_DEPRECATED
) {
7234 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7238 /* we might point at a service, the default service or a global */
7240 parm_ptr
= lp_parm_ptr(NULL
, &parm_table
[parmnum
]);
7242 if (parm_table
[parmnum
].p_class
== P_GLOBAL
) {
7244 ("Global parameter %s found in service section!\n",
7248 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm_table
[parmnum
]);
7252 if (!ServicePtrs
[snum
]->copymap
)
7253 init_copymap(ServicePtrs
[snum
]);
7255 /* this handles the aliases - set the copymap for other entries with
7256 the same data pointer */
7257 for (i
= 0; parm_table
[i
].label
; i
++) {
7258 if ((parm_table
[i
].offset
== parm_table
[parmnum
].offset
)
7259 && (parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
)) {
7260 bitmap_clear(ServicePtrs
[snum
]->copymap
, i
);
7265 /* if it is a special case then go ahead */
7266 if (parm_table
[parmnum
].special
) {
7267 return parm_table
[parmnum
].special(NULL
, snum
, pszParmValue
,
7271 /* now switch on the type of variable it is */
7272 switch (parm_table
[parmnum
].type
)
7275 *(bool *)parm_ptr
= lp_bool(pszParmValue
);
7279 *(bool *)parm_ptr
= !lp_bool(pszParmValue
);
7283 *(int *)parm_ptr
= lp_int(pszParmValue
);
7287 *(char *)parm_ptr
= *pszParmValue
;
7291 i
= sscanf(pszParmValue
, "%o", (int *)parm_ptr
);
7293 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName
));
7300 if (conv_str_size_error(pszParmValue
, &val
)) {
7301 if (val
<= INT_MAX
) {
7302 *(int *)parm_ptr
= (int)val
;
7307 DEBUG(0,("lp_do_parameter(%s): value is not "
7308 "a valid size specifier!\n", pszParmValue
));
7314 TALLOC_FREE(*((char ***)parm_ptr
));
7315 *(char ***)parm_ptr
= str_list_make_v3(
7316 NULL
, pszParmValue
, NULL
);
7320 string_set((char **)parm_ptr
, pszParmValue
);
7325 char *upper_string
= strupper_talloc(talloc_tos(),
7327 string_set((char **)parm_ptr
, upper_string
);
7328 TALLOC_FREE(upper_string
);
7332 lp_set_enum_parm( &parm_table
[parmnum
], pszParmValue
, (int*)parm_ptr
);
7341 /***************************************************************************
7342 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7343 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7344 ***************************************************************************/
7346 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
)
7349 parmnum
= map_parameter(pszParmName
);
7351 parm_table
[parmnum
].flags
&= ~FLAG_CMDLINE
;
7352 if (!lp_do_parameter(-1, pszParmName
, pszParmValue
)) {
7355 parm_table
[parmnum
].flags
|= FLAG_CMDLINE
;
7357 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7358 * be grouped in the table, so we don't have to search the
7361 i
>=0 && parm_table
[i
].offset
== parm_table
[parmnum
].offset
7362 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;
7364 parm_table
[i
].flags
|= FLAG_CMDLINE
;
7366 for (i
=parmnum
+1;i
<NUMPARAMETERS
&& parm_table
[i
].offset
== parm_table
[parmnum
].offset
7367 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;i
++) {
7368 parm_table
[i
].flags
|= FLAG_CMDLINE
;
7372 store_lp_set_cmdline(pszParmName
, pszParmValue
);
7377 /* it might be parametric */
7378 if (strchr(pszParmName
, ':') != NULL
) {
7379 set_param_opt(&Globals
.param_opt
, pszParmName
, pszParmValue
, FLAG_CMDLINE
);
7381 store_lp_set_cmdline(pszParmName
, pszParmValue
);
7386 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName
));
7390 bool lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
7392 return lp_set_cmdline_helper(pszParmName
, pszParmValue
, true);
7395 /***************************************************************************
7396 Process a parameter.
7397 ***************************************************************************/
7399 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
7402 if (!bInGlobalSection
&& bGlobalOnly
)
7405 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName
, pszParmValue
));
7407 return (lp_do_parameter(bInGlobalSection
? -2 : iServiceIndex
,
7408 pszParmName
, pszParmValue
));
7412 set a option from the commandline in 'a=b' format. Use to support --option
7414 bool lp_set_option(const char *option
)
7419 s
= talloc_strdup(NULL
, option
);
7432 /* skip white spaces after the = sign */
7435 } while (*p
== ' ');
7437 ret
= lp_set_cmdline(s
, p
);
7442 /**************************************************************************
7443 Print a parameter of the specified type.
7444 ***************************************************************************/
7446 static void print_parameter(struct parm_struct
*p
, void *ptr
, FILE * f
)
7448 /* For the seperation of lists values that we print below */
7449 const char *list_sep
= ", ";
7454 for (i
= 0; p
->enum_list
[i
].name
; i
++) {
7455 if (*(int *)ptr
== p
->enum_list
[i
].value
) {
7457 p
->enum_list
[i
].name
);
7464 fprintf(f
, "%s", BOOLSTR(*(bool *)ptr
));
7468 fprintf(f
, "%s", BOOLSTR(!*(bool *)ptr
));
7473 fprintf(f
, "%d", *(int *)ptr
);
7477 fprintf(f
, "%c", *(char *)ptr
);
7481 int val
= *(int *)ptr
;
7485 fprintf(f
, "0%o", val
);
7494 if ((char ***)ptr
&& *(char ***)ptr
) {
7495 char **list
= *(char ***)ptr
;
7496 for (; *list
; list
++) {
7497 /* surround strings with whitespace in double quotes */
7498 if (*(list
+1) == NULL
) {
7499 /* last item, no extra separator */
7502 if ( strchr_m( *list
, ' ' ) ) {
7503 fprintf(f
, "\"%s\"%s", *list
, list_sep
);
7505 fprintf(f
, "%s%s", *list
, list_sep
);
7513 if (*(char **)ptr
) {
7514 fprintf(f
, "%s", *(char **)ptr
);
7522 /***************************************************************************
7523 Check if two parameters are equal.
7524 ***************************************************************************/
7526 static bool equal_parameter(parm_type type
, void *ptr1
, void *ptr2
)
7531 return (*((bool *)ptr1
) == *((bool *)ptr2
));
7537 return (*((int *)ptr1
) == *((int *)ptr2
));
7540 return (*((char *)ptr1
) == *((char *)ptr2
));
7544 return str_list_equal(*(const char ***)ptr1
, *(const char ***)ptr2
);
7549 char *p1
= *(char **)ptr1
, *p2
= *(char **)ptr2
;
7554 return (p1
== p2
|| strequal(p1
, p2
));
7562 /***************************************************************************
7563 Initialize any local varients in the sDefault table.
7564 ***************************************************************************/
7566 void init_locals(void)
7571 /***************************************************************************
7572 Process a new section (service). At this stage all sections are services.
7573 Later we'll have special sections that permit server parameters to be set.
7574 Returns true on success, false on failure.
7575 ***************************************************************************/
7577 static bool do_section(const char *pszSectionName
, void *userdata
)
7580 bool isglobal
= ((strwicmp(pszSectionName
, GLOBAL_NAME
) == 0) ||
7581 (strwicmp(pszSectionName
, GLOBAL_NAME2
) == 0));
7584 /* if we were in a global section then do the local inits */
7585 if (bInGlobalSection
&& !isglobal
)
7588 /* if we've just struck a global section, note the fact. */
7589 bInGlobalSection
= isglobal
;
7591 /* check for multiple global sections */
7592 if (bInGlobalSection
) {
7593 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName
));
7597 if (!bInGlobalSection
&& bGlobalOnly
)
7600 /* if we have a current service, tidy it up before moving on */
7603 if (iServiceIndex
>= 0)
7604 bRetval
= service_ok(iServiceIndex
);
7606 /* if all is still well, move to the next record in the services array */
7608 /* We put this here to avoid an odd message order if messages are */
7609 /* issued by the post-processing of a previous section. */
7610 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName
));
7612 iServiceIndex
= add_a_service(&sDefault
, pszSectionName
);
7613 if (iServiceIndex
< 0) {
7614 DEBUG(0, ("Failed to add a new service\n"));
7617 /* Clean all parametric options for service */
7618 /* They will be added during parsing again */
7619 free_param_opts(&ServicePtrs
[iServiceIndex
]->param_opt
);
7626 /***************************************************************************
7627 Determine if a partcular base parameter is currentl set to the default value.
7628 ***************************************************************************/
7630 static bool is_default(int i
)
7632 if (!defaults_saved
)
7634 switch (parm_table
[i
].type
) {
7637 return str_list_equal((const char **)parm_table
[i
].def
.lvalue
,
7638 *(const char ***)lp_parm_ptr(NULL
,
7642 return strequal(parm_table
[i
].def
.svalue
,
7643 *(char **)lp_parm_ptr(NULL
,
7647 return parm_table
[i
].def
.bvalue
==
7648 *(bool *)lp_parm_ptr(NULL
,
7651 return parm_table
[i
].def
.cvalue
==
7652 *(char *)lp_parm_ptr(NULL
,
7658 return parm_table
[i
].def
.ivalue
==
7659 *(int *)lp_parm_ptr(NULL
,
7667 /***************************************************************************
7668 Display the contents of the global structure.
7669 ***************************************************************************/
7671 static void dump_globals(FILE *f
)
7674 struct parmlist_entry
*data
;
7676 fprintf(f
, "[global]\n");
7678 for (i
= 0; parm_table
[i
].label
; i
++)
7679 if (parm_table
[i
].p_class
== P_GLOBAL
&&
7680 !(parm_table
[i
].flags
& FLAG_META
) &&
7681 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
))) {
7682 if (defaults_saved
&& is_default(i
))
7684 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
7685 print_parameter(&parm_table
[i
], lp_parm_ptr(NULL
,
7690 if (Globals
.param_opt
!= NULL
) {
7691 data
= Globals
.param_opt
;
7693 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
7700 /***************************************************************************
7701 Return true if a local parameter is currently set to the global default.
7702 ***************************************************************************/
7704 bool lp_is_default(int snum
, struct parm_struct
*parm
)
7706 return equal_parameter(parm
->type
,
7707 lp_parm_ptr(ServicePtrs
[snum
], parm
),
7708 lp_parm_ptr(NULL
, parm
));
7711 /***************************************************************************
7712 Display the contents of a single services record.
7713 ***************************************************************************/
7715 static void dump_a_service(struct loadparm_service
*pService
, FILE * f
)
7718 struct parmlist_entry
*data
;
7720 if (pService
!= &sDefault
)
7721 fprintf(f
, "[%s]\n", pService
->szService
);
7723 for (i
= 0; parm_table
[i
].label
; i
++) {
7725 if (parm_table
[i
].p_class
== P_LOCAL
&&
7726 !(parm_table
[i
].flags
& FLAG_META
) &&
7727 (*parm_table
[i
].label
!= '-') &&
7728 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
)))
7730 if (pService
== &sDefault
) {
7731 if (defaults_saved
&& is_default(i
))
7734 if (equal_parameter(parm_table
[i
].type
,
7735 lp_parm_ptr(pService
, &parm_table
[i
]),
7736 lp_parm_ptr(NULL
, &parm_table
[i
])))
7740 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
7741 print_parameter(&parm_table
[i
],
7742 lp_parm_ptr(pService
, &parm_table
[i
]),
7748 if (pService
->param_opt
!= NULL
) {
7749 data
= pService
->param_opt
;
7751 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
7757 /***************************************************************************
7758 Display the contents of a parameter of a single services record.
7759 ***************************************************************************/
7761 bool dump_a_parameter(int snum
, char *parm_name
, FILE * f
, bool isGlobal
)
7764 bool result
= false;
7767 fstring local_parm_name
;
7769 const char *parm_opt_value
;
7771 /* check for parametrical option */
7772 fstrcpy( local_parm_name
, parm_name
);
7773 parm_opt
= strchr( local_parm_name
, ':');
7778 if (strlen(parm_opt
)) {
7779 parm_opt_value
= lp_parm_const_string( snum
,
7780 local_parm_name
, parm_opt
, NULL
);
7781 if (parm_opt_value
) {
7782 printf( "%s\n", parm_opt_value
);
7789 /* check for a key and print the value */
7796 for (i
= 0; parm_table
[i
].label
; i
++) {
7797 if (strwicmp(parm_table
[i
].label
, parm_name
) == 0 &&
7798 !(parm_table
[i
].flags
& FLAG_META
) &&
7799 (parm_table
[i
].p_class
== p_class
|| parm_table
[i
].flags
& flag
) &&
7800 (*parm_table
[i
].label
!= '-') &&
7801 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
)))
7806 ptr
= lp_parm_ptr(NULL
,
7809 ptr
= lp_parm_ptr(ServicePtrs
[snum
],
7813 print_parameter(&parm_table
[i
],
7824 /***************************************************************************
7825 Return info about the requested parameter (given as a string).
7826 Return NULL when the string is not a valid parameter name.
7827 ***************************************************************************/
7829 struct parm_struct
*lp_get_parameter(const char *param_name
)
7831 int num
= map_parameter(param_name
);
7837 return &parm_table
[num
];
7840 /***************************************************************************
7841 Return info about the next parameter in a service.
7842 snum==GLOBAL_SECTION_SNUM gives the globals.
7843 Return NULL when out of parameters.
7844 ***************************************************************************/
7846 struct parm_struct
*lp_next_parameter(int snum
, int *i
, int allparameters
)
7849 /* do the globals */
7850 for (; parm_table
[*i
].label
; (*i
)++) {
7851 if (parm_table
[*i
].p_class
== P_SEPARATOR
)
7852 return &parm_table
[(*i
)++];
7854 if ((*parm_table
[*i
].label
== '-'))
7858 && (parm_table
[*i
].offset
==
7859 parm_table
[(*i
) - 1].offset
)
7860 && (parm_table
[*i
].p_class
==
7861 parm_table
[(*i
) - 1].p_class
))
7864 if (is_default(*i
) && !allparameters
)
7867 return &parm_table
[(*i
)++];
7870 struct loadparm_service
*pService
= ServicePtrs
[snum
];
7872 for (; parm_table
[*i
].label
; (*i
)++) {
7873 if (parm_table
[*i
].p_class
== P_SEPARATOR
)
7874 return &parm_table
[(*i
)++];
7876 if (parm_table
[*i
].p_class
== P_LOCAL
&&
7877 (*parm_table
[*i
].label
!= '-') &&
7879 (parm_table
[*i
].offset
!=
7880 parm_table
[(*i
) - 1].offset
)))
7882 if (allparameters
||
7883 !equal_parameter(parm_table
[*i
].type
,
7884 lp_parm_ptr(pService
,
7889 return &parm_table
[(*i
)++];
7900 /***************************************************************************
7901 Display the contents of a single copy structure.
7902 ***************************************************************************/
7903 static void dump_copy_map(bool *pcopymap
)
7909 printf("\n\tNon-Copied parameters:\n");
7911 for (i
= 0; parm_table
[i
].label
; i
++)
7912 if (parm_table
[i
].p_class
== P_LOCAL
&&
7913 parm_table
[i
].ptr
&& !pcopymap
[i
] &&
7914 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
- 1].ptr
)))
7916 printf("\t\t%s\n", parm_table
[i
].label
);
7921 /***************************************************************************
7922 Return TRUE if the passed service number is within range.
7923 ***************************************************************************/
7925 bool lp_snum_ok(int iService
)
7927 return (LP_SNUM_OK(iService
) && ServicePtrs
[iService
]->bAvailable
);
7930 /***************************************************************************
7931 Auto-load some home services.
7932 ***************************************************************************/
7934 static void lp_add_auto_services(char *str
)
7944 s
= SMB_STRDUP(str
);
7948 homes
= lp_servicenumber(HOMES_NAME
);
7950 for (p
= strtok_r(s
, LIST_SEP
, &saveptr
); p
;
7951 p
= strtok_r(NULL
, LIST_SEP
, &saveptr
)) {
7954 if (lp_servicenumber(p
) >= 0)
7957 home
= get_user_home_dir(talloc_tos(), p
);
7959 if (home
&& home
[0] && homes
>= 0)
7960 lp_add_home(p
, homes
, p
, home
);
7967 /***************************************************************************
7968 Auto-load one printer.
7969 ***************************************************************************/
7971 void lp_add_one_printer(const char *name
, const char *comment
,
7972 const char *location
, void *pdata
)
7974 int printers
= lp_servicenumber(PRINTERS_NAME
);
7977 if (lp_servicenumber(name
) < 0) {
7978 lp_add_printer(name
, printers
);
7979 if ((i
= lp_servicenumber(name
)) >= 0) {
7980 string_set(&ServicePtrs
[i
]->comment
, comment
);
7981 ServicePtrs
[i
]->autoloaded
= true;
7986 /***************************************************************************
7987 Have we loaded a services file yet?
7988 ***************************************************************************/
7990 bool lp_loaded(void)
7995 /***************************************************************************
7996 Unload unused services.
7997 ***************************************************************************/
7999 void lp_killunused(struct smbd_server_connection
*sconn
,
8000 bool (*snumused
) (struct smbd_server_connection
*, int))
8003 for (i
= 0; i
< iNumServices
; i
++) {
8007 /* don't kill autoloaded or usershare services */
8008 if ( ServicePtrs
[i
]->autoloaded
||
8009 ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
8013 if (!snumused
|| !snumused(sconn
, i
)) {
8014 free_service_byindex(i
);
8020 * Kill all except autoloaded and usershare services - convenience wrapper
8022 void lp_kill_all_services(void)
8024 lp_killunused(NULL
, NULL
);
8027 /***************************************************************************
8029 ***************************************************************************/
8031 void lp_killservice(int iServiceIn
)
8033 if (VALID(iServiceIn
)) {
8034 free_service_byindex(iServiceIn
);
8038 /***************************************************************************
8039 Save the curent values of all global and sDefault parameters into the
8040 defaults union. This allows swat and testparm to show only the
8041 changed (ie. non-default) parameters.
8042 ***************************************************************************/
8044 static void lp_save_defaults(void)
8047 for (i
= 0; parm_table
[i
].label
; i
++) {
8048 if (i
> 0 && parm_table
[i
].offset
== parm_table
[i
- 1].offset
8049 && parm_table
[i
].p_class
== parm_table
[i
- 1].p_class
)
8051 switch (parm_table
[i
].type
) {
8054 parm_table
[i
].def
.lvalue
= str_list_copy(
8055 NULL
, *(const char ***)lp_parm_ptr(NULL
, &parm_table
[i
]));
8059 parm_table
[i
].def
.svalue
= SMB_STRDUP(*(char **)lp_parm_ptr(NULL
, &parm_table
[i
]));
8063 parm_table
[i
].def
.bvalue
=
8064 *(bool *)lp_parm_ptr(NULL
, &parm_table
[i
]);
8067 parm_table
[i
].def
.cvalue
=
8068 *(char *)lp_parm_ptr(NULL
, &parm_table
[i
]);
8074 parm_table
[i
].def
.ivalue
=
8075 *(int *)lp_parm_ptr(NULL
, &parm_table
[i
]);
8081 defaults_saved
= true;
8084 /***********************************************************
8085 If we should send plaintext/LANMAN passwords in the clinet
8086 ************************************************************/
8088 static void set_allowed_client_auth(void)
8090 if (Globals
.bClientNTLMv2Auth
) {
8091 Globals
.bClientLanManAuth
= false;
8093 if (!Globals
.bClientLanManAuth
) {
8094 Globals
.bClientPlaintextAuth
= false;
8098 /***************************************************************************
8100 The following code allows smbd to read a user defined share file.
8101 Yes, this is my intent. Yes, I'm comfortable with that...
8103 THE FOLLOWING IS SECURITY CRITICAL CODE.
8105 It washes your clothes, it cleans your house, it guards you while you sleep...
8106 Do not f%^k with it....
8107 ***************************************************************************/
8109 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8111 /***************************************************************************
8112 Check allowed stat state of a usershare file.
8113 Ensure we print out who is dicking with us so the admin can
8114 get their sorry ass fired.
8115 ***************************************************************************/
8117 static bool check_usershare_stat(const char *fname
,
8118 const SMB_STRUCT_STAT
*psbuf
)
8120 if (!S_ISREG(psbuf
->st_ex_mode
)) {
8121 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8122 "not a regular file\n",
8123 fname
, (unsigned int)psbuf
->st_ex_uid
));
8127 /* Ensure this doesn't have the other write bit set. */
8128 if (psbuf
->st_ex_mode
& S_IWOTH
) {
8129 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8130 "public write. Refusing to allow as a usershare file.\n",
8131 fname
, (unsigned int)psbuf
->st_ex_uid
));
8135 /* Should be 10k or less. */
8136 if (psbuf
->st_ex_size
> MAX_USERSHARE_FILE_SIZE
) {
8137 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8138 "too large (%u) to be a user share file.\n",
8139 fname
, (unsigned int)psbuf
->st_ex_uid
,
8140 (unsigned int)psbuf
->st_ex_size
));
8147 /***************************************************************************
8148 Parse the contents of a usershare file.
8149 ***************************************************************************/
8151 enum usershare_err
parse_usershare_file(TALLOC_CTX
*ctx
,
8152 SMB_STRUCT_STAT
*psbuf
,
8153 const char *servicename
,
8157 char **pp_sharepath
,
8159 char **pp_cp_servicename
,
8160 struct security_descriptor
**ppsd
,
8163 const char **prefixallowlist
= lp_usershare_prefix_allow_list();
8164 const char **prefixdenylist
= lp_usershare_prefix_deny_list();
8167 SMB_STRUCT_STAT sbuf
;
8168 char *sharepath
= NULL
;
8169 char *comment
= NULL
;
8171 *pp_sharepath
= NULL
;
8174 *pallow_guest
= false;
8177 return USERSHARE_MALFORMED_FILE
;
8180 if (strcmp(lines
[0], "#VERSION 1") == 0) {
8182 } else if (strcmp(lines
[0], "#VERSION 2") == 0) {
8185 return USERSHARE_MALFORMED_FILE
;
8188 return USERSHARE_BAD_VERSION
;
8191 if (strncmp(lines
[1], "path=", 5) != 0) {
8192 return USERSHARE_MALFORMED_PATH
;
8195 sharepath
= talloc_strdup(ctx
, &lines
[1][5]);
8197 return USERSHARE_POSIX_ERR
;
8199 trim_string(sharepath
, " ", " ");
8201 if (strncmp(lines
[2], "comment=", 8) != 0) {
8202 return USERSHARE_MALFORMED_COMMENT_DEF
;
8205 comment
= talloc_strdup(ctx
, &lines
[2][8]);
8207 return USERSHARE_POSIX_ERR
;
8209 trim_string(comment
, " ", " ");
8210 trim_char(comment
, '"', '"');
8212 if (strncmp(lines
[3], "usershare_acl=", 14) != 0) {
8213 return USERSHARE_MALFORMED_ACL_DEF
;
8216 if (!parse_usershare_acl(ctx
, &lines
[3][14], ppsd
)) {
8217 return USERSHARE_ACL_ERR
;
8221 if (strncmp(lines
[4], "guest_ok=", 9) != 0) {
8222 return USERSHARE_MALFORMED_ACL_DEF
;
8224 if (lines
[4][9] == 'y') {
8225 *pallow_guest
= true;
8228 /* Backwards compatible extension to file version #2. */
8230 if (strncmp(lines
[5], "sharename=", 10) != 0) {
8231 return USERSHARE_MALFORMED_SHARENAME_DEF
;
8233 if (!strequal(&lines
[5][10], servicename
)) {
8234 return USERSHARE_BAD_SHARENAME
;
8236 *pp_cp_servicename
= talloc_strdup(ctx
, &lines
[5][10]);
8237 if (!*pp_cp_servicename
) {
8238 return USERSHARE_POSIX_ERR
;
8243 if (*pp_cp_servicename
== NULL
) {
8244 *pp_cp_servicename
= talloc_strdup(ctx
, servicename
);
8245 if (!*pp_cp_servicename
) {
8246 return USERSHARE_POSIX_ERR
;
8250 if (snum
!= -1 && (strcmp(sharepath
, ServicePtrs
[snum
]->szPath
) == 0)) {
8251 /* Path didn't change, no checks needed. */
8252 *pp_sharepath
= sharepath
;
8253 *pp_comment
= comment
;
8254 return USERSHARE_OK
;
8257 /* The path *must* be absolute. */
8258 if (sharepath
[0] != '/') {
8259 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8260 servicename
, sharepath
));
8261 return USERSHARE_PATH_NOT_ABSOLUTE
;
8264 /* If there is a usershare prefix deny list ensure one of these paths
8265 doesn't match the start of the user given path. */
8266 if (prefixdenylist
) {
8268 for ( i
=0; prefixdenylist
[i
]; i
++ ) {
8269 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8270 servicename
, i
, prefixdenylist
[i
], sharepath
));
8271 if (memcmp( sharepath
, prefixdenylist
[i
], strlen(prefixdenylist
[i
])) == 0) {
8272 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8273 "usershare prefix deny list entries.\n",
8274 servicename
, sharepath
));
8275 return USERSHARE_PATH_IS_DENIED
;
8280 /* If there is a usershare prefix allow list ensure one of these paths
8281 does match the start of the user given path. */
8283 if (prefixallowlist
) {
8285 for ( i
=0; prefixallowlist
[i
]; i
++ ) {
8286 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8287 servicename
, i
, prefixallowlist
[i
], sharepath
));
8288 if (memcmp( sharepath
, prefixallowlist
[i
], strlen(prefixallowlist
[i
])) == 0) {
8292 if (prefixallowlist
[i
] == NULL
) {
8293 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8294 "usershare prefix allow list entries.\n",
8295 servicename
, sharepath
));
8296 return USERSHARE_PATH_NOT_ALLOWED
;
8300 /* Ensure this is pointing to a directory. */
8301 dp
= opendir(sharepath
);
8304 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8305 servicename
, sharepath
));
8306 return USERSHARE_PATH_NOT_DIRECTORY
;
8309 /* Ensure the owner of the usershare file has permission to share
8312 if (sys_stat(sharepath
, &sbuf
, false) == -1) {
8313 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8314 servicename
, sharepath
, strerror(errno
) ));
8316 return USERSHARE_POSIX_ERR
;
8321 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
8322 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8323 servicename
, sharepath
));
8324 return USERSHARE_PATH_NOT_DIRECTORY
;
8327 /* Check if sharing is restricted to owner-only. */
8328 /* psbuf is the stat of the usershare definition file,
8329 sbuf is the stat of the target directory to be shared. */
8331 if (lp_usershare_owner_only()) {
8332 /* root can share anything. */
8333 if ((psbuf
->st_ex_uid
!= 0) && (sbuf
.st_ex_uid
!= psbuf
->st_ex_uid
)) {
8334 return USERSHARE_PATH_NOT_ALLOWED
;
8338 *pp_sharepath
= sharepath
;
8339 *pp_comment
= comment
;
8340 return USERSHARE_OK
;
8343 /***************************************************************************
8344 Deal with a usershare file.
8347 -1 - Bad name, invalid contents.
8348 - service name already existed and not a usershare, problem
8349 with permissions to share directory etc.
8350 ***************************************************************************/
8352 static int process_usershare_file(const char *dir_name
, const char *file_name
, int snum_template
)
8354 SMB_STRUCT_STAT sbuf
;
8355 SMB_STRUCT_STAT lsbuf
;
8357 char *sharepath
= NULL
;
8358 char *comment
= NULL
;
8359 char *cp_service_name
= NULL
;
8360 char **lines
= NULL
;
8364 TALLOC_CTX
*ctx
= talloc_stackframe();
8365 struct security_descriptor
*psd
= NULL
;
8366 bool guest_ok
= false;
8367 char *canon_name
= NULL
;
8368 bool added_service
= false;
8371 /* Ensure share name doesn't contain invalid characters. */
8372 if (!validate_net_name(file_name
, INVALID_SHARENAME_CHARS
, strlen(file_name
))) {
8373 DEBUG(0,("process_usershare_file: share name %s contains "
8374 "invalid characters (any of %s)\n",
8375 file_name
, INVALID_SHARENAME_CHARS
));
8379 canon_name
= canonicalize_servicename(ctx
, file_name
);
8384 fname
= talloc_asprintf(ctx
, "%s/%s", dir_name
, file_name
);
8389 /* Minimize the race condition by doing an lstat before we
8390 open and fstat. Ensure this isn't a symlink link. */
8392 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
8393 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8394 fname
, strerror(errno
) ));
8398 /* This must be a regular file, not a symlink, directory or
8399 other strange filetype. */
8400 if (!check_usershare_stat(fname
, &lsbuf
)) {
8408 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
,
8413 if (NT_STATUS_IS_OK(status
) &&
8414 (data
.dptr
!= NULL
) &&
8415 (data
.dsize
== sizeof(iService
))) {
8416 memcpy(&iService
, data
.dptr
, sizeof(iService
));
8420 if (iService
!= -1 &&
8421 timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
8422 &lsbuf
.st_ex_mtime
) == 0) {
8423 /* Nothing changed - Mark valid and return. */
8424 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8426 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
8431 /* Try and open the file read only - no symlinks allowed. */
8433 fd
= open(fname
, O_RDONLY
|O_NOFOLLOW
, 0);
8435 fd
= open(fname
, O_RDONLY
, 0);
8439 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8440 fname
, strerror(errno
) ));
8444 /* Now fstat to be *SURE* it's a regular file. */
8445 if (sys_fstat(fd
, &sbuf
, false) != 0) {
8447 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8448 fname
, strerror(errno
) ));
8452 /* Is it the same dev/inode as was lstated ? */
8453 if (!check_same_stat(&lsbuf
, &sbuf
)) {
8455 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8456 "Symlink spoofing going on ?\n", fname
));
8460 /* This must be a regular file, not a symlink, directory or
8461 other strange filetype. */
8462 if (!check_usershare_stat(fname
, &sbuf
)) {
8466 lines
= fd_lines_load(fd
, &numlines
, MAX_USERSHARE_FILE_SIZE
, NULL
);
8469 if (lines
== NULL
) {
8470 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8471 fname
, (unsigned int)sbuf
.st_ex_uid
));
8475 if (parse_usershare_file(ctx
, &sbuf
, file_name
,
8476 iService
, lines
, numlines
, &sharepath
,
8477 &comment
, &cp_service_name
,
8478 &psd
, &guest_ok
) != USERSHARE_OK
) {
8482 /* Everything ok - add the service possibly using a template. */
8484 const struct loadparm_service
*sp
= &sDefault
;
8485 if (snum_template
!= -1) {
8486 sp
= ServicePtrs
[snum_template
];
8489 if ((iService
= add_a_service(sp
, cp_service_name
)) < 0) {
8490 DEBUG(0, ("process_usershare_file: Failed to add "
8491 "new service %s\n", cp_service_name
));
8495 added_service
= true;
8497 /* Read only is controlled by usershare ACL below. */
8498 ServicePtrs
[iService
]->bRead_only
= false;
8501 /* Write the ACL of the new/modified share. */
8502 if (!set_share_security(canon_name
, psd
)) {
8503 DEBUG(0, ("process_usershare_file: Failed to set share "
8504 "security for user share %s\n",
8509 /* If from a template it may be marked invalid. */
8510 ServicePtrs
[iService
]->valid
= true;
8512 /* Set the service as a valid usershare. */
8513 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
8515 /* Set guest access. */
8516 if (lp_usershare_allow_guests()) {
8517 ServicePtrs
[iService
]->bGuest_ok
= guest_ok
;
8520 /* And note when it was loaded. */
8521 ServicePtrs
[iService
]->usershare_last_mod
= sbuf
.st_ex_mtime
;
8522 string_set(&ServicePtrs
[iService
]->szPath
, sharepath
);
8523 string_set(&ServicePtrs
[iService
]->comment
, comment
);
8529 if (ret
== -1 && iService
!= -1 && added_service
) {
8530 lp_remove_service(iService
);
8538 /***************************************************************************
8539 Checks if a usershare entry has been modified since last load.
8540 ***************************************************************************/
8542 static bool usershare_exists(int iService
, struct timespec
*last_mod
)
8544 SMB_STRUCT_STAT lsbuf
;
8545 const char *usersharepath
= Globals
.szUsersharePath
;
8548 if (asprintf(&fname
, "%s/%s",
8550 ServicePtrs
[iService
]->szService
) < 0) {
8554 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
8559 if (!S_ISREG(lsbuf
.st_ex_mode
)) {
8565 *last_mod
= lsbuf
.st_ex_mtime
;
8569 /***************************************************************************
8570 Load a usershare service by name. Returns a valid servicenumber or -1.
8571 ***************************************************************************/
8573 int load_usershare_service(const char *servicename
)
8575 SMB_STRUCT_STAT sbuf
;
8576 const char *usersharepath
= Globals
.szUsersharePath
;
8577 int max_user_shares
= Globals
.iUsershareMaxShares
;
8578 int snum_template
= -1;
8580 if (*usersharepath
== 0 || max_user_shares
== 0) {
8584 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
8585 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8586 usersharepath
, strerror(errno
) ));
8590 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
8591 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8597 * This directory must be owned by root, and have the 't' bit set.
8598 * It also must not be writable by "other".
8602 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
8604 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
8606 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8607 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8612 /* Ensure the template share exists if it's set. */
8613 if (Globals
.szUsershareTemplateShare
[0]) {
8614 /* We can't use lp_servicenumber here as we are recommending that
8615 template shares have -valid=false set. */
8616 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
8617 if (ServicePtrs
[snum_template
]->szService
&&
8618 strequal(ServicePtrs
[snum_template
]->szService
,
8619 Globals
.szUsershareTemplateShare
)) {
8624 if (snum_template
== -1) {
8625 DEBUG(0,("load_usershare_service: usershare template share %s "
8626 "does not exist.\n",
8627 Globals
.szUsershareTemplateShare
));
8632 return process_usershare_file(usersharepath
, servicename
, snum_template
);
8635 /***************************************************************************
8636 Load all user defined shares from the user share directory.
8637 We only do this if we're enumerating the share list.
8638 This is the function that can delete usershares that have
8640 ***************************************************************************/
8642 int load_usershare_shares(struct smbd_server_connection
*sconn
,
8643 bool (*snumused
) (struct smbd_server_connection
*, int))
8646 SMB_STRUCT_STAT sbuf
;
8648 int num_usershares
= 0;
8649 int max_user_shares
= Globals
.iUsershareMaxShares
;
8650 unsigned int num_dir_entries
, num_bad_dir_entries
, num_tmp_dir_entries
;
8651 unsigned int allowed_bad_entries
= ((2*max_user_shares
)/10);
8652 unsigned int allowed_tmp_entries
= ((2*max_user_shares
)/10);
8654 int snum_template
= -1;
8655 const char *usersharepath
= Globals
.szUsersharePath
;
8656 int ret
= lp_numservices();
8657 TALLOC_CTX
*tmp_ctx
;
8659 if (max_user_shares
== 0 || *usersharepath
== '\0') {
8660 return lp_numservices();
8663 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
8664 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8665 usersharepath
, strerror(errno
) ));
8670 * This directory must be owned by root, and have the 't' bit set.
8671 * It also must not be writable by "other".
8675 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
8677 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
8679 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8680 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8685 /* Ensure the template share exists if it's set. */
8686 if (Globals
.szUsershareTemplateShare
[0]) {
8687 /* We can't use lp_servicenumber here as we are recommending that
8688 template shares have -valid=false set. */
8689 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
8690 if (ServicePtrs
[snum_template
]->szService
&&
8691 strequal(ServicePtrs
[snum_template
]->szService
,
8692 Globals
.szUsershareTemplateShare
)) {
8697 if (snum_template
== -1) {
8698 DEBUG(0,("load_usershare_shares: usershare template share %s "
8699 "does not exist.\n",
8700 Globals
.szUsershareTemplateShare
));
8705 /* Mark all existing usershares as pending delete. */
8706 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
8707 if (VALID(iService
) && ServicePtrs
[iService
]->usershare
) {
8708 ServicePtrs
[iService
]->usershare
= USERSHARE_PENDING_DELETE
;
8712 dp
= opendir(usersharepath
);
8714 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8715 usersharepath
, strerror(errno
) ));
8719 for (num_dir_entries
= 0, num_bad_dir_entries
= 0, num_tmp_dir_entries
= 0;
8721 num_dir_entries
++ ) {
8723 const char *n
= de
->d_name
;
8725 /* Ignore . and .. */
8727 if ((n
[1] == '\0') || (n
[1] == '.' && n
[2] == '\0')) {
8733 /* Temporary file used when creating a share. */
8734 num_tmp_dir_entries
++;
8737 /* Allow 20% tmp entries. */
8738 if (num_tmp_dir_entries
> allowed_tmp_entries
) {
8739 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8740 "in directory %s\n",
8741 num_tmp_dir_entries
, usersharepath
));
8745 r
= process_usershare_file(usersharepath
, n
, snum_template
);
8747 /* Update the services count. */
8749 if (num_usershares
>= max_user_shares
) {
8750 DEBUG(0,("load_usershare_shares: max user shares reached "
8751 "on file %s in directory %s\n",
8752 n
, usersharepath
));
8755 } else if (r
== -1) {
8756 num_bad_dir_entries
++;
8759 /* Allow 20% bad entries. */
8760 if (num_bad_dir_entries
> allowed_bad_entries
) {
8761 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8762 "in directory %s\n",
8763 num_bad_dir_entries
, usersharepath
));
8767 /* Allow 20% bad entries. */
8768 if (num_dir_entries
> max_user_shares
+ allowed_bad_entries
) {
8769 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8770 "in directory %s\n",
8771 num_dir_entries
, usersharepath
));
8778 /* Sweep through and delete any non-refreshed usershares that are
8779 not currently in use. */
8780 tmp_ctx
= talloc_stackframe();
8781 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
8782 if (VALID(iService
) && (ServicePtrs
[iService
]->usershare
== USERSHARE_PENDING_DELETE
)) {
8785 if (snumused
&& snumused(sconn
, iService
)) {
8789 servname
= lp_servicename(tmp_ctx
, iService
);
8791 /* Remove from the share ACL db. */
8792 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8794 delete_share_security(servname
);
8795 free_service_byindex(iService
);
8798 talloc_free(tmp_ctx
);
8800 return lp_numservices();
8803 /********************************************************
8804 Destroy global resources allocated in this file
8805 ********************************************************/
8807 void gfree_loadparm(void)
8813 /* Free resources allocated to services */
8815 for ( i
= 0; i
< iNumServices
; i
++ ) {
8817 free_service_byindex(i
);
8821 SAFE_FREE( ServicePtrs
);
8824 /* Now release all resources allocated to global
8825 parameters and the default service */
8827 free_global_parameters();
8831 /***************************************************************************
8832 Allow client apps to specify that they are a client
8833 ***************************************************************************/
8834 static void lp_set_in_client(bool b
)
8840 /***************************************************************************
8841 Determine if we're running in a client app
8842 ***************************************************************************/
8843 static bool lp_is_in_client(void)
8848 /***************************************************************************
8849 Load the services array from the services file. Return true on success,
8851 ***************************************************************************/
8853 static bool lp_load_ex(const char *pszFname
,
8857 bool initialize_globals
,
8858 bool allow_include_registry
,
8859 bool load_all_shares
)
8866 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8868 bInGlobalSection
= true;
8869 bGlobalOnly
= global_only
;
8870 bAllowIncludeRegistry
= allow_include_registry
;
8872 init_globals(initialize_globals
);
8876 if (save_defaults
) {
8881 if (!initialize_globals
) {
8882 free_param_opts(&Globals
.param_opt
);
8883 apply_lp_set_cmdline();
8886 lp_do_parameter(-1, "idmap config * : backend", Globals
.szIdmapBackend
);
8888 /* We get sections first, so have to start 'behind' to make up */
8891 if (lp_config_backend_is_file()) {
8892 n2
= talloc_sub_basic(talloc_tos(), get_current_username(),
8893 current_user_info
.domain
,
8896 smb_panic("lp_load_ex: out of memory");
8899 add_to_file_list(pszFname
, n2
);
8901 bRetval
= pm_process(n2
, do_section
, do_parameter
, NULL
);
8904 /* finish up the last section */
8905 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval
)));
8907 if (iServiceIndex
>= 0) {
8908 bRetval
= service_ok(iServiceIndex
);
8912 if (lp_config_backend_is_registry()) {
8913 /* config backend changed to registry in config file */
8915 * We need to use this extra global variable here to
8916 * survive restart: init_globals uses this as a default
8917 * for ConfigBackend. Otherwise, init_globals would
8918 * send us into an endless loop here.
8920 config_backend
= CONFIG_BACKEND_REGISTRY
;
8922 DEBUG(1, ("lp_load_ex: changing to config backend "
8925 lp_kill_all_services();
8926 return lp_load_ex(pszFname
, global_only
, save_defaults
,
8927 add_ipc
, initialize_globals
,
8928 allow_include_registry
,
8931 } else if (lp_config_backend_is_registry()) {
8932 bRetval
= process_registry_globals();
8934 DEBUG(0, ("Illegal config backend given: %d\n",
8935 lp_config_backend()));
8939 if (bRetval
&& lp_registry_shares()) {
8940 if (load_all_shares
) {
8941 bRetval
= process_registry_shares();
8943 bRetval
= reload_registry_shares();
8948 char *serv
= lp_auto_services(talloc_tos());
8949 lp_add_auto_services(serv
);
8954 /* When 'restrict anonymous = 2' guest connections to ipc$
8956 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8957 if ( lp_enable_asu_support() ) {
8958 lp_add_ipc("ADMIN$", false);
8962 set_allowed_client_auth();
8964 if (lp_security() == SEC_ADS
&& strchr(lp_passwordserver(), ':')) {
8965 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
8966 lp_passwordserver()));
8971 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8972 /* if bWINSsupport is true and we are in the client */
8973 if (lp_is_in_client() && Globals
.bWINSsupport
) {
8974 lp_do_parameter(GLOBAL_SECTION_SNUM
, "wins server", "127.0.0.1");
8979 fault_configure(smb_panic_s3
);
8981 bAllowIncludeRegistry
= true;
8986 bool lp_load(const char *pszFname
,
8990 bool initialize_globals
)
8992 return lp_load_ex(pszFname
,
8997 true, /* allow_include_registry */
8998 false); /* load_all_shares*/
9001 bool lp_load_initial_only(const char *pszFname
)
9003 return lp_load_ex(pszFname
,
9004 true, /* global only */
9005 false, /* save_defaults */
9006 false, /* add_ipc */
9007 true, /* initialize_globals */
9008 false, /* allow_include_registry */
9009 false); /* load_all_shares*/
9013 * most common lp_load wrapper, loading only the globals
9015 bool lp_load_global(const char *file_name
)
9017 return lp_load_ex(file_name
,
9018 true, /* global_only */
9019 false, /* save_defaults */
9020 false, /* add_ipc */
9021 true, /* initialize_globals */
9022 true, /* allow_include_registry */
9023 false); /* load_all_shares*/
9027 * lp_load wrapper, especially for clients
9029 bool lp_load_client(const char *file_name
)
9031 lp_set_in_client(true);
9033 return lp_load_global(file_name
);
9037 * lp_load wrapper, loading only globals, but intended
9038 * for subsequent calls, not reinitializing the globals
9041 bool lp_load_global_no_reinit(const char *file_name
)
9043 return lp_load_ex(file_name
,
9044 true, /* global_only */
9045 false, /* save_defaults */
9046 false, /* add_ipc */
9047 false, /* initialize_globals */
9048 true, /* allow_include_registry */
9049 false); /* load_all_shares*/
9053 * lp_load wrapper, especially for clients, no reinitialization
9055 bool lp_load_client_no_reinit(const char *file_name
)
9057 lp_set_in_client(true);
9059 return lp_load_global_no_reinit(file_name
);
9062 bool lp_load_with_registry_shares(const char *pszFname
,
9066 bool initialize_globals
)
9068 return lp_load_ex(pszFname
,
9073 true, /* allow_include_registry */
9074 true); /* load_all_shares*/
9077 /***************************************************************************
9078 Return the max number of services.
9079 ***************************************************************************/
9081 int lp_numservices(void)
9083 return (iNumServices
);
9086 /***************************************************************************
9087 Display the contents of the services array in human-readable form.
9088 ***************************************************************************/
9090 void lp_dump(FILE *f
, bool show_defaults
, int maxtoprint
)
9095 defaults_saved
= false;
9099 dump_a_service(&sDefault
, f
);
9101 for (iService
= 0; iService
< maxtoprint
; iService
++) {
9103 lp_dump_one(f
, show_defaults
, iService
);
9107 /***************************************************************************
9108 Display the contents of one service in human-readable form.
9109 ***************************************************************************/
9111 void lp_dump_one(FILE * f
, bool show_defaults
, int snum
)
9114 if (ServicePtrs
[snum
]->szService
[0] == '\0')
9116 dump_a_service(ServicePtrs
[snum
], f
);
9120 /***************************************************************************
9121 Return the number of the service with the given name, or -1 if it doesn't
9122 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9123 getservicebyname()! This works ONLY if all services have been loaded, and
9124 does not copy the found service.
9125 ***************************************************************************/
9127 int lp_servicenumber(const char *pszServiceName
)
9130 fstring serviceName
;
9132 if (!pszServiceName
) {
9133 return GLOBAL_SECTION_SNUM
;
9136 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
9137 if (VALID(iService
) && ServicePtrs
[iService
]->szService
) {
9139 * The substitution here is used to support %U is
9142 fstrcpy(serviceName
, ServicePtrs
[iService
]->szService
);
9143 standard_sub_basic(get_current_username(),
9144 current_user_info
.domain
,
9145 serviceName
,sizeof(serviceName
));
9146 if (strequal(serviceName
, pszServiceName
)) {
9152 if (iService
>= 0 && ServicePtrs
[iService
]->usershare
== USERSHARE_VALID
) {
9153 struct timespec last_mod
;
9155 if (!usershare_exists(iService
, &last_mod
)) {
9156 /* Remove the share security tdb entry for it. */
9157 delete_share_security(lp_servicename(talloc_tos(), iService
));
9158 /* Remove it from the array. */
9159 free_service_byindex(iService
);
9160 /* Doesn't exist anymore. */
9161 return GLOBAL_SECTION_SNUM
;
9164 /* Has it been modified ? If so delete and reload. */
9165 if (timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
9167 /* Remove it from the array. */
9168 free_service_byindex(iService
);
9169 /* and now reload it. */
9170 iService
= load_usershare_service(pszServiceName
);
9175 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName
));
9176 return GLOBAL_SECTION_SNUM
;
9182 /*******************************************************************
9183 A useful volume label function.
9184 ********************************************************************/
9186 const char *volume_label(TALLOC_CTX
*ctx
, int snum
)
9189 const char *label
= lp_volume(ctx
, snum
);
9191 label
= lp_servicename(ctx
, snum
);
9194 /* This returns a 33 byte guarenteed null terminated string. */
9195 ret
= talloc_strndup(ctx
, label
, 32);
9202 /*******************************************************************
9203 Get the default server type we will announce as via nmbd.
9204 ********************************************************************/
9206 int lp_default_server_announce(void)
9208 int default_server_announce
= 0;
9209 default_server_announce
|= SV_TYPE_WORKSTATION
;
9210 default_server_announce
|= SV_TYPE_SERVER
;
9211 default_server_announce
|= SV_TYPE_SERVER_UNIX
;
9213 /* note that the flag should be set only if we have a
9214 printer service but nmbd doesn't actually load the
9215 services so we can't tell --jerry */
9217 default_server_announce
|= SV_TYPE_PRINTQ_SERVER
;
9219 default_server_announce
|= SV_TYPE_SERVER_NT
;
9220 default_server_announce
|= SV_TYPE_NT
;
9222 switch (lp_server_role()) {
9223 case ROLE_DOMAIN_MEMBER
:
9224 default_server_announce
|= SV_TYPE_DOMAIN_MEMBER
;
9226 case ROLE_DOMAIN_PDC
:
9227 default_server_announce
|= SV_TYPE_DOMAIN_CTRL
;
9229 case ROLE_DOMAIN_BDC
:
9230 default_server_announce
|= SV_TYPE_DOMAIN_BAKCTRL
;
9232 case ROLE_STANDALONE
:
9236 if (lp_time_server())
9237 default_server_announce
|= SV_TYPE_TIME_SOURCE
;
9239 if (lp_host_msdfs())
9240 default_server_announce
|= SV_TYPE_DFS_SERVER
;
9242 return default_server_announce
;
9245 /***********************************************************
9246 If we are PDC then prefer us as DMB
9247 ************************************************************/
9249 bool lp_domain_master(void)
9251 if (Globals
.domain_master
== Auto
)
9252 return (lp_server_role() == ROLE_DOMAIN_PDC
);
9254 return (bool)Globals
.domain_master
;
9257 /***********************************************************
9258 If we are PDC then prefer us as DMB
9259 ************************************************************/
9261 static bool lp_domain_master_true_or_auto(void)
9263 if (Globals
.domain_master
) /* auto or yes */
9269 /***********************************************************
9270 If we are DMB then prefer us as LMB
9271 ************************************************************/
9273 bool lp_preferred_master(void)
9275 if (Globals
.iPreferredMaster
== Auto
)
9276 return (lp_local_master() && lp_domain_master());
9278 return (bool)Globals
.iPreferredMaster
;
9281 /*******************************************************************
9283 ********************************************************************/
9285 void lp_remove_service(int snum
)
9287 ServicePtrs
[snum
]->valid
= false;
9288 invalid_services
[num_invalid_services
++] = snum
;
9291 /*******************************************************************
9293 ********************************************************************/
9295 void lp_copy_service(int snum
, const char *new_name
)
9297 do_section(new_name
, NULL
);
9299 snum
= lp_servicenumber(new_name
);
9301 char *name
= lp_servicename(talloc_tos(), snum
);
9302 lp_do_parameter(snum
, "copy", name
);
9307 const char *lp_printername(TALLOC_CTX
*ctx
, int snum
)
9309 const char *ret
= lp__printername(talloc_tos(), snum
);
9310 if (ret
== NULL
|| *ret
== '\0') {
9311 ret
= lp_const_servicename(snum
);
9318 /***********************************************************
9319 Allow daemons such as winbindd to fix their logfile name.
9320 ************************************************************/
9322 void lp_set_logfile(const char *name
)
9324 string_set(&Globals
.logfile
, name
);
9325 debug_set_logfile(name
);
9328 /*******************************************************************
9329 Return the max print jobs per queue.
9330 ********************************************************************/
9332 int lp_maxprintjobs(int snum
)
9334 int maxjobs
= LP_SNUM_OK(snum
) ? ServicePtrs
[snum
]->iMaxPrintJobs
: sDefault
.iMaxPrintJobs
;
9335 if (maxjobs
<= 0 || maxjobs
>= PRINT_MAX_JOBID
)
9336 maxjobs
= PRINT_MAX_JOBID
- 1;
9341 const char *lp_printcapname(void)
9343 if ((Globals
.szPrintcapname
!= NULL
) &&
9344 (Globals
.szPrintcapname
[0] != '\0'))
9345 return Globals
.szPrintcapname
;
9347 if (sDefault
.iPrinting
== PRINT_CUPS
) {
9355 if (sDefault
.iPrinting
== PRINT_BSD
)
9356 return "/etc/printcap";
9358 return PRINTCAP_NAME
;
9361 static uint32 spoolss_state
;
9363 bool lp_disable_spoolss( void )
9365 if ( spoolss_state
== SVCCTL_STATE_UNKNOWN
)
9366 spoolss_state
= lp__disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
9368 return spoolss_state
== SVCCTL_STOPPED
? true : false;
9371 void lp_set_spoolss_state( uint32 state
)
9373 SMB_ASSERT( (state
== SVCCTL_STOPPED
) || (state
== SVCCTL_RUNNING
) );
9375 spoolss_state
= state
;
9378 uint32
lp_get_spoolss_state( void )
9380 return lp_disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
9383 /*******************************************************************
9384 Ensure we don't use sendfile if server smb signing is active.
9385 ********************************************************************/
9387 bool lp_use_sendfile(int snum
, struct smb_signing_state
*signing_state
)
9389 bool sign_active
= false;
9391 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9392 if (get_Protocol() < PROTOCOL_NT1
) {
9395 if (signing_state
) {
9396 sign_active
= smb_signing_is_active(signing_state
);
9398 return (lp__use_sendfile(snum
) &&
9399 (get_remote_arch() != RA_WIN95
) &&
9403 /*******************************************************************
9404 Turn off sendfile if we find the underlying OS doesn't support it.
9405 ********************************************************************/
9407 void set_use_sendfile(int snum
, bool val
)
9409 if (LP_SNUM_OK(snum
))
9410 ServicePtrs
[snum
]->bUseSendfile
= val
;
9412 sDefault
.bUseSendfile
= val
;
9415 /*******************************************************************
9416 Turn off storing DOS attributes if this share doesn't support it.
9417 ********************************************************************/
9419 void set_store_dos_attributes(int snum
, bool val
)
9421 if (!LP_SNUM_OK(snum
))
9423 ServicePtrs
[(snum
)]->bStoreDosAttributes
= val
;
9426 void lp_set_mangling_method(const char *new_method
)
9428 string_set(&Globals
.szManglingMethod
, new_method
);
9431 /*******************************************************************
9432 Global state for POSIX pathname processing.
9433 ********************************************************************/
9435 static bool posix_pathnames
;
9437 bool lp_posix_pathnames(void)
9439 return posix_pathnames
;
9442 /*******************************************************************
9443 Change everything needed to ensure POSIX pathname processing (currently
9445 ********************************************************************/
9447 void lp_set_posix_pathnames(void)
9449 posix_pathnames
= true;
9452 /*******************************************************************
9453 Global state for POSIX lock processing - CIFS unix extensions.
9454 ********************************************************************/
9456 bool posix_default_lock_was_set
;
9457 static enum brl_flavour posix_cifsx_locktype
; /* By default 0 == WINDOWS_LOCK */
9459 enum brl_flavour
lp_posix_cifsu_locktype(files_struct
*fsp
)
9461 if (posix_default_lock_was_set
) {
9462 return posix_cifsx_locktype
;
9464 return fsp
->posix_open
? POSIX_LOCK
: WINDOWS_LOCK
;
9468 /*******************************************************************
9469 ********************************************************************/
9471 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val
)
9473 posix_default_lock_was_set
= true;
9474 posix_cifsx_locktype
= val
;
9477 int lp_min_receive_file_size(void)
9479 if (Globals
.iminreceivefile
< 0) {
9482 return MIN(Globals
.iminreceivefile
, BUFFER_SIZE
);
9485 /*******************************************************************
9486 If socket address is an empty character string, it is necessary to
9487 define it as "0.0.0.0".
9488 ********************************************************************/
9490 const char *lp_socket_address(void)
9492 char *sock_addr
= Globals
.szSocketAddress
;
9494 if (sock_addr
[0] == '\0'){
9495 string_set(&Globals
.szSocketAddress
, "0.0.0.0");
9497 return Globals
.szSocketAddress
;
9500 /*******************************************************************
9501 Safe wide links checks.
9502 This helper function always verify the validity of wide links,
9503 even after a configuration file reload.
9504 ********************************************************************/
9506 static bool lp_widelinks_internal(int snum
)
9508 return (bool)(LP_SNUM_OK(snum
)? ServicePtrs
[(snum
)]->bWidelinks
:
9509 sDefault
.bWidelinks
);
9512 void widelinks_warning(int snum
)
9514 if (lp_allow_insecure_widelinks()) {
9518 if (lp_unix_extensions() && lp_widelinks_internal(snum
)) {
9519 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9520 "These parameters are incompatible. "
9521 "Wide links will be disabled for this share.\n",
9522 lp_servicename(talloc_tos(), snum
) ));
9526 bool lp_widelinks(int snum
)
9528 /* wide links is always incompatible with unix extensions */
9529 if (lp_unix_extensions()) {
9531 * Unless we have "allow insecure widelinks"
9534 if (!lp_allow_insecure_widelinks()) {
9539 return lp_widelinks_internal(snum
);
9542 bool lp_writeraw(void)
9544 if (lp_async_smb_echo_handler()) {
9547 return lp__writeraw();
9550 bool lp_readraw(void)
9552 if (lp_async_smb_echo_handler()) {
9555 return lp__readraw();
9558 int lp_server_role(void)
9560 return lp_find_server_role(lp__server_role(),
9562 lp__domain_logons(),
9563 lp_domain_master_true_or_auto());
9566 int lp_security(void)
9568 return lp_find_security(lp__server_role(),