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"
60 #include "lib/smbconf/smbconf.h"
61 #include "lib/smbconf/smbconf_init.h"
62 #include "lib/param/loadparm.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 #define CONFIG_BACKEND_FILE 0
101 #define CONFIG_BACKEND_REGISTRY 1
103 static int config_backend
= CONFIG_BACKEND_FILE
;
105 /* some helpful bits */
106 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
107 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
109 #define USERSHARE_VALID 1
110 #define USERSHARE_PENDING_DELETE 2
112 static bool defaults_saved
= false;
114 #define LOADPARM_EXTRA_GLOBALS \
115 struct parmlist_entry *param_opt; \
118 int iminreceivefile; \
119 char *szPrintcapname; \
121 int iPreferredMaster; \
123 char *szLdapMachineSuffix; \
124 char *szLdapUserSuffix; \
125 char *szLdapIdmapSuffix; \
126 char *szLdapGroupSuffix; \
129 char *szSocketAddress; \
130 char *szUsershareTemplateShare; \
133 int winbindMaxDomainConnections; \
134 int ismb2_max_credits; \
136 char *tls_certfile; \
140 char *panic_action; \
141 int bPreferredMaster;
143 #include "param/param_global.h"
145 static struct loadparm_global Globals
;
147 /* This is a default service used to prime a services structure */
148 static struct loadparm_service sDefault
=
153 .usershare_last_mod
= {0, 0},
157 .szInvalidUsers
= NULL
,
158 .szValidUsers
= NULL
,
159 .szAdminUsers
= NULL
,
164 .szRootPreExec
= NULL
,
165 .szRootPostExec
= NULL
,
166 .szCupsOptions
= NULL
,
167 .szPrintcommand
= NULL
,
168 .szLpqcommand
= NULL
,
169 .szLprmcommand
= NULL
,
170 .szLppausecommand
= NULL
,
171 .szLpresumecommand
= NULL
,
172 .szQueuepausecommand
= NULL
,
173 .szQueueresumecommand
= NULL
,
174 .szPrintername
= NULL
,
175 .szPrintjobUsername
= NULL
,
176 .szDontdescend
= NULL
,
177 .szHostsallow
= NULL
,
179 .szMagicScript
= NULL
,
180 .szMagicOutput
= NULL
,
183 .szVetoOplockFiles
= NULL
,
191 .szVfsObjects
= NULL
,
192 .szMSDfsProxy
= NULL
,
193 .szAioWriteBehind
= NULL
,
196 .iMaxPrintJobs
= 1000,
197 .iMaxReportedPrintJobs
= 0,
198 .iWriteCacheSize
= 0,
199 .iCreate_mask
= 0744,
200 .iCreate_force_mode
= 0,
201 .iSecurity_mask
= 0777,
202 .iSecurity_force_mode
= 0,
204 .iDir_force_mode
= 0,
205 .iDir_Security_mask
= 0777,
206 .iDir_Security_force_mode
= 0,
207 .iMaxConnections
= 0,
208 .iDefaultCase
= CASE_LOWER
,
209 .iPrinting
= DEFAULT_PRINTING
,
210 .iOplockContentionLimit
= 2,
213 .iDfreeCacheTime
= 0,
214 .bPreexecClose
= false,
215 .bRootpreexecClose
= false,
216 .iCaseSensitive
= Auto
,
217 .bCasePreserve
= true,
218 .bShortCasePreserve
= true,
219 .bHideDotFiles
= true,
220 .bHideSpecialFiles
= false,
221 .bHideUnReadable
= false,
222 .bHideUnWriteableFiles
= false,
224 .bAccessBasedShareEnum
= false,
228 .bGuest_only
= false,
229 .bAdministrative_share
= false,
232 .bPrintNotifyBackchannel
= true,
233 .bMap_system
= false,
234 .bMap_hidden
= false,
235 .bMap_archive
= true,
236 .bStoreDosAttributes
= false,
237 .bDmapiSupport
= false,
239 .iStrictLocking
= Auto
,
240 .bPosixLocking
= true,
243 .bKernelOplocks
= false,
244 .bLevel2OpLocks
= true,
246 .bMangledNames
= true,
249 .bSyncAlways
= false,
250 .bStrictAllocate
= false,
251 .bStrictSync
= false,
254 .bDeleteReadonly
= false,
255 .bFakeOplocks
= false,
256 .bDeleteVetoFiles
= false,
257 .bDosFilemode
= false,
258 .bDosFiletimes
= true,
259 .bDosFiletimeResolution
= false,
260 .bFakeDirCreateTimes
= false,
261 .bBlockingLocks
= true,
262 .bInheritPerms
= false,
263 .bInheritACLS
= false,
264 .bInheritOwner
= false,
266 .bUseClientDriver
= false,
267 .bDefaultDevmode
= true,
268 .bForcePrintername
= false,
269 .bNTAclSupport
= true,
270 .bForceUnknownAclUser
= false,
271 .bUseSendfile
= false,
272 .bProfileAcls
= false,
273 .bMap_acl_inherit
= false,
276 .bAclCheckPermissions
= true,
277 .bAclMapFullControl
= true,
278 .bAclGroupControl
= false,
279 .bChangeNotify
= true,
280 .bKernelChangeNotify
= true,
281 .iallocation_roundup_size
= SMB_ROUNDUP_ALLOCATION_SIZE
,
284 .iMap_readonly
= MAP_READONLY_YES
,
285 #ifdef BROKEN_DIRECTORY_HANDLING
286 .iDirectoryNameCacheSize
= 0,
288 .iDirectoryNameCacheSize
= 100,
290 .ismb_encrypt
= Auto
,
295 /* local variables */
296 static struct loadparm_service
**ServicePtrs
= NULL
;
297 static int iNumServices
= 0;
298 static int iServiceIndex
= 0;
299 static struct db_context
*ServiceHash
;
300 static int *invalid_services
= NULL
;
301 static int num_invalid_services
= 0;
302 static bool bInGlobalSection
= true;
303 static bool bGlobalOnly
= false;
305 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
307 /* prototypes for the special type handlers */
308 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
309 static bool handle_copy(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
310 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
311 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
312 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
313 static bool handle_debug_list(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
314 static bool handle_realm(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
315 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
316 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
317 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
318 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
319 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
321 static void set_allowed_client_auth(void);
323 static void add_to_file_list(const char *fname
, const char *subfname
);
324 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
);
325 static void free_param_opts(struct parmlist_entry
**popts
);
327 #include "lib/param/param_enums.c"
329 static const struct enum_list enum_printing
[] = {
330 {PRINT_SYSV
, "sysv"},
332 {PRINT_HPUX
, "hpux"},
336 {PRINT_LPRNG
, "lprng"},
337 {PRINT_CUPS
, "cups"},
338 {PRINT_IPRINT
, "iprint"},
340 {PRINT_LPROS2
, "os2"},
341 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
342 {PRINT_TEST
, "test"},
344 #endif /* DEVELOPER */
348 static const struct enum_list enum_ldap_sasl_wrapping
[] = {
350 {ADS_AUTH_SASL_SIGN
, "sign"},
351 {ADS_AUTH_SASL_SEAL
, "seal"},
355 static const struct enum_list enum_ldap_ssl
[] = {
356 {LDAP_SSL_OFF
, "no"},
357 {LDAP_SSL_OFF
, "off"},
358 {LDAP_SSL_START_TLS
, "start tls"},
359 {LDAP_SSL_START_TLS
, "start_tls"},
363 /* LDAP Dereferencing Alias types */
364 #define SAMBA_LDAP_DEREF_NEVER 0
365 #define SAMBA_LDAP_DEREF_SEARCHING 1
366 #define SAMBA_LDAP_DEREF_FINDING 2
367 #define SAMBA_LDAP_DEREF_ALWAYS 3
369 static const struct enum_list enum_ldap_deref
[] = {
370 {SAMBA_LDAP_DEREF_NEVER
, "never"},
371 {SAMBA_LDAP_DEREF_SEARCHING
, "searching"},
372 {SAMBA_LDAP_DEREF_FINDING
, "finding"},
373 {SAMBA_LDAP_DEREF_ALWAYS
, "always"},
377 static const struct enum_list enum_ldap_passwd_sync
[] = {
378 {LDAP_PASSWD_SYNC_OFF
, "no"},
379 {LDAP_PASSWD_SYNC_OFF
, "off"},
380 {LDAP_PASSWD_SYNC_ON
, "yes"},
381 {LDAP_PASSWD_SYNC_ON
, "on"},
382 {LDAP_PASSWD_SYNC_ONLY
, "only"},
386 static const struct enum_list enum_map_readonly
[] = {
387 {MAP_READONLY_NO
, "no"},
388 {MAP_READONLY_NO
, "false"},
389 {MAP_READONLY_NO
, "0"},
390 {MAP_READONLY_YES
, "yes"},
391 {MAP_READONLY_YES
, "true"},
392 {MAP_READONLY_YES
, "1"},
393 {MAP_READONLY_PERMISSIONS
, "permissions"},
394 {MAP_READONLY_PERMISSIONS
, "perms"},
398 static const struct enum_list enum_case
[] = {
399 {CASE_LOWER
, "lower"},
400 {CASE_UPPER
, "upper"},
405 /* ACL compatibility options. */
406 static const struct enum_list enum_acl_compat_vals
[] = {
407 { ACL_COMPAT_AUTO
, "auto" },
408 { ACL_COMPAT_WINNT
, "winnt" },
409 { ACL_COMPAT_WIN2K
, "win2k" },
414 Do you want session setups at user level security with a invalid
415 password to be rejected or allowed in as guest? WinNT rejects them
416 but it can be a pain as it means "net view" needs to use a password
418 You have 3 choices in the setting of map_to_guest:
420 "Never" means session setups with an invalid password
421 are rejected. This is the default.
423 "Bad User" means session setups with an invalid password
424 are rejected, unless the username does not exist, in which case it
425 is treated as a guest login
427 "Bad Password" means session setups with an invalid password
428 are treated as a guest login
430 Note that map_to_guest only has an effect in user or server
434 static const struct enum_list enum_map_to_guest
[] = {
435 {NEVER_MAP_TO_GUEST
, "Never"},
436 {MAP_TO_GUEST_ON_BAD_USER
, "Bad User"},
437 {MAP_TO_GUEST_ON_BAD_PASSWORD
, "Bad Password"},
438 {MAP_TO_GUEST_ON_BAD_UID
, "Bad Uid"},
442 /* Config backend options */
444 static const struct enum_list enum_config_backend
[] = {
445 {CONFIG_BACKEND_FILE
, "file"},
446 {CONFIG_BACKEND_REGISTRY
, "registry"},
450 /* ADS kerberos ticket verification options */
452 static const struct enum_list enum_kerberos_method
[] = {
453 {KERBEROS_VERIFY_SECRETS
, "default"},
454 {KERBEROS_VERIFY_SECRETS
, "secrets only"},
455 {KERBEROS_VERIFY_SYSTEM_KEYTAB
, "system keytab"},
456 {KERBEROS_VERIFY_DEDICATED_KEYTAB
, "dedicated keytab"},
457 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB
, "secrets and keytab"},
461 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
463 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
464 * screen in SWAT. This is used to exclude parameters as well as to squash all
465 * parameters that have been duplicated by pseudonyms.
467 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
468 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
469 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
472 * NOTE2: Handling of duplicated (synonym) parameters:
473 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
474 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
475 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
476 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
479 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
480 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
482 static struct parm_struct parm_table
[] = {
483 {N_("Base Options"), P_SEP
, P_SEPARATOR
},
486 .label
= "dos charset",
489 .offset
= GLOBAL_VAR(dos_charset
),
490 .special
= handle_dos_charset
,
492 .flags
= FLAG_ADVANCED
495 .label
= "unix charset",
498 .offset
= GLOBAL_VAR(unix_charset
),
499 .special
= handle_charset
,
501 .flags
= FLAG_ADVANCED
507 .offset
= LOCAL_VAR(comment
),
510 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
516 .offset
= LOCAL_VAR(szPath
),
519 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
522 .label
= "directory",
525 .offset
= LOCAL_VAR(szPath
),
531 .label
= "workgroup",
534 .offset
= GLOBAL_VAR(szWorkgroup
),
537 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
543 .offset
= GLOBAL_VAR(szRealm
),
544 .special
= handle_realm
,
546 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
549 .label
= "netbios name",
552 .offset
= GLOBAL_VAR(szNetbiosName
),
555 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
558 .label
= "netbios aliases",
561 .offset
= GLOBAL_VAR(szNetbiosAliases
),
562 .special
= handle_netbios_aliases
,
564 .flags
= FLAG_ADVANCED
,
567 .label
= "netbios scope",
570 .offset
= GLOBAL_VAR(szNetbiosScope
),
573 .flags
= FLAG_ADVANCED
,
576 .label
= "server string",
579 .offset
= GLOBAL_VAR(szServerString
),
582 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
585 .label
= "interfaces",
588 .offset
= GLOBAL_VAR(szInterfaces
),
591 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
594 .label
= "bind interfaces only",
597 .offset
= GLOBAL_VAR(bBindInterfacesOnly
),
600 .flags
= FLAG_ADVANCED
| FLAG_WIZARD
,
603 .label
= "config backend",
606 .offset
= GLOBAL_VAR(ConfigBackend
),
608 .enum_list
= enum_config_backend
,
609 .flags
= FLAG_HIDE
|FLAG_ADVANCED
|FLAG_META
,
612 .label
= "server role",
615 .offset
= GLOBAL_VAR(server_role
),
617 .enum_list
= enum_server_role
,
618 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
621 {N_("Security Options"), P_SEP
, P_SEPARATOR
},
627 .offset
= GLOBAL_VAR(security
),
629 .enum_list
= enum_security
,
630 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
633 .label
= "auth methods",
636 .offset
= GLOBAL_VAR(AuthMethods
),
639 .flags
= FLAG_ADVANCED
,
642 .label
= "encrypt passwords",
645 .offset
= GLOBAL_VAR(bEncryptPasswords
),
648 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
651 .label
= "client schannel",
654 .offset
= GLOBAL_VAR(clientSchannel
),
656 .enum_list
= enum_bool_auto
,
657 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
660 .label
= "server schannel",
663 .offset
= GLOBAL_VAR(serverSchannel
),
665 .enum_list
= enum_bool_auto
,
666 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
669 .label
= "allow trusted domains",
672 .offset
= GLOBAL_VAR(bAllowTrustedDomains
),
675 .flags
= FLAG_ADVANCED
,
678 .label
= "map to guest",
681 .offset
= GLOBAL_VAR(map_to_guest
),
683 .enum_list
= enum_map_to_guest
,
684 .flags
= FLAG_ADVANCED
,
687 .label
= "null passwords",
690 .offset
= GLOBAL_VAR(bNullPasswords
),
693 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
696 .label
= "obey pam restrictions",
699 .offset
= GLOBAL_VAR(bObeyPamRestrictions
),
702 .flags
= FLAG_ADVANCED
,
705 .label
= "password server",
708 .offset
= GLOBAL_VAR(szPasswordServer
),
711 .flags
= FLAG_ADVANCED
| FLAG_WIZARD
,
714 .label
= "smb passwd file",
717 .offset
= GLOBAL_VAR(szSMBPasswdFile
),
720 .flags
= FLAG_ADVANCED
,
723 .label
= "private dir",
726 .offset
= GLOBAL_VAR(szPrivateDir
),
729 .flags
= FLAG_ADVANCED
,
732 .label
= "private directory",
735 .offset
= GLOBAL_VAR(szPrivateDir
),
741 .label
= "passdb backend",
744 .offset
= GLOBAL_VAR(passdb_backend
),
747 .flags
= FLAG_ADVANCED
| FLAG_WIZARD
,
750 .label
= "algorithmic rid base",
753 .offset
= GLOBAL_VAR(AlgorithmicRidBase
),
756 .flags
= FLAG_ADVANCED
,
759 .label
= "root directory",
762 .offset
= GLOBAL_VAR(szRootdir
),
765 .flags
= FLAG_ADVANCED
,
771 .offset
= GLOBAL_VAR(szRootdir
),
780 .offset
= GLOBAL_VAR(szRootdir
),
786 .label
= "guest account",
789 .offset
= GLOBAL_VAR(szGuestaccount
),
792 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
795 .label
= "enable privileges",
798 .offset
= GLOBAL_VAR(bEnablePrivileges
),
801 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
805 .label
= "pam password change",
808 .offset
= GLOBAL_VAR(bPamPasswordChange
),
811 .flags
= FLAG_ADVANCED
,
814 .label
= "passwd program",
817 .offset
= GLOBAL_VAR(szPasswdProgram
),
820 .flags
= FLAG_ADVANCED
,
823 .label
= "passwd chat",
826 .offset
= GLOBAL_VAR(szPasswdChat
),
829 .flags
= FLAG_ADVANCED
,
832 .label
= "passwd chat debug",
835 .offset
= GLOBAL_VAR(bPasswdChatDebug
),
838 .flags
= FLAG_ADVANCED
,
841 .label
= "passwd chat timeout",
844 .offset
= GLOBAL_VAR(iPasswdChatTimeout
),
847 .flags
= FLAG_ADVANCED
,
850 .label
= "check password script",
853 .offset
= GLOBAL_VAR(szCheckPasswordScript
),
856 .flags
= FLAG_ADVANCED
,
859 .label
= "username map",
862 .offset
= GLOBAL_VAR(szUsernameMap
),
865 .flags
= FLAG_ADVANCED
,
868 .label
= "password level",
871 .offset
= GLOBAL_VAR(pwordlevel
),
874 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
877 .label
= "username level",
880 .offset
= GLOBAL_VAR(unamelevel
),
883 .flags
= FLAG_ADVANCED
,
886 .label
= "unix password sync",
889 .offset
= GLOBAL_VAR(bUnixPasswdSync
),
892 .flags
= FLAG_ADVANCED
,
895 .label
= "restrict anonymous",
898 .offset
= GLOBAL_VAR(restrict_anonymous
),
901 .flags
= FLAG_ADVANCED
,
904 .label
= "lanman auth",
907 .offset
= GLOBAL_VAR(bLanmanAuth
),
910 .flags
= FLAG_ADVANCED
,
913 .label
= "ntlm auth",
916 .offset
= GLOBAL_VAR(bNTLMAuth
),
919 .flags
= FLAG_ADVANCED
,
922 .label
= "client NTLMv2 auth",
925 .offset
= GLOBAL_VAR(bClientNTLMv2Auth
),
928 .flags
= FLAG_ADVANCED
,
931 .label
= "client lanman auth",
934 .offset
= GLOBAL_VAR(bClientLanManAuth
),
937 .flags
= FLAG_ADVANCED
,
940 .label
= "client plaintext auth",
943 .offset
= GLOBAL_VAR(bClientPlaintextAuth
),
946 .flags
= FLAG_ADVANCED
,
949 .label
= "client use spnego principal",
952 .offset
= GLOBAL_VAR(client_use_spnego_principal
),
955 .flags
= FLAG_ADVANCED
,
961 .offset
= LOCAL_VAR(szUsername
),
964 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
| FLAG_DEPRECATED
,
970 .offset
= LOCAL_VAR(szUsername
),
979 .offset
= LOCAL_VAR(szUsername
),
985 .label
= "invalid users",
988 .offset
= LOCAL_VAR(szInvalidUsers
),
991 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
994 .label
= "valid users",
997 .offset
= LOCAL_VAR(szValidUsers
),
1000 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1003 .label
= "admin users",
1006 .offset
= LOCAL_VAR(szAdminUsers
),
1009 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1012 .label
= "read list",
1015 .offset
= LOCAL_VAR(readlist
),
1018 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1021 .label
= "write list",
1024 .offset
= LOCAL_VAR(writelist
),
1027 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1030 .label
= "force user",
1033 .offset
= LOCAL_VAR(force_user
),
1036 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1039 .label
= "force group",
1042 .offset
= LOCAL_VAR(force_group
),
1045 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1051 .offset
= LOCAL_VAR(force_group
),
1054 .flags
= FLAG_ADVANCED
,
1057 .label
= "read only",
1060 .offset
= LOCAL_VAR(bRead_only
),
1063 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
,
1066 .label
= "write ok",
1069 .offset
= LOCAL_VAR(bRead_only
),
1075 .label
= "writeable",
1078 .offset
= LOCAL_VAR(bRead_only
),
1084 .label
= "writable",
1087 .offset
= LOCAL_VAR(bRead_only
),
1093 .label
= "acl check permissions",
1096 .offset
= LOCAL_VAR(bAclCheckPermissions
),
1099 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
| FLAG_DEPRECATED
,
1102 .label
= "acl group control",
1105 .offset
= LOCAL_VAR(bAclGroupControl
),
1108 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1111 .label
= "acl map full control",
1114 .offset
= LOCAL_VAR(bAclMapFullControl
),
1117 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1120 .label
= "create mask",
1123 .offset
= LOCAL_VAR(iCreate_mask
),
1126 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1129 .label
= "create mode",
1132 .offset
= LOCAL_VAR(iCreate_mask
),
1138 .label
= "force create mode",
1141 .offset
= LOCAL_VAR(iCreate_force_mode
),
1144 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1147 .label
= "security mask",
1150 .offset
= LOCAL_VAR(iSecurity_mask
),
1153 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1156 .label
= "force security mode",
1159 .offset
= LOCAL_VAR(iSecurity_force_mode
),
1162 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1165 .label
= "directory mask",
1168 .offset
= LOCAL_VAR(iDir_mask
),
1171 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1174 .label
= "directory mode",
1177 .offset
= LOCAL_VAR(iDir_mask
),
1180 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
1183 .label
= "force directory mode",
1186 .offset
= LOCAL_VAR(iDir_force_mode
),
1189 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1192 .label
= "directory security mask",
1195 .offset
= LOCAL_VAR(iDir_Security_mask
),
1198 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1201 .label
= "force directory security mode",
1204 .offset
= LOCAL_VAR(iDir_Security_force_mode
),
1207 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1210 .label
= "force unknown acl user",
1213 .offset
= LOCAL_VAR(bForceUnknownAclUser
),
1216 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1219 .label
= "inherit permissions",
1222 .offset
= LOCAL_VAR(bInheritPerms
),
1225 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1228 .label
= "inherit acls",
1231 .offset
= LOCAL_VAR(bInheritACLS
),
1234 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1237 .label
= "inherit owner",
1240 .offset
= LOCAL_VAR(bInheritOwner
),
1243 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1246 .label
= "guest only",
1249 .offset
= LOCAL_VAR(bGuest_only
),
1252 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
1255 .label
= "only guest",
1258 .offset
= LOCAL_VAR(bGuest_only
),
1264 .label
= "administrative share",
1267 .offset
= LOCAL_VAR(bAdministrative_share
),
1270 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
1274 .label
= "guest ok",
1277 .offset
= LOCAL_VAR(bGuest_ok
),
1280 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
1286 .offset
= LOCAL_VAR(bGuest_ok
),
1292 .label
= "only user",
1295 .offset
= LOCAL_VAR(bOnlyUser
),
1298 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_DEPRECATED
,
1301 .label
= "hosts allow",
1304 .offset
= LOCAL_VAR(szHostsallow
),
1307 .flags
= FLAG_GLOBAL
| FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
1310 .label
= "allow hosts",
1313 .offset
= LOCAL_VAR(szHostsallow
),
1319 .label
= "hosts deny",
1322 .offset
= LOCAL_VAR(szHostsdeny
),
1325 .flags
= FLAG_GLOBAL
| FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
1328 .label
= "deny hosts",
1331 .offset
= LOCAL_VAR(szHostsdeny
),
1337 .label
= "preload modules",
1339 .p_class
= P_GLOBAL
,
1340 .offset
= GLOBAL_VAR(szPreloadModules
),
1343 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
1346 .label
= "dedicated keytab file",
1348 .p_class
= P_GLOBAL
,
1349 .offset
= GLOBAL_VAR(szDedicatedKeytabFile
),
1352 .flags
= FLAG_ADVANCED
,
1355 .label
= "kerberos method",
1357 .p_class
= P_GLOBAL
,
1358 .offset
= GLOBAL_VAR(iKerberosMethod
),
1360 .enum_list
= enum_kerberos_method
,
1361 .flags
= FLAG_ADVANCED
,
1364 .label
= "map untrusted to domain",
1366 .p_class
= P_GLOBAL
,
1367 .offset
= GLOBAL_VAR(bMapUntrustedToDomain
),
1370 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
1374 {N_("Logging Options"), P_SEP
, P_SEPARATOR
},
1377 .label
= "log level",
1379 .p_class
= P_GLOBAL
,
1380 .offset
= GLOBAL_VAR(szLogLevel
),
1381 .special
= handle_debug_list
,
1383 .flags
= FLAG_ADVANCED
,
1386 .label
= "debuglevel",
1388 .p_class
= P_GLOBAL
,
1389 .offset
= GLOBAL_VAR(szLogLevel
),
1390 .special
= handle_debug_list
,
1397 .p_class
= P_GLOBAL
,
1398 .offset
= GLOBAL_VAR(syslog
),
1401 .flags
= FLAG_ADVANCED
,
1404 .label
= "syslog only",
1406 .p_class
= P_GLOBAL
,
1407 .offset
= GLOBAL_VAR(bSyslogOnly
),
1410 .flags
= FLAG_ADVANCED
,
1413 .label
= "log file",
1415 .p_class
= P_GLOBAL
,
1416 .offset
= GLOBAL_VAR(logfile
),
1419 .flags
= FLAG_ADVANCED
,
1422 .label
= "max log size",
1424 .p_class
= P_GLOBAL
,
1425 .offset
= GLOBAL_VAR(max_log_size
),
1428 .flags
= FLAG_ADVANCED
,
1431 .label
= "debug timestamp",
1433 .p_class
= P_GLOBAL
,
1434 .offset
= GLOBAL_VAR(bTimestampLogs
),
1437 .flags
= FLAG_ADVANCED
,
1440 .label
= "timestamp logs",
1442 .p_class
= P_GLOBAL
,
1443 .offset
= GLOBAL_VAR(bTimestampLogs
),
1446 .flags
= FLAG_ADVANCED
,
1449 .label
= "debug prefix timestamp",
1451 .p_class
= P_GLOBAL
,
1452 .offset
= GLOBAL_VAR(bDebugPrefixTimestamp
),
1455 .flags
= FLAG_ADVANCED
,
1458 .label
= "debug hires timestamp",
1460 .p_class
= P_GLOBAL
,
1461 .offset
= GLOBAL_VAR(bDebugHiresTimestamp
),
1464 .flags
= FLAG_ADVANCED
,
1467 .label
= "debug pid",
1469 .p_class
= P_GLOBAL
,
1470 .offset
= GLOBAL_VAR(bDebugPid
),
1473 .flags
= FLAG_ADVANCED
,
1476 .label
= "debug uid",
1478 .p_class
= P_GLOBAL
,
1479 .offset
= GLOBAL_VAR(bDebugUid
),
1482 .flags
= FLAG_ADVANCED
,
1485 .label
= "debug class",
1487 .p_class
= P_GLOBAL
,
1488 .offset
= GLOBAL_VAR(bDebugClass
),
1491 .flags
= FLAG_ADVANCED
,
1494 .label
= "enable core files",
1496 .p_class
= P_GLOBAL
,
1497 .offset
= GLOBAL_VAR(bEnableCoreFiles
),
1500 .flags
= FLAG_ADVANCED
,
1503 {N_("Protocol Options"), P_SEP
, P_SEPARATOR
},
1506 .label
= "allocation roundup size",
1509 .offset
= LOCAL_VAR(iallocation_roundup_size
),
1512 .flags
= FLAG_ADVANCED
,
1515 .label
= "aio read size",
1518 .offset
= LOCAL_VAR(iAioReadSize
),
1521 .flags
= FLAG_ADVANCED
,
1524 .label
= "aio write size",
1527 .offset
= LOCAL_VAR(iAioWriteSize
),
1530 .flags
= FLAG_ADVANCED
,
1533 .label
= "aio write behind",
1536 .offset
= LOCAL_VAR(szAioWriteBehind
),
1539 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1542 .label
= "smb ports",
1544 .p_class
= P_GLOBAL
,
1545 .offset
= GLOBAL_VAR(smb_ports
),
1548 .flags
= FLAG_ADVANCED
,
1551 .label
= "large readwrite",
1553 .p_class
= P_GLOBAL
,
1554 .offset
= GLOBAL_VAR(bLargeReadwrite
),
1557 .flags
= FLAG_ADVANCED
,
1560 .label
= "server max protocol",
1562 .p_class
= P_GLOBAL
,
1563 .offset
= GLOBAL_VAR(srv_maxprotocol
),
1565 .enum_list
= enum_protocol
,
1566 .flags
= FLAG_ADVANCED
,
1569 .label
= "max protocol",
1571 .p_class
= P_GLOBAL
,
1572 .offset
= GLOBAL_VAR(srv_maxprotocol
),
1574 .enum_list
= enum_protocol
,
1575 .flags
= FLAG_ADVANCED
,
1578 .label
= "protocol",
1580 .p_class
= P_GLOBAL
,
1581 .offset
= GLOBAL_VAR(srv_maxprotocol
),
1583 .enum_list
= enum_protocol
,
1584 .flags
= FLAG_ADVANCED
,
1587 .label
= "server min protocol",
1589 .p_class
= P_GLOBAL
,
1590 .offset
= GLOBAL_VAR(srv_minprotocol
),
1592 .enum_list
= enum_protocol
,
1593 .flags
= FLAG_ADVANCED
,
1596 .label
= "min protocol",
1598 .p_class
= P_GLOBAL
,
1599 .offset
= GLOBAL_VAR(srv_minprotocol
),
1601 .enum_list
= enum_protocol
,
1602 .flags
= FLAG_ADVANCED
,
1605 .label
= "client max protocol",
1607 .p_class
= P_GLOBAL
,
1608 .offset
= GLOBAL_VAR(cli_maxprotocol
),
1610 .enum_list
= enum_protocol
,
1611 .flags
= FLAG_ADVANCED
,
1614 .label
= "client min protocol",
1616 .p_class
= P_GLOBAL
,
1617 .offset
= GLOBAL_VAR(cli_minprotocol
),
1619 .enum_list
= enum_protocol
,
1620 .flags
= FLAG_ADVANCED
,
1625 .p_class
= P_GLOBAL
,
1626 .offset
= GLOBAL_VAR(bUnicode
),
1631 .label
= "min receivefile size",
1633 .p_class
= P_GLOBAL
,
1634 .offset
= GLOBAL_VAR(iminreceivefile
),
1637 .flags
= FLAG_ADVANCED
,
1640 .label
= "read raw",
1642 .p_class
= P_GLOBAL
,
1643 .offset
= GLOBAL_VAR(bReadRaw
),
1646 .flags
= FLAG_ADVANCED
,
1649 .label
= "write raw",
1651 .p_class
= P_GLOBAL
,
1652 .offset
= GLOBAL_VAR(bWriteRaw
),
1655 .flags
= FLAG_ADVANCED
,
1658 .label
= "disable netbios",
1660 .p_class
= P_GLOBAL
,
1661 .offset
= GLOBAL_VAR(bDisableNetbios
),
1664 .flags
= FLAG_ADVANCED
,
1667 .label
= "reset on zero vc",
1669 .p_class
= P_GLOBAL
,
1670 .offset
= GLOBAL_VAR(bResetOnZeroVC
),
1673 .flags
= FLAG_ADVANCED
,
1676 .label
= "log writeable files on exit",
1678 .p_class
= P_GLOBAL
,
1679 .offset
= GLOBAL_VAR(bLogWriteableFilesOnExit
),
1682 .flags
= FLAG_ADVANCED
,
1685 .label
= "acl compatibility",
1687 .p_class
= P_GLOBAL
,
1688 .offset
= GLOBAL_VAR(iAclCompat
),
1690 .enum_list
= enum_acl_compat_vals
,
1691 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1694 .label
= "defer sharing violations",
1696 .p_class
= P_GLOBAL
,
1697 .offset
= GLOBAL_VAR(bDeferSharingViolations
),
1700 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
1703 .label
= "ea support",
1706 .offset
= LOCAL_VAR(bEASupport
),
1709 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1712 .label
= "nt acl support",
1715 .offset
= LOCAL_VAR(bNTAclSupport
),
1718 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1721 .label
= "nt pipe support",
1723 .p_class
= P_GLOBAL
,
1724 .offset
= GLOBAL_VAR(bNTPipeSupport
),
1727 .flags
= FLAG_ADVANCED
,
1730 .label
= "nt status support",
1732 .p_class
= P_GLOBAL
,
1733 .offset
= GLOBAL_VAR(bNTStatusSupport
),
1736 .flags
= FLAG_ADVANCED
,
1739 .label
= "profile acls",
1742 .offset
= LOCAL_VAR(bProfileAcls
),
1745 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
1748 .label
= "map acl inherit",
1751 .offset
= LOCAL_VAR(bMap_acl_inherit
),
1754 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1757 .label
= "afs share",
1760 .offset
= LOCAL_VAR(bAfs_Share
),
1763 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1768 .p_class
= P_GLOBAL
,
1769 .offset
= GLOBAL_VAR(max_mux
),
1772 .flags
= FLAG_ADVANCED
,
1775 .label
= "max xmit",
1777 .p_class
= P_GLOBAL
,
1778 .offset
= GLOBAL_VAR(max_xmit
),
1781 .flags
= FLAG_ADVANCED
,
1784 .label
= "name resolve order",
1786 .p_class
= P_GLOBAL
,
1787 .offset
= GLOBAL_VAR(szNameResolveOrder
),
1790 .flags
= FLAG_ADVANCED
| FLAG_WIZARD
,
1795 .p_class
= P_GLOBAL
,
1796 .offset
= GLOBAL_VAR(max_ttl
),
1799 .flags
= FLAG_ADVANCED
,
1802 .label
= "max wins ttl",
1804 .p_class
= P_GLOBAL
,
1805 .offset
= GLOBAL_VAR(max_wins_ttl
),
1808 .flags
= FLAG_ADVANCED
,
1811 .label
= "min wins ttl",
1813 .p_class
= P_GLOBAL
,
1814 .offset
= GLOBAL_VAR(min_wins_ttl
),
1817 .flags
= FLAG_ADVANCED
,
1820 .label
= "time server",
1822 .p_class
= P_GLOBAL
,
1823 .offset
= GLOBAL_VAR(bTimeServer
),
1826 .flags
= FLAG_ADVANCED
,
1829 .label
= "unix extensions",
1831 .p_class
= P_GLOBAL
,
1832 .offset
= GLOBAL_VAR(bUnixExtensions
),
1835 .flags
= FLAG_ADVANCED
,
1838 .label
= "use spnego",
1840 .p_class
= P_GLOBAL
,
1841 .offset
= GLOBAL_VAR(bUseSpnego
),
1844 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
1847 .label
= "client signing",
1849 .p_class
= P_GLOBAL
,
1850 .offset
= GLOBAL_VAR(client_signing
),
1852 .enum_list
= enum_smb_signing_vals
,
1853 .flags
= FLAG_ADVANCED
,
1856 .label
= "server signing",
1858 .p_class
= P_GLOBAL
,
1859 .offset
= GLOBAL_VAR(server_signing
),
1861 .enum_list
= enum_smb_signing_vals
,
1862 .flags
= FLAG_ADVANCED
,
1865 .label
= "smb encrypt",
1868 .offset
= LOCAL_VAR(ismb_encrypt
),
1870 .enum_list
= enum_smb_signing_vals
,
1871 .flags
= FLAG_ADVANCED
,
1874 .label
= "client use spnego",
1876 .p_class
= P_GLOBAL
,
1877 .offset
= GLOBAL_VAR(bClientUseSpnego
),
1880 .flags
= FLAG_ADVANCED
,
1883 .label
= "client ldap sasl wrapping",
1885 .p_class
= P_GLOBAL
,
1886 .offset
= GLOBAL_VAR(client_ldap_sasl_wrapping
),
1888 .enum_list
= enum_ldap_sasl_wrapping
,
1889 .flags
= FLAG_ADVANCED
,
1892 .label
= "enable asu support",
1894 .p_class
= P_GLOBAL
,
1895 .offset
= GLOBAL_VAR(bASUSupport
),
1898 .flags
= FLAG_ADVANCED
,
1901 .label
= "svcctl list",
1903 .p_class
= P_GLOBAL
,
1904 .offset
= GLOBAL_VAR(szServicesList
),
1907 .flags
= FLAG_ADVANCED
,
1910 .label
= "cldap port",
1912 .p_class
= P_GLOBAL
,
1913 .offset
= GLOBAL_VAR(cldap_port
),
1918 .label
= "dgram port",
1920 .p_class
= P_GLOBAL
,
1921 .offset
= GLOBAL_VAR(dgram_port
),
1926 .label
= "nbt port",
1928 .p_class
= P_GLOBAL
,
1929 .offset
= GLOBAL_VAR(nbt_port
),
1934 .label
= "krb5 port",
1936 .p_class
= P_GLOBAL
,
1937 .offset
= GLOBAL_VAR(krb5_port
),
1942 .label
= "kpasswd port",
1944 .p_class
= P_GLOBAL
,
1945 .offset
= GLOBAL_VAR(kpasswd_port
),
1950 .label
= "web port",
1952 .p_class
= P_GLOBAL
,
1953 .offset
= GLOBAL_VAR(web_port
),
1958 .label
= "rpc big endian",
1960 .p_class
= P_GLOBAL
,
1961 .offset
= GLOBAL_VAR(bRpcBigEndian
),
1966 {N_("Tuning Options"), P_SEP
, P_SEPARATOR
},
1969 .label
= "block size",
1972 .offset
= LOCAL_VAR(iBlock_size
),
1975 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
1978 .label
= "deadtime",
1980 .p_class
= P_GLOBAL
,
1981 .offset
= GLOBAL_VAR(deadtime
),
1984 .flags
= FLAG_ADVANCED
,
1987 .label
= "getwd cache",
1989 .p_class
= P_GLOBAL
,
1990 .offset
= GLOBAL_VAR(getwd_cache
),
1993 .flags
= FLAG_ADVANCED
,
1996 .label
= "keepalive",
1998 .p_class
= P_GLOBAL
,
1999 .offset
= GLOBAL_VAR(iKeepalive
),
2002 .flags
= FLAG_ADVANCED
,
2005 .label
= "change notify",
2008 .offset
= LOCAL_VAR(bChangeNotify
),
2011 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2014 .label
= "directory name cache size",
2017 .offset
= LOCAL_VAR(iDirectoryNameCacheSize
),
2020 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2023 .label
= "kernel change notify",
2026 .offset
= LOCAL_VAR(bKernelChangeNotify
),
2029 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2032 .label
= "lpq cache time",
2034 .p_class
= P_GLOBAL
,
2035 .offset
= GLOBAL_VAR(lpqcachetime
),
2038 .flags
= FLAG_ADVANCED
,
2041 .label
= "max smbd processes",
2043 .p_class
= P_GLOBAL
,
2044 .offset
= GLOBAL_VAR(iMaxSmbdProcesses
),
2047 .flags
= FLAG_ADVANCED
,
2050 .label
= "max connections",
2053 .offset
= LOCAL_VAR(iMaxConnections
),
2056 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2059 .label
= "paranoid server security",
2061 .p_class
= P_GLOBAL
,
2062 .offset
= GLOBAL_VAR(paranoid_server_security
),
2065 .flags
= FLAG_ADVANCED
,
2068 .label
= "max disk size",
2070 .p_class
= P_GLOBAL
,
2071 .offset
= GLOBAL_VAR(maxdisksize
),
2074 .flags
= FLAG_ADVANCED
,
2077 .label
= "max open files",
2079 .p_class
= P_GLOBAL
,
2080 .offset
= GLOBAL_VAR(max_open_files
),
2083 .flags
= FLAG_ADVANCED
,
2086 .label
= "min print space",
2089 .offset
= LOCAL_VAR(iMinPrintSpace
),
2092 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2095 .label
= "socket options",
2097 .p_class
= P_GLOBAL
,
2098 .offset
= GLOBAL_VAR(socket_options
),
2101 .flags
= FLAG_ADVANCED
,
2104 .label
= "strict allocate",
2107 .offset
= LOCAL_VAR(bStrictAllocate
),
2110 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2113 .label
= "strict sync",
2116 .offset
= LOCAL_VAR(bStrictSync
),
2119 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2122 .label
= "sync always",
2125 .offset
= LOCAL_VAR(bSyncAlways
),
2128 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2131 .label
= "use mmap",
2133 .p_class
= P_GLOBAL
,
2134 .offset
= GLOBAL_VAR(bUseMmap
),
2137 .flags
= FLAG_ADVANCED
,
2140 .label
= "use sendfile",
2143 .offset
= LOCAL_VAR(bUseSendfile
),
2146 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2149 .label
= "hostname lookups",
2151 .p_class
= P_GLOBAL
,
2152 .offset
= GLOBAL_VAR(bHostnameLookups
),
2155 .flags
= FLAG_ADVANCED
,
2158 .label
= "write cache size",
2161 .offset
= LOCAL_VAR(iWriteCacheSize
),
2164 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2167 .label
= "name cache timeout",
2169 .p_class
= P_GLOBAL
,
2170 .offset
= GLOBAL_VAR(name_cache_timeout
),
2173 .flags
= FLAG_ADVANCED
,
2176 .label
= "ctdbd socket",
2178 .p_class
= P_GLOBAL
,
2179 .offset
= GLOBAL_VAR(ctdbdSocket
),
2182 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
2185 .label
= "cluster addresses",
2187 .p_class
= P_GLOBAL
,
2188 .offset
= GLOBAL_VAR(szClusterAddresses
),
2191 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
2194 .label
= "clustering",
2196 .p_class
= P_GLOBAL
,
2197 .offset
= GLOBAL_VAR(clustering
),
2200 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
2203 .label
= "ctdb timeout",
2205 .p_class
= P_GLOBAL
,
2206 .offset
= GLOBAL_VAR(ctdb_timeout
),
2209 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
2212 .label
= "ctdb locktime warn threshold",
2214 .p_class
= P_GLOBAL
,
2215 .offset
= GLOBAL_VAR(ctdb_locktime_warn_threshold
),
2218 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
2221 .label
= "smb2 max read",
2223 .p_class
= P_GLOBAL
,
2224 .offset
= GLOBAL_VAR(ismb2_max_read
),
2227 .flags
= FLAG_ADVANCED
,
2230 .label
= "smb2 max write",
2232 .p_class
= P_GLOBAL
,
2233 .offset
= GLOBAL_VAR(ismb2_max_write
),
2236 .flags
= FLAG_ADVANCED
,
2239 .label
= "smb2 max trans",
2241 .p_class
= P_GLOBAL
,
2242 .offset
= GLOBAL_VAR(ismb2_max_trans
),
2245 .flags
= FLAG_ADVANCED
,
2248 .label
= "smb2 max credits",
2250 .p_class
= P_GLOBAL
,
2251 .offset
= GLOBAL_VAR(ismb2_max_credits
),
2254 .flags
= FLAG_ADVANCED
,
2257 {N_("Printing Options"), P_SEP
, P_SEPARATOR
},
2260 .label
= "max reported print jobs",
2263 .offset
= LOCAL_VAR(iMaxReportedPrintJobs
),
2266 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2269 .label
= "max print jobs",
2272 .offset
= LOCAL_VAR(iMaxPrintJobs
),
2275 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2278 .label
= "load printers",
2280 .p_class
= P_GLOBAL
,
2281 .offset
= GLOBAL_VAR(bLoadPrinters
),
2284 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2287 .label
= "printcap cache time",
2289 .p_class
= P_GLOBAL
,
2290 .offset
= GLOBAL_VAR(PrintcapCacheTime
),
2293 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2296 .label
= "printcap name",
2298 .p_class
= P_GLOBAL
,
2299 .offset
= GLOBAL_VAR(szPrintcapname
),
2302 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2305 .label
= "printcap",
2307 .p_class
= P_GLOBAL
,
2308 .offset
= GLOBAL_VAR(szPrintcapname
),
2314 .label
= "printable",
2317 .offset
= LOCAL_VAR(bPrint_ok
),
2320 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2323 .label
= "print notify backchannel",
2326 .offset
= LOCAL_VAR(bPrintNotifyBackchannel
),
2329 .flags
= FLAG_ADVANCED
,
2332 .label
= "print ok",
2335 .offset
= LOCAL_VAR(bPrint_ok
),
2341 .label
= "printing",
2344 .offset
= LOCAL_VAR(iPrinting
),
2345 .special
= handle_printing
,
2346 .enum_list
= enum_printing
,
2347 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2350 .label
= "cups options",
2353 .offset
= LOCAL_VAR(szCupsOptions
),
2356 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2359 .label
= "cups server",
2361 .p_class
= P_GLOBAL
,
2362 .offset
= GLOBAL_VAR(szCupsServer
),
2365 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2368 .label
= "cups encrypt",
2370 .p_class
= P_GLOBAL
,
2371 .offset
= GLOBAL_VAR(CupsEncrypt
),
2373 .enum_list
= enum_bool_auto
,
2374 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2378 .label
= "cups connection timeout",
2380 .p_class
= P_GLOBAL
,
2381 .offset
= GLOBAL_VAR(cups_connection_timeout
),
2384 .flags
= FLAG_ADVANCED
,
2387 .label
= "iprint server",
2389 .p_class
= P_GLOBAL
,
2390 .offset
= GLOBAL_VAR(szIPrintServer
),
2393 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2396 .label
= "print command",
2399 .offset
= LOCAL_VAR(szPrintcommand
),
2402 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2405 .label
= "disable spoolss",
2407 .p_class
= P_GLOBAL
,
2408 .offset
= GLOBAL_VAR(bDisableSpoolss
),
2411 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2414 .label
= "enable spoolss",
2416 .p_class
= P_GLOBAL
,
2417 .offset
= GLOBAL_VAR(bDisableSpoolss
),
2423 .label
= "lpq command",
2426 .offset
= LOCAL_VAR(szLpqcommand
),
2429 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2432 .label
= "lprm command",
2435 .offset
= LOCAL_VAR(szLprmcommand
),
2438 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2441 .label
= "lppause command",
2444 .offset
= LOCAL_VAR(szLppausecommand
),
2447 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2450 .label
= "lpresume command",
2453 .offset
= LOCAL_VAR(szLpresumecommand
),
2456 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2459 .label
= "queuepause command",
2462 .offset
= LOCAL_VAR(szQueuepausecommand
),
2465 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2468 .label
= "queueresume command",
2471 .offset
= LOCAL_VAR(szQueueresumecommand
),
2474 .flags
= FLAG_ADVANCED
| FLAG_PRINT
| FLAG_GLOBAL
,
2477 .label
= "addport command",
2479 .p_class
= P_GLOBAL
,
2480 .offset
= GLOBAL_VAR(szAddPortCommand
),
2483 .flags
= FLAG_ADVANCED
,
2486 .label
= "enumports command",
2488 .p_class
= P_GLOBAL
,
2489 .offset
= GLOBAL_VAR(szEnumPortsCommand
),
2492 .flags
= FLAG_ADVANCED
,
2495 .label
= "addprinter command",
2497 .p_class
= P_GLOBAL
,
2498 .offset
= GLOBAL_VAR(szAddPrinterCommand
),
2501 .flags
= FLAG_ADVANCED
,
2504 .label
= "deleteprinter command",
2506 .p_class
= P_GLOBAL
,
2507 .offset
= GLOBAL_VAR(szDeletePrinterCommand
),
2510 .flags
= FLAG_ADVANCED
,
2513 .label
= "show add printer wizard",
2515 .p_class
= P_GLOBAL
,
2516 .offset
= GLOBAL_VAR(bMsAddPrinterWizard
),
2519 .flags
= FLAG_ADVANCED
,
2522 .label
= "os2 driver map",
2524 .p_class
= P_GLOBAL
,
2525 .offset
= GLOBAL_VAR(szOs2DriverMap
),
2528 .flags
= FLAG_ADVANCED
,
2532 .label
= "printer name",
2535 .offset
= LOCAL_VAR(szPrintername
),
2538 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2544 .offset
= LOCAL_VAR(szPrintername
),
2550 .label
= "use client driver",
2553 .offset
= LOCAL_VAR(bUseClientDriver
),
2556 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2559 .label
= "default devmode",
2562 .offset
= LOCAL_VAR(bDefaultDevmode
),
2565 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2568 .label
= "force printername",
2571 .offset
= LOCAL_VAR(bForcePrintername
),
2574 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2577 .label
= "printjob username",
2580 .offset
= LOCAL_VAR(szPrintjobUsername
),
2583 .flags
= FLAG_ADVANCED
| FLAG_PRINT
,
2586 {N_("Filename Handling"), P_SEP
, P_SEPARATOR
},
2589 .label
= "mangling method",
2591 .p_class
= P_GLOBAL
,
2592 .offset
= GLOBAL_VAR(szManglingMethod
),
2595 .flags
= FLAG_ADVANCED
,
2598 .label
= "mangle prefix",
2600 .p_class
= P_GLOBAL
,
2601 .offset
= GLOBAL_VAR(mangle_prefix
),
2604 .flags
= FLAG_ADVANCED
,
2608 .label
= "default case",
2611 .offset
= LOCAL_VAR(iDefaultCase
),
2613 .enum_list
= enum_case
,
2614 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
2617 .label
= "case sensitive",
2620 .offset
= LOCAL_VAR(iCaseSensitive
),
2622 .enum_list
= enum_bool_auto
,
2623 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2626 .label
= "casesignames",
2629 .offset
= LOCAL_VAR(iCaseSensitive
),
2631 .enum_list
= enum_bool_auto
,
2632 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
| FLAG_HIDE
,
2635 .label
= "preserve case",
2638 .offset
= LOCAL_VAR(bCasePreserve
),
2641 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2644 .label
= "short preserve case",
2647 .offset
= LOCAL_VAR(bShortCasePreserve
),
2650 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2653 .label
= "mangling char",
2656 .offset
= LOCAL_VAR(magic_char
),
2659 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2662 .label
= "hide dot files",
2665 .offset
= LOCAL_VAR(bHideDotFiles
),
2668 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2671 .label
= "hide special files",
2674 .offset
= LOCAL_VAR(bHideSpecialFiles
),
2677 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2680 .label
= "hide unreadable",
2683 .offset
= LOCAL_VAR(bHideUnReadable
),
2686 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2689 .label
= "hide unwriteable files",
2692 .offset
= LOCAL_VAR(bHideUnWriteableFiles
),
2695 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2698 .label
= "delete veto files",
2701 .offset
= LOCAL_VAR(bDeleteVetoFiles
),
2704 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2707 .label
= "veto files",
2710 .offset
= LOCAL_VAR(szVetoFiles
),
2713 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2716 .label
= "hide files",
2719 .offset
= LOCAL_VAR(szHideFiles
),
2722 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2725 .label
= "veto oplock files",
2728 .offset
= LOCAL_VAR(szVetoOplockFiles
),
2731 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2734 .label
= "map archive",
2737 .offset
= LOCAL_VAR(bMap_archive
),
2740 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2743 .label
= "map hidden",
2746 .offset
= LOCAL_VAR(bMap_hidden
),
2749 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2752 .label
= "map system",
2755 .offset
= LOCAL_VAR(bMap_system
),
2758 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2761 .label
= "map readonly",
2764 .offset
= LOCAL_VAR(iMap_readonly
),
2766 .enum_list
= enum_map_readonly
,
2767 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2770 .label
= "mangled names",
2773 .offset
= LOCAL_VAR(bMangledNames
),
2776 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2779 .label
= "max stat cache size",
2781 .p_class
= P_GLOBAL
,
2782 .offset
= GLOBAL_VAR(iMaxStatCacheSize
),
2785 .flags
= FLAG_ADVANCED
,
2788 .label
= "stat cache",
2790 .p_class
= P_GLOBAL
,
2791 .offset
= GLOBAL_VAR(bStatCache
),
2794 .flags
= FLAG_ADVANCED
,
2797 .label
= "store dos attributes",
2800 .offset
= LOCAL_VAR(bStoreDosAttributes
),
2803 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2806 .label
= "dmapi support",
2809 .offset
= LOCAL_VAR(bDmapiSupport
),
2812 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
2816 {N_("Domain Options"), P_SEP
, P_SEPARATOR
},
2819 .label
= "machine password timeout",
2821 .p_class
= P_GLOBAL
,
2822 .offset
= GLOBAL_VAR(machine_password_timeout
),
2825 .flags
= FLAG_ADVANCED
| FLAG_WIZARD
,
2828 {N_("Logon Options"), P_SEP
, P_SEPARATOR
},
2831 .label
= "add user script",
2833 .p_class
= P_GLOBAL
,
2834 .offset
= GLOBAL_VAR(szAddUserScript
),
2837 .flags
= FLAG_ADVANCED
,
2840 .label
= "rename user script",
2842 .p_class
= P_GLOBAL
,
2843 .offset
= GLOBAL_VAR(szRenameUserScript
),
2846 .flags
= FLAG_ADVANCED
,
2849 .label
= "delete user script",
2851 .p_class
= P_GLOBAL
,
2852 .offset
= GLOBAL_VAR(szDelUserScript
),
2855 .flags
= FLAG_ADVANCED
,
2858 .label
= "add group script",
2860 .p_class
= P_GLOBAL
,
2861 .offset
= GLOBAL_VAR(szAddGroupScript
),
2864 .flags
= FLAG_ADVANCED
,
2867 .label
= "delete group script",
2869 .p_class
= P_GLOBAL
,
2870 .offset
= GLOBAL_VAR(szDelGroupScript
),
2873 .flags
= FLAG_ADVANCED
,
2876 .label
= "add user to group script",
2878 .p_class
= P_GLOBAL
,
2879 .offset
= GLOBAL_VAR(szAddUserToGroupScript
),
2882 .flags
= FLAG_ADVANCED
,
2885 .label
= "delete user from group script",
2887 .p_class
= P_GLOBAL
,
2888 .offset
= GLOBAL_VAR(szDelUserFromGroupScript
),
2891 .flags
= FLAG_ADVANCED
,
2894 .label
= "set primary group script",
2896 .p_class
= P_GLOBAL
,
2897 .offset
= GLOBAL_VAR(szSetPrimaryGroupScript
),
2900 .flags
= FLAG_ADVANCED
,
2903 .label
= "add machine script",
2905 .p_class
= P_GLOBAL
,
2906 .offset
= GLOBAL_VAR(szAddMachineScript
),
2909 .flags
= FLAG_ADVANCED
,
2912 .label
= "shutdown script",
2914 .p_class
= P_GLOBAL
,
2915 .offset
= GLOBAL_VAR(szShutdownScript
),
2918 .flags
= FLAG_ADVANCED
,
2921 .label
= "abort shutdown script",
2923 .p_class
= P_GLOBAL
,
2924 .offset
= GLOBAL_VAR(szAbortShutdownScript
),
2927 .flags
= FLAG_ADVANCED
,
2930 .label
= "username map script",
2932 .p_class
= P_GLOBAL
,
2933 .offset
= GLOBAL_VAR(szUsernameMapScript
),
2936 .flags
= FLAG_ADVANCED
,
2939 .label
= "username map cache time",
2941 .p_class
= P_GLOBAL
,
2942 .offset
= GLOBAL_VAR(iUsernameMapCacheTime
),
2945 .flags
= FLAG_ADVANCED
,
2948 .label
= "logon script",
2950 .p_class
= P_GLOBAL
,
2951 .offset
= GLOBAL_VAR(szLogonScript
),
2954 .flags
= FLAG_ADVANCED
,
2957 .label
= "logon path",
2959 .p_class
= P_GLOBAL
,
2960 .offset
= GLOBAL_VAR(szLogonPath
),
2963 .flags
= FLAG_ADVANCED
,
2966 .label
= "logon drive",
2968 .p_class
= P_GLOBAL
,
2969 .offset
= GLOBAL_VAR(szLogonDrive
),
2972 .flags
= FLAG_ADVANCED
,
2975 .label
= "logon home",
2977 .p_class
= P_GLOBAL
,
2978 .offset
= GLOBAL_VAR(szLogonHome
),
2981 .flags
= FLAG_ADVANCED
,
2984 .label
= "domain logons",
2986 .p_class
= P_GLOBAL
,
2987 .offset
= GLOBAL_VAR(bDomainLogons
),
2990 .flags
= FLAG_ADVANCED
,
2994 .label
= "init logon delayed hosts",
2996 .p_class
= P_GLOBAL
,
2997 .offset
= GLOBAL_VAR(szInitLogonDelayedHosts
),
3000 .flags
= FLAG_ADVANCED
,
3004 .label
= "init logon delay",
3006 .p_class
= P_GLOBAL
,
3007 .offset
= GLOBAL_VAR(InitLogonDelay
),
3010 .flags
= FLAG_ADVANCED
,
3014 {N_("Browse Options"), P_SEP
, P_SEPARATOR
},
3017 .label
= "os level",
3019 .p_class
= P_GLOBAL
,
3020 .offset
= GLOBAL_VAR(os_level
),
3023 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
3026 .label
= "lm announce",
3028 .p_class
= P_GLOBAL
,
3029 .offset
= GLOBAL_VAR(lm_announce
),
3031 .enum_list
= enum_bool_auto
,
3032 .flags
= FLAG_ADVANCED
,
3035 .label
= "lm interval",
3037 .p_class
= P_GLOBAL
,
3038 .offset
= GLOBAL_VAR(lm_interval
),
3041 .flags
= FLAG_ADVANCED
,
3044 .label
= "preferred master",
3046 .p_class
= P_GLOBAL
,
3047 .offset
= GLOBAL_VAR(iPreferredMaster
),
3049 .enum_list
= enum_bool_auto
,
3050 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
3053 .label
= "prefered master",
3055 .p_class
= P_GLOBAL
,
3056 .offset
= GLOBAL_VAR(iPreferredMaster
),
3058 .enum_list
= enum_bool_auto
,
3062 .label
= "local master",
3064 .p_class
= P_GLOBAL
,
3065 .offset
= GLOBAL_VAR(bLocalMaster
),
3068 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
3071 .label
= "domain master",
3073 .p_class
= P_GLOBAL
,
3074 .offset
= GLOBAL_VAR(iDomainMaster
),
3076 .enum_list
= enum_bool_auto
,
3077 .flags
= FLAG_BASIC
| FLAG_ADVANCED
,
3080 .label
= "browse list",
3082 .p_class
= P_GLOBAL
,
3083 .offset
= GLOBAL_VAR(bBrowseList
),
3086 .flags
= FLAG_ADVANCED
,
3089 .label
= "browseable",
3092 .offset
= LOCAL_VAR(bBrowseable
),
3095 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
3098 .label
= "browsable",
3101 .offset
= LOCAL_VAR(bBrowseable
),
3107 .label
= "access based share enum",
3110 .offset
= LOCAL_VAR(bAccessBasedShareEnum
),
3113 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
3116 .label
= "enhanced browsing",
3118 .p_class
= P_GLOBAL
,
3119 .offset
= GLOBAL_VAR(enhanced_browsing
),
3122 .flags
= FLAG_ADVANCED
,
3125 {N_("WINS Options"), P_SEP
, P_SEPARATOR
},
3128 .label
= "dns proxy",
3130 .p_class
= P_GLOBAL
,
3131 .offset
= GLOBAL_VAR(bWINSdnsProxy
),
3134 .flags
= FLAG_ADVANCED
,
3137 .label
= "wins proxy",
3139 .p_class
= P_GLOBAL
,
3140 .offset
= GLOBAL_VAR(bWINSproxy
),
3143 .flags
= FLAG_ADVANCED
,
3146 .label
= "wins server",
3148 .p_class
= P_GLOBAL
,
3149 .offset
= GLOBAL_VAR(szWINSservers
),
3152 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
3155 .label
= "wins support",
3157 .p_class
= P_GLOBAL
,
3158 .offset
= GLOBAL_VAR(bWINSsupport
),
3161 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
,
3164 .label
= "wins hook",
3166 .p_class
= P_GLOBAL
,
3167 .offset
= GLOBAL_VAR(szWINSHook
),
3170 .flags
= FLAG_ADVANCED
,
3173 {N_("Locking Options"), P_SEP
, P_SEPARATOR
},
3176 .label
= "blocking locks",
3179 .offset
= LOCAL_VAR(bBlockingLocks
),
3182 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3185 .label
= "csc policy",
3188 .offset
= LOCAL_VAR(iCSCPolicy
),
3190 .enum_list
= enum_csc_policy
,
3191 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3194 .label
= "fake oplocks",
3197 .offset
= LOCAL_VAR(bFakeOplocks
),
3200 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3203 .label
= "kernel oplocks",
3206 .offset
= LOCAL_VAR(bKernelOplocks
),
3209 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3215 .offset
= LOCAL_VAR(bLocking
),
3218 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3221 .label
= "lock spin time",
3223 .p_class
= P_GLOBAL
,
3224 .offset
= GLOBAL_VAR(iLockSpinTime
),
3227 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
3233 .offset
= LOCAL_VAR(bOpLocks
),
3236 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3239 .label
= "level2 oplocks",
3242 .offset
= LOCAL_VAR(bLevel2OpLocks
),
3245 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3248 .label
= "oplock break wait time",
3250 .p_class
= P_GLOBAL
,
3251 .offset
= GLOBAL_VAR(oplock_break_wait_time
),
3254 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
3257 .label
= "oplock contention limit",
3260 .offset
= LOCAL_VAR(iOplockContentionLimit
),
3263 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3266 .label
= "posix locking",
3269 .offset
= LOCAL_VAR(bPosixLocking
),
3272 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3275 .label
= "strict locking",
3278 .offset
= LOCAL_VAR(iStrictLocking
),
3280 .enum_list
= enum_bool_auto
,
3281 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3284 {N_("Ldap Options"), P_SEP
, P_SEPARATOR
},
3287 .label
= "ldap admin dn",
3289 .p_class
= P_GLOBAL
,
3290 .offset
= GLOBAL_VAR(szLdapAdminDn
),
3293 .flags
= FLAG_ADVANCED
,
3296 .label
= "ldap delete dn",
3298 .p_class
= P_GLOBAL
,
3299 .offset
= GLOBAL_VAR(ldap_delete_dn
),
3302 .flags
= FLAG_ADVANCED
,
3305 .label
= "ldap group suffix",
3307 .p_class
= P_GLOBAL
,
3308 .offset
= GLOBAL_VAR(szLdapGroupSuffix
),
3311 .flags
= FLAG_ADVANCED
,
3314 .label
= "ldap idmap suffix",
3316 .p_class
= P_GLOBAL
,
3317 .offset
= GLOBAL_VAR(szLdapIdmapSuffix
),
3320 .flags
= FLAG_ADVANCED
,
3323 .label
= "ldap machine suffix",
3325 .p_class
= P_GLOBAL
,
3326 .offset
= GLOBAL_VAR(szLdapMachineSuffix
),
3329 .flags
= FLAG_ADVANCED
,
3332 .label
= "ldap passwd sync",
3334 .p_class
= P_GLOBAL
,
3335 .offset
= GLOBAL_VAR(ldap_passwd_sync
),
3337 .enum_list
= enum_ldap_passwd_sync
,
3338 .flags
= FLAG_ADVANCED
,
3341 .label
= "ldap password sync",
3343 .p_class
= P_GLOBAL
,
3344 .offset
= GLOBAL_VAR(ldap_passwd_sync
),
3346 .enum_list
= enum_ldap_passwd_sync
,
3350 .label
= "ldap replication sleep",
3352 .p_class
= P_GLOBAL
,
3353 .offset
= GLOBAL_VAR(ldap_replication_sleep
),
3356 .flags
= FLAG_ADVANCED
,
3359 .label
= "ldap suffix",
3361 .p_class
= P_GLOBAL
,
3362 .offset
= GLOBAL_VAR(szLdapSuffix
),
3365 .flags
= FLAG_ADVANCED
,
3368 .label
= "ldap ssl",
3370 .p_class
= P_GLOBAL
,
3371 .offset
= GLOBAL_VAR(ldap_ssl
),
3373 .enum_list
= enum_ldap_ssl
,
3374 .flags
= FLAG_ADVANCED
,
3377 .label
= "ldap ssl ads",
3379 .p_class
= P_GLOBAL
,
3380 .offset
= GLOBAL_VAR(ldap_ssl_ads
),
3383 .flags
= FLAG_ADVANCED
,
3386 .label
= "ldap deref",
3388 .p_class
= P_GLOBAL
,
3389 .offset
= GLOBAL_VAR(ldap_deref
),
3391 .enum_list
= enum_ldap_deref
,
3392 .flags
= FLAG_ADVANCED
,
3395 .label
= "ldap follow referral",
3397 .p_class
= P_GLOBAL
,
3398 .offset
= GLOBAL_VAR(ldap_follow_referral
),
3400 .enum_list
= enum_bool_auto
,
3401 .flags
= FLAG_ADVANCED
,
3404 .label
= "ldap timeout",
3406 .p_class
= P_GLOBAL
,
3407 .offset
= GLOBAL_VAR(ldap_timeout
),
3410 .flags
= FLAG_ADVANCED
,
3413 .label
= "ldap connection timeout",
3415 .p_class
= P_GLOBAL
,
3416 .offset
= GLOBAL_VAR(ldap_connection_timeout
),
3419 .flags
= FLAG_ADVANCED
,
3422 .label
= "ldap page size",
3424 .p_class
= P_GLOBAL
,
3425 .offset
= GLOBAL_VAR(ldap_page_size
),
3428 .flags
= FLAG_ADVANCED
,
3431 .label
= "ldap user suffix",
3433 .p_class
= P_GLOBAL
,
3434 .offset
= GLOBAL_VAR(szLdapUserSuffix
),
3437 .flags
= FLAG_ADVANCED
,
3440 .label
= "ldap debug level",
3442 .p_class
= P_GLOBAL
,
3443 .offset
= GLOBAL_VAR(ldap_debug_level
),
3444 .special
= handle_ldap_debug_level
,
3446 .flags
= FLAG_ADVANCED
,
3449 .label
= "ldap debug threshold",
3451 .p_class
= P_GLOBAL
,
3452 .offset
= GLOBAL_VAR(ldap_debug_threshold
),
3455 .flags
= FLAG_ADVANCED
,
3458 {N_("EventLog Options"), P_SEP
, P_SEPARATOR
},
3461 .label
= "eventlog list",
3463 .p_class
= P_GLOBAL
,
3464 .offset
= GLOBAL_VAR(szEventLogs
),
3467 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
| FLAG_SHARE
,
3470 {N_("Miscellaneous Options"), P_SEP
, P_SEPARATOR
},
3473 .label
= "add share command",
3475 .p_class
= P_GLOBAL
,
3476 .offset
= GLOBAL_VAR(szAddShareCommand
),
3479 .flags
= FLAG_ADVANCED
,
3482 .label
= "change share command",
3484 .p_class
= P_GLOBAL
,
3485 .offset
= GLOBAL_VAR(szChangeShareCommand
),
3488 .flags
= FLAG_ADVANCED
,
3491 .label
= "delete share command",
3493 .p_class
= P_GLOBAL
,
3494 .offset
= GLOBAL_VAR(szDeleteShareCommand
),
3497 .flags
= FLAG_ADVANCED
,
3500 .label
= "config file",
3502 .p_class
= P_GLOBAL
,
3503 .offset
= GLOBAL_VAR(szConfigFile
),
3506 .flags
= FLAG_HIDE
|FLAG_META
,
3511 .p_class
= P_GLOBAL
,
3512 .offset
= GLOBAL_VAR(szAutoServices
),
3515 .flags
= FLAG_ADVANCED
,
3518 .label
= "auto services",
3520 .p_class
= P_GLOBAL
,
3521 .offset
= GLOBAL_VAR(szAutoServices
),
3524 .flags
= FLAG_ADVANCED
,
3527 .label
= "lock directory",
3529 .p_class
= P_GLOBAL
,
3530 .offset
= GLOBAL_VAR(szLockDir
),
3533 .flags
= FLAG_ADVANCED
,
3536 .label
= "lock dir",
3538 .p_class
= P_GLOBAL
,
3539 .offset
= GLOBAL_VAR(szLockDir
),
3545 .label
= "state directory",
3547 .p_class
= P_GLOBAL
,
3548 .offset
= GLOBAL_VAR(szStateDir
),
3551 .flags
= FLAG_ADVANCED
,
3554 .label
= "cache directory",
3556 .p_class
= P_GLOBAL
,
3557 .offset
= GLOBAL_VAR(szCacheDir
),
3560 .flags
= FLAG_ADVANCED
,
3563 .label
= "pid directory",
3565 .p_class
= P_GLOBAL
,
3566 .offset
= GLOBAL_VAR(szPidDir
),
3569 .flags
= FLAG_ADVANCED
,
3572 .label
= "ntp signd socket directory",
3574 .p_class
= P_GLOBAL
,
3575 .offset
= GLOBAL_VAR(szNTPSignDSocketDirectory
),
3578 .flags
= FLAG_ADVANCED
,
3583 .label
= "utmp directory",
3585 .p_class
= P_GLOBAL
,
3586 .offset
= GLOBAL_VAR(szUtmpDir
),
3589 .flags
= FLAG_ADVANCED
,
3592 .label
= "wtmp directory",
3594 .p_class
= P_GLOBAL
,
3595 .offset
= GLOBAL_VAR(szWtmpDir
),
3598 .flags
= FLAG_ADVANCED
,
3603 .p_class
= P_GLOBAL
,
3604 .offset
= GLOBAL_VAR(bUtmp
),
3607 .flags
= FLAG_ADVANCED
,
3611 .label
= "default service",
3613 .p_class
= P_GLOBAL
,
3614 .offset
= GLOBAL_VAR(szDefaultService
),
3617 .flags
= FLAG_ADVANCED
,
3622 .p_class
= P_GLOBAL
,
3623 .offset
= GLOBAL_VAR(szDefaultService
),
3626 .flags
= FLAG_ADVANCED
,
3629 .label
= "message command",
3631 .p_class
= P_GLOBAL
,
3632 .offset
= GLOBAL_VAR(szMsgCommand
),
3635 .flags
= FLAG_ADVANCED
,
3638 .label
= "dfree cache time",
3641 .offset
= LOCAL_VAR(iDfreeCacheTime
),
3644 .flags
= FLAG_ADVANCED
,
3647 .label
= "dfree command",
3650 .offset
= LOCAL_VAR(szDfree
),
3653 .flags
= FLAG_ADVANCED
,
3656 .label
= "get quota command",
3658 .p_class
= P_GLOBAL
,
3659 .offset
= GLOBAL_VAR(szGetQuota
),
3662 .flags
= FLAG_ADVANCED
,
3665 .label
= "set quota command",
3667 .p_class
= P_GLOBAL
,
3668 .offset
= GLOBAL_VAR(szSetQuota
),
3671 .flags
= FLAG_ADVANCED
,
3674 .label
= "remote announce",
3676 .p_class
= P_GLOBAL
,
3677 .offset
= GLOBAL_VAR(szRemoteAnnounce
),
3680 .flags
= FLAG_ADVANCED
,
3683 .label
= "remote browse sync",
3685 .p_class
= P_GLOBAL
,
3686 .offset
= GLOBAL_VAR(szRemoteBrowseSync
),
3689 .flags
= FLAG_ADVANCED
,
3692 .label
= "socket address",
3694 .p_class
= P_GLOBAL
,
3695 .offset
= GLOBAL_VAR(szSocketAddress
),
3698 .flags
= FLAG_ADVANCED
,
3701 .label
= "nmbd bind explicit broadcast",
3703 .p_class
= P_GLOBAL
,
3704 .offset
= GLOBAL_VAR(bNmbdBindExplicitBroadcast
),
3707 .flags
= FLAG_ADVANCED
,
3710 .label
= "homedir map",
3712 .p_class
= P_GLOBAL
,
3713 .offset
= GLOBAL_VAR(szNISHomeMapName
),
3716 .flags
= FLAG_ADVANCED
,
3719 .label
= "afs username map",
3721 .p_class
= P_GLOBAL
,
3722 .offset
= GLOBAL_VAR(szAfsUsernameMap
),
3725 .flags
= FLAG_ADVANCED
,
3728 .label
= "afs token lifetime",
3730 .p_class
= P_GLOBAL
,
3731 .offset
= GLOBAL_VAR(iAfsTokenLifetime
),
3734 .flags
= FLAG_ADVANCED
,
3737 .label
= "log nt token command",
3739 .p_class
= P_GLOBAL
,
3740 .offset
= GLOBAL_VAR(szLogNtTokenCommand
),
3743 .flags
= FLAG_ADVANCED
,
3746 .label
= "NIS homedir",
3748 .p_class
= P_GLOBAL
,
3749 .offset
= GLOBAL_VAR(bNISHomeMap
),
3752 .flags
= FLAG_ADVANCED
,
3758 .offset
= LOCAL_VAR(valid
),
3767 .offset
= LOCAL_VAR(szCopy
),
3768 .special
= handle_copy
,
3776 .offset
= LOCAL_VAR(szInclude
),
3777 .special
= handle_include
,
3779 .flags
= FLAG_HIDE
|FLAG_META
,
3785 .offset
= LOCAL_VAR(szPreExec
),
3788 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
3794 .offset
= LOCAL_VAR(szPreExec
),
3797 .flags
= FLAG_ADVANCED
,
3800 .label
= "preexec close",
3803 .offset
= LOCAL_VAR(bPreexecClose
),
3806 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3809 .label
= "postexec",
3812 .offset
= LOCAL_VAR(szPostExec
),
3815 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
3818 .label
= "root preexec",
3821 .offset
= LOCAL_VAR(szRootPreExec
),
3824 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
3827 .label
= "root preexec close",
3830 .offset
= LOCAL_VAR(bRootpreexecClose
),
3833 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3836 .label
= "root postexec",
3839 .offset
= LOCAL_VAR(szRootPostExec
),
3842 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
3845 .label
= "available",
3848 .offset
= LOCAL_VAR(bAvailable
),
3851 .flags
= FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
,
3854 .label
= "registry shares",
3856 .p_class
= P_GLOBAL
,
3857 .offset
= GLOBAL_VAR(bRegistryShares
),
3860 .flags
= FLAG_ADVANCED
,
3863 .label
= "usershare allow guests",
3865 .p_class
= P_GLOBAL
,
3866 .offset
= GLOBAL_VAR(bUsershareAllowGuests
),
3869 .flags
= FLAG_ADVANCED
,
3872 .label
= "usershare max shares",
3874 .p_class
= P_GLOBAL
,
3875 .offset
= GLOBAL_VAR(iUsershareMaxShares
),
3878 .flags
= FLAG_ADVANCED
,
3881 .label
= "usershare owner only",
3883 .p_class
= P_GLOBAL
,
3884 .offset
= GLOBAL_VAR(bUsershareOwnerOnly
),
3887 .flags
= FLAG_ADVANCED
,
3890 .label
= "usershare path",
3892 .p_class
= P_GLOBAL
,
3893 .offset
= GLOBAL_VAR(szUsersharePath
),
3896 .flags
= FLAG_ADVANCED
,
3899 .label
= "usershare prefix allow list",
3901 .p_class
= P_GLOBAL
,
3902 .offset
= GLOBAL_VAR(szUsersharePrefixAllowList
),
3905 .flags
= FLAG_ADVANCED
,
3908 .label
= "usershare prefix deny list",
3910 .p_class
= P_GLOBAL
,
3911 .offset
= GLOBAL_VAR(szUsersharePrefixDenyList
),
3914 .flags
= FLAG_ADVANCED
,
3917 .label
= "usershare template share",
3919 .p_class
= P_GLOBAL
,
3920 .offset
= GLOBAL_VAR(szUsershareTemplateShare
),
3923 .flags
= FLAG_ADVANCED
,
3929 .offset
= LOCAL_VAR(volume
),
3932 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3938 .offset
= LOCAL_VAR(fstype
),
3941 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3944 .label
= "set directory",
3947 .offset
= LOCAL_VAR(bNo_set_dir
),
3950 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3953 .label
= "allow insecure wide links",
3955 .p_class
= P_GLOBAL
,
3956 .offset
= GLOBAL_VAR(bAllowInsecureWidelinks
),
3959 .flags
= FLAG_ADVANCED
,
3962 .label
= "wide links",
3965 .offset
= LOCAL_VAR(bWidelinks
),
3968 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3971 .label
= "follow symlinks",
3974 .offset
= LOCAL_VAR(bSymlinks
),
3977 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
3980 .label
= "dont descend",
3983 .offset
= LOCAL_VAR(szDontdescend
),
3986 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3989 .label
= "magic script",
3992 .offset
= LOCAL_VAR(szMagicScript
),
3995 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
3998 .label
= "magic output",
4001 .offset
= LOCAL_VAR(szMagicOutput
),
4004 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
4007 .label
= "delete readonly",
4010 .offset
= LOCAL_VAR(bDeleteReadonly
),
4013 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
4016 .label
= "dos filemode",
4019 .offset
= LOCAL_VAR(bDosFilemode
),
4022 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
4025 .label
= "dos filetimes",
4028 .offset
= LOCAL_VAR(bDosFiletimes
),
4031 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
4034 .label
= "dos filetime resolution",
4037 .offset
= LOCAL_VAR(bDosFiletimeResolution
),
4040 .flags
= FLAG_ADVANCED
| FLAG_SHARE
| FLAG_GLOBAL
,
4043 .label
= "fake directory create times",
4046 .offset
= LOCAL_VAR(bFakeDirCreateTimes
),
4049 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
4052 .label
= "async smb echo handler",
4054 .p_class
= P_GLOBAL
,
4055 .offset
= GLOBAL_VAR(bAsyncSMBEchoHandler
),
4058 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
4061 .label
= "panic action",
4063 .p_class
= P_GLOBAL
,
4064 .offset
= GLOBAL_VAR(szPanicAction
),
4067 .flags
= FLAG_ADVANCED
,
4070 .label
= "perfcount module",
4072 .p_class
= P_GLOBAL
,
4073 .offset
= GLOBAL_VAR(szSMBPerfcountModule
),
4076 .flags
= FLAG_ADVANCED
,
4079 {N_("VFS module options"), P_SEP
, P_SEPARATOR
},
4082 .label
= "vfs objects",
4085 .offset
= LOCAL_VAR(szVfsObjects
),
4088 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
4091 .label
= "vfs object",
4094 .offset
= LOCAL_VAR(szVfsObjects
),
4101 {N_("MSDFS options"), P_SEP
, P_SEPARATOR
},
4104 .label
= "msdfs root",
4107 .offset
= LOCAL_VAR(bMSDfsRoot
),
4110 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
4113 .label
= "msdfs proxy",
4116 .offset
= LOCAL_VAR(szMSDfsProxy
),
4119 .flags
= FLAG_ADVANCED
| FLAG_SHARE
,
4122 .label
= "host msdfs",
4124 .p_class
= P_GLOBAL
,
4125 .offset
= GLOBAL_VAR(bHostMSDfs
),
4128 .flags
= FLAG_ADVANCED
,
4131 {N_("Winbind options"), P_SEP
, P_SEPARATOR
},
4134 .label
= "passdb expand explicit",
4136 .p_class
= P_GLOBAL
,
4137 .offset
= GLOBAL_VAR(bPassdbExpandExplicit
),
4140 .flags
= FLAG_ADVANCED
,
4143 .label
= "idmap backend",
4145 .p_class
= P_GLOBAL
,
4146 .offset
= GLOBAL_VAR(szIdmapBackend
),
4147 .special
= handle_idmap_backend
,
4149 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
4152 .label
= "idmap cache time",
4154 .p_class
= P_GLOBAL
,
4155 .offset
= GLOBAL_VAR(iIdmapCacheTime
),
4158 .flags
= FLAG_ADVANCED
,
4161 .label
= "idmap negative cache time",
4163 .p_class
= P_GLOBAL
,
4164 .offset
= GLOBAL_VAR(iIdmapNegativeCacheTime
),
4167 .flags
= FLAG_ADVANCED
,
4170 .label
= "idmap uid",
4172 .p_class
= P_GLOBAL
,
4173 .offset
= GLOBAL_VAR(szIdmapUID
),
4174 .special
= handle_idmap_uid
,
4176 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
4179 .label
= "winbind uid",
4181 .p_class
= P_GLOBAL
,
4182 .offset
= GLOBAL_VAR(szIdmapUID
),
4183 .special
= handle_idmap_uid
,
4188 .label
= "idmap gid",
4190 .p_class
= P_GLOBAL
,
4191 .offset
= GLOBAL_VAR(szIdmapGID
),
4192 .special
= handle_idmap_gid
,
4194 .flags
= FLAG_ADVANCED
| FLAG_DEPRECATED
,
4197 .label
= "winbind gid",
4199 .p_class
= P_GLOBAL
,
4200 .offset
= GLOBAL_VAR(szIdmapGID
),
4201 .special
= handle_idmap_gid
,
4206 .label
= "template homedir",
4208 .p_class
= P_GLOBAL
,
4209 .offset
= GLOBAL_VAR(szTemplateHomedir
),
4212 .flags
= FLAG_ADVANCED
,
4215 .label
= "template shell",
4217 .p_class
= P_GLOBAL
,
4218 .offset
= GLOBAL_VAR(szTemplateShell
),
4221 .flags
= FLAG_ADVANCED
,
4224 .label
= "winbind separator",
4226 .p_class
= P_GLOBAL
,
4227 .offset
= GLOBAL_VAR(szWinbindSeparator
),
4230 .flags
= FLAG_ADVANCED
,
4233 .label
= "winbind cache time",
4235 .p_class
= P_GLOBAL
,
4236 .offset
= GLOBAL_VAR(winbind_cache_time
),
4239 .flags
= FLAG_ADVANCED
,
4242 .label
= "winbind reconnect delay",
4244 .p_class
= P_GLOBAL
,
4245 .offset
= GLOBAL_VAR(winbind_reconnect_delay
),
4248 .flags
= FLAG_ADVANCED
,
4251 .label
= "winbind max clients",
4253 .p_class
= P_GLOBAL
,
4254 .offset
= GLOBAL_VAR(winbind_max_clients
),
4257 .flags
= FLAG_ADVANCED
,
4260 .label
= "winbind enum users",
4262 .p_class
= P_GLOBAL
,
4263 .offset
= GLOBAL_VAR(bWinbindEnumUsers
),
4266 .flags
= FLAG_ADVANCED
,
4269 .label
= "winbind enum groups",
4271 .p_class
= P_GLOBAL
,
4272 .offset
= GLOBAL_VAR(bWinbindEnumGroups
),
4275 .flags
= FLAG_ADVANCED
,
4278 .label
= "winbind use default domain",
4280 .p_class
= P_GLOBAL
,
4281 .offset
= GLOBAL_VAR(bWinbindUseDefaultDomain
),
4284 .flags
= FLAG_ADVANCED
,
4287 .label
= "winbind trusted domains only",
4289 .p_class
= P_GLOBAL
,
4290 .offset
= GLOBAL_VAR(bWinbindTrustedDomainsOnly
),
4293 .flags
= FLAG_ADVANCED
,
4296 .label
= "winbind nested groups",
4298 .p_class
= P_GLOBAL
,
4299 .offset
= GLOBAL_VAR(bWinbindNestedGroups
),
4302 .flags
= FLAG_ADVANCED
,
4305 .label
= "winbind expand groups",
4307 .p_class
= P_GLOBAL
,
4308 .offset
= GLOBAL_VAR(winbind_expand_groups
),
4311 .flags
= FLAG_ADVANCED
,
4314 .label
= "winbind nss info",
4316 .p_class
= P_GLOBAL
,
4317 .offset
= GLOBAL_VAR(szWinbindNssInfo
),
4320 .flags
= FLAG_ADVANCED
,
4323 .label
= "winbind refresh tickets",
4325 .p_class
= P_GLOBAL
,
4326 .offset
= GLOBAL_VAR(bWinbindRefreshTickets
),
4329 .flags
= FLAG_ADVANCED
,
4332 .label
= "winbind offline logon",
4334 .p_class
= P_GLOBAL
,
4335 .offset
= GLOBAL_VAR(bWinbindOfflineLogon
),
4338 .flags
= FLAG_ADVANCED
,
4341 .label
= "winbind normalize names",
4343 .p_class
= P_GLOBAL
,
4344 .offset
= GLOBAL_VAR(bWinbindNormalizeNames
),
4347 .flags
= FLAG_ADVANCED
,
4350 .label
= "winbind rpc only",
4352 .p_class
= P_GLOBAL
,
4353 .offset
= GLOBAL_VAR(bWinbindRpcOnly
),
4356 .flags
= FLAG_ADVANCED
,
4359 .label
= "create krb5 conf",
4361 .p_class
= P_GLOBAL
,
4362 .offset
= GLOBAL_VAR(bCreateKrb5Conf
),
4365 .flags
= FLAG_ADVANCED
,
4368 .label
= "ncalrpc dir",
4370 .p_class
= P_GLOBAL
,
4371 .offset
= GLOBAL_VAR(ncalrpc_dir
),
4374 .flags
= FLAG_ADVANCED
,
4377 .label
= "winbind max domain connections",
4379 .p_class
= P_GLOBAL
,
4380 .offset
= GLOBAL_VAR(winbindMaxDomainConnections
),
4383 .flags
= FLAG_ADVANCED
,
4386 .label
= "winbindd socket directory",
4388 .p_class
= P_GLOBAL
,
4389 .offset
= GLOBAL_VAR(szWinbinddSocketDirectory
),
4392 .flags
= FLAG_ADVANCED
,
4395 .label
= "winbindd privileged socket directory",
4397 .p_class
= P_GLOBAL
,
4398 .offset
= GLOBAL_VAR(szWinbinddPrivilegedSocketDirectory
),
4401 .flags
= FLAG_ADVANCED
,
4404 .label
= "winbind sealed pipes",
4406 .p_class
= P_GLOBAL
,
4407 .offset
= GLOBAL_VAR(bWinbindSealedPipes
),
4410 .flags
= FLAG_ADVANCED
,
4413 {N_("DNS options"), P_SEP
, P_SEPARATOR
},
4415 .label
= "allow dns updates",
4417 .p_class
= P_GLOBAL
,
4418 .offset
= GLOBAL_VAR(allow_dns_updates
),
4420 .enum_list
= enum_dns_update_settings
,
4421 .flags
= FLAG_ADVANCED
,
4424 .label
= "dns forwarder",
4426 .p_class
= P_GLOBAL
,
4427 .offset
= GLOBAL_VAR(dns_forwarder
),
4430 .flags
= FLAG_ADVANCED
,
4433 .label
= "dns recursive queries",
4435 .p_class
= P_GLOBAL
,
4436 .offset
= GLOBAL_VAR(dns_recursive_queries
),
4441 .label
= "dns update command",
4443 .p_class
= P_GLOBAL
,
4444 .offset
= GLOBAL_VAR(szDNSUpdateCommand
),
4447 .flags
= FLAG_ADVANCED
,
4450 .label
= "nsupdate command",
4452 .p_class
= P_GLOBAL
,
4453 .offset
= GLOBAL_VAR(szNSUpdateCommand
),
4456 .flags
= FLAG_ADVANCED
,
4459 .label
= "rndc command",
4461 .p_class
= P_GLOBAL
,
4462 .offset
= GLOBAL_VAR(szRNDCCommand
),
4465 .flags
= FLAG_ADVANCED
,
4468 .label
= "multicast dns register",
4470 .p_class
= P_GLOBAL
,
4471 .offset
= GLOBAL_VAR(bMulticastDnsRegister
),
4474 .flags
= FLAG_ADVANCED
| FLAG_GLOBAL
,
4477 {N_("AD DC options"), P_SEP
, P_SEPARATOR
},
4480 .label
= "samba kcc command",
4482 .p_class
= P_GLOBAL
,
4483 .offset
= GLOBAL_VAR(szSambaKCCCommand
),
4486 .flags
= FLAG_ADVANCED
,
4489 .label
= "server services",
4491 .p_class
= P_GLOBAL
,
4492 .offset
= GLOBAL_VAR(server_services
),
4497 .label
= "dcerpc endpoint servers",
4499 .p_class
= P_GLOBAL
,
4500 .offset
= GLOBAL_VAR(dcerpc_ep_servers
),
4505 .label
= "spn update command",
4507 .p_class
= P_GLOBAL
,
4508 .offset
= GLOBAL_VAR(szSPNUpdateCommand
),
4511 .flags
= FLAG_ADVANCED
,
4514 .label
= "share backend",
4516 .p_class
= P_GLOBAL
,
4517 .offset
= GLOBAL_VAR(szShareBackend
),
4522 .label
= "ntvfs handler",
4525 .offset
= LOCAL_VAR(ntvfs_handler
),
4530 {N_("TLS options"), P_SEP
, P_SEPARATOR
},
4533 .label
= "tls enabled",
4535 .p_class
= P_GLOBAL
,
4536 .offset
= GLOBAL_VAR(tls_enabled
),
4541 .label
= "tls keyfile",
4543 .p_class
= P_GLOBAL
,
4544 .offset
= GLOBAL_VAR(tls_keyfile
),
4549 .label
= "tls certfile",
4551 .p_class
= P_GLOBAL
,
4552 .offset
= GLOBAL_VAR(tls_certfile
),
4557 .label
= "tls cafile",
4559 .p_class
= P_GLOBAL
,
4560 .offset
= GLOBAL_VAR(tls_cafile
),
4565 .label
= "tls crlfile",
4567 .p_class
= P_GLOBAL
,
4568 .offset
= GLOBAL_VAR(tls_crlfile
),
4573 .label
= "tls dh params file",
4575 .p_class
= P_GLOBAL
,
4576 .offset
= GLOBAL_VAR(tls_dhpfile
),
4581 {NULL
, P_BOOL
, P_NONE
, 0, NULL
, NULL
, 0}
4584 /***************************************************************************
4585 Initialise the sDefault parameter structure for the printer values.
4586 ***************************************************************************/
4588 static void init_printer_values(struct loadparm_service
*pService
)
4590 /* choose defaults depending on the type of printing */
4591 switch (pService
->iPrinting
) {
4596 string_set(&pService
->szLpqcommand
, "lpq -P'%p'");
4597 string_set(&pService
->szLprmcommand
, "lprm -P'%p' %j");
4598 string_set(&pService
->szPrintcommand
, "lpr -r -P'%p' %s");
4603 string_set(&pService
->szLpqcommand
, "lpq -P'%p'");
4604 string_set(&pService
->szLprmcommand
, "lprm -P'%p' %j");
4605 string_set(&pService
->szPrintcommand
, "lpr -r -P'%p' %s");
4606 string_set(&pService
->szQueuepausecommand
, "lpc stop '%p'");
4607 string_set(&pService
->szQueueresumecommand
, "lpc start '%p'");
4608 string_set(&pService
->szLppausecommand
, "lpc hold '%p' %j");
4609 string_set(&pService
->szLpresumecommand
, "lpc release '%p' %j");
4615 /* set the lpq command to contain the destination printer
4616 name only. This is used by cups_queue_get() */
4617 string_set(&pService
->szLpqcommand
, "%p");
4618 string_set(&pService
->szLprmcommand
, "");
4619 string_set(&pService
->szPrintcommand
, "");
4620 string_set(&pService
->szLppausecommand
, "");
4621 string_set(&pService
->szLpresumecommand
, "");
4622 string_set(&pService
->szQueuepausecommand
, "");
4623 string_set(&pService
->szQueueresumecommand
, "");
4625 string_set(&pService
->szLpqcommand
, "lpq -P'%p'");
4626 string_set(&pService
->szLprmcommand
, "lprm -P'%p' %j");
4627 string_set(&pService
->szPrintcommand
, "lpr -P'%p' %s; rm %s");
4628 string_set(&pService
->szLppausecommand
, "lp -i '%p-%j' -H hold");
4629 string_set(&pService
->szLpresumecommand
, "lp -i '%p-%j' -H resume");
4630 string_set(&pService
->szQueuepausecommand
, "disable '%p'");
4631 string_set(&pService
->szQueueresumecommand
, "enable '%p'");
4632 #endif /* HAVE_CUPS */
4637 string_set(&pService
->szLpqcommand
, "lpstat -o%p");
4638 string_set(&pService
->szLprmcommand
, "cancel %p-%j");
4639 string_set(&pService
->szPrintcommand
, "lp -c -d%p %s; rm %s");
4640 string_set(&pService
->szQueuepausecommand
, "disable %p");
4641 string_set(&pService
->szQueueresumecommand
, "enable %p");
4643 string_set(&pService
->szLppausecommand
, "lp -i %p-%j -H hold");
4644 string_set(&pService
->szLpresumecommand
, "lp -i %p-%j -H resume");
4649 string_set(&pService
->szLpqcommand
, "lpq -P%p");
4650 string_set(&pService
->szLprmcommand
, "lprm -P%p %j");
4651 string_set(&pService
->szPrintcommand
, "lp -r -P%p %s");
4654 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4658 const char *tdbfile
;
4659 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
4662 tdbfile
= talloc_asprintf(
4663 tmp_ctx
, "tdbfile=%s",
4664 lp_parm_const_string(-1, "vlp", "tdbfile",
4666 if (tdbfile
== NULL
) {
4667 tdbfile
="tdbfile=/tmp/vlp.tdb";
4670 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s print %%p %%s",
4672 string_set(&pService
->szPrintcommand
,
4673 tmp
? tmp
: "vlp print %p %s");
4675 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpq %%p",
4677 string_set(&pService
->szLpqcommand
,
4678 tmp
? tmp
: "vlp lpq %p");
4680 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lprm %%p %%j",
4682 string_set(&pService
->szLprmcommand
,
4683 tmp
? tmp
: "vlp lprm %p %j");
4685 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lppause %%p %%j",
4687 string_set(&pService
->szLppausecommand
,
4688 tmp
? tmp
: "vlp lppause %p %j");
4690 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpresume %%p %%j",
4692 string_set(&pService
->szLpresumecommand
,
4693 tmp
? tmp
: "vlp lpresume %p %j");
4695 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queuepause %%p",
4697 string_set(&pService
->szQueuepausecommand
,
4698 tmp
? tmp
: "vlp queuepause %p");
4700 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queueresume %%p",
4702 string_set(&pService
->szQueueresumecommand
,
4703 tmp
? tmp
: "vlp queueresume %p");
4704 TALLOC_FREE(tmp_ctx
);
4708 #endif /* DEVELOPER */
4713 * Function to return the default value for the maximum number of open
4714 * file descriptors permitted. This function tries to consult the
4715 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4716 * the smaller of those.
4718 static int max_open_files(void)
4720 int sysctl_max
= MAX_OPEN_FILES
;
4721 int rlimit_max
= MAX_OPEN_FILES
;
4723 #ifdef HAVE_SYSCTLBYNAME
4725 size_t size
= sizeof(sysctl_max
);
4726 sysctlbyname("kern.maxfilesperproc", &sysctl_max
, &size
, NULL
,
4731 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4737 if (getrlimit(RLIMIT_NOFILE
, &rl
) == 0)
4738 rlimit_max
= rl
.rlim_cur
;
4740 #if defined(RLIM_INFINITY)
4741 if(rl
.rlim_cur
== RLIM_INFINITY
)
4742 rlimit_max
= MAX_OPEN_FILES
;
4747 if (sysctl_max
< MIN_OPEN_FILES_WINDOWS
) {
4748 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4749 "minimum Windows limit (%d)\n",
4751 MIN_OPEN_FILES_WINDOWS
));
4752 sysctl_max
= MIN_OPEN_FILES_WINDOWS
;
4755 if (rlimit_max
< MIN_OPEN_FILES_WINDOWS
) {
4756 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4757 "minimum Windows limit (%d)\n",
4759 MIN_OPEN_FILES_WINDOWS
));
4760 rlimit_max
= MIN_OPEN_FILES_WINDOWS
;
4763 return MIN(sysctl_max
, rlimit_max
);
4767 * Common part of freeing allocated data for one parameter.
4769 static void free_one_parameter_common(void *parm_ptr
,
4770 struct parm_struct parm
)
4772 if ((parm
.type
== P_STRING
) ||
4773 (parm
.type
== P_USTRING
))
4775 string_free((char**)parm_ptr
);
4776 } else if (parm
.type
== P_LIST
) {
4777 TALLOC_FREE(*((char***)parm_ptr
));
4782 * Free the allocated data for one parameter for a share
4783 * given as a service struct.
4785 static void free_one_parameter(struct loadparm_service
*service
,
4786 struct parm_struct parm
)
4790 if (parm
.p_class
!= P_LOCAL
) {
4794 parm_ptr
= lp_parm_ptr(service
, &parm
);
4796 free_one_parameter_common(parm_ptr
, parm
);
4800 * Free the allocated parameter data of a share given
4801 * as a service struct.
4803 static void free_parameters(struct loadparm_service
*service
)
4807 for (i
=0; parm_table
[i
].label
; i
++) {
4808 free_one_parameter(service
, parm_table
[i
]);
4813 * Free the allocated data for one parameter for a given share
4814 * specified by an snum.
4816 static void free_one_parameter_by_snum(int snum
, struct parm_struct parm
)
4821 parm_ptr
= lp_parm_ptr(NULL
, &parm
);
4822 } else if (parm
.p_class
!= P_LOCAL
) {
4825 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm
);
4828 free_one_parameter_common(parm_ptr
, parm
);
4832 * Free the allocated parameter data for a share specified
4835 static void free_parameters_by_snum(int snum
)
4839 for (i
=0; parm_table
[i
].label
; i
++) {
4840 free_one_parameter_by_snum(snum
, parm_table
[i
]);
4845 * Free the allocated global parameters.
4847 static void free_global_parameters(void)
4849 free_param_opts(&Globals
.param_opt
);
4850 free_parameters_by_snum(GLOBAL_SECTION_SNUM
);
4853 static int map_parameter(const char *pszParmName
);
4855 struct lp_stored_option
{
4856 struct lp_stored_option
*prev
, *next
;
4861 static struct lp_stored_option
*stored_options
;
4864 save options set by lp_set_cmdline() into a list. This list is
4865 re-applied when we do a globals reset, so that cmdline set options
4866 are sticky across reloads of smb.conf
4868 static bool store_lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
4870 struct lp_stored_option
*entry
, *entry_next
;
4871 for (entry
= stored_options
; entry
!= NULL
; entry
= entry_next
) {
4872 entry_next
= entry
->next
;
4873 if (strcmp(pszParmName
, entry
->label
) == 0) {
4874 DLIST_REMOVE(stored_options
, entry
);
4880 entry
= talloc(NULL
, struct lp_stored_option
);
4885 entry
->label
= talloc_strdup(entry
, pszParmName
);
4886 if (!entry
->label
) {
4891 entry
->value
= talloc_strdup(entry
, pszParmValue
);
4892 if (!entry
->value
) {
4897 DLIST_ADD_END(stored_options
, entry
, struct lp_stored_option
);
4902 static bool apply_lp_set_cmdline(void)
4904 struct lp_stored_option
*entry
= NULL
;
4905 for (entry
= stored_options
; entry
!= NULL
; entry
= entry
->next
) {
4906 if (!lp_set_cmdline_helper(entry
->label
, entry
->value
, false)) {
4907 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
4908 entry
->label
, entry
->value
));
4915 /***************************************************************************
4916 Initialise the global parameter structure.
4917 ***************************************************************************/
4919 static void init_globals(bool reinit_globals
)
4921 static bool done_init
= false;
4925 /* If requested to initialize only once and we've already done it... */
4926 if (!reinit_globals
&& done_init
) {
4927 /* ... then we have nothing more to do */
4932 /* The logfile can be set before this is invoked. Free it if so. */
4933 if (Globals
.logfile
!= NULL
) {
4934 string_free(&Globals
.logfile
);
4935 Globals
.logfile
= NULL
;
4939 free_global_parameters();
4942 /* This memset and the free_global_parameters() above will
4943 * wipe out smb.conf options set with lp_set_cmdline(). The
4944 * apply_lp_set_cmdline() call puts these values back in the
4945 * table once the defaults are set */
4946 ZERO_STRUCT(Globals
);
4948 for (i
= 0; parm_table
[i
].label
; i
++) {
4949 if ((parm_table
[i
].type
== P_STRING
||
4950 parm_table
[i
].type
== P_USTRING
))
4952 string_set((char **)lp_parm_ptr(NULL
, &parm_table
[i
]), "");
4957 string_set(&sDefault
.fstype
, FSTYPE_STRING
);
4958 string_set(&sDefault
.szPrintjobUsername
, "%U");
4960 init_printer_values(&sDefault
);
4963 DEBUG(3, ("Initialising global parameters\n"));
4965 /* Must manually force to upper case here, as this does not go via the handler */
4966 string_set(&Globals
.szNetbiosName
, myhostname_upper());
4968 string_set(&Globals
.szSMBPasswdFile
, get_dyn_SMB_PASSWD_FILE());
4969 string_set(&Globals
.szPrivateDir
, get_dyn_PRIVATE_DIR());
4971 /* use the new 'hash2' method by default, with a prefix of 1 */
4972 string_set(&Globals
.szManglingMethod
, "hash2");
4973 Globals
.mangle_prefix
= 1;
4975 string_set(&Globals
.szGuestaccount
, GUEST_ACCOUNT
);
4977 /* using UTF8 by default allows us to support all chars */
4978 string_set(&Globals
.unix_charset
, DEFAULT_UNIX_CHARSET
);
4980 /* Use codepage 850 as a default for the dos character set */
4981 string_set(&Globals
.dos_charset
, DEFAULT_DOS_CHARSET
);
4984 * Allow the default PASSWD_CHAT to be overridden in local.h.
4986 string_set(&Globals
.szPasswdChat
, DEFAULT_PASSWD_CHAT
);
4988 string_set(&Globals
.szWorkgroup
, DEFAULT_WORKGROUP
);
4990 string_set(&Globals
.szPasswdProgram
, "");
4991 string_set(&Globals
.szLockDir
, get_dyn_LOCKDIR());
4992 string_set(&Globals
.szStateDir
, get_dyn_STATEDIR());
4993 string_set(&Globals
.szCacheDir
, get_dyn_CACHEDIR());
4994 string_set(&Globals
.szPidDir
, get_dyn_PIDDIR());
4995 string_set(&Globals
.szSocketAddress
, "0.0.0.0");
4997 * By default support explicit binding to broadcast
5000 Globals
.bNmbdBindExplicitBroadcast
= true;
5002 if (asprintf(&s
, "Samba %s", samba_version_string()) < 0) {
5003 smb_panic("init_globals: ENOMEM");
5005 string_set(&Globals
.szServerString
, s
);
5008 string_set(&Globals
.szPanicAction
, "/bin/sleep 999999999");
5011 string_set(&Globals
.socket_options
, DEFAULT_SOCKET_OPTIONS
);
5013 string_set(&Globals
.szLogonDrive
, "");
5014 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5015 string_set(&Globals
.szLogonHome
, "\\\\%N\\%U");
5016 string_set(&Globals
.szLogonPath
, "\\\\%N\\%U\\profile");
5018 Globals
.szNameResolveOrder
= (const char **)str_list_make_v3(NULL
, "lmhosts wins host bcast", NULL
);
5019 string_set(&Globals
.szPasswordServer
, "*");
5021 Globals
.AlgorithmicRidBase
= BASE_RID
;
5023 Globals
.bLoadPrinters
= true;
5024 Globals
.PrintcapCacheTime
= 750; /* 12.5 minutes */
5026 Globals
.ConfigBackend
= config_backend
;
5027 Globals
.server_role
= ROLE_AUTO
;
5029 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5030 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5031 Globals
.max_xmit
= 0x4104;
5032 Globals
.max_mux
= 50; /* This is *needed* for profile support. */
5033 Globals
.lpqcachetime
= 30; /* changed to handle large print servers better -- jerry */
5034 Globals
.bDisableSpoolss
= false;
5035 Globals
.iMaxSmbdProcesses
= 0;/* no limit specified */
5036 Globals
.pwordlevel
= 0;
5037 Globals
.unamelevel
= 0;
5038 Globals
.deadtime
= 0;
5039 Globals
.getwd_cache
= true;
5040 Globals
.bLargeReadwrite
= true;
5041 Globals
.max_log_size
= 5000;
5042 Globals
.max_open_files
= max_open_files();
5043 Globals
.open_files_db_hash_size
= SMB_OPEN_DATABASE_TDB_HASH_SIZE
;
5044 Globals
.srv_maxprotocol
= PROTOCOL_SMB2_10
;
5045 Globals
.srv_minprotocol
= PROTOCOL_LANMAN1
;
5046 Globals
.security
= SEC_USER
;
5047 Globals
.paranoid_server_security
= true;
5048 Globals
.bEncryptPasswords
= true;
5049 Globals
.clientSchannel
= Auto
;
5050 Globals
.serverSchannel
= Auto
;
5051 Globals
.bReadRaw
= true;
5052 Globals
.bWriteRaw
= true;
5053 Globals
.bNullPasswords
= false;
5054 Globals
.bObeyPamRestrictions
= false;
5056 Globals
.bSyslogOnly
= false;
5057 Globals
.bTimestampLogs
= true;
5058 string_set(&Globals
.szLogLevel
, "0");
5059 Globals
.bDebugPrefixTimestamp
= false;
5060 Globals
.bDebugHiresTimestamp
= true;
5061 Globals
.bDebugPid
= false;
5062 Globals
.bDebugUid
= false;
5063 Globals
.bDebugClass
= false;
5064 Globals
.bEnableCoreFiles
= true;
5065 Globals
.max_ttl
= 60 * 60 * 24 * 3; /* 3 days default. */
5066 Globals
.max_wins_ttl
= 60 * 60 * 24 * 6; /* 6 days default. */
5067 Globals
.min_wins_ttl
= 60 * 60 * 6; /* 6 hours default. */
5068 Globals
.machine_password_timeout
= 60 * 60 * 24 * 7; /* 7 days default. */
5069 Globals
.lm_announce
= Auto
; /* = Auto: send only if LM clients found */
5070 Globals
.lm_interval
= 60;
5071 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5072 Globals
.bNISHomeMap
= false;
5073 #ifdef WITH_NISPLUS_HOME
5074 string_set(&Globals
.szNISHomeMapName
, "auto_home.org_dir");
5076 string_set(&Globals
.szNISHomeMapName
, "auto.home");
5079 Globals
.bTimeServer
= false;
5080 Globals
.bBindInterfacesOnly
= false;
5081 Globals
.bUnixPasswdSync
= false;
5082 Globals
.bPamPasswordChange
= false;
5083 Globals
.bPasswdChatDebug
= false;
5084 Globals
.iPasswdChatTimeout
= 2; /* 2 second default. */
5085 Globals
.bNTPipeSupport
= true; /* Do NT pipes by default. */
5086 Globals
.bNTStatusSupport
= true; /* Use NT status by default. */
5087 Globals
.bStatCache
= true; /* use stat cache by default */
5088 Globals
.iMaxStatCacheSize
= 256; /* 256k by default */
5089 Globals
.restrict_anonymous
= 0;
5090 Globals
.bClientLanManAuth
= false; /* Do NOT use the LanMan hash if it is available */
5091 Globals
.bClientPlaintextAuth
= false; /* Do NOT use a plaintext password even if is requested by the server */
5092 Globals
.bLanmanAuth
= false; /* Do NOT use the LanMan hash, even if it is supplied */
5093 Globals
.bNTLMAuth
= true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5094 Globals
.bClientNTLMv2Auth
= true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
5095 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
5097 Globals
.map_to_guest
= 0; /* By Default, "Never" */
5098 Globals
.oplock_break_wait_time
= 0; /* By Default, 0 msecs. */
5099 Globals
.enhanced_browsing
= true;
5100 Globals
.iLockSpinTime
= WINDOWS_MINIMUM_LOCK_TIMEOUT_MS
; /* msec. */
5101 #ifdef MMAP_BLACKLIST
5102 Globals
.bUseMmap
= false;
5104 Globals
.bUseMmap
= true;
5106 Globals
.bUnicode
= true;
5107 Globals
.bUnixExtensions
= true;
5108 Globals
.bResetOnZeroVC
= false;
5109 Globals
.bLogWriteableFilesOnExit
= false;
5110 Globals
.bCreateKrb5Conf
= true;
5111 Globals
.winbindMaxDomainConnections
= 1;
5113 /* hostname lookups can be very expensive and are broken on
5114 a large number of sites (tridge) */
5115 Globals
.bHostnameLookups
= false;
5117 string_set(&Globals
.passdb_backend
, "tdbsam");
5118 string_set(&Globals
.szLdapSuffix
, "");
5119 string_set(&Globals
.szLdapMachineSuffix
, "");
5120 string_set(&Globals
.szLdapUserSuffix
, "");
5121 string_set(&Globals
.szLdapGroupSuffix
, "");
5122 string_set(&Globals
.szLdapIdmapSuffix
, "");
5124 string_set(&Globals
.szLdapAdminDn
, "");
5125 Globals
.ldap_ssl
= LDAP_SSL_START_TLS
;
5126 Globals
.ldap_ssl_ads
= false;
5127 Globals
.ldap_deref
= -1;
5128 Globals
.ldap_passwd_sync
= LDAP_PASSWD_SYNC_OFF
;
5129 Globals
.ldap_delete_dn
= false;
5130 Globals
.ldap_replication_sleep
= 1000; /* wait 1 sec for replication */
5131 Globals
.ldap_follow_referral
= Auto
;
5132 Globals
.ldap_timeout
= LDAP_DEFAULT_TIMEOUT
;
5133 Globals
.ldap_connection_timeout
= LDAP_CONNECTION_DEFAULT_TIMEOUT
;
5134 Globals
.ldap_page_size
= LDAP_PAGE_SIZE
;
5136 Globals
.ldap_debug_level
= 0;
5137 Globals
.ldap_debug_threshold
= 10;
5139 /* This is what we tell the afs client. in reality we set the token
5140 * to never expire, though, when this runs out the afs client will
5141 * forget the token. Set to 0 to get NEVERDATE.*/
5142 Globals
.iAfsTokenLifetime
= 604800;
5143 Globals
.cups_connection_timeout
= CUPS_DEFAULT_CONNECTION_TIMEOUT
;
5145 /* these parameters are set to defaults that are more appropriate
5146 for the increasing samba install base:
5148 as a member of the workgroup, that will possibly become a
5149 _local_ master browser (lm = true). this is opposed to a forced
5150 local master browser startup (pm = true).
5152 doesn't provide WINS server service by default (wsupp = false),
5153 and doesn't provide domain master browser services by default, either.
5157 Globals
.bMsAddPrinterWizard
= true;
5158 Globals
.os_level
= 20;
5159 Globals
.bLocalMaster
= true;
5160 Globals
.iDomainMaster
= Auto
; /* depending on bDomainLogons */
5161 Globals
.bDomainLogons
= false;
5162 Globals
.bBrowseList
= true;
5163 Globals
.bWINSsupport
= false;
5164 Globals
.bWINSproxy
= false;
5166 TALLOC_FREE(Globals
.szInitLogonDelayedHosts
);
5167 Globals
.InitLogonDelay
= 100; /* 100 ms default delay */
5169 Globals
.bWINSdnsProxy
= true;
5171 Globals
.bAllowTrustedDomains
= true;
5172 string_set(&Globals
.szIdmapBackend
, "tdb");
5174 string_set(&Globals
.szTemplateShell
, "/bin/false");
5175 string_set(&Globals
.szTemplateHomedir
, "/home/%D/%U");
5176 string_set(&Globals
.szWinbindSeparator
, "\\");
5178 string_set(&Globals
.szCupsServer
, "");
5179 string_set(&Globals
.szIPrintServer
, "");
5181 #ifdef CLUSTER_SUPPORT
5182 string_set(&Globals
.ctdbdSocket
, CTDB_PATH
);
5184 string_set(&Globals
.ctdbdSocket
, "");
5187 Globals
.szClusterAddresses
= NULL
;
5188 Globals
.clustering
= false;
5189 Globals
.ctdb_timeout
= 0;
5190 Globals
.ctdb_locktime_warn_threshold
= 0;
5192 Globals
.winbind_cache_time
= 300; /* 5 minutes */
5193 Globals
.winbind_reconnect_delay
= 30; /* 30 seconds */
5194 Globals
.winbind_max_clients
= 200;
5195 Globals
.bWinbindEnumUsers
= false;
5196 Globals
.bWinbindEnumGroups
= false;
5197 Globals
.bWinbindUseDefaultDomain
= false;
5198 Globals
.bWinbindTrustedDomainsOnly
= false;
5199 Globals
.bWinbindNestedGroups
= true;
5200 Globals
.winbind_expand_groups
= 1;
5201 Globals
.szWinbindNssInfo
= (const char **)str_list_make_v3(NULL
, "template", NULL
);
5202 Globals
.bWinbindRefreshTickets
= false;
5203 Globals
.bWinbindOfflineLogon
= false;
5205 Globals
.iIdmapCacheTime
= 86400 * 7; /* a week by default */
5206 Globals
.iIdmapNegativeCacheTime
= 120; /* 2 minutes by default */
5208 Globals
.bPassdbExpandExplicit
= false;
5210 Globals
.name_cache_timeout
= 660; /* In seconds */
5212 Globals
.bUseSpnego
= true;
5213 Globals
.bClientUseSpnego
= true;
5215 Globals
.client_signing
= SMB_SIGNING_DEFAULT
;
5216 Globals
.server_signing
= SMB_SIGNING_DEFAULT
;
5218 Globals
.bDeferSharingViolations
= true;
5219 Globals
.smb_ports
= (const char **)str_list_make_v3(NULL
, SMB_PORTS
, NULL
);
5221 Globals
.bEnablePrivileges
= true;
5222 Globals
.bHostMSDfs
= true;
5223 Globals
.bASUSupport
= false;
5225 /* User defined shares. */
5226 if (asprintf(&s
, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5227 smb_panic("init_globals: ENOMEM");
5229 string_set(&Globals
.szUsersharePath
, s
);
5231 string_set(&Globals
.szUsershareTemplateShare
, "");
5232 Globals
.iUsershareMaxShares
= 0;
5233 /* By default disallow sharing of directories not owned by the sharer. */
5234 Globals
.bUsershareOwnerOnly
= true;
5235 /* By default disallow guest access to usershares. */
5236 Globals
.bUsershareAllowGuests
= false;
5238 Globals
.iKeepalive
= DEFAULT_KEEPALIVE
;
5240 /* By default no shares out of the registry */
5241 Globals
.bRegistryShares
= false;
5243 Globals
.iminreceivefile
= 0;
5245 Globals
.bMapUntrustedToDomain
= false;
5246 Globals
.bMulticastDnsRegister
= true;
5248 Globals
.ismb2_max_read
= DEFAULT_SMB2_MAX_READ
;
5249 Globals
.ismb2_max_write
= DEFAULT_SMB2_MAX_WRITE
;
5250 Globals
.ismb2_max_trans
= DEFAULT_SMB2_MAX_TRANSACT
;
5251 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
5253 string_set(&Globals
.ncalrpc_dir
, get_dyn_NCALRPCDIR());
5255 /* Now put back the settings that were set with lp_set_cmdline() */
5256 apply_lp_set_cmdline();
5259 /*******************************************************************
5260 Convenience routine to grab string parameters into talloced memory
5261 and run standard_sub_basic on them. The buffers can be written to by
5262 callers without affecting the source string.
5263 ********************************************************************/
5265 static char *lp_string(TALLOC_CTX
*ctx
, const char *s
)
5269 /* The follow debug is useful for tracking down memory problems
5270 especially if you have an inner loop that is calling a lp_*()
5271 function that returns a string. Perhaps this debug should be
5272 present all the time? */
5275 DEBUG(10, ("lp_string(%s)\n", s
));
5281 ret
= talloc_sub_basic(ctx
,
5282 get_current_username(),
5283 current_user_info
.domain
,
5285 if (trim_char(ret
, '\"', '\"')) {
5286 if (strchr(ret
,'\"') != NULL
) {
5288 ret
= talloc_sub_basic(ctx
,
5289 get_current_username(),
5290 current_user_info
.domain
,
5298 In this section all the functions that are used to access the
5299 parameters from the rest of the program are defined
5302 #define FN_GLOBAL_STRING(fn_name,ptr) \
5303 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5304 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5305 const char *lp_ ## fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5306 #define FN_GLOBAL_LIST(fn_name,ptr) \
5307 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5308 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5309 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
5310 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5311 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
5312 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5313 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
5315 #define FN_LOCAL_STRING(fn_name,val) \
5316 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));}
5317 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5318 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5319 #define FN_LOCAL_LIST(fn_name,val) \
5320 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5321 #define FN_LOCAL_BOOL(fn_name,val) \
5322 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5323 #define FN_LOCAL_INTEGER(fn_name,val) \
5324 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5326 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5327 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5328 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5329 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5330 #define FN_LOCAL_CHAR(fn_name,val) \
5331 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5334 static FN_GLOBAL_BOOL(domain_logons
, bDomainLogons
)
5335 static FN_GLOBAL_BOOL(_readraw
, bReadRaw
)
5336 static FN_GLOBAL_BOOL(_writeraw
, bWriteRaw
)
5338 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5339 * build process or in smb.conf, we use that value. Otherwise they
5340 * default to the value of lp_lockdir(). */
5341 const char *lp_statedir(void) {
5342 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5343 (strcmp(get_dyn_STATEDIR(), Globals
.szStateDir
) != 0))
5344 return(*(char **)(&Globals
.szStateDir
) ?
5345 *(char **)(&Globals
.szStateDir
) : "");
5347 return(*(char **)(&Globals
.szLockDir
) ?
5348 *(char **)(&Globals
.szLockDir
) : "");
5350 const char *lp_cachedir(void) {
5351 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5352 (strcmp(get_dyn_CACHEDIR(), Globals
.szCacheDir
) != 0))
5353 return(*(char **)(&Globals
.szCacheDir
) ?
5354 *(char **)(&Globals
.szCacheDir
) : "");
5356 return(*(char **)(&Globals
.szLockDir
) ?
5357 *(char **)(&Globals
.szLockDir
) : "");
5359 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int
,
5360 winbindMaxDomainConnections
)
5362 int lp_winbind_max_domain_connections(void)
5364 if (lp_winbind_offline_logon() &&
5365 lp_winbind_max_domain_connections_int() > 1) {
5366 DEBUG(1, ("offline logons active, restricting max domain "
5367 "connections to 1\n"));
5370 return MAX(1, lp_winbind_max_domain_connections_int());
5373 int lp_smb2_max_credits(void)
5375 if (Globals
.ismb2_max_credits
== 0) {
5376 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
5378 return Globals
.ismb2_max_credits
;
5380 int lp_cups_encrypt(void)
5383 #ifdef HAVE_HTTPCONNECTENCRYPT
5384 switch (Globals
.CupsEncrypt
) {
5386 result
= HTTP_ENCRYPT_REQUIRED
;
5389 result
= HTTP_ENCRYPT_ALWAYS
;
5392 result
= HTTP_ENCRYPT_NEVER
;
5399 /* These functions remain in source3/param for now */
5401 FN_GLOBAL_INTEGER(security
, security
)
5402 FN_GLOBAL_INTEGER(usershare_max_shares
, iUsershareMaxShares
)
5403 FN_GLOBAL_STRING(configfile
, szConfigFile
)
5405 #include "lib/param/param_functions.c"
5407 FN_LOCAL_STRING(servicename
, szService
)
5408 FN_LOCAL_CONST_STRING(const_servicename
, szService
)
5410 /* local prototypes */
5412 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
);
5413 static const char *get_boolean(bool bool_value
);
5414 static int getservicebyname(const char *pszServiceName
,
5415 struct loadparm_service
*pserviceDest
);
5416 static void copy_service(struct loadparm_service
*pserviceDest
,
5417 struct loadparm_service
*pserviceSource
,
5418 struct bitmap
*pcopymapDest
);
5419 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
5421 static bool do_section(const char *pszSectionName
, void *userdata
);
5422 static void init_copymap(struct loadparm_service
*pservice
);
5423 static bool hash_a_service(const char *name
, int number
);
5424 static void free_service_byindex(int iService
);
5425 static void show_parameter(int parmIndex
);
5426 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
);
5429 * This is a helper function for parametrical options support. It returns a
5430 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5431 * parametrical functions are quite simple
5433 static struct parmlist_entry
*get_parametrics_by_service(struct loadparm_service
*service
, const char *type
,
5436 bool global_section
= false;
5438 struct parmlist_entry
*data
;
5440 if (service
== NULL
) {
5441 data
= Globals
.param_opt
;
5442 global_section
= true;
5444 data
= service
->param_opt
;
5447 if (asprintf(¶m_key
, "%s:%s", type
, option
) == -1) {
5448 DEBUG(0,("asprintf failed!\n"));
5453 if (strwicmp(data
->key
, param_key
) == 0) {
5454 string_free(¶m_key
);
5460 if (!global_section
) {
5461 /* Try to fetch the same option but from globals */
5462 /* but only if we are not already working with Globals */
5463 data
= Globals
.param_opt
;
5465 if (strwicmp(data
->key
, param_key
) == 0) {
5466 string_free(¶m_key
);
5473 string_free(¶m_key
);
5479 * This is a helper function for parametrical options support. It returns a
5480 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5481 * parametrical functions are quite simple
5483 static struct parmlist_entry
*get_parametrics(int snum
, const char *type
,
5486 if (snum
>= iNumServices
) return NULL
;
5489 return get_parametrics_by_service(NULL
, type
, option
);
5491 return get_parametrics_by_service(ServicePtrs
[snum
], type
, option
);
5496 #define MISSING_PARAMETER(name) \
5497 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5499 /*******************************************************************
5500 convenience routine to return int parameters.
5501 ********************************************************************/
5502 static int lp_int(const char *s
)
5506 MISSING_PARAMETER(lp_int
);
5510 return (int)strtol(s
, NULL
, 0);
5513 /*******************************************************************
5514 convenience routine to return unsigned long parameters.
5515 ********************************************************************/
5516 static unsigned long lp_ulong(const char *s
)
5520 MISSING_PARAMETER(lp_ulong
);
5524 return strtoul(s
, NULL
, 0);
5527 /*******************************************************************
5528 convenience routine to return boolean parameters.
5529 ********************************************************************/
5530 static bool lp_bool(const char *s
)
5535 MISSING_PARAMETER(lp_bool
);
5539 if (!set_boolean(s
, &ret
)) {
5540 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s
));
5547 /*******************************************************************
5548 convenience routine to return enum parameters.
5549 ********************************************************************/
5550 static int lp_enum(const char *s
,const struct enum_list
*_enum
)
5554 if (!s
|| !*s
|| !_enum
) {
5555 MISSING_PARAMETER(lp_enum
);
5559 for (i
=0; _enum
[i
].name
; i
++) {
5560 if (strequal(_enum
[i
].name
,s
))
5561 return _enum
[i
].value
;
5564 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s
));
5568 #undef MISSING_PARAMETER
5570 /* Return parametric option from a given service. Type is a part of option before ':' */
5571 /* Parametric option has following syntax: 'Type: option = value' */
5572 char *lp_parm_talloc_string(TALLOC_CTX
*ctx
, int snum
, const char *type
, const char *option
, const char *def
)
5574 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5576 if (data
== NULL
||data
->value
==NULL
) {
5578 return lp_string(ctx
, def
);
5584 return lp_string(ctx
, data
->value
);
5587 /* Return parametric option from a given service. Type is a part of option before ':' */
5588 /* Parametric option has following syntax: 'Type: option = value' */
5589 const char *lp_parm_const_string(int snum
, const char *type
, const char *option
, const char *def
)
5591 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5593 if (data
== NULL
||data
->value
==NULL
)
5599 const char *lp_parm_const_string_service(struct loadparm_service
*service
, const char *type
, const char *option
)
5601 struct parmlist_entry
*data
= get_parametrics_by_service(service
, type
, option
);
5603 if (data
== NULL
||data
->value
==NULL
)
5610 /* Return parametric option from a given service. Type is a part of option before ':' */
5611 /* Parametric option has following syntax: 'Type: option = value' */
5613 const char **lp_parm_string_list(int snum
, const char *type
, const char *option
, const char **def
)
5615 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5617 if (data
== NULL
||data
->value
==NULL
)
5618 return (const char **)def
;
5620 if (data
->list
==NULL
) {
5621 data
->list
= str_list_make_v3(NULL
, data
->value
, NULL
);
5624 return (const char **)data
->list
;
5627 /* Return parametric option from a given service. Type is a part of option before ':' */
5628 /* Parametric option has following syntax: 'Type: option = value' */
5630 int lp_parm_int(int snum
, const char *type
, const char *option
, int def
)
5632 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5634 if (data
&& data
->value
&& *data
->value
)
5635 return lp_int(data
->value
);
5640 /* Return parametric option from a given service. Type is a part of option before ':' */
5641 /* Parametric option has following syntax: 'Type: option = value' */
5643 unsigned long lp_parm_ulong(int snum
, const char *type
, const char *option
, unsigned long def
)
5645 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5647 if (data
&& data
->value
&& *data
->value
)
5648 return lp_ulong(data
->value
);
5653 /* Return parametric option from a given service. Type is a part of option before ':' */
5654 /* Parametric option has following syntax: 'Type: option = value' */
5656 bool lp_parm_bool(int snum
, const char *type
, const char *option
, bool def
)
5658 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5660 if (data
&& data
->value
&& *data
->value
)
5661 return lp_bool(data
->value
);
5666 /* Return parametric option from a given service. Type is a part of option before ':' */
5667 /* Parametric option has following syntax: 'Type: option = value' */
5669 int lp_parm_enum(int snum
, const char *type
, const char *option
,
5670 const struct enum_list
*_enum
, int def
)
5672 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
5674 if (data
&& data
->value
&& *data
->value
&& _enum
)
5675 return lp_enum(data
->value
, _enum
);
5681 /***************************************************************************
5682 Initialise a service to the defaults.
5683 ***************************************************************************/
5685 static void init_service(struct loadparm_service
*pservice
)
5687 memset((char *)pservice
, '\0', sizeof(struct loadparm_service
));
5688 copy_service(pservice
, &sDefault
, NULL
);
5693 * free a param_opts structure.
5694 * param_opts handling should be moved to talloc;
5695 * then this whole functions reduces to a TALLOC_FREE().
5698 static void free_param_opts(struct parmlist_entry
**popts
)
5700 struct parmlist_entry
*opt
, *next_opt
;
5702 if (popts
== NULL
) {
5706 if (*popts
!= NULL
) {
5707 DEBUG(5, ("Freeing parametrics:\n"));
5710 while (opt
!= NULL
) {
5711 string_free(&opt
->key
);
5712 string_free(&opt
->value
);
5713 TALLOC_FREE(opt
->list
);
5714 next_opt
= opt
->next
;
5721 /***************************************************************************
5722 Free the dynamically allocated parts of a service struct.
5723 ***************************************************************************/
5725 static void free_service(struct loadparm_service
*pservice
)
5730 if (pservice
->szService
)
5731 DEBUG(5, ("free_service: Freeing service %s\n",
5732 pservice
->szService
));
5734 free_parameters(pservice
);
5736 string_free(&pservice
->szService
);
5737 TALLOC_FREE(pservice
->copymap
);
5739 free_param_opts(&pservice
->param_opt
);
5741 ZERO_STRUCTP(pservice
);
5745 /***************************************************************************
5746 remove a service indexed in the ServicePtrs array from the ServiceHash
5747 and free the dynamically allocated parts
5748 ***************************************************************************/
5750 static void free_service_byindex(int idx
)
5752 if ( !LP_SNUM_OK(idx
) )
5755 ServicePtrs
[idx
]->valid
= false;
5756 invalid_services
[num_invalid_services
++] = idx
;
5758 /* we have to cleanup the hash record */
5760 if (ServicePtrs
[idx
]->szService
) {
5761 char *canon_name
= canonicalize_servicename(
5763 ServicePtrs
[idx
]->szService
);
5765 dbwrap_delete_bystring(ServiceHash
, canon_name
);
5766 TALLOC_FREE(canon_name
);
5769 free_service(ServicePtrs
[idx
]);
5772 /***************************************************************************
5773 Add a new service to the services array initialising it with the given
5775 ***************************************************************************/
5777 static int add_a_service(const struct loadparm_service
*pservice
, const char *name
)
5780 struct loadparm_service tservice
;
5781 int num_to_alloc
= iNumServices
+ 1;
5783 tservice
= *pservice
;
5785 /* it might already exist */
5787 i
= getservicebyname(name
, NULL
);
5793 /* find an invalid one */
5795 if (num_invalid_services
> 0) {
5796 i
= invalid_services
[--num_invalid_services
];
5799 /* if not, then create one */
5800 if (i
== iNumServices
) {
5801 struct loadparm_service
**tsp
;
5804 tsp
= SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs
, struct loadparm_service
*, num_to_alloc
);
5806 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5810 ServicePtrs
[iNumServices
] = SMB_MALLOC_P(struct loadparm_service
);
5811 if (!ServicePtrs
[iNumServices
]) {
5812 DEBUG(0,("add_a_service: out of memory!\n"));
5817 /* enlarge invalid_services here for now... */
5818 tinvalid
= SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services
, int,
5820 if (tinvalid
== NULL
) {
5821 DEBUG(0,("add_a_service: failed to enlarge "
5822 "invalid_services!\n"));
5825 invalid_services
= tinvalid
;
5827 free_service_byindex(i
);
5830 ServicePtrs
[i
]->valid
= true;
5832 init_service(ServicePtrs
[i
]);
5833 copy_service(ServicePtrs
[i
], &tservice
, NULL
);
5835 string_set(&ServicePtrs
[i
]->szService
, name
);
5837 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5838 i
, ServicePtrs
[i
]->szService
));
5840 if (!hash_a_service(ServicePtrs
[i
]->szService
, i
)) {
5847 /***************************************************************************
5848 Convert a string to uppercase and remove whitespaces.
5849 ***************************************************************************/
5851 char *canonicalize_servicename(TALLOC_CTX
*ctx
, const char *src
)
5856 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5860 result
= talloc_strdup(ctx
, src
);
5861 SMB_ASSERT(result
!= NULL
);
5867 /***************************************************************************
5868 Add a name/index pair for the services array to the hash table.
5869 ***************************************************************************/
5871 static bool hash_a_service(const char *name
, int idx
)
5875 if ( !ServiceHash
) {
5876 DEBUG(10,("hash_a_service: creating servicehash\n"));
5877 ServiceHash
= db_open_rbt(NULL
);
5878 if ( !ServiceHash
) {
5879 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5884 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5887 canon_name
= canonicalize_servicename(talloc_tos(), name
);
5889 dbwrap_store_bystring(ServiceHash
, canon_name
,
5890 make_tdb_data((uint8
*)&idx
, sizeof(idx
)),
5893 TALLOC_FREE(canon_name
);
5898 /***************************************************************************
5899 Add a new home service, with the specified home directory, defaults coming
5901 ***************************************************************************/
5903 bool lp_add_home(const char *pszHomename
, int iDefaultService
,
5904 const char *user
, const char *pszHomedir
)
5908 if (pszHomename
== NULL
|| user
== NULL
|| pszHomedir
== NULL
||
5909 pszHomedir
[0] == '\0') {
5913 i
= add_a_service(ServicePtrs
[iDefaultService
], pszHomename
);
5918 if (!(*(ServicePtrs
[iDefaultService
]->szPath
))
5919 || strequal(ServicePtrs
[iDefaultService
]->szPath
,
5920 lp_pathname(talloc_tos(), GLOBAL_SECTION_SNUM
))) {
5921 string_set(&ServicePtrs
[i
]->szPath
, pszHomedir
);
5924 if (!(*(ServicePtrs
[i
]->comment
))) {
5925 char *comment
= NULL
;
5926 if (asprintf(&comment
, "Home directory of %s", user
) < 0) {
5929 string_set(&ServicePtrs
[i
]->comment
, comment
);
5933 /* set the browseable flag from the global default */
5935 ServicePtrs
[i
]->bBrowseable
= sDefault
.bBrowseable
;
5936 ServicePtrs
[i
]->bAccessBasedShareEnum
= sDefault
.bAccessBasedShareEnum
;
5938 ServicePtrs
[i
]->autoloaded
= true;
5940 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename
,
5941 user
, ServicePtrs
[i
]->szPath
));
5946 /***************************************************************************
5947 Add a new service, based on an old one.
5948 ***************************************************************************/
5950 int lp_add_service(const char *pszService
, int iDefaultService
)
5952 if (iDefaultService
< 0) {
5953 return add_a_service(&sDefault
, pszService
);
5956 return (add_a_service(ServicePtrs
[iDefaultService
], pszService
));
5959 /***************************************************************************
5960 Add the IPC service.
5961 ***************************************************************************/
5963 static bool lp_add_ipc(const char *ipc_name
, bool guest_ok
)
5965 char *comment
= NULL
;
5966 int i
= add_a_service(&sDefault
, ipc_name
);
5971 if (asprintf(&comment
, "IPC Service (%s)",
5972 Globals
.szServerString
) < 0) {
5976 string_set(&ServicePtrs
[i
]->szPath
, tmpdir());
5977 string_set(&ServicePtrs
[i
]->szUsername
, "");
5978 string_set(&ServicePtrs
[i
]->comment
, comment
);
5979 string_set(&ServicePtrs
[i
]->fstype
, "IPC");
5980 ServicePtrs
[i
]->iMaxConnections
= 0;
5981 ServicePtrs
[i
]->bAvailable
= true;
5982 ServicePtrs
[i
]->bRead_only
= true;
5983 ServicePtrs
[i
]->bGuest_only
= false;
5984 ServicePtrs
[i
]->bAdministrative_share
= true;
5985 ServicePtrs
[i
]->bGuest_ok
= guest_ok
;
5986 ServicePtrs
[i
]->bPrint_ok
= false;
5987 ServicePtrs
[i
]->bBrowseable
= sDefault
.bBrowseable
;
5989 DEBUG(3, ("adding IPC service\n"));
5995 /***************************************************************************
5996 Add a new printer service, with defaults coming from service iFrom.
5997 ***************************************************************************/
5999 bool lp_add_printer(const char *pszPrintername
, int iDefaultService
)
6001 const char *comment
= "From Printcap";
6002 int i
= add_a_service(ServicePtrs
[iDefaultService
], pszPrintername
);
6007 /* note that we do NOT default the availability flag to true - */
6008 /* we take it from the default service passed. This allows all */
6009 /* dynamic printers to be disabled by disabling the [printers] */
6010 /* entry (if/when the 'available' keyword is implemented!). */
6012 /* the printer name is set to the service name. */
6013 string_set(&ServicePtrs
[i
]->szPrintername
, pszPrintername
);
6014 string_set(&ServicePtrs
[i
]->comment
, comment
);
6016 /* set the browseable flag from the gloabl default */
6017 ServicePtrs
[i
]->bBrowseable
= sDefault
.bBrowseable
;
6019 /* Printers cannot be read_only. */
6020 ServicePtrs
[i
]->bRead_only
= false;
6021 /* No share modes on printer services. */
6022 ServicePtrs
[i
]->bShareModes
= false;
6023 /* No oplocks on printer services. */
6024 ServicePtrs
[i
]->bOpLocks
= false;
6025 /* Printer services must be printable. */
6026 ServicePtrs
[i
]->bPrint_ok
= true;
6028 DEBUG(3, ("adding printer service %s\n", pszPrintername
));
6034 /***************************************************************************
6035 Check whether the given parameter name is valid.
6036 Parametric options (names containing a colon) are considered valid.
6037 ***************************************************************************/
6039 bool lp_parameter_is_valid(const char *pszParmName
)
6041 return ((map_parameter(pszParmName
) != -1) ||
6042 (strchr(pszParmName
, ':') != NULL
));
6045 /***************************************************************************
6046 Check whether the given name is the name of a global parameter.
6047 Returns true for strings belonging to parameters of class
6048 P_GLOBAL, false for all other strings, also for parametric options
6049 and strings not belonging to any option.
6050 ***************************************************************************/
6052 bool lp_parameter_is_global(const char *pszParmName
)
6054 int num
= map_parameter(pszParmName
);
6057 return (parm_table
[num
].p_class
== P_GLOBAL
);
6063 /**************************************************************************
6064 Check whether the given name is the canonical name of a parameter.
6065 Returns false if it is not a valid parameter Name.
6066 For parametric options, true is returned.
6067 **************************************************************************/
6069 bool lp_parameter_is_canonical(const char *parm_name
)
6071 if (!lp_parameter_is_valid(parm_name
)) {
6075 return (map_parameter(parm_name
) ==
6076 map_parameter_canonical(parm_name
, NULL
));
6079 /**************************************************************************
6080 Determine the canonical name for a parameter.
6081 Indicate when it is an inverse (boolean) synonym instead of a
6083 **************************************************************************/
6085 bool lp_canonicalize_parameter(const char *parm_name
, const char **canon_parm
,
6090 if (!lp_parameter_is_valid(parm_name
)) {
6095 num
= map_parameter_canonical(parm_name
, inverse
);
6097 /* parametric option */
6098 *canon_parm
= parm_name
;
6100 *canon_parm
= parm_table
[num
].label
;
6107 /**************************************************************************
6108 Determine the canonical name for a parameter.
6109 Turn the value given into the inverse boolean expression when
6110 the synonym is an invers boolean synonym.
6112 Return true if parm_name is a valid parameter name and
6113 in case it is an invers boolean synonym, if the val string could
6114 successfully be converted to the reverse bool.
6115 Return false in all other cases.
6116 **************************************************************************/
6118 bool lp_canonicalize_parameter_with_value(const char *parm_name
,
6120 const char **canon_parm
,
6121 const char **canon_val
)
6126 if (!lp_parameter_is_valid(parm_name
)) {
6132 num
= map_parameter_canonical(parm_name
, &inverse
);
6134 /* parametric option */
6135 *canon_parm
= parm_name
;
6138 *canon_parm
= parm_table
[num
].label
;
6140 if (!lp_invert_boolean(val
, canon_val
)) {
6152 /***************************************************************************
6153 Map a parameter's string representation to something we can use.
6154 Returns false if the parameter string is not recognised, else TRUE.
6155 ***************************************************************************/
6157 static int map_parameter(const char *pszParmName
)
6161 if (*pszParmName
== '-' && !strequal(pszParmName
, "-valid"))
6164 for (iIndex
= 0; parm_table
[iIndex
].label
; iIndex
++)
6165 if (strwicmp(parm_table
[iIndex
].label
, pszParmName
) == 0)
6168 /* Warn only if it isn't parametric option */
6169 if (strchr(pszParmName
, ':') == NULL
)
6170 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName
));
6171 /* We do return 'fail' for parametric options as well because they are
6172 stored in different storage
6177 /***************************************************************************
6178 Map a parameter's string representation to the index of the canonical
6179 form of the parameter (it might be a synonym).
6180 Returns -1 if the parameter string is not recognised.
6181 ***************************************************************************/
6183 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
)
6185 int parm_num
, canon_num
;
6186 bool loc_inverse
= false;
6188 parm_num
= map_parameter(pszParmName
);
6189 if ((parm_num
< 0) || !(parm_table
[parm_num
].flags
& FLAG_HIDE
)) {
6190 /* invalid, parametric or no canidate for synonyms ... */
6194 for (canon_num
= 0; parm_table
[canon_num
].label
; canon_num
++) {
6195 if (is_synonym_of(parm_num
, canon_num
, &loc_inverse
)) {
6196 parm_num
= canon_num
;
6202 if (inverse
!= NULL
) {
6203 *inverse
= loc_inverse
;
6208 /***************************************************************************
6209 return true if parameter number parm1 is a synonym of parameter
6210 number parm2 (parm2 being the principal name).
6211 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
6213 ***************************************************************************/
6215 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
)
6217 if ((parm_table
[parm1
].offset
== parm_table
[parm2
].offset
) &&
6218 (parm_table
[parm1
].p_class
== parm_table
[parm2
].p_class
) &&
6219 (parm_table
[parm1
].flags
& FLAG_HIDE
) &&
6220 !(parm_table
[parm2
].flags
& FLAG_HIDE
))
6222 if (inverse
!= NULL
) {
6223 if ((parm_table
[parm1
].type
== P_BOOLREV
) &&
6224 (parm_table
[parm2
].type
== P_BOOL
))
6236 /***************************************************************************
6237 Show one parameter's name, type, [values,] and flags.
6238 (helper functions for show_parameter_list)
6239 ***************************************************************************/
6241 static void show_parameter(int parmIndex
)
6243 int enumIndex
, flagIndex
;
6248 const char *type
[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6249 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6251 unsigned flags
[] = { FLAG_BASIC
, FLAG_SHARE
, FLAG_PRINT
, FLAG_GLOBAL
,
6252 FLAG_WIZARD
, FLAG_ADVANCED
, FLAG_DEVELOPER
, FLAG_DEPRECATED
,
6254 const char *flag_names
[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6255 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6256 "FLAG_DEPRECATED", "FLAG_HIDE", NULL
};
6258 printf("%s=%s", parm_table
[parmIndex
].label
,
6259 type
[parm_table
[parmIndex
].type
]);
6260 if (parm_table
[parmIndex
].type
== P_ENUM
) {
6263 parm_table
[parmIndex
].enum_list
[enumIndex
].name
;
6267 enumIndex
? "|" : "",
6268 parm_table
[parmIndex
].enum_list
[enumIndex
].name
);
6273 for (flagIndex
=0; flag_names
[flagIndex
]; flagIndex
++) {
6274 if (parm_table
[parmIndex
].flags
& flags
[flagIndex
]) {
6277 flag_names
[flagIndex
]);
6282 /* output synonyms */
6284 for (parmIndex2
=0; parm_table
[parmIndex2
].label
; parmIndex2
++) {
6285 if (is_synonym_of(parmIndex
, parmIndex2
, &inverse
)) {
6286 printf(" (%ssynonym of %s)", inverse
? "inverse " : "",
6287 parm_table
[parmIndex2
].label
);
6288 } else if (is_synonym_of(parmIndex2
, parmIndex
, &inverse
)) {
6290 printf(" (synonyms: ");
6295 printf("%s%s", parm_table
[parmIndex2
].label
,
6296 inverse
? "[i]" : "");
6306 /***************************************************************************
6307 Show all parameter's name, type, [values,] and flags.
6308 ***************************************************************************/
6310 void show_parameter_list(void)
6312 int classIndex
, parmIndex
;
6313 const char *section_names
[] = { "local", "global", NULL
};
6315 for (classIndex
=0; section_names
[classIndex
]; classIndex
++) {
6316 printf("[%s]\n", section_names
[classIndex
]);
6317 for (parmIndex
= 0; parm_table
[parmIndex
].label
; parmIndex
++) {
6318 if (parm_table
[parmIndex
].p_class
== classIndex
) {
6319 show_parameter(parmIndex
);
6325 /***************************************************************************
6326 Check if a given string correctly represents a boolean value.
6327 ***************************************************************************/
6329 bool lp_string_is_valid_boolean(const char *parm_value
)
6331 return set_boolean(parm_value
, NULL
);
6334 /***************************************************************************
6335 Get the standard string representation of a boolean value ("yes" or "no")
6336 ***************************************************************************/
6338 static const char *get_boolean(bool bool_value
)
6340 static const char *yes_str
= "yes";
6341 static const char *no_str
= "no";
6343 return (bool_value
? yes_str
: no_str
);
6346 /***************************************************************************
6347 Provide the string of the negated boolean value associated to the boolean
6348 given as a string. Returns false if the passed string does not correctly
6349 represent a boolean.
6350 ***************************************************************************/
6352 bool lp_invert_boolean(const char *str
, const char **inverse_str
)
6356 if (!set_boolean(str
, &val
)) {
6360 *inverse_str
= get_boolean(!val
);
6364 /***************************************************************************
6365 Provide the canonical string representation of a boolean value given
6366 as a string. Return true on success, false if the string given does
6367 not correctly represent a boolean.
6368 ***************************************************************************/
6370 bool lp_canonicalize_boolean(const char *str
, const char**canon_str
)
6374 if (!set_boolean(str
, &val
)) {
6378 *canon_str
= get_boolean(val
);
6382 /***************************************************************************
6383 Find a service by name. Otherwise works like get_service.
6384 ***************************************************************************/
6386 static int getservicebyname(const char *pszServiceName
, struct loadparm_service
*pserviceDest
)
6393 if (ServiceHash
== NULL
) {
6397 canon_name
= canonicalize_servicename(talloc_tos(), pszServiceName
);
6399 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
, canon_name
,
6402 if (NT_STATUS_IS_OK(status
) &&
6403 (data
.dptr
!= NULL
) &&
6404 (data
.dsize
== sizeof(iService
)))
6406 iService
= *(int *)data
.dptr
;
6409 TALLOC_FREE(canon_name
);
6411 if ((iService
!= -1) && (LP_SNUM_OK(iService
))
6412 && (pserviceDest
!= NULL
)) {
6413 copy_service(pserviceDest
, ServicePtrs
[iService
], NULL
);
6419 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
6420 struct loadparm_service
*lp_service(const char *pszServiceName
)
6422 int iService
= getservicebyname(pszServiceName
, NULL
);
6423 if (iService
== -1 || !LP_SNUM_OK(iService
)) {
6426 return ServicePtrs
[iService
];
6429 struct loadparm_service
*lp_servicebynum(int snum
)
6431 if ((snum
== -1) || !LP_SNUM_OK(snum
)) {
6434 return ServicePtrs
[snum
];
6437 struct loadparm_service
*lp_default_loadparm_service()
6443 /***************************************************************************
6444 Copy a service structure to another.
6445 If pcopymapDest is NULL then copy all fields
6446 ***************************************************************************/
6449 * Add a parametric option to a parmlist_entry,
6450 * replacing old value, if already present.
6452 static void set_param_opt(struct parmlist_entry
**opt_list
,
6453 const char *opt_name
,
6454 const char *opt_value
,
6457 struct parmlist_entry
*new_opt
, *opt
;
6460 if (opt_list
== NULL
) {
6467 /* Traverse destination */
6469 /* If we already have same option, override it */
6470 if (strwicmp(opt
->key
, opt_name
) == 0) {
6471 if ((opt
->priority
& FLAG_CMDLINE
) &&
6472 !(priority
& FLAG_CMDLINE
)) {
6473 /* it's been marked as not to be
6477 string_free(&opt
->value
);
6478 TALLOC_FREE(opt
->list
);
6479 opt
->value
= SMB_STRDUP(opt_value
);
6480 opt
->priority
= priority
;
6487 new_opt
= SMB_XMALLOC_P(struct parmlist_entry
);
6488 new_opt
->key
= SMB_STRDUP(opt_name
);
6489 new_opt
->value
= SMB_STRDUP(opt_value
);
6490 new_opt
->list
= NULL
;
6491 new_opt
->priority
= priority
;
6492 DLIST_ADD(*opt_list
, new_opt
);
6496 static void copy_service(struct loadparm_service
*pserviceDest
, struct loadparm_service
*pserviceSource
,
6497 struct bitmap
*pcopymapDest
)
6500 bool bcopyall
= (pcopymapDest
== NULL
);
6501 struct parmlist_entry
*data
;
6503 for (i
= 0; parm_table
[i
].label
; i
++)
6504 if (parm_table
[i
].p_class
== P_LOCAL
&&
6505 (bcopyall
|| bitmap_query(pcopymapDest
,i
))) {
6506 void *src_ptr
= lp_parm_ptr(pserviceSource
, &parm_table
[i
]);
6507 void *dest_ptr
= lp_parm_ptr(pserviceDest
, &parm_table
[i
]);
6509 switch (parm_table
[i
].type
) {
6512 *(bool *)dest_ptr
= *(bool *)src_ptr
;
6519 *(int *)dest_ptr
= *(int *)src_ptr
;
6523 *(char *)dest_ptr
= *(char *)src_ptr
;
6527 string_set((char **)dest_ptr
,
6533 char *upper_string
= strupper_talloc(talloc_tos(),
6535 string_set((char **)dest_ptr
,
6537 TALLOC_FREE(upper_string
);
6541 TALLOC_FREE(*((char ***)dest_ptr
));
6542 *((char ***)dest_ptr
) = str_list_copy(NULL
,
6543 *(const char ***)src_ptr
);
6551 init_copymap(pserviceDest
);
6552 if (pserviceSource
->copymap
)
6553 bitmap_copy(pserviceDest
->copymap
,
6554 pserviceSource
->copymap
);
6557 data
= pserviceSource
->param_opt
;
6559 set_param_opt(&pserviceDest
->param_opt
, data
->key
, data
->value
, data
->priority
);
6564 /***************************************************************************
6565 Check a service for consistency. Return false if the service is in any way
6566 incomplete or faulty, else true.
6567 ***************************************************************************/
6569 bool service_ok(int iService
)
6574 if (ServicePtrs
[iService
]->szService
[0] == '\0') {
6575 DEBUG(0, ("The following message indicates an internal error:\n"));
6576 DEBUG(0, ("No service name in service entry.\n"));
6580 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6581 /* I can't see why you'd want a non-printable printer service... */
6582 if (strwicmp(ServicePtrs
[iService
]->szService
, PRINTERS_NAME
) == 0) {
6583 if (!ServicePtrs
[iService
]->bPrint_ok
) {
6584 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6585 ServicePtrs
[iService
]->szService
));
6586 ServicePtrs
[iService
]->bPrint_ok
= true;
6588 /* [printers] service must also be non-browsable. */
6589 if (ServicePtrs
[iService
]->bBrowseable
)
6590 ServicePtrs
[iService
]->bBrowseable
= false;
6593 if (ServicePtrs
[iService
]->szPath
[0] == '\0' &&
6594 strwicmp(ServicePtrs
[iService
]->szService
, HOMES_NAME
) != 0 &&
6595 ServicePtrs
[iService
]->szMSDfsProxy
[0] == '\0'
6597 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6598 ServicePtrs
[iService
]->szService
));
6599 ServicePtrs
[iService
]->bAvailable
= false;
6602 /* If a service is flagged unavailable, log the fact at level 1. */
6603 if (!ServicePtrs
[iService
]->bAvailable
)
6604 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6605 ServicePtrs
[iService
]->szService
));
6610 static struct smbconf_ctx
*lp_smbconf_ctx(void)
6613 static struct smbconf_ctx
*conf_ctx
= NULL
;
6615 if (conf_ctx
== NULL
) {
6616 err
= smbconf_init(NULL
, &conf_ctx
, "registry:");
6617 if (!SBC_ERROR_IS_OK(err
)) {
6618 DEBUG(1, ("error initializing registry configuration: "
6619 "%s\n", sbcErrorString(err
)));
6627 static bool process_smbconf_service(struct smbconf_service
*service
)
6632 if (service
== NULL
) {
6636 ret
= do_section(service
->name
, NULL
);
6640 for (count
= 0; count
< service
->num_params
; count
++) {
6641 ret
= do_parameter(service
->param_names
[count
],
6642 service
->param_values
[count
],
6648 if (iServiceIndex
>= 0) {
6649 return service_ok(iServiceIndex
);
6655 * load a service from registry and activate it
6657 bool process_registry_service(const char *service_name
)
6660 struct smbconf_service
*service
= NULL
;
6661 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
6662 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
6665 if (conf_ctx
== NULL
) {
6669 DEBUG(5, ("process_registry_service: service name %s\n", service_name
));
6671 if (!smbconf_share_exists(conf_ctx
, service_name
)) {
6673 * Registry does not contain data for this service (yet),
6674 * but make sure lp_load doesn't return false.
6680 err
= smbconf_get_share(conf_ctx
, mem_ctx
, service_name
, &service
);
6681 if (!SBC_ERROR_IS_OK(err
)) {
6685 ret
= process_smbconf_service(service
);
6691 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
6694 TALLOC_FREE(mem_ctx
);
6699 * process_registry_globals
6701 static bool process_registry_globals(void)
6705 add_to_file_list(INCLUDE_REGISTRY_NAME
, INCLUDE_REGISTRY_NAME
);
6707 ret
= do_parameter("registry shares", "yes", NULL
);
6712 return process_registry_service(GLOBAL_NAME
);
6715 bool process_registry_shares(void)
6719 struct smbconf_service
**service
= NULL
;
6720 uint32_t num_shares
= 0;
6721 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
6722 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
6725 if (conf_ctx
== NULL
) {
6729 err
= smbconf_get_config(conf_ctx
, mem_ctx
, &num_shares
, &service
);
6730 if (!SBC_ERROR_IS_OK(err
)) {
6736 for (count
= 0; count
< num_shares
; count
++) {
6737 if (strequal(service
[count
]->name
, GLOBAL_NAME
)) {
6740 ret
= process_smbconf_service(service
[count
]);
6747 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
6750 TALLOC_FREE(mem_ctx
);
6755 * reload those shares from registry that are already
6756 * activated in the services array.
6758 static bool reload_registry_shares(void)
6763 for (i
= 0; i
< iNumServices
; i
++) {
6768 if (ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
6772 ret
= process_registry_service(ServicePtrs
[i
]->szService
);
6783 #define MAX_INCLUDE_DEPTH 100
6785 static uint8_t include_depth
;
6787 static struct file_lists
{
6788 struct file_lists
*next
;
6792 } *file_lists
= NULL
;
6794 /*******************************************************************
6795 Keep a linked list of all config files so we know when one has changed
6796 it's date and needs to be reloaded.
6797 ********************************************************************/
6799 static void add_to_file_list(const char *fname
, const char *subfname
)
6801 struct file_lists
*f
= file_lists
;
6804 if (f
->name
&& !strcmp(f
->name
, fname
))
6810 f
= SMB_MALLOC_P(struct file_lists
);
6813 f
->next
= file_lists
;
6814 f
->name
= SMB_STRDUP(fname
);
6819 f
->subfname
= SMB_STRDUP(subfname
);
6826 f
->modtime
= file_modtime(subfname
);
6828 time_t t
= file_modtime(subfname
);
6836 * Free the file lists
6838 static void free_file_list(void)
6840 struct file_lists
*f
;
6841 struct file_lists
*next
;
6846 SAFE_FREE( f
->name
);
6847 SAFE_FREE( f
->subfname
);
6856 * Utility function for outsiders to check if we're running on registry.
6858 bool lp_config_backend_is_registry(void)
6860 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY
);
6864 * Utility function to check if the config backend is FILE.
6866 bool lp_config_backend_is_file(void)
6868 return (lp_config_backend() == CONFIG_BACKEND_FILE
);
6871 /*******************************************************************
6872 Check if a config file has changed date.
6873 ********************************************************************/
6875 bool lp_file_list_changed(void)
6877 struct file_lists
*f
= file_lists
;
6879 DEBUG(6, ("lp_file_list_changed()\n"));
6884 if (strequal(f
->name
, INCLUDE_REGISTRY_NAME
)) {
6885 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
6887 if (conf_ctx
== NULL
) {
6890 if (smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
,
6893 DEBUGADD(6, ("registry config changed\n"));
6898 n2
= talloc_sub_basic(talloc_tos(),
6899 get_current_username(),
6900 current_user_info
.domain
,
6905 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6906 f
->name
, n2
, ctime(&f
->modtime
)));
6908 mod_time
= file_modtime(n2
);
6911 ((f
->modtime
!= mod_time
) ||
6912 (f
->subfname
== NULL
) ||
6913 (strcmp(n2
, f
->subfname
) != 0)))
6916 ("file %s modified: %s\n", n2
,
6918 f
->modtime
= mod_time
;
6919 SAFE_FREE(f
->subfname
);
6920 f
->subfname
= SMB_STRDUP(n2
);
6933 * Initialize iconv conversion descriptors.
6935 * This is called the first time it is needed, and also called again
6936 * every time the configuration is reloaded, because the charset or
6937 * codepage might have changed.
6939 static void init_iconv(void)
6941 global_iconv_handle
= smb_iconv_handle_reinit(NULL
, lp_dos_charset(),
6943 true, global_iconv_handle
);
6946 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
6948 if (strcmp(*ptr
, pszParmValue
) != 0) {
6949 string_set(ptr
, pszParmValue
);
6955 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
6957 bool is_utf8
= false;
6958 size_t len
= strlen(pszParmValue
);
6960 if (len
== 4 || len
== 5) {
6961 /* Don't use StrCaseCmp here as we don't want to
6962 initialize iconv. */
6963 if ((toupper_m(pszParmValue
[0]) == 'U') &&
6964 (toupper_m(pszParmValue
[1]) == 'T') &&
6965 (toupper_m(pszParmValue
[2]) == 'F')) {
6967 if (pszParmValue
[3] == '8') {
6971 if (pszParmValue
[3] == '-' &&
6972 pszParmValue
[4] == '8') {
6979 if (strcmp(*ptr
, pszParmValue
) != 0) {
6981 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
6982 "be UTF8, using (default value) %s instead.\n",
6983 DEFAULT_DOS_CHARSET
));
6984 pszParmValue
= DEFAULT_DOS_CHARSET
;
6986 string_set(ptr
, pszParmValue
);
6992 static bool handle_realm(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
6995 char *realm
= strupper_talloc(talloc_tos(), pszParmValue
);
6996 char *dnsdomain
= strlower_talloc(realm
, pszParmValue
);
6998 ret
&= string_set(&Globals
.szRealm
, pszParmValue
);
6999 ret
&= string_set(&Globals
.szRealm_upper
, realm
);
7000 ret
&= string_set(&Globals
.szRealm_lower
, dnsdomain
);
7006 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7008 TALLOC_FREE(Globals
.szNetbiosAliases
);
7009 Globals
.szNetbiosAliases
= (const char **)str_list_make_v3(NULL
, pszParmValue
, NULL
);
7010 return set_netbios_aliases(Globals
.szNetbiosAliases
);
7013 /***************************************************************************
7014 Handle the include operation.
7015 ***************************************************************************/
7016 static bool bAllowIncludeRegistry
= true;
7018 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7022 if (include_depth
>= MAX_INCLUDE_DEPTH
) {
7023 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7028 if (strequal(pszParmValue
, INCLUDE_REGISTRY_NAME
)) {
7029 if (!bAllowIncludeRegistry
) {
7032 if (bInGlobalSection
) {
7035 ret
= process_registry_globals();
7039 DEBUG(1, ("\"include = registry\" only effective "
7040 "in %s section\n", GLOBAL_NAME
));
7045 fname
= talloc_sub_basic(talloc_tos(), get_current_username(),
7046 current_user_info
.domain
,
7049 add_to_file_list(pszParmValue
, fname
);
7051 string_set(ptr
, fname
);
7053 if (file_exist(fname
)) {
7056 ret
= pm_process(fname
, do_section
, do_parameter
, NULL
);
7062 DEBUG(2, ("Can't find include file %s\n", fname
));
7067 /***************************************************************************
7068 Handle the interpretation of the copy parameter.
7069 ***************************************************************************/
7071 static bool handle_copy(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7075 struct loadparm_service serviceTemp
;
7077 string_set(ptr
, pszParmValue
);
7079 init_service(&serviceTemp
);
7083 DEBUG(3, ("Copying service from service %s\n", pszParmValue
));
7085 if ((iTemp
= getservicebyname(pszParmValue
, &serviceTemp
)) >= 0) {
7086 if (iTemp
== iServiceIndex
) {
7087 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue
));
7089 copy_service(ServicePtrs
[iServiceIndex
],
7091 ServicePtrs
[iServiceIndex
]->copymap
);
7095 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue
));
7099 free_service(&serviceTemp
);
7103 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7105 Globals
.ldap_debug_level
= lp_int(pszParmValue
);
7106 init_ldap_debugging();
7110 /***************************************************************************
7111 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7116 idmap uid = 1000-1999
7119 We only do simple parsing checks here. The strings are parsed into useful
7120 structures in the idmap daemon code.
7122 ***************************************************************************/
7124 /* Some lp_ routines to return idmap [ug]id information */
7126 static uid_t idmap_uid_low
, idmap_uid_high
;
7127 static gid_t idmap_gid_low
, idmap_gid_high
;
7129 bool lp_idmap_uid(uid_t
*low
, uid_t
*high
)
7131 if (idmap_uid_low
== 0 || idmap_uid_high
== 0)
7135 *low
= idmap_uid_low
;
7138 *high
= idmap_uid_high
;
7143 bool lp_idmap_gid(gid_t
*low
, gid_t
*high
)
7145 if (idmap_gid_low
== 0 || idmap_gid_high
== 0)
7149 *low
= idmap_gid_low
;
7152 *high
= idmap_gid_high
;
7157 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7159 lp_do_parameter(snum
, "idmap config * : backend", pszParmValue
);
7164 /* Do some simple checks on "idmap [ug]id" parameter values */
7166 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7168 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
7173 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7175 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
7180 /***************************************************************************
7181 Handle the DEBUG level list.
7182 ***************************************************************************/
7184 static bool handle_debug_list(struct loadparm_context
*unused
, int snum
, const char *pszParmValueIn
, char **ptr
)
7186 string_set(ptr
, pszParmValueIn
);
7187 return debug_parse_levels(pszParmValueIn
);
7190 /***************************************************************************
7191 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7192 ***************************************************************************/
7194 static const char *append_ldap_suffix(TALLOC_CTX
*ctx
, const char *str
)
7196 const char *suffix_string
;
7198 suffix_string
= talloc_asprintf(ctx
, "%s,%s", str
,
7199 Globals
.szLdapSuffix
);
7200 if ( !suffix_string
) {
7201 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7205 return suffix_string
;
7208 const char *lp_ldap_machine_suffix(TALLOC_CTX
*ctx
)
7210 if (Globals
.szLdapMachineSuffix
[0])
7211 return append_ldap_suffix(ctx
, Globals
.szLdapMachineSuffix
);
7213 return lp_string(ctx
, Globals
.szLdapSuffix
);
7216 const char *lp_ldap_user_suffix(TALLOC_CTX
*ctx
)
7218 if (Globals
.szLdapUserSuffix
[0])
7219 return append_ldap_suffix(ctx
, Globals
.szLdapUserSuffix
);
7221 return lp_string(ctx
, Globals
.szLdapSuffix
);
7224 const char *lp_ldap_group_suffix(TALLOC_CTX
*ctx
)
7226 if (Globals
.szLdapGroupSuffix
[0])
7227 return append_ldap_suffix(ctx
, Globals
.szLdapGroupSuffix
);
7229 return lp_string(ctx
, Globals
.szLdapSuffix
);
7232 const char *lp_ldap_idmap_suffix(TALLOC_CTX
*ctx
)
7234 if (Globals
.szLdapIdmapSuffix
[0])
7235 return append_ldap_suffix(ctx
, Globals
.szLdapIdmapSuffix
);
7237 return lp_string(ctx
, Globals
.szLdapSuffix
);
7240 /****************************************************************************
7241 set the value for a P_ENUM
7242 ***************************************************************************/
7244 static void lp_set_enum_parm( struct parm_struct
*parm
, const char *pszParmValue
,
7249 for (i
= 0; parm
->enum_list
[i
].name
; i
++) {
7250 if ( strequal(pszParmValue
, parm
->enum_list
[i
].name
)) {
7251 *ptr
= parm
->enum_list
[i
].value
;
7255 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7256 pszParmValue
, parm
->label
));
7259 /***************************************************************************
7260 ***************************************************************************/
7262 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
7264 static int parm_num
= -1;
7265 struct loadparm_service
*s
;
7267 if ( parm_num
== -1 )
7268 parm_num
= map_parameter( "printing" );
7270 lp_set_enum_parm( &parm_table
[parm_num
], pszParmValue
, (int*)ptr
);
7275 s
= ServicePtrs
[snum
];
7277 init_printer_values( s
);
7283 /***************************************************************************
7284 Initialise a copymap.
7285 ***************************************************************************/
7287 static void init_copymap(struct loadparm_service
*pservice
)
7291 TALLOC_FREE(pservice
->copymap
);
7293 pservice
->copymap
= bitmap_talloc(NULL
, NUMPARAMETERS
);
7294 if (!pservice
->copymap
)
7296 ("Couldn't allocate copymap!! (size %d)\n",
7297 (int)NUMPARAMETERS
));
7299 for (i
= 0; i
< NUMPARAMETERS
; i
++)
7300 bitmap_set(pservice
->copymap
, i
);
7304 return the parameter pointer for a parameter
7306 void *lp_parm_ptr(struct loadparm_service
*service
, struct parm_struct
*parm
)
7308 if (service
== NULL
) {
7309 if (parm
->p_class
== P_LOCAL
)
7310 return (void *)(((char *)&sDefault
)+parm
->offset
);
7311 else if (parm
->p_class
== P_GLOBAL
)
7312 return (void *)(((char *)&Globals
)+parm
->offset
);
7315 return (void *)(((char *)service
) + parm
->offset
);
7319 /***************************************************************************
7320 Return the local pointer to a parameter given the service number and parameter
7321 ***************************************************************************/
7323 void *lp_local_ptr_by_snum(int snum
, struct parm_struct
*parm
)
7325 return lp_parm_ptr(ServicePtrs
[snum
], parm
);
7328 /***************************************************************************
7329 Process a parameter for a particular service number. If snum < 0
7330 then assume we are in the globals.
7331 ***************************************************************************/
7333 bool lp_do_parameter(int snum
, const char *pszParmName
, const char *pszParmValue
)
7336 void *parm_ptr
= NULL
; /* where we are going to store the result */
7337 struct parmlist_entry
**opt_list
;
7339 parmnum
= map_parameter(pszParmName
);
7342 if (strchr(pszParmName
, ':') == NULL
) {
7343 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7349 * We've got a parametric option
7352 opt_list
= (snum
< 0)
7353 ? &Globals
.param_opt
: &ServicePtrs
[snum
]->param_opt
;
7354 set_param_opt(opt_list
, pszParmName
, pszParmValue
, 0);
7359 /* if it's already been set by the command line, then we don't
7361 if (parm_table
[parmnum
].flags
& FLAG_CMDLINE
) {
7365 if (parm_table
[parmnum
].flags
& FLAG_DEPRECATED
) {
7366 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7370 /* we might point at a service, the default service or a global */
7372 parm_ptr
= lp_parm_ptr(NULL
, &parm_table
[parmnum
]);
7374 if (parm_table
[parmnum
].p_class
== P_GLOBAL
) {
7376 ("Global parameter %s found in service section!\n",
7380 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm_table
[parmnum
]);
7384 if (!ServicePtrs
[snum
]->copymap
)
7385 init_copymap(ServicePtrs
[snum
]);
7387 /* this handles the aliases - set the copymap for other entries with
7388 the same data pointer */
7389 for (i
= 0; parm_table
[i
].label
; i
++) {
7390 if ((parm_table
[i
].offset
== parm_table
[parmnum
].offset
)
7391 && (parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
)) {
7392 bitmap_clear(ServicePtrs
[snum
]->copymap
, i
);
7397 /* if it is a special case then go ahead */
7398 if (parm_table
[parmnum
].special
) {
7399 return parm_table
[parmnum
].special(NULL
, snum
, pszParmValue
,
7403 /* now switch on the type of variable it is */
7404 switch (parm_table
[parmnum
].type
)
7407 *(bool *)parm_ptr
= lp_bool(pszParmValue
);
7411 *(bool *)parm_ptr
= !lp_bool(pszParmValue
);
7415 *(int *)parm_ptr
= lp_int(pszParmValue
);
7419 *(char *)parm_ptr
= *pszParmValue
;
7423 i
= sscanf(pszParmValue
, "%o", (int *)parm_ptr
);
7425 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName
));
7432 if (conv_str_size_error(pszParmValue
, &val
)) {
7433 if (val
<= INT_MAX
) {
7434 *(int *)parm_ptr
= (int)val
;
7439 DEBUG(0,("lp_do_parameter(%s): value is not "
7440 "a valid size specifier!\n", pszParmValue
));
7446 TALLOC_FREE(*((char ***)parm_ptr
));
7447 *(char ***)parm_ptr
= str_list_make_v3(
7448 NULL
, pszParmValue
, NULL
);
7452 string_set((char **)parm_ptr
, pszParmValue
);
7457 char *upper_string
= strupper_talloc(talloc_tos(),
7459 string_set((char **)parm_ptr
, upper_string
);
7460 TALLOC_FREE(upper_string
);
7464 lp_set_enum_parm( &parm_table
[parmnum
], pszParmValue
, (int*)parm_ptr
);
7473 /***************************************************************************
7474 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7475 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7476 ***************************************************************************/
7478 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
)
7481 parmnum
= map_parameter(pszParmName
);
7483 parm_table
[parmnum
].flags
&= ~FLAG_CMDLINE
;
7484 if (!lp_do_parameter(-1, pszParmName
, pszParmValue
)) {
7487 parm_table
[parmnum
].flags
|= FLAG_CMDLINE
;
7489 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7490 * be grouped in the table, so we don't have to search the
7493 i
>=0 && parm_table
[i
].offset
== parm_table
[parmnum
].offset
7494 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;
7496 parm_table
[i
].flags
|= FLAG_CMDLINE
;
7498 for (i
=parmnum
+1;i
<NUMPARAMETERS
&& parm_table
[i
].offset
== parm_table
[parmnum
].offset
7499 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;i
++) {
7500 parm_table
[i
].flags
|= FLAG_CMDLINE
;
7504 store_lp_set_cmdline(pszParmName
, pszParmValue
);
7509 /* it might be parametric */
7510 if (strchr(pszParmName
, ':') != NULL
) {
7511 set_param_opt(&Globals
.param_opt
, pszParmName
, pszParmValue
, FLAG_CMDLINE
);
7513 store_lp_set_cmdline(pszParmName
, pszParmValue
);
7518 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName
));
7522 bool lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
7524 return lp_set_cmdline_helper(pszParmName
, pszParmValue
, true);
7527 /***************************************************************************
7528 Process a parameter.
7529 ***************************************************************************/
7531 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
7534 if (!bInGlobalSection
&& bGlobalOnly
)
7537 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName
, pszParmValue
));
7539 return (lp_do_parameter(bInGlobalSection
? -2 : iServiceIndex
,
7540 pszParmName
, pszParmValue
));
7544 set a option from the commandline in 'a=b' format. Use to support --option
7546 bool lp_set_option(const char *option
)
7551 s
= talloc_strdup(NULL
, option
);
7564 /* skip white spaces after the = sign */
7567 } while (*p
== ' ');
7569 ret
= lp_set_cmdline(s
, p
);
7574 /**************************************************************************
7575 Print a parameter of the specified type.
7576 ***************************************************************************/
7578 static void print_parameter(struct parm_struct
*p
, void *ptr
, FILE * f
)
7580 /* For the seperation of lists values that we print below */
7581 const char *list_sep
= ", ";
7586 for (i
= 0; p
->enum_list
[i
].name
; i
++) {
7587 if (*(int *)ptr
== p
->enum_list
[i
].value
) {
7589 p
->enum_list
[i
].name
);
7596 fprintf(f
, "%s", BOOLSTR(*(bool *)ptr
));
7600 fprintf(f
, "%s", BOOLSTR(!*(bool *)ptr
));
7605 fprintf(f
, "%d", *(int *)ptr
);
7609 fprintf(f
, "%c", *(char *)ptr
);
7613 int val
= *(int *)ptr
;
7617 fprintf(f
, "0%o", val
);
7626 if ((char ***)ptr
&& *(char ***)ptr
) {
7627 char **list
= *(char ***)ptr
;
7628 for (; *list
; list
++) {
7629 /* surround strings with whitespace in double quotes */
7630 if (*(list
+1) == NULL
) {
7631 /* last item, no extra separator */
7634 if ( strchr_m( *list
, ' ' ) ) {
7635 fprintf(f
, "\"%s\"%s", *list
, list_sep
);
7637 fprintf(f
, "%s%s", *list
, list_sep
);
7645 if (*(char **)ptr
) {
7646 fprintf(f
, "%s", *(char **)ptr
);
7654 /***************************************************************************
7655 Check if two parameters are equal.
7656 ***************************************************************************/
7658 static bool equal_parameter(parm_type type
, void *ptr1
, void *ptr2
)
7663 return (*((bool *)ptr1
) == *((bool *)ptr2
));
7669 return (*((int *)ptr1
) == *((int *)ptr2
));
7672 return (*((char *)ptr1
) == *((char *)ptr2
));
7676 return str_list_equal(*(const char ***)ptr1
, *(const char ***)ptr2
);
7681 char *p1
= *(char **)ptr1
, *p2
= *(char **)ptr2
;
7686 return (p1
== p2
|| strequal(p1
, p2
));
7694 /***************************************************************************
7695 Initialize any local varients in the sDefault table.
7696 ***************************************************************************/
7698 void init_locals(void)
7703 /***************************************************************************
7704 Process a new section (service). At this stage all sections are services.
7705 Later we'll have special sections that permit server parameters to be set.
7706 Returns true on success, false on failure.
7707 ***************************************************************************/
7709 static bool do_section(const char *pszSectionName
, void *userdata
)
7712 bool isglobal
= ((strwicmp(pszSectionName
, GLOBAL_NAME
) == 0) ||
7713 (strwicmp(pszSectionName
, GLOBAL_NAME2
) == 0));
7716 /* if we were in a global section then do the local inits */
7717 if (bInGlobalSection
&& !isglobal
)
7720 /* if we've just struck a global section, note the fact. */
7721 bInGlobalSection
= isglobal
;
7723 /* check for multiple global sections */
7724 if (bInGlobalSection
) {
7725 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName
));
7729 if (!bInGlobalSection
&& bGlobalOnly
)
7732 /* if we have a current service, tidy it up before moving on */
7735 if (iServiceIndex
>= 0)
7736 bRetval
= service_ok(iServiceIndex
);
7738 /* if all is still well, move to the next record in the services array */
7740 /* We put this here to avoid an odd message order if messages are */
7741 /* issued by the post-processing of a previous section. */
7742 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName
));
7744 iServiceIndex
= add_a_service(&sDefault
, pszSectionName
);
7745 if (iServiceIndex
< 0) {
7746 DEBUG(0, ("Failed to add a new service\n"));
7749 /* Clean all parametric options for service */
7750 /* They will be added during parsing again */
7751 free_param_opts(&ServicePtrs
[iServiceIndex
]->param_opt
);
7758 /***************************************************************************
7759 Determine if a partcular base parameter is currentl set to the default value.
7760 ***************************************************************************/
7762 static bool is_default(int i
)
7764 if (!defaults_saved
)
7766 switch (parm_table
[i
].type
) {
7769 return str_list_equal((const char **)parm_table
[i
].def
.lvalue
,
7770 *(const char ***)lp_parm_ptr(NULL
,
7774 return strequal(parm_table
[i
].def
.svalue
,
7775 *(char **)lp_parm_ptr(NULL
,
7779 return parm_table
[i
].def
.bvalue
==
7780 *(bool *)lp_parm_ptr(NULL
,
7783 return parm_table
[i
].def
.cvalue
==
7784 *(char *)lp_parm_ptr(NULL
,
7790 return parm_table
[i
].def
.ivalue
==
7791 *(int *)lp_parm_ptr(NULL
,
7799 /***************************************************************************
7800 Display the contents of the global structure.
7801 ***************************************************************************/
7803 static void dump_globals(FILE *f
)
7806 struct parmlist_entry
*data
;
7808 fprintf(f
, "[global]\n");
7810 for (i
= 0; parm_table
[i
].label
; i
++)
7811 if (parm_table
[i
].p_class
== P_GLOBAL
&&
7812 !(parm_table
[i
].flags
& FLAG_META
) &&
7813 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
))) {
7814 if (defaults_saved
&& is_default(i
))
7816 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
7817 print_parameter(&parm_table
[i
], lp_parm_ptr(NULL
,
7822 if (Globals
.param_opt
!= NULL
) {
7823 data
= Globals
.param_opt
;
7825 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
7832 /***************************************************************************
7833 Return true if a local parameter is currently set to the global default.
7834 ***************************************************************************/
7836 bool lp_is_default(int snum
, struct parm_struct
*parm
)
7838 return equal_parameter(parm
->type
,
7839 lp_parm_ptr(ServicePtrs
[snum
], parm
),
7840 lp_parm_ptr(NULL
, parm
));
7843 /***************************************************************************
7844 Display the contents of a single services record.
7845 ***************************************************************************/
7847 static void dump_a_service(struct loadparm_service
*pService
, FILE * f
)
7850 struct parmlist_entry
*data
;
7852 if (pService
!= &sDefault
)
7853 fprintf(f
, "[%s]\n", pService
->szService
);
7855 for (i
= 0; parm_table
[i
].label
; i
++) {
7857 if (parm_table
[i
].p_class
== P_LOCAL
&&
7858 !(parm_table
[i
].flags
& FLAG_META
) &&
7859 (*parm_table
[i
].label
!= '-') &&
7860 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
)))
7862 if (pService
== &sDefault
) {
7863 if (defaults_saved
&& is_default(i
))
7866 if (equal_parameter(parm_table
[i
].type
,
7867 lp_parm_ptr(pService
, &parm_table
[i
]),
7868 lp_parm_ptr(NULL
, &parm_table
[i
])))
7872 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
7873 print_parameter(&parm_table
[i
],
7874 lp_parm_ptr(pService
, &parm_table
[i
]),
7880 if (pService
->param_opt
!= NULL
) {
7881 data
= pService
->param_opt
;
7883 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
7889 /***************************************************************************
7890 Display the contents of a parameter of a single services record.
7891 ***************************************************************************/
7893 bool dump_a_parameter(int snum
, char *parm_name
, FILE * f
, bool isGlobal
)
7896 bool result
= false;
7899 fstring local_parm_name
;
7901 const char *parm_opt_value
;
7903 /* check for parametrical option */
7904 fstrcpy( local_parm_name
, parm_name
);
7905 parm_opt
= strchr( local_parm_name
, ':');
7910 if (strlen(parm_opt
)) {
7911 parm_opt_value
= lp_parm_const_string( snum
,
7912 local_parm_name
, parm_opt
, NULL
);
7913 if (parm_opt_value
) {
7914 printf( "%s\n", parm_opt_value
);
7921 /* check for a key and print the value */
7928 for (i
= 0; parm_table
[i
].label
; i
++) {
7929 if (strwicmp(parm_table
[i
].label
, parm_name
) == 0 &&
7930 !(parm_table
[i
].flags
& FLAG_META
) &&
7931 (parm_table
[i
].p_class
== p_class
|| parm_table
[i
].flags
& flag
) &&
7932 (*parm_table
[i
].label
!= '-') &&
7933 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
)))
7938 ptr
= lp_parm_ptr(NULL
,
7941 ptr
= lp_parm_ptr(ServicePtrs
[snum
],
7945 print_parameter(&parm_table
[i
],
7956 /***************************************************************************
7957 Return info about the requested parameter (given as a string).
7958 Return NULL when the string is not a valid parameter name.
7959 ***************************************************************************/
7961 struct parm_struct
*lp_get_parameter(const char *param_name
)
7963 int num
= map_parameter(param_name
);
7969 return &parm_table
[num
];
7972 /***************************************************************************
7973 Return info about the next parameter in a service.
7974 snum==GLOBAL_SECTION_SNUM gives the globals.
7975 Return NULL when out of parameters.
7976 ***************************************************************************/
7978 struct parm_struct
*lp_next_parameter(int snum
, int *i
, int allparameters
)
7981 /* do the globals */
7982 for (; parm_table
[*i
].label
; (*i
)++) {
7983 if (parm_table
[*i
].p_class
== P_SEPARATOR
)
7984 return &parm_table
[(*i
)++];
7986 if ((*parm_table
[*i
].label
== '-'))
7990 && (parm_table
[*i
].offset
==
7991 parm_table
[(*i
) - 1].offset
)
7992 && (parm_table
[*i
].p_class
==
7993 parm_table
[(*i
) - 1].p_class
))
7996 if (is_default(*i
) && !allparameters
)
7999 return &parm_table
[(*i
)++];
8002 struct loadparm_service
*pService
= ServicePtrs
[snum
];
8004 for (; parm_table
[*i
].label
; (*i
)++) {
8005 if (parm_table
[*i
].p_class
== P_SEPARATOR
)
8006 return &parm_table
[(*i
)++];
8008 if (parm_table
[*i
].p_class
== P_LOCAL
&&
8009 (*parm_table
[*i
].label
!= '-') &&
8011 (parm_table
[*i
].offset
!=
8012 parm_table
[(*i
) - 1].offset
)))
8014 if (allparameters
||
8015 !equal_parameter(parm_table
[*i
].type
,
8016 lp_parm_ptr(pService
,
8021 return &parm_table
[(*i
)++];
8032 /***************************************************************************
8033 Display the contents of a single copy structure.
8034 ***************************************************************************/
8035 static void dump_copy_map(bool *pcopymap
)
8041 printf("\n\tNon-Copied parameters:\n");
8043 for (i
= 0; parm_table
[i
].label
; i
++)
8044 if (parm_table
[i
].p_class
== P_LOCAL
&&
8045 parm_table
[i
].ptr
&& !pcopymap
[i
] &&
8046 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
- 1].ptr
)))
8048 printf("\t\t%s\n", parm_table
[i
].label
);
8053 /***************************************************************************
8054 Return TRUE if the passed service number is within range.
8055 ***************************************************************************/
8057 bool lp_snum_ok(int iService
)
8059 return (LP_SNUM_OK(iService
) && ServicePtrs
[iService
]->bAvailable
);
8062 /***************************************************************************
8063 Auto-load some home services.
8064 ***************************************************************************/
8066 static void lp_add_auto_services(char *str
)
8076 s
= SMB_STRDUP(str
);
8080 homes
= lp_servicenumber(HOMES_NAME
);
8082 for (p
= strtok_r(s
, LIST_SEP
, &saveptr
); p
;
8083 p
= strtok_r(NULL
, LIST_SEP
, &saveptr
)) {
8086 if (lp_servicenumber(p
) >= 0)
8089 home
= get_user_home_dir(talloc_tos(), p
);
8091 if (home
&& home
[0] && homes
>= 0)
8092 lp_add_home(p
, homes
, p
, home
);
8099 /***************************************************************************
8100 Auto-load one printer.
8101 ***************************************************************************/
8103 void lp_add_one_printer(const char *name
, const char *comment
,
8104 const char *location
, void *pdata
)
8106 int printers
= lp_servicenumber(PRINTERS_NAME
);
8109 if (lp_servicenumber(name
) < 0) {
8110 lp_add_printer(name
, printers
);
8111 if ((i
= lp_servicenumber(name
)) >= 0) {
8112 string_set(&ServicePtrs
[i
]->comment
, comment
);
8113 ServicePtrs
[i
]->autoloaded
= true;
8118 /***************************************************************************
8119 Have we loaded a services file yet?
8120 ***************************************************************************/
8122 bool lp_loaded(void)
8127 /***************************************************************************
8128 Unload unused services.
8129 ***************************************************************************/
8131 void lp_killunused(struct smbd_server_connection
*sconn
,
8132 bool (*snumused
) (struct smbd_server_connection
*, int))
8135 for (i
= 0; i
< iNumServices
; i
++) {
8139 /* don't kill autoloaded or usershare services */
8140 if ( ServicePtrs
[i
]->autoloaded
||
8141 ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
8145 if (!snumused
|| !snumused(sconn
, i
)) {
8146 free_service_byindex(i
);
8152 * Kill all except autoloaded and usershare services - convenience wrapper
8154 void lp_kill_all_services(void)
8156 lp_killunused(NULL
, NULL
);
8159 /***************************************************************************
8161 ***************************************************************************/
8163 void lp_killservice(int iServiceIn
)
8165 if (VALID(iServiceIn
)) {
8166 free_service_byindex(iServiceIn
);
8170 /***************************************************************************
8171 Save the curent values of all global and sDefault parameters into the
8172 defaults union. This allows swat and testparm to show only the
8173 changed (ie. non-default) parameters.
8174 ***************************************************************************/
8176 static void lp_save_defaults(void)
8179 for (i
= 0; parm_table
[i
].label
; i
++) {
8180 if (i
> 0 && parm_table
[i
].offset
== parm_table
[i
- 1].offset
8181 && parm_table
[i
].p_class
== parm_table
[i
- 1].p_class
)
8183 switch (parm_table
[i
].type
) {
8186 parm_table
[i
].def
.lvalue
= str_list_copy(
8187 NULL
, *(const char ***)lp_parm_ptr(NULL
, &parm_table
[i
]));
8191 parm_table
[i
].def
.svalue
= SMB_STRDUP(*(char **)lp_parm_ptr(NULL
, &parm_table
[i
]));
8195 parm_table
[i
].def
.bvalue
=
8196 *(bool *)lp_parm_ptr(NULL
, &parm_table
[i
]);
8199 parm_table
[i
].def
.cvalue
=
8200 *(char *)lp_parm_ptr(NULL
, &parm_table
[i
]);
8206 parm_table
[i
].def
.ivalue
=
8207 *(int *)lp_parm_ptr(NULL
, &parm_table
[i
]);
8213 defaults_saved
= true;
8216 /***********************************************************
8217 If we should send plaintext/LANMAN passwords in the clinet
8218 ************************************************************/
8220 static void set_allowed_client_auth(void)
8222 if (Globals
.bClientNTLMv2Auth
) {
8223 Globals
.bClientLanManAuth
= false;
8225 if (!Globals
.bClientLanManAuth
) {
8226 Globals
.bClientPlaintextAuth
= false;
8230 /***************************************************************************
8232 The following code allows smbd to read a user defined share file.
8233 Yes, this is my intent. Yes, I'm comfortable with that...
8235 THE FOLLOWING IS SECURITY CRITICAL CODE.
8237 It washes your clothes, it cleans your house, it guards you while you sleep...
8238 Do not f%^k with it....
8239 ***************************************************************************/
8241 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8243 /***************************************************************************
8244 Check allowed stat state of a usershare file.
8245 Ensure we print out who is dicking with us so the admin can
8246 get their sorry ass fired.
8247 ***************************************************************************/
8249 static bool check_usershare_stat(const char *fname
,
8250 const SMB_STRUCT_STAT
*psbuf
)
8252 if (!S_ISREG(psbuf
->st_ex_mode
)) {
8253 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8254 "not a regular file\n",
8255 fname
, (unsigned int)psbuf
->st_ex_uid
));
8259 /* Ensure this doesn't have the other write bit set. */
8260 if (psbuf
->st_ex_mode
& S_IWOTH
) {
8261 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8262 "public write. Refusing to allow as a usershare file.\n",
8263 fname
, (unsigned int)psbuf
->st_ex_uid
));
8267 /* Should be 10k or less. */
8268 if (psbuf
->st_ex_size
> MAX_USERSHARE_FILE_SIZE
) {
8269 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8270 "too large (%u) to be a user share file.\n",
8271 fname
, (unsigned int)psbuf
->st_ex_uid
,
8272 (unsigned int)psbuf
->st_ex_size
));
8279 /***************************************************************************
8280 Parse the contents of a usershare file.
8281 ***************************************************************************/
8283 enum usershare_err
parse_usershare_file(TALLOC_CTX
*ctx
,
8284 SMB_STRUCT_STAT
*psbuf
,
8285 const char *servicename
,
8289 char **pp_sharepath
,
8291 char **pp_cp_servicename
,
8292 struct security_descriptor
**ppsd
,
8295 const char **prefixallowlist
= lp_usershare_prefix_allow_list();
8296 const char **prefixdenylist
= lp_usershare_prefix_deny_list();
8299 SMB_STRUCT_STAT sbuf
;
8300 char *sharepath
= NULL
;
8301 char *comment
= NULL
;
8303 *pp_sharepath
= NULL
;
8306 *pallow_guest
= false;
8309 return USERSHARE_MALFORMED_FILE
;
8312 if (strcmp(lines
[0], "#VERSION 1") == 0) {
8314 } else if (strcmp(lines
[0], "#VERSION 2") == 0) {
8317 return USERSHARE_MALFORMED_FILE
;
8320 return USERSHARE_BAD_VERSION
;
8323 if (strncmp(lines
[1], "path=", 5) != 0) {
8324 return USERSHARE_MALFORMED_PATH
;
8327 sharepath
= talloc_strdup(ctx
, &lines
[1][5]);
8329 return USERSHARE_POSIX_ERR
;
8331 trim_string(sharepath
, " ", " ");
8333 if (strncmp(lines
[2], "comment=", 8) != 0) {
8334 return USERSHARE_MALFORMED_COMMENT_DEF
;
8337 comment
= talloc_strdup(ctx
, &lines
[2][8]);
8339 return USERSHARE_POSIX_ERR
;
8341 trim_string(comment
, " ", " ");
8342 trim_char(comment
, '"', '"');
8344 if (strncmp(lines
[3], "usershare_acl=", 14) != 0) {
8345 return USERSHARE_MALFORMED_ACL_DEF
;
8348 if (!parse_usershare_acl(ctx
, &lines
[3][14], ppsd
)) {
8349 return USERSHARE_ACL_ERR
;
8353 if (strncmp(lines
[4], "guest_ok=", 9) != 0) {
8354 return USERSHARE_MALFORMED_ACL_DEF
;
8356 if (lines
[4][9] == 'y') {
8357 *pallow_guest
= true;
8360 /* Backwards compatible extension to file version #2. */
8362 if (strncmp(lines
[5], "sharename=", 10) != 0) {
8363 return USERSHARE_MALFORMED_SHARENAME_DEF
;
8365 if (!strequal(&lines
[5][10], servicename
)) {
8366 return USERSHARE_BAD_SHARENAME
;
8368 *pp_cp_servicename
= talloc_strdup(ctx
, &lines
[5][10]);
8369 if (!*pp_cp_servicename
) {
8370 return USERSHARE_POSIX_ERR
;
8375 if (*pp_cp_servicename
== NULL
) {
8376 *pp_cp_servicename
= talloc_strdup(ctx
, servicename
);
8377 if (!*pp_cp_servicename
) {
8378 return USERSHARE_POSIX_ERR
;
8382 if (snum
!= -1 && (strcmp(sharepath
, ServicePtrs
[snum
]->szPath
) == 0)) {
8383 /* Path didn't change, no checks needed. */
8384 *pp_sharepath
= sharepath
;
8385 *pp_comment
= comment
;
8386 return USERSHARE_OK
;
8389 /* The path *must* be absolute. */
8390 if (sharepath
[0] != '/') {
8391 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8392 servicename
, sharepath
));
8393 return USERSHARE_PATH_NOT_ABSOLUTE
;
8396 /* If there is a usershare prefix deny list ensure one of these paths
8397 doesn't match the start of the user given path. */
8398 if (prefixdenylist
) {
8400 for ( i
=0; prefixdenylist
[i
]; i
++ ) {
8401 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8402 servicename
, i
, prefixdenylist
[i
], sharepath
));
8403 if (memcmp( sharepath
, prefixdenylist
[i
], strlen(prefixdenylist
[i
])) == 0) {
8404 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8405 "usershare prefix deny list entries.\n",
8406 servicename
, sharepath
));
8407 return USERSHARE_PATH_IS_DENIED
;
8412 /* If there is a usershare prefix allow list ensure one of these paths
8413 does match the start of the user given path. */
8415 if (prefixallowlist
) {
8417 for ( i
=0; prefixallowlist
[i
]; i
++ ) {
8418 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8419 servicename
, i
, prefixallowlist
[i
], sharepath
));
8420 if (memcmp( sharepath
, prefixallowlist
[i
], strlen(prefixallowlist
[i
])) == 0) {
8424 if (prefixallowlist
[i
] == NULL
) {
8425 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8426 "usershare prefix allow list entries.\n",
8427 servicename
, sharepath
));
8428 return USERSHARE_PATH_NOT_ALLOWED
;
8432 /* Ensure this is pointing to a directory. */
8433 dp
= opendir(sharepath
);
8436 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8437 servicename
, sharepath
));
8438 return USERSHARE_PATH_NOT_DIRECTORY
;
8441 /* Ensure the owner of the usershare file has permission to share
8444 if (sys_stat(sharepath
, &sbuf
, false) == -1) {
8445 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8446 servicename
, sharepath
, strerror(errno
) ));
8448 return USERSHARE_POSIX_ERR
;
8453 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
8454 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8455 servicename
, sharepath
));
8456 return USERSHARE_PATH_NOT_DIRECTORY
;
8459 /* Check if sharing is restricted to owner-only. */
8460 /* psbuf is the stat of the usershare definition file,
8461 sbuf is the stat of the target directory to be shared. */
8463 if (lp_usershare_owner_only()) {
8464 /* root can share anything. */
8465 if ((psbuf
->st_ex_uid
!= 0) && (sbuf
.st_ex_uid
!= psbuf
->st_ex_uid
)) {
8466 return USERSHARE_PATH_NOT_ALLOWED
;
8470 *pp_sharepath
= sharepath
;
8471 *pp_comment
= comment
;
8472 return USERSHARE_OK
;
8475 /***************************************************************************
8476 Deal with a usershare file.
8479 -1 - Bad name, invalid contents.
8480 - service name already existed and not a usershare, problem
8481 with permissions to share directory etc.
8482 ***************************************************************************/
8484 static int process_usershare_file(const char *dir_name
, const char *file_name
, int snum_template
)
8486 SMB_STRUCT_STAT sbuf
;
8487 SMB_STRUCT_STAT lsbuf
;
8489 char *sharepath
= NULL
;
8490 char *comment
= NULL
;
8491 char *cp_service_name
= NULL
;
8492 char **lines
= NULL
;
8496 TALLOC_CTX
*ctx
= talloc_stackframe();
8497 struct security_descriptor
*psd
= NULL
;
8498 bool guest_ok
= false;
8499 char *canon_name
= NULL
;
8500 bool added_service
= false;
8503 /* Ensure share name doesn't contain invalid characters. */
8504 if (!validate_net_name(file_name
, INVALID_SHARENAME_CHARS
, strlen(file_name
))) {
8505 DEBUG(0,("process_usershare_file: share name %s contains "
8506 "invalid characters (any of %s)\n",
8507 file_name
, INVALID_SHARENAME_CHARS
));
8511 canon_name
= canonicalize_servicename(ctx
, file_name
);
8516 fname
= talloc_asprintf(ctx
, "%s/%s", dir_name
, file_name
);
8521 /* Minimize the race condition by doing an lstat before we
8522 open and fstat. Ensure this isn't a symlink link. */
8524 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
8525 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8526 fname
, strerror(errno
) ));
8530 /* This must be a regular file, not a symlink, directory or
8531 other strange filetype. */
8532 if (!check_usershare_stat(fname
, &lsbuf
)) {
8540 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
,
8545 if (NT_STATUS_IS_OK(status
) &&
8546 (data
.dptr
!= NULL
) &&
8547 (data
.dsize
== sizeof(iService
))) {
8548 memcpy(&iService
, data
.dptr
, sizeof(iService
));
8552 if (iService
!= -1 &&
8553 timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
8554 &lsbuf
.st_ex_mtime
) == 0) {
8555 /* Nothing changed - Mark valid and return. */
8556 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8558 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
8563 /* Try and open the file read only - no symlinks allowed. */
8565 fd
= open(fname
, O_RDONLY
|O_NOFOLLOW
, 0);
8567 fd
= open(fname
, O_RDONLY
, 0);
8571 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8572 fname
, strerror(errno
) ));
8576 /* Now fstat to be *SURE* it's a regular file. */
8577 if (sys_fstat(fd
, &sbuf
, false) != 0) {
8579 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8580 fname
, strerror(errno
) ));
8584 /* Is it the same dev/inode as was lstated ? */
8585 if (!check_same_stat(&lsbuf
, &sbuf
)) {
8587 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8588 "Symlink spoofing going on ?\n", fname
));
8592 /* This must be a regular file, not a symlink, directory or
8593 other strange filetype. */
8594 if (!check_usershare_stat(fname
, &sbuf
)) {
8598 lines
= fd_lines_load(fd
, &numlines
, MAX_USERSHARE_FILE_SIZE
, NULL
);
8601 if (lines
== NULL
) {
8602 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8603 fname
, (unsigned int)sbuf
.st_ex_uid
));
8607 if (parse_usershare_file(ctx
, &sbuf
, file_name
,
8608 iService
, lines
, numlines
, &sharepath
,
8609 &comment
, &cp_service_name
,
8610 &psd
, &guest_ok
) != USERSHARE_OK
) {
8614 /* Everything ok - add the service possibly using a template. */
8616 const struct loadparm_service
*sp
= &sDefault
;
8617 if (snum_template
!= -1) {
8618 sp
= ServicePtrs
[snum_template
];
8621 if ((iService
= add_a_service(sp
, cp_service_name
)) < 0) {
8622 DEBUG(0, ("process_usershare_file: Failed to add "
8623 "new service %s\n", cp_service_name
));
8627 added_service
= true;
8629 /* Read only is controlled by usershare ACL below. */
8630 ServicePtrs
[iService
]->bRead_only
= false;
8633 /* Write the ACL of the new/modified share. */
8634 if (!set_share_security(canon_name
, psd
)) {
8635 DEBUG(0, ("process_usershare_file: Failed to set share "
8636 "security for user share %s\n",
8641 /* If from a template it may be marked invalid. */
8642 ServicePtrs
[iService
]->valid
= true;
8644 /* Set the service as a valid usershare. */
8645 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
8647 /* Set guest access. */
8648 if (lp_usershare_allow_guests()) {
8649 ServicePtrs
[iService
]->bGuest_ok
= guest_ok
;
8652 /* And note when it was loaded. */
8653 ServicePtrs
[iService
]->usershare_last_mod
= sbuf
.st_ex_mtime
;
8654 string_set(&ServicePtrs
[iService
]->szPath
, sharepath
);
8655 string_set(&ServicePtrs
[iService
]->comment
, comment
);
8661 if (ret
== -1 && iService
!= -1 && added_service
) {
8662 lp_remove_service(iService
);
8670 /***************************************************************************
8671 Checks if a usershare entry has been modified since last load.
8672 ***************************************************************************/
8674 static bool usershare_exists(int iService
, struct timespec
*last_mod
)
8676 SMB_STRUCT_STAT lsbuf
;
8677 const char *usersharepath
= Globals
.szUsersharePath
;
8680 if (asprintf(&fname
, "%s/%s",
8682 ServicePtrs
[iService
]->szService
) < 0) {
8686 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
8691 if (!S_ISREG(lsbuf
.st_ex_mode
)) {
8697 *last_mod
= lsbuf
.st_ex_mtime
;
8701 /***************************************************************************
8702 Load a usershare service by name. Returns a valid servicenumber or -1.
8703 ***************************************************************************/
8705 int load_usershare_service(const char *servicename
)
8707 SMB_STRUCT_STAT sbuf
;
8708 const char *usersharepath
= Globals
.szUsersharePath
;
8709 int max_user_shares
= Globals
.iUsershareMaxShares
;
8710 int snum_template
= -1;
8712 if (*usersharepath
== 0 || max_user_shares
== 0) {
8716 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
8717 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8718 usersharepath
, strerror(errno
) ));
8722 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
8723 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8729 * This directory must be owned by root, and have the 't' bit set.
8730 * It also must not be writable by "other".
8734 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
8736 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
8738 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8739 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8744 /* Ensure the template share exists if it's set. */
8745 if (Globals
.szUsershareTemplateShare
[0]) {
8746 /* We can't use lp_servicenumber here as we are recommending that
8747 template shares have -valid=false set. */
8748 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
8749 if (ServicePtrs
[snum_template
]->szService
&&
8750 strequal(ServicePtrs
[snum_template
]->szService
,
8751 Globals
.szUsershareTemplateShare
)) {
8756 if (snum_template
== -1) {
8757 DEBUG(0,("load_usershare_service: usershare template share %s "
8758 "does not exist.\n",
8759 Globals
.szUsershareTemplateShare
));
8764 return process_usershare_file(usersharepath
, servicename
, snum_template
);
8767 /***************************************************************************
8768 Load all user defined shares from the user share directory.
8769 We only do this if we're enumerating the share list.
8770 This is the function that can delete usershares that have
8772 ***************************************************************************/
8774 int load_usershare_shares(struct smbd_server_connection
*sconn
,
8775 bool (*snumused
) (struct smbd_server_connection
*, int))
8778 SMB_STRUCT_STAT sbuf
;
8780 int num_usershares
= 0;
8781 int max_user_shares
= Globals
.iUsershareMaxShares
;
8782 unsigned int num_dir_entries
, num_bad_dir_entries
, num_tmp_dir_entries
;
8783 unsigned int allowed_bad_entries
= ((2*max_user_shares
)/10);
8784 unsigned int allowed_tmp_entries
= ((2*max_user_shares
)/10);
8786 int snum_template
= -1;
8787 const char *usersharepath
= Globals
.szUsersharePath
;
8788 int ret
= lp_numservices();
8789 TALLOC_CTX
*tmp_ctx
;
8791 if (max_user_shares
== 0 || *usersharepath
== '\0') {
8792 return lp_numservices();
8795 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
8796 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8797 usersharepath
, strerror(errno
) ));
8802 * This directory must be owned by root, and have the 't' bit set.
8803 * It also must not be writable by "other".
8807 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
8809 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
8811 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8812 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8817 /* Ensure the template share exists if it's set. */
8818 if (Globals
.szUsershareTemplateShare
[0]) {
8819 /* We can't use lp_servicenumber here as we are recommending that
8820 template shares have -valid=false set. */
8821 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
8822 if (ServicePtrs
[snum_template
]->szService
&&
8823 strequal(ServicePtrs
[snum_template
]->szService
,
8824 Globals
.szUsershareTemplateShare
)) {
8829 if (snum_template
== -1) {
8830 DEBUG(0,("load_usershare_shares: usershare template share %s "
8831 "does not exist.\n",
8832 Globals
.szUsershareTemplateShare
));
8837 /* Mark all existing usershares as pending delete. */
8838 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
8839 if (VALID(iService
) && ServicePtrs
[iService
]->usershare
) {
8840 ServicePtrs
[iService
]->usershare
= USERSHARE_PENDING_DELETE
;
8844 dp
= opendir(usersharepath
);
8846 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8847 usersharepath
, strerror(errno
) ));
8851 for (num_dir_entries
= 0, num_bad_dir_entries
= 0, num_tmp_dir_entries
= 0;
8853 num_dir_entries
++ ) {
8855 const char *n
= de
->d_name
;
8857 /* Ignore . and .. */
8859 if ((n
[1] == '\0') || (n
[1] == '.' && n
[2] == '\0')) {
8865 /* Temporary file used when creating a share. */
8866 num_tmp_dir_entries
++;
8869 /* Allow 20% tmp entries. */
8870 if (num_tmp_dir_entries
> allowed_tmp_entries
) {
8871 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8872 "in directory %s\n",
8873 num_tmp_dir_entries
, usersharepath
));
8877 r
= process_usershare_file(usersharepath
, n
, snum_template
);
8879 /* Update the services count. */
8881 if (num_usershares
>= max_user_shares
) {
8882 DEBUG(0,("load_usershare_shares: max user shares reached "
8883 "on file %s in directory %s\n",
8884 n
, usersharepath
));
8887 } else if (r
== -1) {
8888 num_bad_dir_entries
++;
8891 /* Allow 20% bad entries. */
8892 if (num_bad_dir_entries
> allowed_bad_entries
) {
8893 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8894 "in directory %s\n",
8895 num_bad_dir_entries
, usersharepath
));
8899 /* Allow 20% bad entries. */
8900 if (num_dir_entries
> max_user_shares
+ allowed_bad_entries
) {
8901 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8902 "in directory %s\n",
8903 num_dir_entries
, usersharepath
));
8910 /* Sweep through and delete any non-refreshed usershares that are
8911 not currently in use. */
8912 tmp_ctx
= talloc_stackframe();
8913 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
8914 if (VALID(iService
) && (ServicePtrs
[iService
]->usershare
== USERSHARE_PENDING_DELETE
)) {
8917 if (snumused
&& snumused(sconn
, iService
)) {
8921 servname
= lp_servicename(tmp_ctx
, iService
);
8923 /* Remove from the share ACL db. */
8924 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8926 delete_share_security(servname
);
8927 free_service_byindex(iService
);
8930 talloc_free(tmp_ctx
);
8932 return lp_numservices();
8935 /********************************************************
8936 Destroy global resources allocated in this file
8937 ********************************************************/
8939 void gfree_loadparm(void)
8945 /* Free resources allocated to services */
8947 for ( i
= 0; i
< iNumServices
; i
++ ) {
8949 free_service_byindex(i
);
8953 SAFE_FREE( ServicePtrs
);
8956 /* Now release all resources allocated to global
8957 parameters and the default service */
8959 free_global_parameters();
8963 /***************************************************************************
8964 Allow client apps to specify that they are a client
8965 ***************************************************************************/
8966 static void lp_set_in_client(bool b
)
8972 /***************************************************************************
8973 Determine if we're running in a client app
8974 ***************************************************************************/
8975 static bool lp_is_in_client(void)
8980 /***************************************************************************
8981 Load the services array from the services file. Return true on success,
8983 ***************************************************************************/
8985 static bool lp_load_ex(const char *pszFname
,
8989 bool initialize_globals
,
8990 bool allow_include_registry
,
8991 bool load_all_shares
)
8998 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9000 bInGlobalSection
= true;
9001 bGlobalOnly
= global_only
;
9002 bAllowIncludeRegistry
= allow_include_registry
;
9004 init_globals(initialize_globals
);
9008 if (save_defaults
) {
9013 if (!initialize_globals
) {
9014 free_param_opts(&Globals
.param_opt
);
9015 apply_lp_set_cmdline();
9018 lp_do_parameter(-1, "idmap config * : backend", Globals
.szIdmapBackend
);
9020 /* We get sections first, so have to start 'behind' to make up */
9023 if (lp_config_backend_is_file()) {
9024 n2
= talloc_sub_basic(talloc_tos(), get_current_username(),
9025 current_user_info
.domain
,
9028 smb_panic("lp_load_ex: out of memory");
9031 add_to_file_list(pszFname
, n2
);
9033 bRetval
= pm_process(n2
, do_section
, do_parameter
, NULL
);
9036 /* finish up the last section */
9037 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval
)));
9039 if (iServiceIndex
>= 0) {
9040 bRetval
= service_ok(iServiceIndex
);
9044 if (lp_config_backend_is_registry()) {
9045 /* config backend changed to registry in config file */
9047 * We need to use this extra global variable here to
9048 * survive restart: init_globals uses this as a default
9049 * for ConfigBackend. Otherwise, init_globals would
9050 * send us into an endless loop here.
9052 config_backend
= CONFIG_BACKEND_REGISTRY
;
9054 DEBUG(1, ("lp_load_ex: changing to config backend "
9057 lp_kill_all_services();
9058 return lp_load_ex(pszFname
, global_only
, save_defaults
,
9059 add_ipc
, initialize_globals
,
9060 allow_include_registry
,
9063 } else if (lp_config_backend_is_registry()) {
9064 bRetval
= process_registry_globals();
9066 DEBUG(0, ("Illegal config backend given: %d\n",
9067 lp_config_backend()));
9071 if (bRetval
&& lp_registry_shares()) {
9072 if (load_all_shares
) {
9073 bRetval
= process_registry_shares();
9075 bRetval
= reload_registry_shares();
9080 char *serv
= lp_auto_services(talloc_tos());
9081 lp_add_auto_services(serv
);
9086 /* When 'restrict anonymous = 2' guest connections to ipc$
9088 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9089 if ( lp_enable_asu_support() ) {
9090 lp_add_ipc("ADMIN$", false);
9094 set_allowed_client_auth();
9096 if (lp_security() == SEC_ADS
&& strchr(lp_passwordserver(), ':')) {
9097 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
9098 lp_passwordserver()));
9103 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9104 /* if bWINSsupport is true and we are in the client */
9105 if (lp_is_in_client() && Globals
.bWINSsupport
) {
9106 lp_do_parameter(GLOBAL_SECTION_SNUM
, "wins server", "127.0.0.1");
9111 fault_configure(smb_panic_s3
);
9113 bAllowIncludeRegistry
= true;
9118 bool lp_load(const char *pszFname
,
9122 bool initialize_globals
)
9124 return lp_load_ex(pszFname
,
9129 true, /* allow_include_registry */
9130 false); /* load_all_shares*/
9133 bool lp_load_initial_only(const char *pszFname
)
9135 return lp_load_ex(pszFname
,
9136 true, /* global only */
9137 false, /* save_defaults */
9138 false, /* add_ipc */
9139 true, /* initialize_globals */
9140 false, /* allow_include_registry */
9141 false); /* load_all_shares*/
9145 * most common lp_load wrapper, loading only the globals
9147 bool lp_load_global(const char *file_name
)
9149 return lp_load_ex(file_name
,
9150 true, /* global_only */
9151 false, /* save_defaults */
9152 false, /* add_ipc */
9153 true, /* initialize_globals */
9154 true, /* allow_include_registry */
9155 false); /* load_all_shares*/
9159 * lp_load wrapper, especially for clients
9161 bool lp_load_client(const char *file_name
)
9163 lp_set_in_client(true);
9165 return lp_load_global(file_name
);
9169 * lp_load wrapper, loading only globals, but intended
9170 * for subsequent calls, not reinitializing the globals
9173 bool lp_load_global_no_reinit(const char *file_name
)
9175 return lp_load_ex(file_name
,
9176 true, /* global_only */
9177 false, /* save_defaults */
9178 false, /* add_ipc */
9179 false, /* initialize_globals */
9180 true, /* allow_include_registry */
9181 false); /* load_all_shares*/
9185 * lp_load wrapper, especially for clients, no reinitialization
9187 bool lp_load_client_no_reinit(const char *file_name
)
9189 lp_set_in_client(true);
9191 return lp_load_global_no_reinit(file_name
);
9194 bool lp_load_with_registry_shares(const char *pszFname
,
9198 bool initialize_globals
)
9200 return lp_load_ex(pszFname
,
9205 true, /* allow_include_registry */
9206 true); /* load_all_shares*/
9209 /***************************************************************************
9210 Return the max number of services.
9211 ***************************************************************************/
9213 int lp_numservices(void)
9215 return (iNumServices
);
9218 /***************************************************************************
9219 Display the contents of the services array in human-readable form.
9220 ***************************************************************************/
9222 void lp_dump(FILE *f
, bool show_defaults
, int maxtoprint
)
9227 defaults_saved
= false;
9231 dump_a_service(&sDefault
, f
);
9233 for (iService
= 0; iService
< maxtoprint
; iService
++) {
9235 lp_dump_one(f
, show_defaults
, iService
);
9239 /***************************************************************************
9240 Display the contents of one service in human-readable form.
9241 ***************************************************************************/
9243 void lp_dump_one(FILE * f
, bool show_defaults
, int snum
)
9246 if (ServicePtrs
[snum
]->szService
[0] == '\0')
9248 dump_a_service(ServicePtrs
[snum
], f
);
9252 /***************************************************************************
9253 Return the number of the service with the given name, or -1 if it doesn't
9254 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9255 getservicebyname()! This works ONLY if all services have been loaded, and
9256 does not copy the found service.
9257 ***************************************************************************/
9259 int lp_servicenumber(const char *pszServiceName
)
9262 fstring serviceName
;
9264 if (!pszServiceName
) {
9265 return GLOBAL_SECTION_SNUM
;
9268 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
9269 if (VALID(iService
) && ServicePtrs
[iService
]->szService
) {
9271 * The substitution here is used to support %U is
9274 fstrcpy(serviceName
, ServicePtrs
[iService
]->szService
);
9275 standard_sub_basic(get_current_username(),
9276 current_user_info
.domain
,
9277 serviceName
,sizeof(serviceName
));
9278 if (strequal(serviceName
, pszServiceName
)) {
9284 if (iService
>= 0 && ServicePtrs
[iService
]->usershare
== USERSHARE_VALID
) {
9285 struct timespec last_mod
;
9287 if (!usershare_exists(iService
, &last_mod
)) {
9288 /* Remove the share security tdb entry for it. */
9289 delete_share_security(lp_servicename(talloc_tos(), iService
));
9290 /* Remove it from the array. */
9291 free_service_byindex(iService
);
9292 /* Doesn't exist anymore. */
9293 return GLOBAL_SECTION_SNUM
;
9296 /* Has it been modified ? If so delete and reload. */
9297 if (timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
9299 /* Remove it from the array. */
9300 free_service_byindex(iService
);
9301 /* and now reload it. */
9302 iService
= load_usershare_service(pszServiceName
);
9307 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName
));
9308 return GLOBAL_SECTION_SNUM
;
9314 /*******************************************************************
9315 A useful volume label function.
9316 ********************************************************************/
9318 const char *volume_label(TALLOC_CTX
*ctx
, int snum
)
9321 const char *label
= lp_volume(ctx
, snum
);
9323 label
= lp_servicename(ctx
, snum
);
9326 /* This returns a 33 byte guarenteed null terminated string. */
9327 ret
= talloc_strndup(ctx
, label
, 32);
9334 /*******************************************************************
9335 Get the default server type we will announce as via nmbd.
9336 ********************************************************************/
9338 int lp_default_server_announce(void)
9340 int default_server_announce
= 0;
9341 default_server_announce
|= SV_TYPE_WORKSTATION
;
9342 default_server_announce
|= SV_TYPE_SERVER
;
9343 default_server_announce
|= SV_TYPE_SERVER_UNIX
;
9345 /* note that the flag should be set only if we have a
9346 printer service but nmbd doesn't actually load the
9347 services so we can't tell --jerry */
9349 default_server_announce
|= SV_TYPE_PRINTQ_SERVER
;
9351 default_server_announce
|= SV_TYPE_SERVER_NT
;
9352 default_server_announce
|= SV_TYPE_NT
;
9354 switch (lp_server_role()) {
9355 case ROLE_DOMAIN_MEMBER
:
9356 default_server_announce
|= SV_TYPE_DOMAIN_MEMBER
;
9358 case ROLE_DOMAIN_PDC
:
9359 default_server_announce
|= SV_TYPE_DOMAIN_CTRL
;
9361 case ROLE_DOMAIN_BDC
:
9362 default_server_announce
|= SV_TYPE_DOMAIN_BAKCTRL
;
9364 case ROLE_STANDALONE
:
9368 if (lp_time_server())
9369 default_server_announce
|= SV_TYPE_TIME_SOURCE
;
9371 if (lp_host_msdfs())
9372 default_server_announce
|= SV_TYPE_DFS_SERVER
;
9374 return default_server_announce
;
9377 /***********************************************************
9378 If we are PDC then prefer us as DMB
9379 ************************************************************/
9381 bool lp_domain_master(void)
9383 if (Globals
.iDomainMaster
== Auto
)
9384 return (lp_server_role() == ROLE_DOMAIN_PDC
);
9386 return (bool)Globals
.iDomainMaster
;
9389 /***********************************************************
9390 If we are PDC then prefer us as DMB
9391 ************************************************************/
9393 static bool lp_domain_master_true_or_auto(void)
9395 if (Globals
.iDomainMaster
) /* auto or yes */
9401 /***********************************************************
9402 If we are DMB then prefer us as LMB
9403 ************************************************************/
9405 bool lp_preferred_master(void)
9407 if (Globals
.iPreferredMaster
== Auto
)
9408 return (lp_local_master() && lp_domain_master());
9410 return (bool)Globals
.iPreferredMaster
;
9413 /*******************************************************************
9415 ********************************************************************/
9417 void lp_remove_service(int snum
)
9419 ServicePtrs
[snum
]->valid
= false;
9420 invalid_services
[num_invalid_services
++] = snum
;
9423 /*******************************************************************
9425 ********************************************************************/
9427 void lp_copy_service(int snum
, const char *new_name
)
9429 do_section(new_name
, NULL
);
9431 snum
= lp_servicenumber(new_name
);
9433 char *name
= lp_servicename(talloc_tos(), snum
);
9434 lp_do_parameter(snum
, "copy", name
);
9439 const char *lp_printername(TALLOC_CTX
*ctx
, int snum
)
9441 const char *ret
= lp__printername(talloc_tos(), snum
);
9442 if (ret
== NULL
|| *ret
== '\0') {
9443 ret
= lp_const_servicename(snum
);
9450 /***********************************************************
9451 Allow daemons such as winbindd to fix their logfile name.
9452 ************************************************************/
9454 void lp_set_logfile(const char *name
)
9456 string_set(&Globals
.logfile
, name
);
9457 debug_set_logfile(name
);
9460 /*******************************************************************
9461 Return the max print jobs per queue.
9462 ********************************************************************/
9464 int lp_maxprintjobs(int snum
)
9466 int maxjobs
= LP_SNUM_OK(snum
) ? ServicePtrs
[snum
]->iMaxPrintJobs
: sDefault
.iMaxPrintJobs
;
9467 if (maxjobs
<= 0 || maxjobs
>= PRINT_MAX_JOBID
)
9468 maxjobs
= PRINT_MAX_JOBID
- 1;
9473 const char *lp_printcapname(void)
9475 if ((Globals
.szPrintcapname
!= NULL
) &&
9476 (Globals
.szPrintcapname
[0] != '\0'))
9477 return Globals
.szPrintcapname
;
9479 if (sDefault
.iPrinting
== PRINT_CUPS
) {
9487 if (sDefault
.iPrinting
== PRINT_BSD
)
9488 return "/etc/printcap";
9490 return PRINTCAP_NAME
;
9493 static uint32 spoolss_state
;
9495 bool lp_disable_spoolss( void )
9497 if ( spoolss_state
== SVCCTL_STATE_UNKNOWN
)
9498 spoolss_state
= lp__disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
9500 return spoolss_state
== SVCCTL_STOPPED
? true : false;
9503 void lp_set_spoolss_state( uint32 state
)
9505 SMB_ASSERT( (state
== SVCCTL_STOPPED
) || (state
== SVCCTL_RUNNING
) );
9507 spoolss_state
= state
;
9510 uint32
lp_get_spoolss_state( void )
9512 return lp_disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
9515 /*******************************************************************
9516 Ensure we don't use sendfile if server smb signing is active.
9517 ********************************************************************/
9519 bool lp_use_sendfile(int snum
, struct smb_signing_state
*signing_state
)
9521 bool sign_active
= false;
9523 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9524 if (get_Protocol() < PROTOCOL_NT1
) {
9527 if (signing_state
) {
9528 sign_active
= smb_signing_is_active(signing_state
);
9530 return (lp__use_sendfile(snum
) &&
9531 (get_remote_arch() != RA_WIN95
) &&
9535 /*******************************************************************
9536 Turn off sendfile if we find the underlying OS doesn't support it.
9537 ********************************************************************/
9539 void set_use_sendfile(int snum
, bool val
)
9541 if (LP_SNUM_OK(snum
))
9542 ServicePtrs
[snum
]->bUseSendfile
= val
;
9544 sDefault
.bUseSendfile
= val
;
9547 /*******************************************************************
9548 Turn off storing DOS attributes if this share doesn't support it.
9549 ********************************************************************/
9551 void set_store_dos_attributes(int snum
, bool val
)
9553 if (!LP_SNUM_OK(snum
))
9555 ServicePtrs
[(snum
)]->bStoreDosAttributes
= val
;
9558 void lp_set_mangling_method(const char *new_method
)
9560 string_set(&Globals
.szManglingMethod
, new_method
);
9563 /*******************************************************************
9564 Global state for POSIX pathname processing.
9565 ********************************************************************/
9567 static bool posix_pathnames
;
9569 bool lp_posix_pathnames(void)
9571 return posix_pathnames
;
9574 /*******************************************************************
9575 Change everything needed to ensure POSIX pathname processing (currently
9577 ********************************************************************/
9579 void lp_set_posix_pathnames(void)
9581 posix_pathnames
= true;
9584 /*******************************************************************
9585 Global state for POSIX lock processing - CIFS unix extensions.
9586 ********************************************************************/
9588 bool posix_default_lock_was_set
;
9589 static enum brl_flavour posix_cifsx_locktype
; /* By default 0 == WINDOWS_LOCK */
9591 enum brl_flavour
lp_posix_cifsu_locktype(files_struct
*fsp
)
9593 if (posix_default_lock_was_set
) {
9594 return posix_cifsx_locktype
;
9596 return fsp
->posix_open
? POSIX_LOCK
: WINDOWS_LOCK
;
9600 /*******************************************************************
9601 ********************************************************************/
9603 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val
)
9605 posix_default_lock_was_set
= true;
9606 posix_cifsx_locktype
= val
;
9609 int lp_min_receive_file_size(void)
9611 if (Globals
.iminreceivefile
< 0) {
9614 return MIN(Globals
.iminreceivefile
, BUFFER_SIZE
);
9617 /*******************************************************************
9618 If socket address is an empty character string, it is necessary to
9619 define it as "0.0.0.0".
9620 ********************************************************************/
9622 const char *lp_socket_address(void)
9624 char *sock_addr
= Globals
.szSocketAddress
;
9626 if (sock_addr
[0] == '\0'){
9627 string_set(&Globals
.szSocketAddress
, "0.0.0.0");
9629 return Globals
.szSocketAddress
;
9632 /*******************************************************************
9633 Safe wide links checks.
9634 This helper function always verify the validity of wide links,
9635 even after a configuration file reload.
9636 ********************************************************************/
9638 static bool lp_widelinks_internal(int snum
)
9640 return (bool)(LP_SNUM_OK(snum
)? ServicePtrs
[(snum
)]->bWidelinks
:
9641 sDefault
.bWidelinks
);
9644 void widelinks_warning(int snum
)
9646 if (lp_allow_insecure_widelinks()) {
9650 if (lp_unix_extensions() && lp_widelinks_internal(snum
)) {
9651 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9652 "These parameters are incompatible. "
9653 "Wide links will be disabled for this share.\n",
9654 lp_servicename(talloc_tos(), snum
) ));
9658 bool lp_widelinks(int snum
)
9660 /* wide links is always incompatible with unix extensions */
9661 if (lp_unix_extensions()) {
9663 * Unless we have "allow insecure widelinks"
9666 if (!lp_allow_insecure_widelinks()) {
9671 return lp_widelinks_internal(snum
);
9674 bool lp_writeraw(void)
9676 if (lp_async_smb_echo_handler()) {
9679 return lp__writeraw();
9682 bool lp_readraw(void)
9684 if (lp_async_smb_echo_handler()) {
9687 return lp__readraw();
9690 int lp_server_role(void)
9692 return lp_find_server_role(lp__server_role(),
9695 lp_domain_master_true_or_auto());