s3-param: Merge a number of s4 parameters from lib/param to make this table common
[Samba/gebeck_regimport.git] / source3 / param / loadparm.c
blobd1245480ebb7abf5b7d6d14e574b62636c931c4d
1 /*
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/>.
31 * Load parameters.
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.
37 * To add a parameter:
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
46 * Notes:
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
52 * careful!
56 #include "includes.h"
57 #include "system/filesys.h"
58 #include "util_tdb.h"
59 #include "printing.h"
60 #include "lib/smbconf/smbconf.h"
61 #include "lib/smbconf/smbconf_init.h"
62 #include "lib/param/loadparm.h"
64 #include "ads.h"
65 #include "../librpc/gen_ndr/svcctl.h"
66 #include "intl.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>
75 #endif
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
79 #endif
81 #ifdef CLUSTER_SUPPORT
82 #include "ctdb_private.h"
83 #endif
85 bool bLoaded = false;
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
92 * from registry. */
93 #ifndef INCLUDE_REGISTRY_NAME
94 #define INCLUDE_REGISTRY_NAME "registry"
95 #endif
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; \
116 char *szRealm; \
117 char *szLogLevel; \
118 int iminreceivefile; \
119 char *szPrintcapname; \
120 int CupsEncrypt; \
121 int iPreferredMaster; \
122 int iDomainMaster; \
123 char *szLdapMachineSuffix; \
124 char *szLdapUserSuffix; \
125 char *szLdapIdmapSuffix; \
126 char *szLdapGroupSuffix; \
127 char *szStateDir; \
128 char *szCacheDir; \
129 char *szSocketAddress; \
130 char *szUsershareTemplateShare; \
131 char *szIdmapUID; \
132 char *szIdmapGID; \
133 int winbindMaxDomainConnections; \
134 int ismb2_max_credits; \
135 char *tls_keyfile; \
136 char *tls_certfile; \
137 char *tls_cafile; \
138 char *tls_crlfile; \
139 char *tls_dhpfile; \
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 =
150 .valid = true,
151 .autoloaded = false,
152 .usershare = 0,
153 .usershare_last_mod = {0, 0},
154 .szService = NULL,
155 .szPath = NULL,
156 .szUsername = NULL,
157 .szInvalidUsers = NULL,
158 .szValidUsers = NULL,
159 .szAdminUsers = NULL,
160 .szCopy = NULL,
161 .szInclude = NULL,
162 .szPreExec = NULL,
163 .szPostExec = 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,
178 .szHostsdeny = NULL,
179 .szMagicScript = NULL,
180 .szMagicOutput = NULL,
181 .szVetoFiles = NULL,
182 .szHideFiles = NULL,
183 .szVetoOplockFiles = NULL,
184 .comment = NULL,
185 .force_user = NULL,
186 .force_group = NULL,
187 .readlist = NULL,
188 .writelist = NULL,
189 .volume = NULL,
190 .fstype = NULL,
191 .szVfsObjects = NULL,
192 .szMSDfsProxy = NULL,
193 .szAioWriteBehind = NULL,
194 .szDfree = NULL,
195 .iMinPrintSpace = 0,
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,
203 .iDir_mask = 0755,
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,
211 .iCSCPolicy = 0,
212 .iBlock_size = 1024,
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,
223 .bBrowseable = true,
224 .bAccessBasedShareEnum = false,
225 .bAvailable = true,
226 .bRead_only = true,
227 .bNo_set_dir = true,
228 .bGuest_only = false,
229 .bAdministrative_share = false,
230 .bGuest_ok = false,
231 .bPrint_ok = false,
232 .bPrintNotifyBackchannel = true,
233 .bMap_system = false,
234 .bMap_hidden = false,
235 .bMap_archive = true,
236 .bStoreDosAttributes = false,
237 .bDmapiSupport = false,
238 .bLocking = true,
239 .iStrictLocking = Auto,
240 .bPosixLocking = true,
241 .bShareModes = true,
242 .bOpLocks = true,
243 .bKernelOplocks = false,
244 .bLevel2OpLocks = true,
245 .bOnlyUser = false,
246 .bMangledNames = true,
247 .bWidelinks = false,
248 .bSymlinks = true,
249 .bSyncAlways = false,
250 .bStrictAllocate = false,
251 .bStrictSync = false,
252 .magic_char = '~',
253 .copymap = NULL,
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,
265 .bMSDfsRoot = 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,
274 .bAfs_Share = false,
275 .bEASupport = false,
276 .bAclCheckPermissions = true,
277 .bAclMapFullControl = true,
278 .bAclGroupControl = false,
279 .bChangeNotify = true,
280 .bKernelChangeNotify = true,
281 .iallocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
282 .iAioReadSize = 0,
283 .iAioWriteSize = 0,
284 .iMap_readonly = MAP_READONLY_YES,
285 #ifdef BROKEN_DIRECTORY_HANDLING
286 .iDirectoryNameCacheSize = 0,
287 #else
288 .iDirectoryNameCacheSize = 100,
289 #endif
290 .ismb_encrypt = Auto,
291 .param_opt = NULL,
292 .dummy = ""
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"},
331 {PRINT_AIX, "aix"},
332 {PRINT_HPUX, "hpux"},
333 {PRINT_BSD, "bsd"},
334 {PRINT_QNX, "qnx"},
335 {PRINT_PLP, "plp"},
336 {PRINT_LPRNG, "lprng"},
337 {PRINT_CUPS, "cups"},
338 {PRINT_IPRINT, "iprint"},
339 {PRINT_LPRNT, "nt"},
340 {PRINT_LPROS2, "os2"},
341 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
342 {PRINT_TEST, "test"},
343 {PRINT_VLP, "vlp"},
344 #endif /* DEVELOPER */
345 {-1, NULL}
348 static const struct enum_list enum_ldap_sasl_wrapping[] = {
349 {0, "plain"},
350 {ADS_AUTH_SASL_SIGN, "sign"},
351 {ADS_AUTH_SASL_SEAL, "seal"},
352 {-1, NULL}
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"},
360 {-1, NULL}
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"},
374 {-1, "auto"}
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"},
383 {-1, NULL}
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"},
395 {-1, NULL}
398 static const struct enum_list enum_case[] = {
399 {CASE_LOWER, "lower"},
400 {CASE_UPPER, "upper"},
401 {-1, NULL}
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" },
410 { -1, NULL}
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
431 level security.
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"},
439 {-1, NULL}
442 /* Config backend options */
444 static const struct enum_list enum_config_backend[] = {
445 {CONFIG_BACKEND_FILE, "file"},
446 {CONFIG_BACKEND_REGISTRY, "registry"},
447 {-1, NULL}
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"},
458 {-1, NULL}
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
470 * respective views.
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",
487 .type = P_STRING,
488 .p_class = P_GLOBAL,
489 .offset = GLOBAL_VAR(dos_charset),
490 .special = handle_dos_charset,
491 .enum_list = NULL,
492 .flags = FLAG_ADVANCED
495 .label = "unix charset",
496 .type = P_STRING,
497 .p_class = P_GLOBAL,
498 .offset = GLOBAL_VAR(unix_charset),
499 .special = handle_charset,
500 .enum_list = NULL,
501 .flags = FLAG_ADVANCED
504 .label = "comment",
505 .type = P_STRING,
506 .p_class = P_LOCAL,
507 .offset = LOCAL_VAR(comment),
508 .special = NULL,
509 .enum_list = NULL,
510 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
513 .label = "path",
514 .type = P_STRING,
515 .p_class = P_LOCAL,
516 .offset = LOCAL_VAR(szPath),
517 .special = NULL,
518 .enum_list = NULL,
519 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
522 .label = "directory",
523 .type = P_STRING,
524 .p_class = P_LOCAL,
525 .offset = LOCAL_VAR(szPath),
526 .special = NULL,
527 .enum_list = NULL,
528 .flags = FLAG_HIDE,
531 .label = "workgroup",
532 .type = P_USTRING,
533 .p_class = P_GLOBAL,
534 .offset = GLOBAL_VAR(szWorkgroup),
535 .special = NULL,
536 .enum_list = NULL,
537 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
540 .label = "realm",
541 .type = P_STRING,
542 .p_class = P_GLOBAL,
543 .offset = GLOBAL_VAR(szRealm),
544 .special = handle_realm,
545 .enum_list = NULL,
546 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
549 .label = "netbios name",
550 .type = P_USTRING,
551 .p_class = P_GLOBAL,
552 .offset = GLOBAL_VAR(szNetbiosName),
553 .special = NULL,
554 .enum_list = NULL,
555 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
558 .label = "netbios aliases",
559 .type = P_LIST,
560 .p_class = P_GLOBAL,
561 .offset = GLOBAL_VAR(szNetbiosAliases),
562 .special = handle_netbios_aliases,
563 .enum_list = NULL,
564 .flags = FLAG_ADVANCED,
567 .label = "netbios scope",
568 .type = P_USTRING,
569 .p_class = P_GLOBAL,
570 .offset = GLOBAL_VAR(szNetbiosScope),
571 .special = NULL,
572 .enum_list = NULL,
573 .flags = FLAG_ADVANCED,
576 .label = "server string",
577 .type = P_STRING,
578 .p_class = P_GLOBAL,
579 .offset = GLOBAL_VAR(szServerString),
580 .special = NULL,
581 .enum_list = NULL,
582 .flags = FLAG_BASIC | FLAG_ADVANCED,
585 .label = "interfaces",
586 .type = P_LIST,
587 .p_class = P_GLOBAL,
588 .offset = GLOBAL_VAR(szInterfaces),
589 .special = NULL,
590 .enum_list = NULL,
591 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
594 .label = "bind interfaces only",
595 .type = P_BOOL,
596 .p_class = P_GLOBAL,
597 .offset = GLOBAL_VAR(bBindInterfacesOnly),
598 .special = NULL,
599 .enum_list = NULL,
600 .flags = FLAG_ADVANCED | FLAG_WIZARD,
603 .label = "config backend",
604 .type = P_ENUM,
605 .p_class = P_GLOBAL,
606 .offset = GLOBAL_VAR(ConfigBackend),
607 .special = NULL,
608 .enum_list = enum_config_backend,
609 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
612 .label = "server role",
613 .type = P_ENUM,
614 .p_class = P_GLOBAL,
615 .offset = GLOBAL_VAR(server_role),
616 .special = NULL,
617 .enum_list = enum_server_role,
618 .flags = FLAG_BASIC | FLAG_ADVANCED,
621 {N_("Security Options"), P_SEP, P_SEPARATOR},
624 .label = "security",
625 .type = P_ENUM,
626 .p_class = P_GLOBAL,
627 .offset = GLOBAL_VAR(security),
628 .special = NULL,
629 .enum_list = enum_security,
630 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
633 .label = "auth methods",
634 .type = P_LIST,
635 .p_class = P_GLOBAL,
636 .offset = GLOBAL_VAR(AuthMethods),
637 .special = NULL,
638 .enum_list = NULL,
639 .flags = FLAG_ADVANCED,
642 .label = "encrypt passwords",
643 .type = P_BOOL,
644 .p_class = P_GLOBAL,
645 .offset = GLOBAL_VAR(bEncryptPasswords),
646 .special = NULL,
647 .enum_list = NULL,
648 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
651 .label = "client schannel",
652 .type = P_ENUM,
653 .p_class = P_GLOBAL,
654 .offset = GLOBAL_VAR(clientSchannel),
655 .special = NULL,
656 .enum_list = enum_bool_auto,
657 .flags = FLAG_BASIC | FLAG_ADVANCED,
660 .label = "server schannel",
661 .type = P_ENUM,
662 .p_class = P_GLOBAL,
663 .offset = GLOBAL_VAR(serverSchannel),
664 .special = NULL,
665 .enum_list = enum_bool_auto,
666 .flags = FLAG_BASIC | FLAG_ADVANCED,
669 .label = "allow trusted domains",
670 .type = P_BOOL,
671 .p_class = P_GLOBAL,
672 .offset = GLOBAL_VAR(bAllowTrustedDomains),
673 .special = NULL,
674 .enum_list = NULL,
675 .flags = FLAG_ADVANCED,
678 .label = "map to guest",
679 .type = P_ENUM,
680 .p_class = P_GLOBAL,
681 .offset = GLOBAL_VAR(map_to_guest),
682 .special = NULL,
683 .enum_list = enum_map_to_guest,
684 .flags = FLAG_ADVANCED,
687 .label = "null passwords",
688 .type = P_BOOL,
689 .p_class = P_GLOBAL,
690 .offset = GLOBAL_VAR(bNullPasswords),
691 .special = NULL,
692 .enum_list = NULL,
693 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
696 .label = "obey pam restrictions",
697 .type = P_BOOL,
698 .p_class = P_GLOBAL,
699 .offset = GLOBAL_VAR(bObeyPamRestrictions),
700 .special = NULL,
701 .enum_list = NULL,
702 .flags = FLAG_ADVANCED,
705 .label = "password server",
706 .type = P_STRING,
707 .p_class = P_GLOBAL,
708 .offset = GLOBAL_VAR(szPasswordServer),
709 .special = NULL,
710 .enum_list = NULL,
711 .flags = FLAG_ADVANCED | FLAG_WIZARD,
714 .label = "smb passwd file",
715 .type = P_STRING,
716 .p_class = P_GLOBAL,
717 .offset = GLOBAL_VAR(szSMBPasswdFile),
718 .special = NULL,
719 .enum_list = NULL,
720 .flags = FLAG_ADVANCED,
723 .label = "private dir",
724 .type = P_STRING,
725 .p_class = P_GLOBAL,
726 .offset = GLOBAL_VAR(szPrivateDir),
727 .special = NULL,
728 .enum_list = NULL,
729 .flags = FLAG_ADVANCED,
732 .label = "private directory",
733 .type = P_STRING,
734 .p_class = P_GLOBAL,
735 .offset = GLOBAL_VAR(szPrivateDir),
736 .special = NULL,
737 .enum_list = NULL,
738 .flags = FLAG_HIDE,
741 .label = "passdb backend",
742 .type = P_STRING,
743 .p_class = P_GLOBAL,
744 .offset = GLOBAL_VAR(passdb_backend),
745 .special = NULL,
746 .enum_list = NULL,
747 .flags = FLAG_ADVANCED | FLAG_WIZARD,
750 .label = "algorithmic rid base",
751 .type = P_INTEGER,
752 .p_class = P_GLOBAL,
753 .offset = GLOBAL_VAR(AlgorithmicRidBase),
754 .special = NULL,
755 .enum_list = NULL,
756 .flags = FLAG_ADVANCED,
759 .label = "root directory",
760 .type = P_STRING,
761 .p_class = P_GLOBAL,
762 .offset = GLOBAL_VAR(szRootdir),
763 .special = NULL,
764 .enum_list = NULL,
765 .flags = FLAG_ADVANCED,
768 .label = "root dir",
769 .type = P_STRING,
770 .p_class = P_GLOBAL,
771 .offset = GLOBAL_VAR(szRootdir),
772 .special = NULL,
773 .enum_list = NULL,
774 .flags = FLAG_HIDE,
777 .label = "root",
778 .type = P_STRING,
779 .p_class = P_GLOBAL,
780 .offset = GLOBAL_VAR(szRootdir),
781 .special = NULL,
782 .enum_list = NULL,
783 .flags = FLAG_HIDE,
786 .label = "guest account",
787 .type = P_STRING,
788 .p_class = P_GLOBAL,
789 .offset = GLOBAL_VAR(szGuestaccount),
790 .special = NULL,
791 .enum_list = NULL,
792 .flags = FLAG_BASIC | FLAG_ADVANCED,
795 .label = "enable privileges",
796 .type = P_BOOL,
797 .p_class = P_GLOBAL,
798 .offset = GLOBAL_VAR(bEnablePrivileges),
799 .special = NULL,
800 .enum_list = NULL,
801 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
805 .label = "pam password change",
806 .type = P_BOOL,
807 .p_class = P_GLOBAL,
808 .offset = GLOBAL_VAR(bPamPasswordChange),
809 .special = NULL,
810 .enum_list = NULL,
811 .flags = FLAG_ADVANCED,
814 .label = "passwd program",
815 .type = P_STRING,
816 .p_class = P_GLOBAL,
817 .offset = GLOBAL_VAR(szPasswdProgram),
818 .special = NULL,
819 .enum_list = NULL,
820 .flags = FLAG_ADVANCED,
823 .label = "passwd chat",
824 .type = P_STRING,
825 .p_class = P_GLOBAL,
826 .offset = GLOBAL_VAR(szPasswdChat),
827 .special = NULL,
828 .enum_list = NULL,
829 .flags = FLAG_ADVANCED,
832 .label = "passwd chat debug",
833 .type = P_BOOL,
834 .p_class = P_GLOBAL,
835 .offset = GLOBAL_VAR(bPasswdChatDebug),
836 .special = NULL,
837 .enum_list = NULL,
838 .flags = FLAG_ADVANCED,
841 .label = "passwd chat timeout",
842 .type = P_INTEGER,
843 .p_class = P_GLOBAL,
844 .offset = GLOBAL_VAR(iPasswdChatTimeout),
845 .special = NULL,
846 .enum_list = NULL,
847 .flags = FLAG_ADVANCED,
850 .label = "check password script",
851 .type = P_STRING,
852 .p_class = P_GLOBAL,
853 .offset = GLOBAL_VAR(szCheckPasswordScript),
854 .special = NULL,
855 .enum_list = NULL,
856 .flags = FLAG_ADVANCED,
859 .label = "username map",
860 .type = P_STRING,
861 .p_class = P_GLOBAL,
862 .offset = GLOBAL_VAR(szUsernameMap),
863 .special = NULL,
864 .enum_list = NULL,
865 .flags = FLAG_ADVANCED,
868 .label = "password level",
869 .type = P_INTEGER,
870 .p_class = P_GLOBAL,
871 .offset = GLOBAL_VAR(pwordlevel),
872 .special = NULL,
873 .enum_list = NULL,
874 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
877 .label = "username level",
878 .type = P_INTEGER,
879 .p_class = P_GLOBAL,
880 .offset = GLOBAL_VAR(unamelevel),
881 .special = NULL,
882 .enum_list = NULL,
883 .flags = FLAG_ADVANCED,
886 .label = "unix password sync",
887 .type = P_BOOL,
888 .p_class = P_GLOBAL,
889 .offset = GLOBAL_VAR(bUnixPasswdSync),
890 .special = NULL,
891 .enum_list = NULL,
892 .flags = FLAG_ADVANCED,
895 .label = "restrict anonymous",
896 .type = P_INTEGER,
897 .p_class = P_GLOBAL,
898 .offset = GLOBAL_VAR(restrict_anonymous),
899 .special = NULL,
900 .enum_list = NULL,
901 .flags = FLAG_ADVANCED,
904 .label = "lanman auth",
905 .type = P_BOOL,
906 .p_class = P_GLOBAL,
907 .offset = GLOBAL_VAR(bLanmanAuth),
908 .special = NULL,
909 .enum_list = NULL,
910 .flags = FLAG_ADVANCED,
913 .label = "ntlm auth",
914 .type = P_BOOL,
915 .p_class = P_GLOBAL,
916 .offset = GLOBAL_VAR(bNTLMAuth),
917 .special = NULL,
918 .enum_list = NULL,
919 .flags = FLAG_ADVANCED,
922 .label = "client NTLMv2 auth",
923 .type = P_BOOL,
924 .p_class = P_GLOBAL,
925 .offset = GLOBAL_VAR(bClientNTLMv2Auth),
926 .special = NULL,
927 .enum_list = NULL,
928 .flags = FLAG_ADVANCED,
931 .label = "client lanman auth",
932 .type = P_BOOL,
933 .p_class = P_GLOBAL,
934 .offset = GLOBAL_VAR(bClientLanManAuth),
935 .special = NULL,
936 .enum_list = NULL,
937 .flags = FLAG_ADVANCED,
940 .label = "client plaintext auth",
941 .type = P_BOOL,
942 .p_class = P_GLOBAL,
943 .offset = GLOBAL_VAR(bClientPlaintextAuth),
944 .special = NULL,
945 .enum_list = NULL,
946 .flags = FLAG_ADVANCED,
949 .label = "client use spnego principal",
950 .type = P_BOOL,
951 .p_class = P_GLOBAL,
952 .offset = GLOBAL_VAR(client_use_spnego_principal),
953 .special = NULL,
954 .enum_list = NULL,
955 .flags = FLAG_ADVANCED,
958 .label = "username",
959 .type = P_STRING,
960 .p_class = P_LOCAL,
961 .offset = LOCAL_VAR(szUsername),
962 .special = NULL,
963 .enum_list = NULL,
964 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
967 .label = "user",
968 .type = P_STRING,
969 .p_class = P_LOCAL,
970 .offset = LOCAL_VAR(szUsername),
971 .special = NULL,
972 .enum_list = NULL,
973 .flags = FLAG_HIDE,
976 .label = "users",
977 .type = P_STRING,
978 .p_class = P_LOCAL,
979 .offset = LOCAL_VAR(szUsername),
980 .special = NULL,
981 .enum_list = NULL,
982 .flags = FLAG_HIDE,
985 .label = "invalid users",
986 .type = P_LIST,
987 .p_class = P_LOCAL,
988 .offset = LOCAL_VAR(szInvalidUsers),
989 .special = NULL,
990 .enum_list = NULL,
991 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
994 .label = "valid users",
995 .type = P_LIST,
996 .p_class = P_LOCAL,
997 .offset = LOCAL_VAR(szValidUsers),
998 .special = NULL,
999 .enum_list = NULL,
1000 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1003 .label = "admin users",
1004 .type = P_LIST,
1005 .p_class = P_LOCAL,
1006 .offset = LOCAL_VAR(szAdminUsers),
1007 .special = NULL,
1008 .enum_list = NULL,
1009 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1012 .label = "read list",
1013 .type = P_LIST,
1014 .p_class = P_LOCAL,
1015 .offset = LOCAL_VAR(readlist),
1016 .special = NULL,
1017 .enum_list = NULL,
1018 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1021 .label = "write list",
1022 .type = P_LIST,
1023 .p_class = P_LOCAL,
1024 .offset = LOCAL_VAR(writelist),
1025 .special = NULL,
1026 .enum_list = NULL,
1027 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1030 .label = "force user",
1031 .type = P_STRING,
1032 .p_class = P_LOCAL,
1033 .offset = LOCAL_VAR(force_user),
1034 .special = NULL,
1035 .enum_list = NULL,
1036 .flags = FLAG_ADVANCED | FLAG_SHARE,
1039 .label = "force group",
1040 .type = P_STRING,
1041 .p_class = P_LOCAL,
1042 .offset = LOCAL_VAR(force_group),
1043 .special = NULL,
1044 .enum_list = NULL,
1045 .flags = FLAG_ADVANCED | FLAG_SHARE,
1048 .label = "group",
1049 .type = P_STRING,
1050 .p_class = P_LOCAL,
1051 .offset = LOCAL_VAR(force_group),
1052 .special = NULL,
1053 .enum_list = NULL,
1054 .flags = FLAG_ADVANCED,
1057 .label = "read only",
1058 .type = P_BOOL,
1059 .p_class = P_LOCAL,
1060 .offset = LOCAL_VAR(bRead_only),
1061 .special = NULL,
1062 .enum_list = NULL,
1063 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1066 .label = "write ok",
1067 .type = P_BOOLREV,
1068 .p_class = P_LOCAL,
1069 .offset = LOCAL_VAR(bRead_only),
1070 .special = NULL,
1071 .enum_list = NULL,
1072 .flags = FLAG_HIDE,
1075 .label = "writeable",
1076 .type = P_BOOLREV,
1077 .p_class = P_LOCAL,
1078 .offset = LOCAL_VAR(bRead_only),
1079 .special = NULL,
1080 .enum_list = NULL,
1081 .flags = FLAG_HIDE,
1084 .label = "writable",
1085 .type = P_BOOLREV,
1086 .p_class = P_LOCAL,
1087 .offset = LOCAL_VAR(bRead_only),
1088 .special = NULL,
1089 .enum_list = NULL,
1090 .flags = FLAG_HIDE,
1093 .label = "acl check permissions",
1094 .type = P_BOOL,
1095 .p_class = P_LOCAL,
1096 .offset = LOCAL_VAR(bAclCheckPermissions),
1097 .special = NULL,
1098 .enum_list = NULL,
1099 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1102 .label = "acl group control",
1103 .type = P_BOOL,
1104 .p_class = P_LOCAL,
1105 .offset = LOCAL_VAR(bAclGroupControl),
1106 .special = NULL,
1107 .enum_list = NULL,
1108 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1111 .label = "acl map full control",
1112 .type = P_BOOL,
1113 .p_class = P_LOCAL,
1114 .offset = LOCAL_VAR(bAclMapFullControl),
1115 .special = NULL,
1116 .enum_list = NULL,
1117 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1120 .label = "create mask",
1121 .type = P_OCTAL,
1122 .p_class = P_LOCAL,
1123 .offset = LOCAL_VAR(iCreate_mask),
1124 .special = NULL,
1125 .enum_list = NULL,
1126 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1129 .label = "create mode",
1130 .type = P_OCTAL,
1131 .p_class = P_LOCAL,
1132 .offset = LOCAL_VAR(iCreate_mask),
1133 .special = NULL,
1134 .enum_list = NULL,
1135 .flags = FLAG_HIDE,
1138 .label = "force create mode",
1139 .type = P_OCTAL,
1140 .p_class = P_LOCAL,
1141 .offset = LOCAL_VAR(iCreate_force_mode),
1142 .special = NULL,
1143 .enum_list = NULL,
1144 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1147 .label = "security mask",
1148 .type = P_OCTAL,
1149 .p_class = P_LOCAL,
1150 .offset = LOCAL_VAR(iSecurity_mask),
1151 .special = NULL,
1152 .enum_list = NULL,
1153 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1156 .label = "force security mode",
1157 .type = P_OCTAL,
1158 .p_class = P_LOCAL,
1159 .offset = LOCAL_VAR(iSecurity_force_mode),
1160 .special = NULL,
1161 .enum_list = NULL,
1162 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1165 .label = "directory mask",
1166 .type = P_OCTAL,
1167 .p_class = P_LOCAL,
1168 .offset = LOCAL_VAR(iDir_mask),
1169 .special = NULL,
1170 .enum_list = NULL,
1171 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1174 .label = "directory mode",
1175 .type = P_OCTAL,
1176 .p_class = P_LOCAL,
1177 .offset = LOCAL_VAR(iDir_mask),
1178 .special = NULL,
1179 .enum_list = NULL,
1180 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1183 .label = "force directory mode",
1184 .type = P_OCTAL,
1185 .p_class = P_LOCAL,
1186 .offset = LOCAL_VAR(iDir_force_mode),
1187 .special = NULL,
1188 .enum_list = NULL,
1189 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1192 .label = "directory security mask",
1193 .type = P_OCTAL,
1194 .p_class = P_LOCAL,
1195 .offset = LOCAL_VAR(iDir_Security_mask),
1196 .special = NULL,
1197 .enum_list = NULL,
1198 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1201 .label = "force directory security mode",
1202 .type = P_OCTAL,
1203 .p_class = P_LOCAL,
1204 .offset = LOCAL_VAR(iDir_Security_force_mode),
1205 .special = NULL,
1206 .enum_list = NULL,
1207 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1210 .label = "force unknown acl user",
1211 .type = P_BOOL,
1212 .p_class = P_LOCAL,
1213 .offset = LOCAL_VAR(bForceUnknownAclUser),
1214 .special = NULL,
1215 .enum_list = NULL,
1216 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1219 .label = "inherit permissions",
1220 .type = P_BOOL,
1221 .p_class = P_LOCAL,
1222 .offset = LOCAL_VAR(bInheritPerms),
1223 .special = NULL,
1224 .enum_list = NULL,
1225 .flags = FLAG_ADVANCED | FLAG_SHARE,
1228 .label = "inherit acls",
1229 .type = P_BOOL,
1230 .p_class = P_LOCAL,
1231 .offset = LOCAL_VAR(bInheritACLS),
1232 .special = NULL,
1233 .enum_list = NULL,
1234 .flags = FLAG_ADVANCED | FLAG_SHARE,
1237 .label = "inherit owner",
1238 .type = P_BOOL,
1239 .p_class = P_LOCAL,
1240 .offset = LOCAL_VAR(bInheritOwner),
1241 .special = NULL,
1242 .enum_list = NULL,
1243 .flags = FLAG_ADVANCED | FLAG_SHARE,
1246 .label = "guest only",
1247 .type = P_BOOL,
1248 .p_class = P_LOCAL,
1249 .offset = LOCAL_VAR(bGuest_only),
1250 .special = NULL,
1251 .enum_list = NULL,
1252 .flags = FLAG_ADVANCED | FLAG_SHARE,
1255 .label = "only guest",
1256 .type = P_BOOL,
1257 .p_class = P_LOCAL,
1258 .offset = LOCAL_VAR(bGuest_only),
1259 .special = NULL,
1260 .enum_list = NULL,
1261 .flags = FLAG_HIDE,
1264 .label = "administrative share",
1265 .type = P_BOOL,
1266 .p_class = P_LOCAL,
1267 .offset = LOCAL_VAR(bAdministrative_share),
1268 .special = NULL,
1269 .enum_list = NULL,
1270 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1274 .label = "guest ok",
1275 .type = P_BOOL,
1276 .p_class = P_LOCAL,
1277 .offset = LOCAL_VAR(bGuest_ok),
1278 .special = NULL,
1279 .enum_list = NULL,
1280 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1283 .label = "public",
1284 .type = P_BOOL,
1285 .p_class = P_LOCAL,
1286 .offset = LOCAL_VAR(bGuest_ok),
1287 .special = NULL,
1288 .enum_list = NULL,
1289 .flags = FLAG_HIDE,
1292 .label = "only user",
1293 .type = P_BOOL,
1294 .p_class = P_LOCAL,
1295 .offset = LOCAL_VAR(bOnlyUser),
1296 .special = NULL,
1297 .enum_list = NULL,
1298 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1301 .label = "hosts allow",
1302 .type = P_LIST,
1303 .p_class = P_LOCAL,
1304 .offset = LOCAL_VAR(szHostsallow),
1305 .special = NULL,
1306 .enum_list = NULL,
1307 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1310 .label = "allow hosts",
1311 .type = P_LIST,
1312 .p_class = P_LOCAL,
1313 .offset = LOCAL_VAR(szHostsallow),
1314 .special = NULL,
1315 .enum_list = NULL,
1316 .flags = FLAG_HIDE,
1319 .label = "hosts deny",
1320 .type = P_LIST,
1321 .p_class = P_LOCAL,
1322 .offset = LOCAL_VAR(szHostsdeny),
1323 .special = NULL,
1324 .enum_list = NULL,
1325 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1328 .label = "deny hosts",
1329 .type = P_LIST,
1330 .p_class = P_LOCAL,
1331 .offset = LOCAL_VAR(szHostsdeny),
1332 .special = NULL,
1333 .enum_list = NULL,
1334 .flags = FLAG_HIDE,
1337 .label = "preload modules",
1338 .type = P_LIST,
1339 .p_class = P_GLOBAL,
1340 .offset = GLOBAL_VAR(szPreloadModules),
1341 .special = NULL,
1342 .enum_list = NULL,
1343 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1346 .label = "dedicated keytab file",
1347 .type = P_STRING,
1348 .p_class = P_GLOBAL,
1349 .offset = GLOBAL_VAR(szDedicatedKeytabFile),
1350 .special = NULL,
1351 .enum_list = NULL,
1352 .flags = FLAG_ADVANCED,
1355 .label = "kerberos method",
1356 .type = P_ENUM,
1357 .p_class = P_GLOBAL,
1358 .offset = GLOBAL_VAR(iKerberosMethod),
1359 .special = NULL,
1360 .enum_list = enum_kerberos_method,
1361 .flags = FLAG_ADVANCED,
1364 .label = "map untrusted to domain",
1365 .type = P_BOOL,
1366 .p_class = P_GLOBAL,
1367 .offset = GLOBAL_VAR(bMapUntrustedToDomain),
1368 .special = NULL,
1369 .enum_list = NULL,
1370 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1374 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1377 .label = "log level",
1378 .type = P_STRING,
1379 .p_class = P_GLOBAL,
1380 .offset = GLOBAL_VAR(szLogLevel),
1381 .special = handle_debug_list,
1382 .enum_list = NULL,
1383 .flags = FLAG_ADVANCED,
1386 .label = "debuglevel",
1387 .type = P_STRING,
1388 .p_class = P_GLOBAL,
1389 .offset = GLOBAL_VAR(szLogLevel),
1390 .special = handle_debug_list,
1391 .enum_list = NULL,
1392 .flags = FLAG_HIDE,
1395 .label = "syslog",
1396 .type = P_INTEGER,
1397 .p_class = P_GLOBAL,
1398 .offset = GLOBAL_VAR(syslog),
1399 .special = NULL,
1400 .enum_list = NULL,
1401 .flags = FLAG_ADVANCED,
1404 .label = "syslog only",
1405 .type = P_BOOL,
1406 .p_class = P_GLOBAL,
1407 .offset = GLOBAL_VAR(bSyslogOnly),
1408 .special = NULL,
1409 .enum_list = NULL,
1410 .flags = FLAG_ADVANCED,
1413 .label = "log file",
1414 .type = P_STRING,
1415 .p_class = P_GLOBAL,
1416 .offset = GLOBAL_VAR(logfile),
1417 .special = NULL,
1418 .enum_list = NULL,
1419 .flags = FLAG_ADVANCED,
1422 .label = "max log size",
1423 .type = P_BYTES,
1424 .p_class = P_GLOBAL,
1425 .offset = GLOBAL_VAR(max_log_size),
1426 .special = NULL,
1427 .enum_list = NULL,
1428 .flags = FLAG_ADVANCED,
1431 .label = "debug timestamp",
1432 .type = P_BOOL,
1433 .p_class = P_GLOBAL,
1434 .offset = GLOBAL_VAR(bTimestampLogs),
1435 .special = NULL,
1436 .enum_list = NULL,
1437 .flags = FLAG_ADVANCED,
1440 .label = "timestamp logs",
1441 .type = P_BOOL,
1442 .p_class = P_GLOBAL,
1443 .offset = GLOBAL_VAR(bTimestampLogs),
1444 .special = NULL,
1445 .enum_list = NULL,
1446 .flags = FLAG_ADVANCED,
1449 .label = "debug prefix timestamp",
1450 .type = P_BOOL,
1451 .p_class = P_GLOBAL,
1452 .offset = GLOBAL_VAR(bDebugPrefixTimestamp),
1453 .special = NULL,
1454 .enum_list = NULL,
1455 .flags = FLAG_ADVANCED,
1458 .label = "debug hires timestamp",
1459 .type = P_BOOL,
1460 .p_class = P_GLOBAL,
1461 .offset = GLOBAL_VAR(bDebugHiresTimestamp),
1462 .special = NULL,
1463 .enum_list = NULL,
1464 .flags = FLAG_ADVANCED,
1467 .label = "debug pid",
1468 .type = P_BOOL,
1469 .p_class = P_GLOBAL,
1470 .offset = GLOBAL_VAR(bDebugPid),
1471 .special = NULL,
1472 .enum_list = NULL,
1473 .flags = FLAG_ADVANCED,
1476 .label = "debug uid",
1477 .type = P_BOOL,
1478 .p_class = P_GLOBAL,
1479 .offset = GLOBAL_VAR(bDebugUid),
1480 .special = NULL,
1481 .enum_list = NULL,
1482 .flags = FLAG_ADVANCED,
1485 .label = "debug class",
1486 .type = P_BOOL,
1487 .p_class = P_GLOBAL,
1488 .offset = GLOBAL_VAR(bDebugClass),
1489 .special = NULL,
1490 .enum_list = NULL,
1491 .flags = FLAG_ADVANCED,
1494 .label = "enable core files",
1495 .type = P_BOOL,
1496 .p_class = P_GLOBAL,
1497 .offset = GLOBAL_VAR(bEnableCoreFiles),
1498 .special = NULL,
1499 .enum_list = NULL,
1500 .flags = FLAG_ADVANCED,
1503 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1506 .label = "allocation roundup size",
1507 .type = P_BYTES,
1508 .p_class = P_LOCAL,
1509 .offset = LOCAL_VAR(iallocation_roundup_size),
1510 .special = NULL,
1511 .enum_list = NULL,
1512 .flags = FLAG_ADVANCED,
1515 .label = "aio read size",
1516 .type = P_BYTES,
1517 .p_class = P_LOCAL,
1518 .offset = LOCAL_VAR(iAioReadSize),
1519 .special = NULL,
1520 .enum_list = NULL,
1521 .flags = FLAG_ADVANCED,
1524 .label = "aio write size",
1525 .type = P_BYTES,
1526 .p_class = P_LOCAL,
1527 .offset = LOCAL_VAR(iAioWriteSize),
1528 .special = NULL,
1529 .enum_list = NULL,
1530 .flags = FLAG_ADVANCED,
1533 .label = "aio write behind",
1534 .type = P_STRING,
1535 .p_class = P_LOCAL,
1536 .offset = LOCAL_VAR(szAioWriteBehind),
1537 .special = NULL,
1538 .enum_list = NULL,
1539 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1542 .label = "smb ports",
1543 .type = P_LIST,
1544 .p_class = P_GLOBAL,
1545 .offset = GLOBAL_VAR(smb_ports),
1546 .special = NULL,
1547 .enum_list = NULL,
1548 .flags = FLAG_ADVANCED,
1551 .label = "large readwrite",
1552 .type = P_BOOL,
1553 .p_class = P_GLOBAL,
1554 .offset = GLOBAL_VAR(bLargeReadwrite),
1555 .special = NULL,
1556 .enum_list = NULL,
1557 .flags = FLAG_ADVANCED,
1560 .label = "server max protocol",
1561 .type = P_ENUM,
1562 .p_class = P_GLOBAL,
1563 .offset = GLOBAL_VAR(srv_maxprotocol),
1564 .special = NULL,
1565 .enum_list = enum_protocol,
1566 .flags = FLAG_ADVANCED,
1569 .label = "max protocol",
1570 .type = P_ENUM,
1571 .p_class = P_GLOBAL,
1572 .offset = GLOBAL_VAR(srv_maxprotocol),
1573 .special = NULL,
1574 .enum_list = enum_protocol,
1575 .flags = FLAG_ADVANCED,
1578 .label = "protocol",
1579 .type = P_ENUM,
1580 .p_class = P_GLOBAL,
1581 .offset = GLOBAL_VAR(srv_maxprotocol),
1582 .special = NULL,
1583 .enum_list = enum_protocol,
1584 .flags = FLAG_ADVANCED,
1587 .label = "server min protocol",
1588 .type = P_ENUM,
1589 .p_class = P_GLOBAL,
1590 .offset = GLOBAL_VAR(srv_minprotocol),
1591 .special = NULL,
1592 .enum_list = enum_protocol,
1593 .flags = FLAG_ADVANCED,
1596 .label = "min protocol",
1597 .type = P_ENUM,
1598 .p_class = P_GLOBAL,
1599 .offset = GLOBAL_VAR(srv_minprotocol),
1600 .special = NULL,
1601 .enum_list = enum_protocol,
1602 .flags = FLAG_ADVANCED,
1605 .label = "client max protocol",
1606 .type = P_ENUM,
1607 .p_class = P_GLOBAL,
1608 .offset = GLOBAL_VAR(cli_maxprotocol),
1609 .special = NULL,
1610 .enum_list = enum_protocol,
1611 .flags = FLAG_ADVANCED,
1614 .label = "client min protocol",
1615 .type = P_ENUM,
1616 .p_class = P_GLOBAL,
1617 .offset = GLOBAL_VAR(cli_minprotocol),
1618 .special = NULL,
1619 .enum_list = enum_protocol,
1620 .flags = FLAG_ADVANCED,
1623 .label = "unicode",
1624 .type = P_BOOL,
1625 .p_class = P_GLOBAL,
1626 .offset = GLOBAL_VAR(bUnicode),
1627 .special = NULL,
1628 .enum_list = NULL
1631 .label = "min receivefile size",
1632 .type = P_BYTES,
1633 .p_class = P_GLOBAL,
1634 .offset = GLOBAL_VAR(iminreceivefile),
1635 .special = NULL,
1636 .enum_list = NULL,
1637 .flags = FLAG_ADVANCED,
1640 .label = "read raw",
1641 .type = P_BOOL,
1642 .p_class = P_GLOBAL,
1643 .offset = GLOBAL_VAR(bReadRaw),
1644 .special = NULL,
1645 .enum_list = NULL,
1646 .flags = FLAG_ADVANCED,
1649 .label = "write raw",
1650 .type = P_BOOL,
1651 .p_class = P_GLOBAL,
1652 .offset = GLOBAL_VAR(bWriteRaw),
1653 .special = NULL,
1654 .enum_list = NULL,
1655 .flags = FLAG_ADVANCED,
1658 .label = "disable netbios",
1659 .type = P_BOOL,
1660 .p_class = P_GLOBAL,
1661 .offset = GLOBAL_VAR(bDisableNetbios),
1662 .special = NULL,
1663 .enum_list = NULL,
1664 .flags = FLAG_ADVANCED,
1667 .label = "reset on zero vc",
1668 .type = P_BOOL,
1669 .p_class = P_GLOBAL,
1670 .offset = GLOBAL_VAR(bResetOnZeroVC),
1671 .special = NULL,
1672 .enum_list = NULL,
1673 .flags = FLAG_ADVANCED,
1676 .label = "log writeable files on exit",
1677 .type = P_BOOL,
1678 .p_class = P_GLOBAL,
1679 .offset = GLOBAL_VAR(bLogWriteableFilesOnExit),
1680 .special = NULL,
1681 .enum_list = NULL,
1682 .flags = FLAG_ADVANCED,
1685 .label = "acl compatibility",
1686 .type = P_ENUM,
1687 .p_class = P_GLOBAL,
1688 .offset = GLOBAL_VAR(iAclCompat),
1689 .special = NULL,
1690 .enum_list = enum_acl_compat_vals,
1691 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1694 .label = "defer sharing violations",
1695 .type = P_BOOL,
1696 .p_class = P_GLOBAL,
1697 .offset = GLOBAL_VAR(bDeferSharingViolations),
1698 .special = NULL,
1699 .enum_list = NULL,
1700 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1703 .label = "ea support",
1704 .type = P_BOOL,
1705 .p_class = P_LOCAL,
1706 .offset = LOCAL_VAR(bEASupport),
1707 .special = NULL,
1708 .enum_list = NULL,
1709 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1712 .label = "nt acl support",
1713 .type = P_BOOL,
1714 .p_class = P_LOCAL,
1715 .offset = LOCAL_VAR(bNTAclSupport),
1716 .special = NULL,
1717 .enum_list = NULL,
1718 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1721 .label = "nt pipe support",
1722 .type = P_BOOL,
1723 .p_class = P_GLOBAL,
1724 .offset = GLOBAL_VAR(bNTPipeSupport),
1725 .special = NULL,
1726 .enum_list = NULL,
1727 .flags = FLAG_ADVANCED,
1730 .label = "nt status support",
1731 .type = P_BOOL,
1732 .p_class = P_GLOBAL,
1733 .offset = GLOBAL_VAR(bNTStatusSupport),
1734 .special = NULL,
1735 .enum_list = NULL,
1736 .flags = FLAG_ADVANCED,
1739 .label = "profile acls",
1740 .type = P_BOOL,
1741 .p_class = P_LOCAL,
1742 .offset = LOCAL_VAR(bProfileAcls),
1743 .special = NULL,
1744 .enum_list = NULL,
1745 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1748 .label = "map acl inherit",
1749 .type = P_BOOL,
1750 .p_class = P_LOCAL,
1751 .offset = LOCAL_VAR(bMap_acl_inherit),
1752 .special = NULL,
1753 .enum_list = NULL,
1754 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1757 .label = "afs share",
1758 .type = P_BOOL,
1759 .p_class = P_LOCAL,
1760 .offset = LOCAL_VAR(bAfs_Share),
1761 .special = NULL,
1762 .enum_list = NULL,
1763 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1766 .label = "max mux",
1767 .type = P_INTEGER,
1768 .p_class = P_GLOBAL,
1769 .offset = GLOBAL_VAR(max_mux),
1770 .special = NULL,
1771 .enum_list = NULL,
1772 .flags = FLAG_ADVANCED,
1775 .label = "max xmit",
1776 .type = P_BYTES,
1777 .p_class = P_GLOBAL,
1778 .offset = GLOBAL_VAR(max_xmit),
1779 .special = NULL,
1780 .enum_list = NULL,
1781 .flags = FLAG_ADVANCED,
1784 .label = "name resolve order",
1785 .type = P_LIST,
1786 .p_class = P_GLOBAL,
1787 .offset = GLOBAL_VAR(szNameResolveOrder),
1788 .special = NULL,
1789 .enum_list = NULL,
1790 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1793 .label = "max ttl",
1794 .type = P_INTEGER,
1795 .p_class = P_GLOBAL,
1796 .offset = GLOBAL_VAR(max_ttl),
1797 .special = NULL,
1798 .enum_list = NULL,
1799 .flags = FLAG_ADVANCED,
1802 .label = "max wins ttl",
1803 .type = P_INTEGER,
1804 .p_class = P_GLOBAL,
1805 .offset = GLOBAL_VAR(max_wins_ttl),
1806 .special = NULL,
1807 .enum_list = NULL,
1808 .flags = FLAG_ADVANCED,
1811 .label = "min wins ttl",
1812 .type = P_INTEGER,
1813 .p_class = P_GLOBAL,
1814 .offset = GLOBAL_VAR(min_wins_ttl),
1815 .special = NULL,
1816 .enum_list = NULL,
1817 .flags = FLAG_ADVANCED,
1820 .label = "time server",
1821 .type = P_BOOL,
1822 .p_class = P_GLOBAL,
1823 .offset = GLOBAL_VAR(bTimeServer),
1824 .special = NULL,
1825 .enum_list = NULL,
1826 .flags = FLAG_ADVANCED,
1829 .label = "unix extensions",
1830 .type = P_BOOL,
1831 .p_class = P_GLOBAL,
1832 .offset = GLOBAL_VAR(bUnixExtensions),
1833 .special = NULL,
1834 .enum_list = NULL,
1835 .flags = FLAG_ADVANCED,
1838 .label = "use spnego",
1839 .type = P_BOOL,
1840 .p_class = P_GLOBAL,
1841 .offset = GLOBAL_VAR(bUseSpnego),
1842 .special = NULL,
1843 .enum_list = NULL,
1844 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1847 .label = "client signing",
1848 .type = P_ENUM,
1849 .p_class = P_GLOBAL,
1850 .offset = GLOBAL_VAR(client_signing),
1851 .special = NULL,
1852 .enum_list = enum_smb_signing_vals,
1853 .flags = FLAG_ADVANCED,
1856 .label = "server signing",
1857 .type = P_ENUM,
1858 .p_class = P_GLOBAL,
1859 .offset = GLOBAL_VAR(server_signing),
1860 .special = NULL,
1861 .enum_list = enum_smb_signing_vals,
1862 .flags = FLAG_ADVANCED,
1865 .label = "smb encrypt",
1866 .type = P_ENUM,
1867 .p_class = P_LOCAL,
1868 .offset = LOCAL_VAR(ismb_encrypt),
1869 .special = NULL,
1870 .enum_list = enum_smb_signing_vals,
1871 .flags = FLAG_ADVANCED,
1874 .label = "client use spnego",
1875 .type = P_BOOL,
1876 .p_class = P_GLOBAL,
1877 .offset = GLOBAL_VAR(bClientUseSpnego),
1878 .special = NULL,
1879 .enum_list = NULL,
1880 .flags = FLAG_ADVANCED,
1883 .label = "client ldap sasl wrapping",
1884 .type = P_ENUM,
1885 .p_class = P_GLOBAL,
1886 .offset = GLOBAL_VAR(client_ldap_sasl_wrapping),
1887 .special = NULL,
1888 .enum_list = enum_ldap_sasl_wrapping,
1889 .flags = FLAG_ADVANCED,
1892 .label = "enable asu support",
1893 .type = P_BOOL,
1894 .p_class = P_GLOBAL,
1895 .offset = GLOBAL_VAR(bASUSupport),
1896 .special = NULL,
1897 .enum_list = NULL,
1898 .flags = FLAG_ADVANCED,
1901 .label = "svcctl list",
1902 .type = P_LIST,
1903 .p_class = P_GLOBAL,
1904 .offset = GLOBAL_VAR(szServicesList),
1905 .special = NULL,
1906 .enum_list = NULL,
1907 .flags = FLAG_ADVANCED,
1910 .label = "cldap port",
1911 .type = P_INTEGER,
1912 .p_class = P_GLOBAL,
1913 .offset = GLOBAL_VAR(cldap_port),
1914 .special = NULL,
1915 .enum_list = NULL
1918 .label = "dgram port",
1919 .type = P_INTEGER,
1920 .p_class = P_GLOBAL,
1921 .offset = GLOBAL_VAR(dgram_port),
1922 .special = NULL,
1923 .enum_list = NULL
1926 .label = "nbt port",
1927 .type = P_INTEGER,
1928 .p_class = P_GLOBAL,
1929 .offset = GLOBAL_VAR(nbt_port),
1930 .special = NULL,
1931 .enum_list = NULL
1934 .label = "krb5 port",
1935 .type = P_INTEGER,
1936 .p_class = P_GLOBAL,
1937 .offset = GLOBAL_VAR(krb5_port),
1938 .special = NULL,
1939 .enum_list = NULL
1942 .label = "kpasswd port",
1943 .type = P_INTEGER,
1944 .p_class = P_GLOBAL,
1945 .offset = GLOBAL_VAR(kpasswd_port),
1946 .special = NULL,
1947 .enum_list = NULL
1950 .label = "web port",
1951 .type = P_INTEGER,
1952 .p_class = P_GLOBAL,
1953 .offset = GLOBAL_VAR(web_port),
1954 .special = NULL,
1955 .enum_list = NULL
1958 .label = "rpc big endian",
1959 .type = P_BOOL,
1960 .p_class = P_GLOBAL,
1961 .offset = GLOBAL_VAR(bRpcBigEndian),
1962 .special = NULL,
1963 .enum_list = NULL
1966 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1969 .label = "block size",
1970 .type = P_BYTES,
1971 .p_class = P_LOCAL,
1972 .offset = LOCAL_VAR(iBlock_size),
1973 .special = NULL,
1974 .enum_list = NULL,
1975 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1978 .label = "deadtime",
1979 .type = P_INTEGER,
1980 .p_class = P_GLOBAL,
1981 .offset = GLOBAL_VAR(deadtime),
1982 .special = NULL,
1983 .enum_list = NULL,
1984 .flags = FLAG_ADVANCED,
1987 .label = "getwd cache",
1988 .type = P_BOOL,
1989 .p_class = P_GLOBAL,
1990 .offset = GLOBAL_VAR(getwd_cache),
1991 .special = NULL,
1992 .enum_list = NULL,
1993 .flags = FLAG_ADVANCED,
1996 .label = "keepalive",
1997 .type = P_INTEGER,
1998 .p_class = P_GLOBAL,
1999 .offset = GLOBAL_VAR(iKeepalive),
2000 .special = NULL,
2001 .enum_list = NULL,
2002 .flags = FLAG_ADVANCED,
2005 .label = "change notify",
2006 .type = P_BOOL,
2007 .p_class = P_LOCAL,
2008 .offset = LOCAL_VAR(bChangeNotify),
2009 .special = NULL,
2010 .enum_list = NULL,
2011 .flags = FLAG_ADVANCED | FLAG_SHARE,
2014 .label = "directory name cache size",
2015 .type = P_INTEGER,
2016 .p_class = P_LOCAL,
2017 .offset = LOCAL_VAR(iDirectoryNameCacheSize),
2018 .special = NULL,
2019 .enum_list = NULL,
2020 .flags = FLAG_ADVANCED | FLAG_SHARE,
2023 .label = "kernel change notify",
2024 .type = P_BOOL,
2025 .p_class = P_LOCAL,
2026 .offset = LOCAL_VAR(bKernelChangeNotify),
2027 .special = NULL,
2028 .enum_list = NULL,
2029 .flags = FLAG_ADVANCED | FLAG_SHARE,
2032 .label = "lpq cache time",
2033 .type = P_INTEGER,
2034 .p_class = P_GLOBAL,
2035 .offset = GLOBAL_VAR(lpqcachetime),
2036 .special = NULL,
2037 .enum_list = NULL,
2038 .flags = FLAG_ADVANCED,
2041 .label = "max smbd processes",
2042 .type = P_INTEGER,
2043 .p_class = P_GLOBAL,
2044 .offset = GLOBAL_VAR(iMaxSmbdProcesses),
2045 .special = NULL,
2046 .enum_list = NULL,
2047 .flags = FLAG_ADVANCED,
2050 .label = "max connections",
2051 .type = P_INTEGER,
2052 .p_class = P_LOCAL,
2053 .offset = LOCAL_VAR(iMaxConnections),
2054 .special = NULL,
2055 .enum_list = NULL,
2056 .flags = FLAG_ADVANCED | FLAG_SHARE,
2059 .label = "paranoid server security",
2060 .type = P_BOOL,
2061 .p_class = P_GLOBAL,
2062 .offset = GLOBAL_VAR(paranoid_server_security),
2063 .special = NULL,
2064 .enum_list = NULL,
2065 .flags = FLAG_ADVANCED,
2068 .label = "max disk size",
2069 .type = P_BYTES,
2070 .p_class = P_GLOBAL,
2071 .offset = GLOBAL_VAR(maxdisksize),
2072 .special = NULL,
2073 .enum_list = NULL,
2074 .flags = FLAG_ADVANCED,
2077 .label = "max open files",
2078 .type = P_INTEGER,
2079 .p_class = P_GLOBAL,
2080 .offset = GLOBAL_VAR(max_open_files),
2081 .special = NULL,
2082 .enum_list = NULL,
2083 .flags = FLAG_ADVANCED,
2086 .label = "min print space",
2087 .type = P_INTEGER,
2088 .p_class = P_LOCAL,
2089 .offset = LOCAL_VAR(iMinPrintSpace),
2090 .special = NULL,
2091 .enum_list = NULL,
2092 .flags = FLAG_ADVANCED | FLAG_PRINT,
2095 .label = "socket options",
2096 .type = P_STRING,
2097 .p_class = P_GLOBAL,
2098 .offset = GLOBAL_VAR(socket_options),
2099 .special = NULL,
2100 .enum_list = NULL,
2101 .flags = FLAG_ADVANCED,
2104 .label = "strict allocate",
2105 .type = P_BOOL,
2106 .p_class = P_LOCAL,
2107 .offset = LOCAL_VAR(bStrictAllocate),
2108 .special = NULL,
2109 .enum_list = NULL,
2110 .flags = FLAG_ADVANCED | FLAG_SHARE,
2113 .label = "strict sync",
2114 .type = P_BOOL,
2115 .p_class = P_LOCAL,
2116 .offset = LOCAL_VAR(bStrictSync),
2117 .special = NULL,
2118 .enum_list = NULL,
2119 .flags = FLAG_ADVANCED | FLAG_SHARE,
2122 .label = "sync always",
2123 .type = P_BOOL,
2124 .p_class = P_LOCAL,
2125 .offset = LOCAL_VAR(bSyncAlways),
2126 .special = NULL,
2127 .enum_list = NULL,
2128 .flags = FLAG_ADVANCED | FLAG_SHARE,
2131 .label = "use mmap",
2132 .type = P_BOOL,
2133 .p_class = P_GLOBAL,
2134 .offset = GLOBAL_VAR(bUseMmap),
2135 .special = NULL,
2136 .enum_list = NULL,
2137 .flags = FLAG_ADVANCED,
2140 .label = "use sendfile",
2141 .type = P_BOOL,
2142 .p_class = P_LOCAL,
2143 .offset = LOCAL_VAR(bUseSendfile),
2144 .special = NULL,
2145 .enum_list = NULL,
2146 .flags = FLAG_ADVANCED | FLAG_SHARE,
2149 .label = "hostname lookups",
2150 .type = P_BOOL,
2151 .p_class = P_GLOBAL,
2152 .offset = GLOBAL_VAR(bHostnameLookups),
2153 .special = NULL,
2154 .enum_list = NULL,
2155 .flags = FLAG_ADVANCED,
2158 .label = "write cache size",
2159 .type = P_BYTES,
2160 .p_class = P_LOCAL,
2161 .offset = LOCAL_VAR(iWriteCacheSize),
2162 .special = NULL,
2163 .enum_list = NULL,
2164 .flags = FLAG_ADVANCED | FLAG_SHARE,
2167 .label = "name cache timeout",
2168 .type = P_INTEGER,
2169 .p_class = P_GLOBAL,
2170 .offset = GLOBAL_VAR(name_cache_timeout),
2171 .special = NULL,
2172 .enum_list = NULL,
2173 .flags = FLAG_ADVANCED,
2176 .label = "ctdbd socket",
2177 .type = P_STRING,
2178 .p_class = P_GLOBAL,
2179 .offset = GLOBAL_VAR(ctdbdSocket),
2180 .special = NULL,
2181 .enum_list = NULL,
2182 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2185 .label = "cluster addresses",
2186 .type = P_LIST,
2187 .p_class = P_GLOBAL,
2188 .offset = GLOBAL_VAR(szClusterAddresses),
2189 .special = NULL,
2190 .enum_list = NULL,
2191 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2194 .label = "clustering",
2195 .type = P_BOOL,
2196 .p_class = P_GLOBAL,
2197 .offset = GLOBAL_VAR(clustering),
2198 .special = NULL,
2199 .enum_list = NULL,
2200 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2203 .label = "ctdb timeout",
2204 .type = P_INTEGER,
2205 .p_class = P_GLOBAL,
2206 .offset = GLOBAL_VAR(ctdb_timeout),
2207 .special = NULL,
2208 .enum_list = NULL,
2209 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2212 .label = "ctdb locktime warn threshold",
2213 .type = P_INTEGER,
2214 .p_class = P_GLOBAL,
2215 .offset = GLOBAL_VAR(ctdb_locktime_warn_threshold),
2216 .special = NULL,
2217 .enum_list = NULL,
2218 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2221 .label = "smb2 max read",
2222 .type = P_BYTES,
2223 .p_class = P_GLOBAL,
2224 .offset = GLOBAL_VAR(ismb2_max_read),
2225 .special = NULL,
2226 .enum_list = NULL,
2227 .flags = FLAG_ADVANCED,
2230 .label = "smb2 max write",
2231 .type = P_BYTES,
2232 .p_class = P_GLOBAL,
2233 .offset = GLOBAL_VAR(ismb2_max_write),
2234 .special = NULL,
2235 .enum_list = NULL,
2236 .flags = FLAG_ADVANCED,
2239 .label = "smb2 max trans",
2240 .type = P_BYTES,
2241 .p_class = P_GLOBAL,
2242 .offset = GLOBAL_VAR(ismb2_max_trans),
2243 .special = NULL,
2244 .enum_list = NULL,
2245 .flags = FLAG_ADVANCED,
2248 .label = "smb2 max credits",
2249 .type = P_INTEGER,
2250 .p_class = P_GLOBAL,
2251 .offset = GLOBAL_VAR(ismb2_max_credits),
2252 .special = NULL,
2253 .enum_list = NULL,
2254 .flags = FLAG_ADVANCED,
2257 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2260 .label = "max reported print jobs",
2261 .type = P_INTEGER,
2262 .p_class = P_LOCAL,
2263 .offset = LOCAL_VAR(iMaxReportedPrintJobs),
2264 .special = NULL,
2265 .enum_list = NULL,
2266 .flags = FLAG_ADVANCED | FLAG_PRINT,
2269 .label = "max print jobs",
2270 .type = P_INTEGER,
2271 .p_class = P_LOCAL,
2272 .offset = LOCAL_VAR(iMaxPrintJobs),
2273 .special = NULL,
2274 .enum_list = NULL,
2275 .flags = FLAG_ADVANCED | FLAG_PRINT,
2278 .label = "load printers",
2279 .type = P_BOOL,
2280 .p_class = P_GLOBAL,
2281 .offset = GLOBAL_VAR(bLoadPrinters),
2282 .special = NULL,
2283 .enum_list = NULL,
2284 .flags = FLAG_ADVANCED | FLAG_PRINT,
2287 .label = "printcap cache time",
2288 .type = P_INTEGER,
2289 .p_class = P_GLOBAL,
2290 .offset = GLOBAL_VAR(PrintcapCacheTime),
2291 .special = NULL,
2292 .enum_list = NULL,
2293 .flags = FLAG_ADVANCED | FLAG_PRINT,
2296 .label = "printcap name",
2297 .type = P_STRING,
2298 .p_class = P_GLOBAL,
2299 .offset = GLOBAL_VAR(szPrintcapname),
2300 .special = NULL,
2301 .enum_list = NULL,
2302 .flags = FLAG_ADVANCED | FLAG_PRINT,
2305 .label = "printcap",
2306 .type = P_STRING,
2307 .p_class = P_GLOBAL,
2308 .offset = GLOBAL_VAR(szPrintcapname),
2309 .special = NULL,
2310 .enum_list = NULL,
2311 .flags = FLAG_HIDE,
2314 .label = "printable",
2315 .type = P_BOOL,
2316 .p_class = P_LOCAL,
2317 .offset = LOCAL_VAR(bPrint_ok),
2318 .special = NULL,
2319 .enum_list = NULL,
2320 .flags = FLAG_ADVANCED | FLAG_PRINT,
2323 .label = "print notify backchannel",
2324 .type = P_BOOL,
2325 .p_class = P_LOCAL,
2326 .offset = LOCAL_VAR(bPrintNotifyBackchannel),
2327 .special = NULL,
2328 .enum_list = NULL,
2329 .flags = FLAG_ADVANCED,
2332 .label = "print ok",
2333 .type = P_BOOL,
2334 .p_class = P_LOCAL,
2335 .offset = LOCAL_VAR(bPrint_ok),
2336 .special = NULL,
2337 .enum_list = NULL,
2338 .flags = FLAG_HIDE,
2341 .label = "printing",
2342 .type = P_ENUM,
2343 .p_class = P_LOCAL,
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",
2351 .type = P_STRING,
2352 .p_class = P_LOCAL,
2353 .offset = LOCAL_VAR(szCupsOptions),
2354 .special = NULL,
2355 .enum_list = NULL,
2356 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2359 .label = "cups server",
2360 .type = P_STRING,
2361 .p_class = P_GLOBAL,
2362 .offset = GLOBAL_VAR(szCupsServer),
2363 .special = NULL,
2364 .enum_list = NULL,
2365 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2368 .label = "cups encrypt",
2369 .type = P_ENUM,
2370 .p_class = P_GLOBAL,
2371 .offset = GLOBAL_VAR(CupsEncrypt),
2372 .special = NULL,
2373 .enum_list = enum_bool_auto,
2374 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2378 .label = "cups connection timeout",
2379 .type = P_INTEGER,
2380 .p_class = P_GLOBAL,
2381 .offset = GLOBAL_VAR(cups_connection_timeout),
2382 .special = NULL,
2383 .enum_list = NULL,
2384 .flags = FLAG_ADVANCED,
2387 .label = "iprint server",
2388 .type = P_STRING,
2389 .p_class = P_GLOBAL,
2390 .offset = GLOBAL_VAR(szIPrintServer),
2391 .special = NULL,
2392 .enum_list = NULL,
2393 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2396 .label = "print command",
2397 .type = P_STRING,
2398 .p_class = P_LOCAL,
2399 .offset = LOCAL_VAR(szPrintcommand),
2400 .special = NULL,
2401 .enum_list = NULL,
2402 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2405 .label = "disable spoolss",
2406 .type = P_BOOL,
2407 .p_class = P_GLOBAL,
2408 .offset = GLOBAL_VAR(bDisableSpoolss),
2409 .special = NULL,
2410 .enum_list = NULL,
2411 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2414 .label = "enable spoolss",
2415 .type = P_BOOLREV,
2416 .p_class = P_GLOBAL,
2417 .offset = GLOBAL_VAR(bDisableSpoolss),
2418 .special = NULL,
2419 .enum_list = NULL,
2420 .flags = FLAG_HIDE,
2423 .label = "lpq command",
2424 .type = P_STRING,
2425 .p_class = P_LOCAL,
2426 .offset = LOCAL_VAR(szLpqcommand),
2427 .special = NULL,
2428 .enum_list = NULL,
2429 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2432 .label = "lprm command",
2433 .type = P_STRING,
2434 .p_class = P_LOCAL,
2435 .offset = LOCAL_VAR(szLprmcommand),
2436 .special = NULL,
2437 .enum_list = NULL,
2438 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2441 .label = "lppause command",
2442 .type = P_STRING,
2443 .p_class = P_LOCAL,
2444 .offset = LOCAL_VAR(szLppausecommand),
2445 .special = NULL,
2446 .enum_list = NULL,
2447 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2450 .label = "lpresume command",
2451 .type = P_STRING,
2452 .p_class = P_LOCAL,
2453 .offset = LOCAL_VAR(szLpresumecommand),
2454 .special = NULL,
2455 .enum_list = NULL,
2456 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2459 .label = "queuepause command",
2460 .type = P_STRING,
2461 .p_class = P_LOCAL,
2462 .offset = LOCAL_VAR(szQueuepausecommand),
2463 .special = NULL,
2464 .enum_list = NULL,
2465 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2468 .label = "queueresume command",
2469 .type = P_STRING,
2470 .p_class = P_LOCAL,
2471 .offset = LOCAL_VAR(szQueueresumecommand),
2472 .special = NULL,
2473 .enum_list = NULL,
2474 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2477 .label = "addport command",
2478 .type = P_STRING,
2479 .p_class = P_GLOBAL,
2480 .offset = GLOBAL_VAR(szAddPortCommand),
2481 .special = NULL,
2482 .enum_list = NULL,
2483 .flags = FLAG_ADVANCED,
2486 .label = "enumports command",
2487 .type = P_STRING,
2488 .p_class = P_GLOBAL,
2489 .offset = GLOBAL_VAR(szEnumPortsCommand),
2490 .special = NULL,
2491 .enum_list = NULL,
2492 .flags = FLAG_ADVANCED,
2495 .label = "addprinter command",
2496 .type = P_STRING,
2497 .p_class = P_GLOBAL,
2498 .offset = GLOBAL_VAR(szAddPrinterCommand),
2499 .special = NULL,
2500 .enum_list = NULL,
2501 .flags = FLAG_ADVANCED,
2504 .label = "deleteprinter command",
2505 .type = P_STRING,
2506 .p_class = P_GLOBAL,
2507 .offset = GLOBAL_VAR(szDeletePrinterCommand),
2508 .special = NULL,
2509 .enum_list = NULL,
2510 .flags = FLAG_ADVANCED,
2513 .label = "show add printer wizard",
2514 .type = P_BOOL,
2515 .p_class = P_GLOBAL,
2516 .offset = GLOBAL_VAR(bMsAddPrinterWizard),
2517 .special = NULL,
2518 .enum_list = NULL,
2519 .flags = FLAG_ADVANCED,
2522 .label = "os2 driver map",
2523 .type = P_STRING,
2524 .p_class = P_GLOBAL,
2525 .offset = GLOBAL_VAR(szOs2DriverMap),
2526 .special = NULL,
2527 .enum_list = NULL,
2528 .flags = FLAG_ADVANCED,
2532 .label = "printer name",
2533 .type = P_STRING,
2534 .p_class = P_LOCAL,
2535 .offset = LOCAL_VAR(szPrintername),
2536 .special = NULL,
2537 .enum_list = NULL,
2538 .flags = FLAG_ADVANCED | FLAG_PRINT,
2541 .label = "printer",
2542 .type = P_STRING,
2543 .p_class = P_LOCAL,
2544 .offset = LOCAL_VAR(szPrintername),
2545 .special = NULL,
2546 .enum_list = NULL,
2547 .flags = FLAG_HIDE,
2550 .label = "use client driver",
2551 .type = P_BOOL,
2552 .p_class = P_LOCAL,
2553 .offset = LOCAL_VAR(bUseClientDriver),
2554 .special = NULL,
2555 .enum_list = NULL,
2556 .flags = FLAG_ADVANCED | FLAG_PRINT,
2559 .label = "default devmode",
2560 .type = P_BOOL,
2561 .p_class = P_LOCAL,
2562 .offset = LOCAL_VAR(bDefaultDevmode),
2563 .special = NULL,
2564 .enum_list = NULL,
2565 .flags = FLAG_ADVANCED | FLAG_PRINT,
2568 .label = "force printername",
2569 .type = P_BOOL,
2570 .p_class = P_LOCAL,
2571 .offset = LOCAL_VAR(bForcePrintername),
2572 .special = NULL,
2573 .enum_list = NULL,
2574 .flags = FLAG_ADVANCED | FLAG_PRINT,
2577 .label = "printjob username",
2578 .type = P_STRING,
2579 .p_class = P_LOCAL,
2580 .offset = LOCAL_VAR(szPrintjobUsername),
2581 .special = NULL,
2582 .enum_list = NULL,
2583 .flags = FLAG_ADVANCED | FLAG_PRINT,
2586 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2589 .label = "mangling method",
2590 .type = P_STRING,
2591 .p_class = P_GLOBAL,
2592 .offset = GLOBAL_VAR(szManglingMethod),
2593 .special = NULL,
2594 .enum_list = NULL,
2595 .flags = FLAG_ADVANCED,
2598 .label = "mangle prefix",
2599 .type = P_INTEGER,
2600 .p_class = P_GLOBAL,
2601 .offset = GLOBAL_VAR(mangle_prefix),
2602 .special = NULL,
2603 .enum_list = NULL,
2604 .flags = FLAG_ADVANCED,
2608 .label = "default case",
2609 .type = P_ENUM,
2610 .p_class = P_LOCAL,
2611 .offset = LOCAL_VAR(iDefaultCase),
2612 .special = NULL,
2613 .enum_list = enum_case,
2614 .flags = FLAG_ADVANCED | FLAG_SHARE,
2617 .label = "case sensitive",
2618 .type = P_ENUM,
2619 .p_class = P_LOCAL,
2620 .offset = LOCAL_VAR(iCaseSensitive),
2621 .special = NULL,
2622 .enum_list = enum_bool_auto,
2623 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2626 .label = "casesignames",
2627 .type = P_ENUM,
2628 .p_class = P_LOCAL,
2629 .offset = LOCAL_VAR(iCaseSensitive),
2630 .special = NULL,
2631 .enum_list = enum_bool_auto,
2632 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2635 .label = "preserve case",
2636 .type = P_BOOL,
2637 .p_class = P_LOCAL,
2638 .offset = LOCAL_VAR(bCasePreserve),
2639 .special = NULL,
2640 .enum_list = NULL,
2641 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2644 .label = "short preserve case",
2645 .type = P_BOOL,
2646 .p_class = P_LOCAL,
2647 .offset = LOCAL_VAR(bShortCasePreserve),
2648 .special = NULL,
2649 .enum_list = NULL,
2650 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2653 .label = "mangling char",
2654 .type = P_CHAR,
2655 .p_class = P_LOCAL,
2656 .offset = LOCAL_VAR(magic_char),
2657 .special = NULL,
2658 .enum_list = NULL,
2659 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2662 .label = "hide dot files",
2663 .type = P_BOOL,
2664 .p_class = P_LOCAL,
2665 .offset = LOCAL_VAR(bHideDotFiles),
2666 .special = NULL,
2667 .enum_list = NULL,
2668 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2671 .label = "hide special files",
2672 .type = P_BOOL,
2673 .p_class = P_LOCAL,
2674 .offset = LOCAL_VAR(bHideSpecialFiles),
2675 .special = NULL,
2676 .enum_list = NULL,
2677 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2680 .label = "hide unreadable",
2681 .type = P_BOOL,
2682 .p_class = P_LOCAL,
2683 .offset = LOCAL_VAR(bHideUnReadable),
2684 .special = NULL,
2685 .enum_list = NULL,
2686 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2689 .label = "hide unwriteable files",
2690 .type = P_BOOL,
2691 .p_class = P_LOCAL,
2692 .offset = LOCAL_VAR(bHideUnWriteableFiles),
2693 .special = NULL,
2694 .enum_list = NULL,
2695 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2698 .label = "delete veto files",
2699 .type = P_BOOL,
2700 .p_class = P_LOCAL,
2701 .offset = LOCAL_VAR(bDeleteVetoFiles),
2702 .special = NULL,
2703 .enum_list = NULL,
2704 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2707 .label = "veto files",
2708 .type = P_STRING,
2709 .p_class = P_LOCAL,
2710 .offset = LOCAL_VAR(szVetoFiles),
2711 .special = NULL,
2712 .enum_list = NULL,
2713 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2716 .label = "hide files",
2717 .type = P_STRING,
2718 .p_class = P_LOCAL,
2719 .offset = LOCAL_VAR(szHideFiles),
2720 .special = NULL,
2721 .enum_list = NULL,
2722 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2725 .label = "veto oplock files",
2726 .type = P_STRING,
2727 .p_class = P_LOCAL,
2728 .offset = LOCAL_VAR(szVetoOplockFiles),
2729 .special = NULL,
2730 .enum_list = NULL,
2731 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2734 .label = "map archive",
2735 .type = P_BOOL,
2736 .p_class = P_LOCAL,
2737 .offset = LOCAL_VAR(bMap_archive),
2738 .special = NULL,
2739 .enum_list = NULL,
2740 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2743 .label = "map hidden",
2744 .type = P_BOOL,
2745 .p_class = P_LOCAL,
2746 .offset = LOCAL_VAR(bMap_hidden),
2747 .special = NULL,
2748 .enum_list = NULL,
2749 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2752 .label = "map system",
2753 .type = P_BOOL,
2754 .p_class = P_LOCAL,
2755 .offset = LOCAL_VAR(bMap_system),
2756 .special = NULL,
2757 .enum_list = NULL,
2758 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2761 .label = "map readonly",
2762 .type = P_ENUM,
2763 .p_class = P_LOCAL,
2764 .offset = LOCAL_VAR(iMap_readonly),
2765 .special = NULL,
2766 .enum_list = enum_map_readonly,
2767 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2770 .label = "mangled names",
2771 .type = P_BOOL,
2772 .p_class = P_LOCAL,
2773 .offset = LOCAL_VAR(bMangledNames),
2774 .special = NULL,
2775 .enum_list = NULL,
2776 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2779 .label = "max stat cache size",
2780 .type = P_INTEGER,
2781 .p_class = P_GLOBAL,
2782 .offset = GLOBAL_VAR(iMaxStatCacheSize),
2783 .special = NULL,
2784 .enum_list = NULL,
2785 .flags = FLAG_ADVANCED,
2788 .label = "stat cache",
2789 .type = P_BOOL,
2790 .p_class = P_GLOBAL,
2791 .offset = GLOBAL_VAR(bStatCache),
2792 .special = NULL,
2793 .enum_list = NULL,
2794 .flags = FLAG_ADVANCED,
2797 .label = "store dos attributes",
2798 .type = P_BOOL,
2799 .p_class = P_LOCAL,
2800 .offset = LOCAL_VAR(bStoreDosAttributes),
2801 .special = NULL,
2802 .enum_list = NULL,
2803 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2806 .label = "dmapi support",
2807 .type = P_BOOL,
2808 .p_class = P_LOCAL,
2809 .offset = LOCAL_VAR(bDmapiSupport),
2810 .special = NULL,
2811 .enum_list = NULL,
2812 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2816 {N_("Domain Options"), P_SEP, P_SEPARATOR},
2819 .label = "machine password timeout",
2820 .type = P_INTEGER,
2821 .p_class = P_GLOBAL,
2822 .offset = GLOBAL_VAR(machine_password_timeout),
2823 .special = NULL,
2824 .enum_list = NULL,
2825 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2828 {N_("Logon Options"), P_SEP, P_SEPARATOR},
2831 .label = "add user script",
2832 .type = P_STRING,
2833 .p_class = P_GLOBAL,
2834 .offset = GLOBAL_VAR(szAddUserScript),
2835 .special = NULL,
2836 .enum_list = NULL,
2837 .flags = FLAG_ADVANCED,
2840 .label = "rename user script",
2841 .type = P_STRING,
2842 .p_class = P_GLOBAL,
2843 .offset = GLOBAL_VAR(szRenameUserScript),
2844 .special = NULL,
2845 .enum_list = NULL,
2846 .flags = FLAG_ADVANCED,
2849 .label = "delete user script",
2850 .type = P_STRING,
2851 .p_class = P_GLOBAL,
2852 .offset = GLOBAL_VAR(szDelUserScript),
2853 .special = NULL,
2854 .enum_list = NULL,
2855 .flags = FLAG_ADVANCED,
2858 .label = "add group script",
2859 .type = P_STRING,
2860 .p_class = P_GLOBAL,
2861 .offset = GLOBAL_VAR(szAddGroupScript),
2862 .special = NULL,
2863 .enum_list = NULL,
2864 .flags = FLAG_ADVANCED,
2867 .label = "delete group script",
2868 .type = P_STRING,
2869 .p_class = P_GLOBAL,
2870 .offset = GLOBAL_VAR(szDelGroupScript),
2871 .special = NULL,
2872 .enum_list = NULL,
2873 .flags = FLAG_ADVANCED,
2876 .label = "add user to group script",
2877 .type = P_STRING,
2878 .p_class = P_GLOBAL,
2879 .offset = GLOBAL_VAR(szAddUserToGroupScript),
2880 .special = NULL,
2881 .enum_list = NULL,
2882 .flags = FLAG_ADVANCED,
2885 .label = "delete user from group script",
2886 .type = P_STRING,
2887 .p_class = P_GLOBAL,
2888 .offset = GLOBAL_VAR(szDelUserFromGroupScript),
2889 .special = NULL,
2890 .enum_list = NULL,
2891 .flags = FLAG_ADVANCED,
2894 .label = "set primary group script",
2895 .type = P_STRING,
2896 .p_class = P_GLOBAL,
2897 .offset = GLOBAL_VAR(szSetPrimaryGroupScript),
2898 .special = NULL,
2899 .enum_list = NULL,
2900 .flags = FLAG_ADVANCED,
2903 .label = "add machine script",
2904 .type = P_STRING,
2905 .p_class = P_GLOBAL,
2906 .offset = GLOBAL_VAR(szAddMachineScript),
2907 .special = NULL,
2908 .enum_list = NULL,
2909 .flags = FLAG_ADVANCED,
2912 .label = "shutdown script",
2913 .type = P_STRING,
2914 .p_class = P_GLOBAL,
2915 .offset = GLOBAL_VAR(szShutdownScript),
2916 .special = NULL,
2917 .enum_list = NULL,
2918 .flags = FLAG_ADVANCED,
2921 .label = "abort shutdown script",
2922 .type = P_STRING,
2923 .p_class = P_GLOBAL,
2924 .offset = GLOBAL_VAR(szAbortShutdownScript),
2925 .special = NULL,
2926 .enum_list = NULL,
2927 .flags = FLAG_ADVANCED,
2930 .label = "username map script",
2931 .type = P_STRING,
2932 .p_class = P_GLOBAL,
2933 .offset = GLOBAL_VAR(szUsernameMapScript),
2934 .special = NULL,
2935 .enum_list = NULL,
2936 .flags = FLAG_ADVANCED,
2939 .label = "username map cache time",
2940 .type = P_INTEGER,
2941 .p_class = P_GLOBAL,
2942 .offset = GLOBAL_VAR(iUsernameMapCacheTime),
2943 .special = NULL,
2944 .enum_list = NULL,
2945 .flags = FLAG_ADVANCED,
2948 .label = "logon script",
2949 .type = P_STRING,
2950 .p_class = P_GLOBAL,
2951 .offset = GLOBAL_VAR(szLogonScript),
2952 .special = NULL,
2953 .enum_list = NULL,
2954 .flags = FLAG_ADVANCED,
2957 .label = "logon path",
2958 .type = P_STRING,
2959 .p_class = P_GLOBAL,
2960 .offset = GLOBAL_VAR(szLogonPath),
2961 .special = NULL,
2962 .enum_list = NULL,
2963 .flags = FLAG_ADVANCED,
2966 .label = "logon drive",
2967 .type = P_STRING,
2968 .p_class = P_GLOBAL,
2969 .offset = GLOBAL_VAR(szLogonDrive),
2970 .special = NULL,
2971 .enum_list = NULL,
2972 .flags = FLAG_ADVANCED,
2975 .label = "logon home",
2976 .type = P_STRING,
2977 .p_class = P_GLOBAL,
2978 .offset = GLOBAL_VAR(szLogonHome),
2979 .special = NULL,
2980 .enum_list = NULL,
2981 .flags = FLAG_ADVANCED,
2984 .label = "domain logons",
2985 .type = P_BOOL,
2986 .p_class = P_GLOBAL,
2987 .offset = GLOBAL_VAR(bDomainLogons),
2988 .special = NULL,
2989 .enum_list = NULL,
2990 .flags = FLAG_ADVANCED,
2994 .label = "init logon delayed hosts",
2995 .type = P_LIST,
2996 .p_class = P_GLOBAL,
2997 .offset = GLOBAL_VAR(szInitLogonDelayedHosts),
2998 .special = NULL,
2999 .enum_list = NULL,
3000 .flags = FLAG_ADVANCED,
3004 .label = "init logon delay",
3005 .type = P_INTEGER,
3006 .p_class = P_GLOBAL,
3007 .offset = GLOBAL_VAR(InitLogonDelay),
3008 .special = NULL,
3009 .enum_list = NULL,
3010 .flags = FLAG_ADVANCED,
3014 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3017 .label = "os level",
3018 .type = P_INTEGER,
3019 .p_class = P_GLOBAL,
3020 .offset = GLOBAL_VAR(os_level),
3021 .special = NULL,
3022 .enum_list = NULL,
3023 .flags = FLAG_BASIC | FLAG_ADVANCED,
3026 .label = "lm announce",
3027 .type = P_ENUM,
3028 .p_class = P_GLOBAL,
3029 .offset = GLOBAL_VAR(lm_announce),
3030 .special = NULL,
3031 .enum_list = enum_bool_auto,
3032 .flags = FLAG_ADVANCED,
3035 .label = "lm interval",
3036 .type = P_INTEGER,
3037 .p_class = P_GLOBAL,
3038 .offset = GLOBAL_VAR(lm_interval),
3039 .special = NULL,
3040 .enum_list = NULL,
3041 .flags = FLAG_ADVANCED,
3044 .label = "preferred master",
3045 .type = P_ENUM,
3046 .p_class = P_GLOBAL,
3047 .offset = GLOBAL_VAR(iPreferredMaster),
3048 .special = NULL,
3049 .enum_list = enum_bool_auto,
3050 .flags = FLAG_BASIC | FLAG_ADVANCED,
3053 .label = "prefered master",
3054 .type = P_ENUM,
3055 .p_class = P_GLOBAL,
3056 .offset = GLOBAL_VAR(iPreferredMaster),
3057 .special = NULL,
3058 .enum_list = enum_bool_auto,
3059 .flags = FLAG_HIDE,
3062 .label = "local master",
3063 .type = P_BOOL,
3064 .p_class = P_GLOBAL,
3065 .offset = GLOBAL_VAR(bLocalMaster),
3066 .special = NULL,
3067 .enum_list = NULL,
3068 .flags = FLAG_BASIC | FLAG_ADVANCED,
3071 .label = "domain master",
3072 .type = P_ENUM,
3073 .p_class = P_GLOBAL,
3074 .offset = GLOBAL_VAR(iDomainMaster),
3075 .special = NULL,
3076 .enum_list = enum_bool_auto,
3077 .flags = FLAG_BASIC | FLAG_ADVANCED,
3080 .label = "browse list",
3081 .type = P_BOOL,
3082 .p_class = P_GLOBAL,
3083 .offset = GLOBAL_VAR(bBrowseList),
3084 .special = NULL,
3085 .enum_list = NULL,
3086 .flags = FLAG_ADVANCED,
3089 .label = "browseable",
3090 .type = P_BOOL,
3091 .p_class = P_LOCAL,
3092 .offset = LOCAL_VAR(bBrowseable),
3093 .special = NULL,
3094 .enum_list = NULL,
3095 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3098 .label = "browsable",
3099 .type = P_BOOL,
3100 .p_class = P_LOCAL,
3101 .offset = LOCAL_VAR(bBrowseable),
3102 .special = NULL,
3103 .enum_list = NULL,
3104 .flags = FLAG_HIDE,
3107 .label = "access based share enum",
3108 .type = P_BOOL,
3109 .p_class = P_LOCAL,
3110 .offset = LOCAL_VAR(bAccessBasedShareEnum),
3111 .special = NULL,
3112 .enum_list = NULL,
3113 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3116 .label = "enhanced browsing",
3117 .type = P_BOOL,
3118 .p_class = P_GLOBAL,
3119 .offset = GLOBAL_VAR(enhanced_browsing),
3120 .special = NULL,
3121 .enum_list = NULL,
3122 .flags = FLAG_ADVANCED,
3125 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3128 .label = "dns proxy",
3129 .type = P_BOOL,
3130 .p_class = P_GLOBAL,
3131 .offset = GLOBAL_VAR(bWINSdnsProxy),
3132 .special = NULL,
3133 .enum_list = NULL,
3134 .flags = FLAG_ADVANCED,
3137 .label = "wins proxy",
3138 .type = P_BOOL,
3139 .p_class = P_GLOBAL,
3140 .offset = GLOBAL_VAR(bWINSproxy),
3141 .special = NULL,
3142 .enum_list = NULL,
3143 .flags = FLAG_ADVANCED,
3146 .label = "wins server",
3147 .type = P_LIST,
3148 .p_class = P_GLOBAL,
3149 .offset = GLOBAL_VAR(szWINSservers),
3150 .special = NULL,
3151 .enum_list = NULL,
3152 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3155 .label = "wins support",
3156 .type = P_BOOL,
3157 .p_class = P_GLOBAL,
3158 .offset = GLOBAL_VAR(bWINSsupport),
3159 .special = NULL,
3160 .enum_list = NULL,
3161 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3164 .label = "wins hook",
3165 .type = P_STRING,
3166 .p_class = P_GLOBAL,
3167 .offset = GLOBAL_VAR(szWINSHook),
3168 .special = NULL,
3169 .enum_list = NULL,
3170 .flags = FLAG_ADVANCED,
3173 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3176 .label = "blocking locks",
3177 .type = P_BOOL,
3178 .p_class = P_LOCAL,
3179 .offset = LOCAL_VAR(bBlockingLocks),
3180 .special = NULL,
3181 .enum_list = NULL,
3182 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3185 .label = "csc policy",
3186 .type = P_ENUM,
3187 .p_class = P_LOCAL,
3188 .offset = LOCAL_VAR(iCSCPolicy),
3189 .special = NULL,
3190 .enum_list = enum_csc_policy,
3191 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3194 .label = "fake oplocks",
3195 .type = P_BOOL,
3196 .p_class = P_LOCAL,
3197 .offset = LOCAL_VAR(bFakeOplocks),
3198 .special = NULL,
3199 .enum_list = NULL,
3200 .flags = FLAG_ADVANCED | FLAG_SHARE,
3203 .label = "kernel oplocks",
3204 .type = P_BOOL,
3205 .p_class = P_LOCAL,
3206 .offset = LOCAL_VAR(bKernelOplocks),
3207 .special = NULL,
3208 .enum_list = NULL,
3209 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3212 .label = "locking",
3213 .type = P_BOOL,
3214 .p_class = P_LOCAL,
3215 .offset = LOCAL_VAR(bLocking),
3216 .special = NULL,
3217 .enum_list = NULL,
3218 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3221 .label = "lock spin time",
3222 .type = P_INTEGER,
3223 .p_class = P_GLOBAL,
3224 .offset = GLOBAL_VAR(iLockSpinTime),
3225 .special = NULL,
3226 .enum_list = NULL,
3227 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3230 .label = "oplocks",
3231 .type = P_BOOL,
3232 .p_class = P_LOCAL,
3233 .offset = LOCAL_VAR(bOpLocks),
3234 .special = NULL,
3235 .enum_list = NULL,
3236 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3239 .label = "level2 oplocks",
3240 .type = P_BOOL,
3241 .p_class = P_LOCAL,
3242 .offset = LOCAL_VAR(bLevel2OpLocks),
3243 .special = NULL,
3244 .enum_list = NULL,
3245 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3248 .label = "oplock break wait time",
3249 .type = P_INTEGER,
3250 .p_class = P_GLOBAL,
3251 .offset = GLOBAL_VAR(oplock_break_wait_time),
3252 .special = NULL,
3253 .enum_list = NULL,
3254 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3257 .label = "oplock contention limit",
3258 .type = P_INTEGER,
3259 .p_class = P_LOCAL,
3260 .offset = LOCAL_VAR(iOplockContentionLimit),
3261 .special = NULL,
3262 .enum_list = NULL,
3263 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3266 .label = "posix locking",
3267 .type = P_BOOL,
3268 .p_class = P_LOCAL,
3269 .offset = LOCAL_VAR(bPosixLocking),
3270 .special = NULL,
3271 .enum_list = NULL,
3272 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3275 .label = "strict locking",
3276 .type = P_ENUM,
3277 .p_class = P_LOCAL,
3278 .offset = LOCAL_VAR(iStrictLocking),
3279 .special = NULL,
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",
3288 .type = P_STRING,
3289 .p_class = P_GLOBAL,
3290 .offset = GLOBAL_VAR(szLdapAdminDn),
3291 .special = NULL,
3292 .enum_list = NULL,
3293 .flags = FLAG_ADVANCED,
3296 .label = "ldap delete dn",
3297 .type = P_BOOL,
3298 .p_class = P_GLOBAL,
3299 .offset = GLOBAL_VAR(ldap_delete_dn),
3300 .special = NULL,
3301 .enum_list = NULL,
3302 .flags = FLAG_ADVANCED,
3305 .label = "ldap group suffix",
3306 .type = P_STRING,
3307 .p_class = P_GLOBAL,
3308 .offset = GLOBAL_VAR(szLdapGroupSuffix),
3309 .special = NULL,
3310 .enum_list = NULL,
3311 .flags = FLAG_ADVANCED,
3314 .label = "ldap idmap suffix",
3315 .type = P_STRING,
3316 .p_class = P_GLOBAL,
3317 .offset = GLOBAL_VAR(szLdapIdmapSuffix),
3318 .special = NULL,
3319 .enum_list = NULL,
3320 .flags = FLAG_ADVANCED,
3323 .label = "ldap machine suffix",
3324 .type = P_STRING,
3325 .p_class = P_GLOBAL,
3326 .offset = GLOBAL_VAR(szLdapMachineSuffix),
3327 .special = NULL,
3328 .enum_list = NULL,
3329 .flags = FLAG_ADVANCED,
3332 .label = "ldap passwd sync",
3333 .type = P_ENUM,
3334 .p_class = P_GLOBAL,
3335 .offset = GLOBAL_VAR(ldap_passwd_sync),
3336 .special = NULL,
3337 .enum_list = enum_ldap_passwd_sync,
3338 .flags = FLAG_ADVANCED,
3341 .label = "ldap password sync",
3342 .type = P_ENUM,
3343 .p_class = P_GLOBAL,
3344 .offset = GLOBAL_VAR(ldap_passwd_sync),
3345 .special = NULL,
3346 .enum_list = enum_ldap_passwd_sync,
3347 .flags = FLAG_HIDE,
3350 .label = "ldap replication sleep",
3351 .type = P_INTEGER,
3352 .p_class = P_GLOBAL,
3353 .offset = GLOBAL_VAR(ldap_replication_sleep),
3354 .special = NULL,
3355 .enum_list = NULL,
3356 .flags = FLAG_ADVANCED,
3359 .label = "ldap suffix",
3360 .type = P_STRING,
3361 .p_class = P_GLOBAL,
3362 .offset = GLOBAL_VAR(szLdapSuffix),
3363 .special = NULL,
3364 .enum_list = NULL,
3365 .flags = FLAG_ADVANCED,
3368 .label = "ldap ssl",
3369 .type = P_ENUM,
3370 .p_class = P_GLOBAL,
3371 .offset = GLOBAL_VAR(ldap_ssl),
3372 .special = NULL,
3373 .enum_list = enum_ldap_ssl,
3374 .flags = FLAG_ADVANCED,
3377 .label = "ldap ssl ads",
3378 .type = P_BOOL,
3379 .p_class = P_GLOBAL,
3380 .offset = GLOBAL_VAR(ldap_ssl_ads),
3381 .special = NULL,
3382 .enum_list = NULL,
3383 .flags = FLAG_ADVANCED,
3386 .label = "ldap deref",
3387 .type = P_ENUM,
3388 .p_class = P_GLOBAL,
3389 .offset = GLOBAL_VAR(ldap_deref),
3390 .special = NULL,
3391 .enum_list = enum_ldap_deref,
3392 .flags = FLAG_ADVANCED,
3395 .label = "ldap follow referral",
3396 .type = P_ENUM,
3397 .p_class = P_GLOBAL,
3398 .offset = GLOBAL_VAR(ldap_follow_referral),
3399 .special = NULL,
3400 .enum_list = enum_bool_auto,
3401 .flags = FLAG_ADVANCED,
3404 .label = "ldap timeout",
3405 .type = P_INTEGER,
3406 .p_class = P_GLOBAL,
3407 .offset = GLOBAL_VAR(ldap_timeout),
3408 .special = NULL,
3409 .enum_list = NULL,
3410 .flags = FLAG_ADVANCED,
3413 .label = "ldap connection timeout",
3414 .type = P_INTEGER,
3415 .p_class = P_GLOBAL,
3416 .offset = GLOBAL_VAR(ldap_connection_timeout),
3417 .special = NULL,
3418 .enum_list = NULL,
3419 .flags = FLAG_ADVANCED,
3422 .label = "ldap page size",
3423 .type = P_INTEGER,
3424 .p_class = P_GLOBAL,
3425 .offset = GLOBAL_VAR(ldap_page_size),
3426 .special = NULL,
3427 .enum_list = NULL,
3428 .flags = FLAG_ADVANCED,
3431 .label = "ldap user suffix",
3432 .type = P_STRING,
3433 .p_class = P_GLOBAL,
3434 .offset = GLOBAL_VAR(szLdapUserSuffix),
3435 .special = NULL,
3436 .enum_list = NULL,
3437 .flags = FLAG_ADVANCED,
3440 .label = "ldap debug level",
3441 .type = P_INTEGER,
3442 .p_class = P_GLOBAL,
3443 .offset = GLOBAL_VAR(ldap_debug_level),
3444 .special = handle_ldap_debug_level,
3445 .enum_list = NULL,
3446 .flags = FLAG_ADVANCED,
3449 .label = "ldap debug threshold",
3450 .type = P_INTEGER,
3451 .p_class = P_GLOBAL,
3452 .offset = GLOBAL_VAR(ldap_debug_threshold),
3453 .special = NULL,
3454 .enum_list = NULL,
3455 .flags = FLAG_ADVANCED,
3458 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3461 .label = "eventlog list",
3462 .type = P_LIST,
3463 .p_class = P_GLOBAL,
3464 .offset = GLOBAL_VAR(szEventLogs),
3465 .special = NULL,
3466 .enum_list = NULL,
3467 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3470 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3473 .label = "add share command",
3474 .type = P_STRING,
3475 .p_class = P_GLOBAL,
3476 .offset = GLOBAL_VAR(szAddShareCommand),
3477 .special = NULL,
3478 .enum_list = NULL,
3479 .flags = FLAG_ADVANCED,
3482 .label = "change share command",
3483 .type = P_STRING,
3484 .p_class = P_GLOBAL,
3485 .offset = GLOBAL_VAR(szChangeShareCommand),
3486 .special = NULL,
3487 .enum_list = NULL,
3488 .flags = FLAG_ADVANCED,
3491 .label = "delete share command",
3492 .type = P_STRING,
3493 .p_class = P_GLOBAL,
3494 .offset = GLOBAL_VAR(szDeleteShareCommand),
3495 .special = NULL,
3496 .enum_list = NULL,
3497 .flags = FLAG_ADVANCED,
3500 .label = "config file",
3501 .type = P_STRING,
3502 .p_class = P_GLOBAL,
3503 .offset = GLOBAL_VAR(szConfigFile),
3504 .special = NULL,
3505 .enum_list = NULL,
3506 .flags = FLAG_HIDE|FLAG_META,
3509 .label = "preload",
3510 .type = P_STRING,
3511 .p_class = P_GLOBAL,
3512 .offset = GLOBAL_VAR(szAutoServices),
3513 .special = NULL,
3514 .enum_list = NULL,
3515 .flags = FLAG_ADVANCED,
3518 .label = "auto services",
3519 .type = P_STRING,
3520 .p_class = P_GLOBAL,
3521 .offset = GLOBAL_VAR(szAutoServices),
3522 .special = NULL,
3523 .enum_list = NULL,
3524 .flags = FLAG_ADVANCED,
3527 .label = "lock directory",
3528 .type = P_STRING,
3529 .p_class = P_GLOBAL,
3530 .offset = GLOBAL_VAR(szLockDir),
3531 .special = NULL,
3532 .enum_list = NULL,
3533 .flags = FLAG_ADVANCED,
3536 .label = "lock dir",
3537 .type = P_STRING,
3538 .p_class = P_GLOBAL,
3539 .offset = GLOBAL_VAR(szLockDir),
3540 .special = NULL,
3541 .enum_list = NULL,
3542 .flags = FLAG_HIDE,
3545 .label = "state directory",
3546 .type = P_STRING,
3547 .p_class = P_GLOBAL,
3548 .offset = GLOBAL_VAR(szStateDir),
3549 .special = NULL,
3550 .enum_list = NULL,
3551 .flags = FLAG_ADVANCED,
3554 .label = "cache directory",
3555 .type = P_STRING,
3556 .p_class = P_GLOBAL,
3557 .offset = GLOBAL_VAR(szCacheDir),
3558 .special = NULL,
3559 .enum_list = NULL,
3560 .flags = FLAG_ADVANCED,
3563 .label = "pid directory",
3564 .type = P_STRING,
3565 .p_class = P_GLOBAL,
3566 .offset = GLOBAL_VAR(szPidDir),
3567 .special = NULL,
3568 .enum_list = NULL,
3569 .flags = FLAG_ADVANCED,
3572 .label = "ntp signd socket directory",
3573 .type = P_STRING,
3574 .p_class = P_GLOBAL,
3575 .offset = GLOBAL_VAR(szNTPSignDSocketDirectory),
3576 .special = NULL,
3577 .enum_list = NULL,
3578 .flags = FLAG_ADVANCED,
3581 #ifdef WITH_UTMP
3583 .label = "utmp directory",
3584 .type = P_STRING,
3585 .p_class = P_GLOBAL,
3586 .offset = GLOBAL_VAR(szUtmpDir),
3587 .special = NULL,
3588 .enum_list = NULL,
3589 .flags = FLAG_ADVANCED,
3592 .label = "wtmp directory",
3593 .type = P_STRING,
3594 .p_class = P_GLOBAL,
3595 .offset = GLOBAL_VAR(szWtmpDir),
3596 .special = NULL,
3597 .enum_list = NULL,
3598 .flags = FLAG_ADVANCED,
3601 .label = "utmp",
3602 .type = P_BOOL,
3603 .p_class = P_GLOBAL,
3604 .offset = GLOBAL_VAR(bUtmp),
3605 .special = NULL,
3606 .enum_list = NULL,
3607 .flags = FLAG_ADVANCED,
3609 #endif
3611 .label = "default service",
3612 .type = P_STRING,
3613 .p_class = P_GLOBAL,
3614 .offset = GLOBAL_VAR(szDefaultService),
3615 .special = NULL,
3616 .enum_list = NULL,
3617 .flags = FLAG_ADVANCED,
3620 .label = "default",
3621 .type = P_STRING,
3622 .p_class = P_GLOBAL,
3623 .offset = GLOBAL_VAR(szDefaultService),
3624 .special = NULL,
3625 .enum_list = NULL,
3626 .flags = FLAG_ADVANCED,
3629 .label = "message command",
3630 .type = P_STRING,
3631 .p_class = P_GLOBAL,
3632 .offset = GLOBAL_VAR(szMsgCommand),
3633 .special = NULL,
3634 .enum_list = NULL,
3635 .flags = FLAG_ADVANCED,
3638 .label = "dfree cache time",
3639 .type = P_INTEGER,
3640 .p_class = P_LOCAL,
3641 .offset = LOCAL_VAR(iDfreeCacheTime),
3642 .special = NULL,
3643 .enum_list = NULL,
3644 .flags = FLAG_ADVANCED,
3647 .label = "dfree command",
3648 .type = P_STRING,
3649 .p_class = P_LOCAL,
3650 .offset = LOCAL_VAR(szDfree),
3651 .special = NULL,
3652 .enum_list = NULL,
3653 .flags = FLAG_ADVANCED,
3656 .label = "get quota command",
3657 .type = P_STRING,
3658 .p_class = P_GLOBAL,
3659 .offset = GLOBAL_VAR(szGetQuota),
3660 .special = NULL,
3661 .enum_list = NULL,
3662 .flags = FLAG_ADVANCED,
3665 .label = "set quota command",
3666 .type = P_STRING,
3667 .p_class = P_GLOBAL,
3668 .offset = GLOBAL_VAR(szSetQuota),
3669 .special = NULL,
3670 .enum_list = NULL,
3671 .flags = FLAG_ADVANCED,
3674 .label = "remote announce",
3675 .type = P_STRING,
3676 .p_class = P_GLOBAL,
3677 .offset = GLOBAL_VAR(szRemoteAnnounce),
3678 .special = NULL,
3679 .enum_list = NULL,
3680 .flags = FLAG_ADVANCED,
3683 .label = "remote browse sync",
3684 .type = P_STRING,
3685 .p_class = P_GLOBAL,
3686 .offset = GLOBAL_VAR(szRemoteBrowseSync),
3687 .special = NULL,
3688 .enum_list = NULL,
3689 .flags = FLAG_ADVANCED,
3692 .label = "socket address",
3693 .type = P_STRING,
3694 .p_class = P_GLOBAL,
3695 .offset = GLOBAL_VAR(szSocketAddress),
3696 .special = NULL,
3697 .enum_list = NULL,
3698 .flags = FLAG_ADVANCED,
3701 .label = "nmbd bind explicit broadcast",
3702 .type = P_BOOL,
3703 .p_class = P_GLOBAL,
3704 .offset = GLOBAL_VAR(bNmbdBindExplicitBroadcast),
3705 .special = NULL,
3706 .enum_list = NULL,
3707 .flags = FLAG_ADVANCED,
3710 .label = "homedir map",
3711 .type = P_STRING,
3712 .p_class = P_GLOBAL,
3713 .offset = GLOBAL_VAR(szNISHomeMapName),
3714 .special = NULL,
3715 .enum_list = NULL,
3716 .flags = FLAG_ADVANCED,
3719 .label = "afs username map",
3720 .type = P_STRING,
3721 .p_class = P_GLOBAL,
3722 .offset = GLOBAL_VAR(szAfsUsernameMap),
3723 .special = NULL,
3724 .enum_list = NULL,
3725 .flags = FLAG_ADVANCED,
3728 .label = "afs token lifetime",
3729 .type = P_INTEGER,
3730 .p_class = P_GLOBAL,
3731 .offset = GLOBAL_VAR(iAfsTokenLifetime),
3732 .special = NULL,
3733 .enum_list = NULL,
3734 .flags = FLAG_ADVANCED,
3737 .label = "log nt token command",
3738 .type = P_STRING,
3739 .p_class = P_GLOBAL,
3740 .offset = GLOBAL_VAR(szLogNtTokenCommand),
3741 .special = NULL,
3742 .enum_list = NULL,
3743 .flags = FLAG_ADVANCED,
3746 .label = "NIS homedir",
3747 .type = P_BOOL,
3748 .p_class = P_GLOBAL,
3749 .offset = GLOBAL_VAR(bNISHomeMap),
3750 .special = NULL,
3751 .enum_list = NULL,
3752 .flags = FLAG_ADVANCED,
3755 .label = "-valid",
3756 .type = P_BOOL,
3757 .p_class = P_LOCAL,
3758 .offset = LOCAL_VAR(valid),
3759 .special = NULL,
3760 .enum_list = NULL,
3761 .flags = FLAG_HIDE,
3764 .label = "copy",
3765 .type = P_STRING,
3766 .p_class = P_LOCAL,
3767 .offset = LOCAL_VAR(szCopy),
3768 .special = handle_copy,
3769 .enum_list = NULL,
3770 .flags = FLAG_HIDE,
3773 .label = "include",
3774 .type = P_STRING,
3775 .p_class = P_LOCAL,
3776 .offset = LOCAL_VAR(szInclude),
3777 .special = handle_include,
3778 .enum_list = NULL,
3779 .flags = FLAG_HIDE|FLAG_META,
3782 .label = "preexec",
3783 .type = P_STRING,
3784 .p_class = P_LOCAL,
3785 .offset = LOCAL_VAR(szPreExec),
3786 .special = NULL,
3787 .enum_list = NULL,
3788 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3791 .label = "exec",
3792 .type = P_STRING,
3793 .p_class = P_LOCAL,
3794 .offset = LOCAL_VAR(szPreExec),
3795 .special = NULL,
3796 .enum_list = NULL,
3797 .flags = FLAG_ADVANCED,
3800 .label = "preexec close",
3801 .type = P_BOOL,
3802 .p_class = P_LOCAL,
3803 .offset = LOCAL_VAR(bPreexecClose),
3804 .special = NULL,
3805 .enum_list = NULL,
3806 .flags = FLAG_ADVANCED | FLAG_SHARE,
3809 .label = "postexec",
3810 .type = P_STRING,
3811 .p_class = P_LOCAL,
3812 .offset = LOCAL_VAR(szPostExec),
3813 .special = NULL,
3814 .enum_list = NULL,
3815 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3818 .label = "root preexec",
3819 .type = P_STRING,
3820 .p_class = P_LOCAL,
3821 .offset = LOCAL_VAR(szRootPreExec),
3822 .special = NULL,
3823 .enum_list = NULL,
3824 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3827 .label = "root preexec close",
3828 .type = P_BOOL,
3829 .p_class = P_LOCAL,
3830 .offset = LOCAL_VAR(bRootpreexecClose),
3831 .special = NULL,
3832 .enum_list = NULL,
3833 .flags = FLAG_ADVANCED | FLAG_SHARE,
3836 .label = "root postexec",
3837 .type = P_STRING,
3838 .p_class = P_LOCAL,
3839 .offset = LOCAL_VAR(szRootPostExec),
3840 .special = NULL,
3841 .enum_list = NULL,
3842 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3845 .label = "available",
3846 .type = P_BOOL,
3847 .p_class = P_LOCAL,
3848 .offset = LOCAL_VAR(bAvailable),
3849 .special = NULL,
3850 .enum_list = NULL,
3851 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3854 .label = "registry shares",
3855 .type = P_BOOL,
3856 .p_class = P_GLOBAL,
3857 .offset = GLOBAL_VAR(bRegistryShares),
3858 .special = NULL,
3859 .enum_list = NULL,
3860 .flags = FLAG_ADVANCED,
3863 .label = "usershare allow guests",
3864 .type = P_BOOL,
3865 .p_class = P_GLOBAL,
3866 .offset = GLOBAL_VAR(bUsershareAllowGuests),
3867 .special = NULL,
3868 .enum_list = NULL,
3869 .flags = FLAG_ADVANCED,
3872 .label = "usershare max shares",
3873 .type = P_INTEGER,
3874 .p_class = P_GLOBAL,
3875 .offset = GLOBAL_VAR(iUsershareMaxShares),
3876 .special = NULL,
3877 .enum_list = NULL,
3878 .flags = FLAG_ADVANCED,
3881 .label = "usershare owner only",
3882 .type = P_BOOL,
3883 .p_class = P_GLOBAL,
3884 .offset = GLOBAL_VAR(bUsershareOwnerOnly),
3885 .special = NULL,
3886 .enum_list = NULL,
3887 .flags = FLAG_ADVANCED,
3890 .label = "usershare path",
3891 .type = P_STRING,
3892 .p_class = P_GLOBAL,
3893 .offset = GLOBAL_VAR(szUsersharePath),
3894 .special = NULL,
3895 .enum_list = NULL,
3896 .flags = FLAG_ADVANCED,
3899 .label = "usershare prefix allow list",
3900 .type = P_LIST,
3901 .p_class = P_GLOBAL,
3902 .offset = GLOBAL_VAR(szUsersharePrefixAllowList),
3903 .special = NULL,
3904 .enum_list = NULL,
3905 .flags = FLAG_ADVANCED,
3908 .label = "usershare prefix deny list",
3909 .type = P_LIST,
3910 .p_class = P_GLOBAL,
3911 .offset = GLOBAL_VAR(szUsersharePrefixDenyList),
3912 .special = NULL,
3913 .enum_list = NULL,
3914 .flags = FLAG_ADVANCED,
3917 .label = "usershare template share",
3918 .type = P_STRING,
3919 .p_class = P_GLOBAL,
3920 .offset = GLOBAL_VAR(szUsershareTemplateShare),
3921 .special = NULL,
3922 .enum_list = NULL,
3923 .flags = FLAG_ADVANCED,
3926 .label = "volume",
3927 .type = P_STRING,
3928 .p_class = P_LOCAL,
3929 .offset = LOCAL_VAR(volume),
3930 .special = NULL,
3931 .enum_list = NULL,
3932 .flags = FLAG_ADVANCED | FLAG_SHARE,
3935 .label = "fstype",
3936 .type = P_STRING,
3937 .p_class = P_LOCAL,
3938 .offset = LOCAL_VAR(fstype),
3939 .special = NULL,
3940 .enum_list = NULL,
3941 .flags = FLAG_ADVANCED | FLAG_SHARE,
3944 .label = "set directory",
3945 .type = P_BOOLREV,
3946 .p_class = P_LOCAL,
3947 .offset = LOCAL_VAR(bNo_set_dir),
3948 .special = NULL,
3949 .enum_list = NULL,
3950 .flags = FLAG_ADVANCED | FLAG_SHARE,
3953 .label = "allow insecure wide links",
3954 .type = P_BOOL,
3955 .p_class = P_GLOBAL,
3956 .offset = GLOBAL_VAR(bAllowInsecureWidelinks),
3957 .special = NULL,
3958 .enum_list = NULL,
3959 .flags = FLAG_ADVANCED,
3962 .label = "wide links",
3963 .type = P_BOOL,
3964 .p_class = P_LOCAL,
3965 .offset = LOCAL_VAR(bWidelinks),
3966 .special = NULL,
3967 .enum_list = NULL,
3968 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3971 .label = "follow symlinks",
3972 .type = P_BOOL,
3973 .p_class = P_LOCAL,
3974 .offset = LOCAL_VAR(bSymlinks),
3975 .special = NULL,
3976 .enum_list = NULL,
3977 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3980 .label = "dont descend",
3981 .type = P_STRING,
3982 .p_class = P_LOCAL,
3983 .offset = LOCAL_VAR(szDontdescend),
3984 .special = NULL,
3985 .enum_list = NULL,
3986 .flags = FLAG_ADVANCED | FLAG_SHARE,
3989 .label = "magic script",
3990 .type = P_STRING,
3991 .p_class = P_LOCAL,
3992 .offset = LOCAL_VAR(szMagicScript),
3993 .special = NULL,
3994 .enum_list = NULL,
3995 .flags = FLAG_ADVANCED | FLAG_SHARE,
3998 .label = "magic output",
3999 .type = P_STRING,
4000 .p_class = P_LOCAL,
4001 .offset = LOCAL_VAR(szMagicOutput),
4002 .special = NULL,
4003 .enum_list = NULL,
4004 .flags = FLAG_ADVANCED | FLAG_SHARE,
4007 .label = "delete readonly",
4008 .type = P_BOOL,
4009 .p_class = P_LOCAL,
4010 .offset = LOCAL_VAR(bDeleteReadonly),
4011 .special = NULL,
4012 .enum_list = NULL,
4013 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4016 .label = "dos filemode",
4017 .type = P_BOOL,
4018 .p_class = P_LOCAL,
4019 .offset = LOCAL_VAR(bDosFilemode),
4020 .special = NULL,
4021 .enum_list = NULL,
4022 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4025 .label = "dos filetimes",
4026 .type = P_BOOL,
4027 .p_class = P_LOCAL,
4028 .offset = LOCAL_VAR(bDosFiletimes),
4029 .special = NULL,
4030 .enum_list = NULL,
4031 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4034 .label = "dos filetime resolution",
4035 .type = P_BOOL,
4036 .p_class = P_LOCAL,
4037 .offset = LOCAL_VAR(bDosFiletimeResolution),
4038 .special = NULL,
4039 .enum_list = NULL,
4040 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4043 .label = "fake directory create times",
4044 .type = P_BOOL,
4045 .p_class = P_LOCAL,
4046 .offset = LOCAL_VAR(bFakeDirCreateTimes),
4047 .special = NULL,
4048 .enum_list = NULL,
4049 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4052 .label = "async smb echo handler",
4053 .type = P_BOOL,
4054 .p_class = P_GLOBAL,
4055 .offset = GLOBAL_VAR(bAsyncSMBEchoHandler),
4056 .special = NULL,
4057 .enum_list = NULL,
4058 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4061 .label = "panic action",
4062 .type = P_STRING,
4063 .p_class = P_GLOBAL,
4064 .offset = GLOBAL_VAR(szPanicAction),
4065 .special = NULL,
4066 .enum_list = NULL,
4067 .flags = FLAG_ADVANCED,
4070 .label = "perfcount module",
4071 .type = P_STRING,
4072 .p_class = P_GLOBAL,
4073 .offset = GLOBAL_VAR(szSMBPerfcountModule),
4074 .special = NULL,
4075 .enum_list = NULL,
4076 .flags = FLAG_ADVANCED,
4079 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4082 .label = "vfs objects",
4083 .type = P_LIST,
4084 .p_class = P_LOCAL,
4085 .offset = LOCAL_VAR(szVfsObjects),
4086 .special = NULL,
4087 .enum_list = NULL,
4088 .flags = FLAG_ADVANCED | FLAG_SHARE,
4091 .label = "vfs object",
4092 .type = P_LIST,
4093 .p_class = P_LOCAL,
4094 .offset = LOCAL_VAR(szVfsObjects),
4095 .special = NULL,
4096 .enum_list = NULL,
4097 .flags = FLAG_HIDE,
4101 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4104 .label = "msdfs root",
4105 .type = P_BOOL,
4106 .p_class = P_LOCAL,
4107 .offset = LOCAL_VAR(bMSDfsRoot),
4108 .special = NULL,
4109 .enum_list = NULL,
4110 .flags = FLAG_ADVANCED | FLAG_SHARE,
4113 .label = "msdfs proxy",
4114 .type = P_STRING,
4115 .p_class = P_LOCAL,
4116 .offset = LOCAL_VAR(szMSDfsProxy),
4117 .special = NULL,
4118 .enum_list = NULL,
4119 .flags = FLAG_ADVANCED | FLAG_SHARE,
4122 .label = "host msdfs",
4123 .type = P_BOOL,
4124 .p_class = P_GLOBAL,
4125 .offset = GLOBAL_VAR(bHostMSDfs),
4126 .special = NULL,
4127 .enum_list = NULL,
4128 .flags = FLAG_ADVANCED,
4131 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4134 .label = "passdb expand explicit",
4135 .type = P_BOOL,
4136 .p_class = P_GLOBAL,
4137 .offset = GLOBAL_VAR(bPassdbExpandExplicit),
4138 .special = NULL,
4139 .enum_list = NULL,
4140 .flags = FLAG_ADVANCED,
4143 .label = "idmap backend",
4144 .type = P_STRING,
4145 .p_class = P_GLOBAL,
4146 .offset = GLOBAL_VAR(szIdmapBackend),
4147 .special = handle_idmap_backend,
4148 .enum_list = NULL,
4149 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4152 .label = "idmap cache time",
4153 .type = P_INTEGER,
4154 .p_class = P_GLOBAL,
4155 .offset = GLOBAL_VAR(iIdmapCacheTime),
4156 .special = NULL,
4157 .enum_list = NULL,
4158 .flags = FLAG_ADVANCED,
4161 .label = "idmap negative cache time",
4162 .type = P_INTEGER,
4163 .p_class = P_GLOBAL,
4164 .offset = GLOBAL_VAR(iIdmapNegativeCacheTime),
4165 .special = NULL,
4166 .enum_list = NULL,
4167 .flags = FLAG_ADVANCED,
4170 .label = "idmap uid",
4171 .type = P_STRING,
4172 .p_class = P_GLOBAL,
4173 .offset = GLOBAL_VAR(szIdmapUID),
4174 .special = handle_idmap_uid,
4175 .enum_list = NULL,
4176 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4179 .label = "winbind uid",
4180 .type = P_STRING,
4181 .p_class = P_GLOBAL,
4182 .offset = GLOBAL_VAR(szIdmapUID),
4183 .special = handle_idmap_uid,
4184 .enum_list = NULL,
4185 .flags = FLAG_HIDE,
4188 .label = "idmap gid",
4189 .type = P_STRING,
4190 .p_class = P_GLOBAL,
4191 .offset = GLOBAL_VAR(szIdmapGID),
4192 .special = handle_idmap_gid,
4193 .enum_list = NULL,
4194 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4197 .label = "winbind gid",
4198 .type = P_STRING,
4199 .p_class = P_GLOBAL,
4200 .offset = GLOBAL_VAR(szIdmapGID),
4201 .special = handle_idmap_gid,
4202 .enum_list = NULL,
4203 .flags = FLAG_HIDE,
4206 .label = "template homedir",
4207 .type = P_STRING,
4208 .p_class = P_GLOBAL,
4209 .offset = GLOBAL_VAR(szTemplateHomedir),
4210 .special = NULL,
4211 .enum_list = NULL,
4212 .flags = FLAG_ADVANCED,
4215 .label = "template shell",
4216 .type = P_STRING,
4217 .p_class = P_GLOBAL,
4218 .offset = GLOBAL_VAR(szTemplateShell),
4219 .special = NULL,
4220 .enum_list = NULL,
4221 .flags = FLAG_ADVANCED,
4224 .label = "winbind separator",
4225 .type = P_STRING,
4226 .p_class = P_GLOBAL,
4227 .offset = GLOBAL_VAR(szWinbindSeparator),
4228 .special = NULL,
4229 .enum_list = NULL,
4230 .flags = FLAG_ADVANCED,
4233 .label = "winbind cache time",
4234 .type = P_INTEGER,
4235 .p_class = P_GLOBAL,
4236 .offset = GLOBAL_VAR(winbind_cache_time),
4237 .special = NULL,
4238 .enum_list = NULL,
4239 .flags = FLAG_ADVANCED,
4242 .label = "winbind reconnect delay",
4243 .type = P_INTEGER,
4244 .p_class = P_GLOBAL,
4245 .offset = GLOBAL_VAR(winbind_reconnect_delay),
4246 .special = NULL,
4247 .enum_list = NULL,
4248 .flags = FLAG_ADVANCED,
4251 .label = "winbind max clients",
4252 .type = P_INTEGER,
4253 .p_class = P_GLOBAL,
4254 .offset = GLOBAL_VAR(winbind_max_clients),
4255 .special = NULL,
4256 .enum_list = NULL,
4257 .flags = FLAG_ADVANCED,
4260 .label = "winbind enum users",
4261 .type = P_BOOL,
4262 .p_class = P_GLOBAL,
4263 .offset = GLOBAL_VAR(bWinbindEnumUsers),
4264 .special = NULL,
4265 .enum_list = NULL,
4266 .flags = FLAG_ADVANCED,
4269 .label = "winbind enum groups",
4270 .type = P_BOOL,
4271 .p_class = P_GLOBAL,
4272 .offset = GLOBAL_VAR(bWinbindEnumGroups),
4273 .special = NULL,
4274 .enum_list = NULL,
4275 .flags = FLAG_ADVANCED,
4278 .label = "winbind use default domain",
4279 .type = P_BOOL,
4280 .p_class = P_GLOBAL,
4281 .offset = GLOBAL_VAR(bWinbindUseDefaultDomain),
4282 .special = NULL,
4283 .enum_list = NULL,
4284 .flags = FLAG_ADVANCED,
4287 .label = "winbind trusted domains only",
4288 .type = P_BOOL,
4289 .p_class = P_GLOBAL,
4290 .offset = GLOBAL_VAR(bWinbindTrustedDomainsOnly),
4291 .special = NULL,
4292 .enum_list = NULL,
4293 .flags = FLAG_ADVANCED,
4296 .label = "winbind nested groups",
4297 .type = P_BOOL,
4298 .p_class = P_GLOBAL,
4299 .offset = GLOBAL_VAR(bWinbindNestedGroups),
4300 .special = NULL,
4301 .enum_list = NULL,
4302 .flags = FLAG_ADVANCED,
4305 .label = "winbind expand groups",
4306 .type = P_INTEGER,
4307 .p_class = P_GLOBAL,
4308 .offset = GLOBAL_VAR(winbind_expand_groups),
4309 .special = NULL,
4310 .enum_list = NULL,
4311 .flags = FLAG_ADVANCED,
4314 .label = "winbind nss info",
4315 .type = P_LIST,
4316 .p_class = P_GLOBAL,
4317 .offset = GLOBAL_VAR(szWinbindNssInfo),
4318 .special = NULL,
4319 .enum_list = NULL,
4320 .flags = FLAG_ADVANCED,
4323 .label = "winbind refresh tickets",
4324 .type = P_BOOL,
4325 .p_class = P_GLOBAL,
4326 .offset = GLOBAL_VAR(bWinbindRefreshTickets),
4327 .special = NULL,
4328 .enum_list = NULL,
4329 .flags = FLAG_ADVANCED,
4332 .label = "winbind offline logon",
4333 .type = P_BOOL,
4334 .p_class = P_GLOBAL,
4335 .offset = GLOBAL_VAR(bWinbindOfflineLogon),
4336 .special = NULL,
4337 .enum_list = NULL,
4338 .flags = FLAG_ADVANCED,
4341 .label = "winbind normalize names",
4342 .type = P_BOOL,
4343 .p_class = P_GLOBAL,
4344 .offset = GLOBAL_VAR(bWinbindNormalizeNames),
4345 .special = NULL,
4346 .enum_list = NULL,
4347 .flags = FLAG_ADVANCED,
4350 .label = "winbind rpc only",
4351 .type = P_BOOL,
4352 .p_class = P_GLOBAL,
4353 .offset = GLOBAL_VAR(bWinbindRpcOnly),
4354 .special = NULL,
4355 .enum_list = NULL,
4356 .flags = FLAG_ADVANCED,
4359 .label = "create krb5 conf",
4360 .type = P_BOOL,
4361 .p_class = P_GLOBAL,
4362 .offset = GLOBAL_VAR(bCreateKrb5Conf),
4363 .special = NULL,
4364 .enum_list = NULL,
4365 .flags = FLAG_ADVANCED,
4368 .label = "ncalrpc dir",
4369 .type = P_STRING,
4370 .p_class = P_GLOBAL,
4371 .offset = GLOBAL_VAR(ncalrpc_dir),
4372 .special = NULL,
4373 .enum_list = NULL,
4374 .flags = FLAG_ADVANCED,
4377 .label = "winbind max domain connections",
4378 .type = P_INTEGER,
4379 .p_class = P_GLOBAL,
4380 .offset = GLOBAL_VAR(winbindMaxDomainConnections),
4381 .special = NULL,
4382 .enum_list = NULL,
4383 .flags = FLAG_ADVANCED,
4386 .label = "winbindd socket directory",
4387 .type = P_STRING,
4388 .p_class = P_GLOBAL,
4389 .offset = GLOBAL_VAR(szWinbinddSocketDirectory),
4390 .special = NULL,
4391 .enum_list = NULL,
4392 .flags = FLAG_ADVANCED,
4395 .label = "winbindd privileged socket directory",
4396 .type = P_STRING,
4397 .p_class = P_GLOBAL,
4398 .offset = GLOBAL_VAR(szWinbinddPrivilegedSocketDirectory),
4399 .special = NULL,
4400 .enum_list = NULL,
4401 .flags = FLAG_ADVANCED,
4404 .label = "winbind sealed pipes",
4405 .type = P_BOOL,
4406 .p_class = P_GLOBAL,
4407 .offset = GLOBAL_VAR(bWinbindSealedPipes),
4408 .special = NULL,
4409 .enum_list = NULL,
4410 .flags = FLAG_ADVANCED,
4413 {N_("DNS options"), P_SEP, P_SEPARATOR},
4415 .label = "allow dns updates",
4416 .type = P_ENUM,
4417 .p_class = P_GLOBAL,
4418 .offset = GLOBAL_VAR(allow_dns_updates),
4419 .special = NULL,
4420 .enum_list = enum_dns_update_settings,
4421 .flags = FLAG_ADVANCED,
4424 .label = "dns forwarder",
4425 .type = P_STRING,
4426 .p_class = P_GLOBAL,
4427 .offset = GLOBAL_VAR(dns_forwarder),
4428 .special = NULL,
4429 .enum_list = NULL,
4430 .flags = FLAG_ADVANCED,
4433 .label = "dns recursive queries",
4434 .type = P_BOOL,
4435 .p_class = P_GLOBAL,
4436 .offset = GLOBAL_VAR(dns_recursive_queries),
4437 .special = NULL,
4438 .enum_list = NULL
4441 .label = "dns update command",
4442 .type = P_CMDLIST,
4443 .p_class = P_GLOBAL,
4444 .offset = GLOBAL_VAR(szDNSUpdateCommand),
4445 .special = NULL,
4446 .enum_list = NULL,
4447 .flags = FLAG_ADVANCED,
4450 .label = "nsupdate command",
4451 .type = P_CMDLIST,
4452 .p_class = P_GLOBAL,
4453 .offset = GLOBAL_VAR(szNSUpdateCommand),
4454 .special = NULL,
4455 .enum_list = NULL,
4456 .flags = FLAG_ADVANCED,
4459 .label = "rndc command",
4460 .type = P_CMDLIST,
4461 .p_class = P_GLOBAL,
4462 .offset = GLOBAL_VAR(szRNDCCommand),
4463 .special = NULL,
4464 .enum_list = NULL,
4465 .flags = FLAG_ADVANCED,
4468 .label = "multicast dns register",
4469 .type = P_BOOL,
4470 .p_class = P_GLOBAL,
4471 .offset = GLOBAL_VAR(bMulticastDnsRegister),
4472 .special = NULL,
4473 .enum_list = NULL,
4474 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4477 {N_("AD DC options"), P_SEP, P_SEPARATOR},
4480 .label = "samba kcc command",
4481 .type = P_CMDLIST,
4482 .p_class = P_GLOBAL,
4483 .offset = GLOBAL_VAR(szSambaKCCCommand),
4484 .special = NULL,
4485 .enum_list = NULL,
4486 .flags = FLAG_ADVANCED,
4489 .label = "server services",
4490 .type = P_LIST,
4491 .p_class = P_GLOBAL,
4492 .offset = GLOBAL_VAR(server_services),
4493 .special = NULL,
4494 .enum_list = NULL
4497 .label = "dcerpc endpoint servers",
4498 .type = P_LIST,
4499 .p_class = P_GLOBAL,
4500 .offset = GLOBAL_VAR(dcerpc_ep_servers),
4501 .special = NULL,
4502 .enum_list = NULL
4505 .label = "spn update command",
4506 .type = P_CMDLIST,
4507 .p_class = P_GLOBAL,
4508 .offset = GLOBAL_VAR(szSPNUpdateCommand),
4509 .special = NULL,
4510 .enum_list = NULL,
4511 .flags = FLAG_ADVANCED,
4514 .label = "share backend",
4515 .type = P_STRING,
4516 .p_class = P_GLOBAL,
4517 .offset = GLOBAL_VAR(szShareBackend),
4518 .special = NULL,
4519 .enum_list = NULL
4522 .label = "ntvfs handler",
4523 .type = P_LIST,
4524 .p_class = P_LOCAL,
4525 .offset = LOCAL_VAR(ntvfs_handler),
4526 .special = NULL,
4527 .enum_list = NULL
4530 {N_("TLS options"), P_SEP, P_SEPARATOR},
4533 .label = "tls enabled",
4534 .type = P_BOOL,
4535 .p_class = P_GLOBAL,
4536 .offset = GLOBAL_VAR(tls_enabled),
4537 .special = NULL,
4538 .enum_list = NULL
4541 .label = "tls keyfile",
4542 .type = P_STRING,
4543 .p_class = P_GLOBAL,
4544 .offset = GLOBAL_VAR(tls_keyfile),
4545 .special = NULL,
4546 .enum_list = NULL
4549 .label = "tls certfile",
4550 .type = P_STRING,
4551 .p_class = P_GLOBAL,
4552 .offset = GLOBAL_VAR(tls_certfile),
4553 .special = NULL,
4554 .enum_list = NULL
4557 .label = "tls cafile",
4558 .type = P_STRING,
4559 .p_class = P_GLOBAL,
4560 .offset = GLOBAL_VAR(tls_cafile),
4561 .special = NULL,
4562 .enum_list = NULL
4565 .label = "tls crlfile",
4566 .type = P_STRING,
4567 .p_class = P_GLOBAL,
4568 .offset = GLOBAL_VAR(tls_crlfile),
4569 .special = NULL,
4570 .enum_list = NULL
4573 .label = "tls dh params file",
4574 .type = P_STRING,
4575 .p_class = P_GLOBAL,
4576 .offset = GLOBAL_VAR(tls_dhpfile),
4577 .special = NULL,
4578 .enum_list = NULL
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) {
4592 case PRINT_BSD:
4593 case PRINT_AIX:
4594 case PRINT_LPRNT:
4595 case PRINT_LPROS2:
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");
4599 break;
4601 case PRINT_LPRNG:
4602 case PRINT_PLP:
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");
4610 break;
4612 case PRINT_CUPS:
4613 case PRINT_IPRINT:
4614 #ifdef HAVE_CUPS
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, "");
4624 #else
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 */
4633 break;
4635 case PRINT_SYSV:
4636 case PRINT_HPUX:
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");
4642 #ifndef HPUX
4643 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4644 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4645 #endif /* HPUX */
4646 break;
4648 case PRINT_QNX:
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");
4652 break;
4654 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4656 case PRINT_TEST:
4657 case PRINT_VLP: {
4658 const char *tdbfile;
4659 TALLOC_CTX *tmp_ctx = talloc_stackframe();
4660 char *tmp;
4662 tdbfile = talloc_asprintf(
4663 tmp_ctx, "tdbfile=%s",
4664 lp_parm_const_string(-1, "vlp", "tdbfile",
4665 "/tmp/vlp.tdb"));
4666 if (tdbfile == NULL) {
4667 tdbfile="tdbfile=/tmp/vlp.tdb";
4670 tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
4671 tdbfile);
4672 string_set(&pService->szPrintcommand,
4673 tmp ? tmp : "vlp print %p %s");
4675 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
4676 tdbfile);
4677 string_set(&pService->szLpqcommand,
4678 tmp ? tmp : "vlp lpq %p");
4680 tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
4681 tdbfile);
4682 string_set(&pService->szLprmcommand,
4683 tmp ? tmp : "vlp lprm %p %j");
4685 tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
4686 tdbfile);
4687 string_set(&pService->szLppausecommand,
4688 tmp ? tmp : "vlp lppause %p %j");
4690 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
4691 tdbfile);
4692 string_set(&pService->szLpresumecommand,
4693 tmp ? tmp : "vlp lpresume %p %j");
4695 tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
4696 tdbfile);
4697 string_set(&pService->szQueuepausecommand,
4698 tmp ? tmp : "vlp queuepause %p");
4700 tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
4701 tdbfile);
4702 string_set(&pService->szQueueresumecommand,
4703 tmp ? tmp : "vlp queueresume %p");
4704 TALLOC_FREE(tmp_ctx);
4706 break;
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,
4729 #endif
4731 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4733 struct rlimit rl;
4735 ZERO_STRUCT(rl);
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;
4743 #endif
4745 #endif
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",
4750 sysctl_max,
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",
4758 rlimit_max,
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)
4788 void *parm_ptr;
4790 if (parm.p_class != P_LOCAL) {
4791 return;
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)
4805 uint32_t i;
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)
4818 void *parm_ptr;
4820 if (snum < 0) {
4821 parm_ptr = lp_parm_ptr(NULL, &parm);
4822 } else if (parm.p_class != P_LOCAL) {
4823 return;
4824 } else {
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
4833 * by an snum.
4835 static void free_parameters_by_snum(int snum)
4837 uint32_t i;
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;
4857 const char *label;
4858 const char *value;
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);
4875 talloc_free(entry);
4876 break;
4880 entry = talloc(NULL, struct lp_stored_option);
4881 if (!entry) {
4882 return false;
4885 entry->label = talloc_strdup(entry, pszParmName);
4886 if (!entry->label) {
4887 talloc_free(entry);
4888 return false;
4891 entry->value = talloc_strdup(entry, pszParmValue);
4892 if (!entry->value) {
4893 talloc_free(entry);
4894 return false;
4897 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
4899 return true;
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));
4909 return false;
4912 return true;
4915 /***************************************************************************
4916 Initialise the global parameter structure.
4917 ***************************************************************************/
4919 static void init_globals(bool reinit_globals)
4921 static bool done_init = false;
4922 char *s = NULL;
4923 int i;
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 */
4928 return;
4931 if (!done_init) {
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;
4937 done_init = true;
4938 } else {
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
4998 * addresses.
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);
5006 SAFE_FREE(s);
5007 #ifdef DEVELOPER
5008 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5009 #endif
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;
5055 Globals.syslog = 1;
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");
5075 #else
5076 string_set(&Globals.szNISHomeMapName, "auto.home");
5077 #endif
5078 #endif
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;
5103 #else
5104 Globals.bUseMmap = true;
5105 #endif
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);
5183 #else
5184 string_set(&Globals.ctdbdSocket, "");
5185 #endif
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);
5230 SAFE_FREE(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)
5267 char *ret;
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? */
5274 #if 0
5275 DEBUG(10, ("lp_string(%s)\n", s));
5276 #endif
5277 if (!s) {
5278 return NULL;
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) {
5287 TALLOC_FREE(ret);
5288 ret = talloc_sub_basic(ctx,
5289 get_current_username(),
5290 current_user_info.domain,
5294 return ret;
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) : "");
5346 else
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) : "");
5355 else
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"));
5368 return 1;
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)
5382 int result = 0;
5383 #ifdef HAVE_HTTPCONNECTENCRYPT
5384 switch (Globals.CupsEncrypt) {
5385 case Auto:
5386 result = HTTP_ENCRYPT_REQUIRED;
5387 break;
5388 case true:
5389 result = HTTP_ENCRYPT_ALWAYS;
5390 break;
5391 case false:
5392 result = HTTP_ENCRYPT_NEVER;
5393 break;
5395 #endif
5396 return result;
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,
5420 void *userdata);
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,
5434 const char *option)
5436 bool global_section = false;
5437 char* param_key;
5438 struct parmlist_entry *data;
5440 if (service == NULL) {
5441 data = Globals.param_opt;
5442 global_section = true;
5443 } else {
5444 data = service->param_opt;
5447 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5448 DEBUG(0,("asprintf failed!\n"));
5449 return NULL;
5452 while (data) {
5453 if (strwicmp(data->key, param_key) == 0) {
5454 string_free(&param_key);
5455 return data;
5457 data = data->next;
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;
5464 while (data) {
5465 if (strwicmp(data->key, param_key) == 0) {
5466 string_free(&param_key);
5467 return data;
5469 data = data->next;
5473 string_free(&param_key);
5475 return NULL;
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,
5484 const char *option)
5486 if (snum >= iNumServices) return NULL;
5488 if (snum < 0) {
5489 return get_parametrics_by_service(NULL, type, option);
5490 } else {
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)
5505 if (!s || !*s) {
5506 MISSING_PARAMETER(lp_int);
5507 return (-1);
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)
5519 if (!s || !*s) {
5520 MISSING_PARAMETER(lp_ulong);
5521 return (0);
5524 return strtoul(s, NULL, 0);
5527 /*******************************************************************
5528 convenience routine to return boolean parameters.
5529 ********************************************************************/
5530 static bool lp_bool(const char *s)
5532 bool ret = false;
5534 if (!s || !*s) {
5535 MISSING_PARAMETER(lp_bool);
5536 return false;
5539 if (!set_boolean(s, &ret)) {
5540 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5541 return false;
5544 return ret;
5547 /*******************************************************************
5548 convenience routine to return enum parameters.
5549 ********************************************************************/
5550 static int lp_enum(const char *s,const struct enum_list *_enum)
5552 int i;
5554 if (!s || !*s || !_enum) {
5555 MISSING_PARAMETER(lp_enum);
5556 return (-1);
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));
5565 return (-1);
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) {
5577 if (def) {
5578 return lp_string(ctx, def);
5579 } else {
5580 return NULL;
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)
5594 return def;
5596 return data->value;
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)
5604 return NULL;
5606 return data->value;
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);
5637 return def;
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);
5650 return def;
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);
5663 return def;
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);
5677 return def;
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) {
5703 return;
5706 if (*popts != NULL) {
5707 DEBUG(5, ("Freeing parametrics:\n"));
5709 opt = *popts;
5710 while (opt != NULL) {
5711 string_free(&opt->key);
5712 string_free(&opt->value);
5713 TALLOC_FREE(opt->list);
5714 next_opt = opt->next;
5715 SAFE_FREE(opt);
5716 opt = next_opt;
5718 *popts = NULL;
5721 /***************************************************************************
5722 Free the dynamically allocated parts of a service struct.
5723 ***************************************************************************/
5725 static void free_service(struct loadparm_service *pservice)
5727 if (!pservice)
5728 return;
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) )
5753 return;
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(
5762 talloc_tos(),
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
5774 service.
5775 ***************************************************************************/
5777 static int add_a_service(const struct loadparm_service *pservice, const char *name)
5779 int i;
5780 struct loadparm_service tservice;
5781 int num_to_alloc = iNumServices + 1;
5783 tservice = *pservice;
5785 /* it might already exist */
5786 if (name) {
5787 i = getservicebyname(name, NULL);
5788 if (i >= 0) {
5789 return (i);
5793 /* find an invalid one */
5794 i = iNumServices;
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;
5802 int *tinvalid;
5804 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
5805 if (tsp == NULL) {
5806 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5807 return (-1);
5809 ServicePtrs = tsp;
5810 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct loadparm_service);
5811 if (!ServicePtrs[iNumServices]) {
5812 DEBUG(0,("add_a_service: out of memory!\n"));
5813 return (-1);
5815 iNumServices++;
5817 /* enlarge invalid_services here for now... */
5818 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5819 num_to_alloc);
5820 if (tinvalid == NULL) {
5821 DEBUG(0,("add_a_service: failed to enlarge "
5822 "invalid_services!\n"));
5823 return (-1);
5825 invalid_services = tinvalid;
5826 } else {
5827 free_service_byindex(i);
5830 ServicePtrs[i]->valid = true;
5832 init_service(ServicePtrs[i]);
5833 copy_service(ServicePtrs[i], &tservice, NULL);
5834 if (name)
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)) {
5841 return (-1);
5844 return (i);
5847 /***************************************************************************
5848 Convert a string to uppercase and remove whitespaces.
5849 ***************************************************************************/
5851 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
5853 char *result;
5855 if ( !src ) {
5856 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5857 return NULL;
5860 result = talloc_strdup(ctx, src);
5861 SMB_ASSERT(result != NULL);
5863 strlower_m(result);
5864 return result;
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)
5873 char *canon_name;
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"));
5880 return false;
5884 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5885 idx, name));
5887 canon_name = canonicalize_servicename(talloc_tos(), name );
5889 dbwrap_store_bystring(ServiceHash, canon_name,
5890 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5891 TDB_REPLACE);
5893 TALLOC_FREE(canon_name);
5895 return true;
5898 /***************************************************************************
5899 Add a new home service, with the specified home directory, defaults coming
5900 from service ifrom.
5901 ***************************************************************************/
5903 bool lp_add_home(const char *pszHomename, int iDefaultService,
5904 const char *user, const char *pszHomedir)
5906 int i;
5908 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
5909 pszHomedir[0] == '\0') {
5910 return false;
5913 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5915 if (i < 0)
5916 return false;
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) {
5927 return false;
5929 string_set(&ServicePtrs[i]->comment, comment);
5930 SAFE_FREE(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 ));
5943 return true;
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);
5968 if (i < 0)
5969 return false;
5971 if (asprintf(&comment, "IPC Service (%s)",
5972 Globals.szServerString) < 0) {
5973 return false;
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"));
5991 SAFE_FREE(comment);
5992 return true;
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);
6004 if (i < 0)
6005 return false;
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));
6030 return true;
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);
6056 if (num >= 0) {
6057 return (parm_table[num].p_class == P_GLOBAL);
6060 return false;
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)) {
6072 return false;
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
6082 "usual" synonym.
6083 **************************************************************************/
6085 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6086 bool *inverse)
6088 int num;
6090 if (!lp_parameter_is_valid(parm_name)) {
6091 *canon_parm = NULL;
6092 return false;
6095 num = map_parameter_canonical(parm_name, inverse);
6096 if (num < 0) {
6097 /* parametric option */
6098 *canon_parm = parm_name;
6099 } else {
6100 *canon_parm = parm_table[num].label;
6103 return true;
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,
6119 const char *val,
6120 const char **canon_parm,
6121 const char **canon_val)
6123 int num;
6124 bool inverse;
6126 if (!lp_parameter_is_valid(parm_name)) {
6127 *canon_parm = NULL;
6128 *canon_val = NULL;
6129 return false;
6132 num = map_parameter_canonical(parm_name, &inverse);
6133 if (num < 0) {
6134 /* parametric option */
6135 *canon_parm = parm_name;
6136 *canon_val = val;
6137 } else {
6138 *canon_parm = parm_table[num].label;
6139 if (inverse) {
6140 if (!lp_invert_boolean(val, canon_val)) {
6141 *canon_val = NULL;
6142 return false;
6144 } else {
6145 *canon_val = val;
6149 return true;
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)
6159 int iIndex;
6161 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6162 return (-1);
6164 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6165 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6166 return (iIndex);
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
6174 return (-1);
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 ... */
6191 goto done;
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;
6197 goto done;
6201 done:
6202 if (inverse != NULL) {
6203 *inverse = loc_inverse;
6205 return parm_num;
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,
6212 false otherwise.
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))
6226 *inverse = true;
6227 } else {
6228 *inverse = false;
6231 return true;
6233 return false;
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;
6244 int parmIndex2;
6245 bool hadFlag;
6246 bool hadSyn;
6247 bool inverse;
6248 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6249 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6250 "P_ENUM", "P_SEP"};
6251 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6252 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6253 FLAG_HIDE};
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) {
6261 printf(",");
6262 for (enumIndex=0;
6263 parm_table[parmIndex].enum_list[enumIndex].name;
6264 enumIndex++)
6266 printf("%s%s",
6267 enumIndex ? "|" : "",
6268 parm_table[parmIndex].enum_list[enumIndex].name);
6271 printf(",");
6272 hadFlag = false;
6273 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6274 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6275 printf("%s%s",
6276 hadFlag ? "|" : "",
6277 flag_names[flagIndex]);
6278 hadFlag = true;
6282 /* output synonyms */
6283 hadSyn = false;
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)) {
6289 if (!hadSyn) {
6290 printf(" (synonyms: ");
6291 hadSyn = true;
6292 } else {
6293 printf(", ");
6295 printf("%s%s", parm_table[parmIndex2].label,
6296 inverse ? "[i]" : "");
6299 if (hadSyn) {
6300 printf(")");
6303 printf("\n");
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)
6354 bool val;
6356 if (!set_boolean(str, &val)) {
6357 return false;
6360 *inverse_str = get_boolean(!val);
6361 return true;
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)
6372 bool val;
6374 if (!set_boolean(str, &val)) {
6375 return false;
6378 *canon_str = get_boolean(val);
6379 return true;
6382 /***************************************************************************
6383 Find a service by name. Otherwise works like get_service.
6384 ***************************************************************************/
6386 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
6388 int iService = -1;
6389 char *canon_name;
6390 TDB_DATA data;
6391 NTSTATUS status;
6393 if (ServiceHash == NULL) {
6394 return -1;
6397 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6399 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
6400 &data);
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);
6416 return (iService);
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)) {
6424 return NULL;
6426 return ServicePtrs[iService];
6429 struct loadparm_service *lp_servicebynum(int snum)
6431 if ((snum == -1) || !LP_SNUM_OK(snum)) {
6432 return NULL;
6434 return ServicePtrs[snum];
6437 struct loadparm_service *lp_default_loadparm_service()
6439 return &sDefault;
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,
6455 unsigned priority)
6457 struct parmlist_entry *new_opt, *opt;
6458 bool not_added;
6460 if (opt_list == NULL) {
6461 return;
6464 opt = *opt_list;
6465 not_added = true;
6467 /* Traverse destination */
6468 while (opt) {
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
6474 overridden */
6475 return;
6477 string_free(&opt->value);
6478 TALLOC_FREE(opt->list);
6479 opt->value = SMB_STRDUP(opt_value);
6480 opt->priority = priority;
6481 not_added = false;
6482 break;
6484 opt = opt->next;
6486 if (not_added) {
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)
6499 int i;
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) {
6510 case P_BOOL:
6511 case P_BOOLREV:
6512 *(bool *)dest_ptr = *(bool *)src_ptr;
6513 break;
6515 case P_INTEGER:
6516 case P_ENUM:
6517 case P_OCTAL:
6518 case P_BYTES:
6519 *(int *)dest_ptr = *(int *)src_ptr;
6520 break;
6522 case P_CHAR:
6523 *(char *)dest_ptr = *(char *)src_ptr;
6524 break;
6526 case P_STRING:
6527 string_set((char **)dest_ptr,
6528 *(char **)src_ptr);
6529 break;
6531 case P_USTRING:
6533 char *upper_string = strupper_talloc(talloc_tos(),
6534 *(char **)src_ptr);
6535 string_set((char **)dest_ptr,
6536 upper_string);
6537 TALLOC_FREE(upper_string);
6538 break;
6540 case P_LIST:
6541 TALLOC_FREE(*((char ***)dest_ptr));
6542 *((char ***)dest_ptr) = str_list_copy(NULL,
6543 *(const char ***)src_ptr);
6544 break;
6545 default:
6546 break;
6550 if (bcopyall) {
6551 init_copymap(pserviceDest);
6552 if (pserviceSource->copymap)
6553 bitmap_copy(pserviceDest->copymap,
6554 pserviceSource->copymap);
6557 data = pserviceSource->param_opt;
6558 while (data) {
6559 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
6560 data = data->next;
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)
6571 bool bRetval;
6573 bRetval = true;
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"));
6577 bRetval = false;
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));
6607 return (bRetval);
6610 static struct smbconf_ctx *lp_smbconf_ctx(void)
6612 sbcErr err;
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)));
6620 conf_ctx = NULL;
6624 return conf_ctx;
6627 static bool process_smbconf_service(struct smbconf_service *service)
6629 uint32_t count;
6630 bool ret;
6632 if (service == NULL) {
6633 return false;
6636 ret = do_section(service->name, NULL);
6637 if (ret != true) {
6638 return false;
6640 for (count = 0; count < service->num_params; count++) {
6641 ret = do_parameter(service->param_names[count],
6642 service->param_values[count],
6643 NULL);
6644 if (ret != true) {
6645 return false;
6648 if (iServiceIndex >= 0) {
6649 return service_ok(iServiceIndex);
6651 return true;
6655 * load a service from registry and activate it
6657 bool process_registry_service(const char *service_name)
6659 sbcErr err;
6660 struct smbconf_service *service = NULL;
6661 TALLOC_CTX *mem_ctx = talloc_stackframe();
6662 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6663 bool ret = false;
6665 if (conf_ctx == NULL) {
6666 goto done;
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.
6676 ret = true;
6677 goto done;
6680 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6681 if (!SBC_ERROR_IS_OK(err)) {
6682 goto done;
6685 ret = process_smbconf_service(service);
6686 if (!ret) {
6687 goto done;
6690 /* store the csn */
6691 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6693 done:
6694 TALLOC_FREE(mem_ctx);
6695 return ret;
6699 * process_registry_globals
6701 static bool process_registry_globals(void)
6703 bool ret;
6705 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6707 ret = do_parameter("registry shares", "yes", NULL);
6708 if (!ret) {
6709 return ret;
6712 return process_registry_service(GLOBAL_NAME);
6715 bool process_registry_shares(void)
6717 sbcErr err;
6718 uint32_t count;
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();
6723 bool ret = false;
6725 if (conf_ctx == NULL) {
6726 goto done;
6729 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6730 if (!SBC_ERROR_IS_OK(err)) {
6731 goto done;
6734 ret = true;
6736 for (count = 0; count < num_shares; count++) {
6737 if (strequal(service[count]->name, GLOBAL_NAME)) {
6738 continue;
6740 ret = process_smbconf_service(service[count]);
6741 if (!ret) {
6742 goto done;
6746 /* store the csn */
6747 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6749 done:
6750 TALLOC_FREE(mem_ctx);
6751 return ret;
6755 * reload those shares from registry that are already
6756 * activated in the services array.
6758 static bool reload_registry_shares(void)
6760 int i;
6761 bool ret = true;
6763 for (i = 0; i < iNumServices; i++) {
6764 if (!VALID(i)) {
6765 continue;
6768 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
6769 continue;
6772 ret = process_registry_service(ServicePtrs[i]->szService);
6773 if (!ret) {
6774 goto done;
6778 done:
6779 return ret;
6783 #define MAX_INCLUDE_DEPTH 100
6785 static uint8_t include_depth;
6787 static struct file_lists {
6788 struct file_lists *next;
6789 char *name;
6790 char *subfname;
6791 time_t modtime;
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;
6803 while (f) {
6804 if (f->name && !strcmp(f->name, fname))
6805 break;
6806 f = f->next;
6809 if (!f) {
6810 f = SMB_MALLOC_P(struct file_lists);
6811 if (!f)
6812 return;
6813 f->next = file_lists;
6814 f->name = SMB_STRDUP(fname);
6815 if (!f->name) {
6816 SAFE_FREE(f);
6817 return;
6819 f->subfname = SMB_STRDUP(subfname);
6820 if (!f->subfname) {
6821 SAFE_FREE(f->name);
6822 SAFE_FREE(f);
6823 return;
6825 file_lists = f;
6826 f->modtime = file_modtime(subfname);
6827 } else {
6828 time_t t = file_modtime(subfname);
6829 if (t)
6830 f->modtime = t;
6832 return;
6836 * Free the file lists
6838 static void free_file_list(void)
6840 struct file_lists *f;
6841 struct file_lists *next;
6843 f = file_lists;
6844 while( f ) {
6845 next = f->next;
6846 SAFE_FREE( f->name );
6847 SAFE_FREE( f->subfname );
6848 SAFE_FREE( f );
6849 f = next;
6851 file_lists = NULL;
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"));
6881 while (f) {
6882 time_t mod_time;
6884 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
6885 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6887 if (conf_ctx == NULL) {
6888 return false;
6890 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
6891 NULL))
6893 DEBUGADD(6, ("registry config changed\n"));
6894 return true;
6896 } else {
6897 char *n2 = NULL;
6898 n2 = talloc_sub_basic(talloc_tos(),
6899 get_current_username(),
6900 current_user_info.domain,
6901 f->name);
6902 if (!n2) {
6903 return false;
6905 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6906 f->name, n2, ctime(&f->modtime)));
6908 mod_time = file_modtime(n2);
6910 if (mod_time &&
6911 ((f->modtime != mod_time) ||
6912 (f->subfname == NULL) ||
6913 (strcmp(n2, f->subfname) != 0)))
6915 DEBUGADD(6,
6916 ("file %s modified: %s\n", n2,
6917 ctime(&mod_time)));
6918 f->modtime = mod_time;
6919 SAFE_FREE(f->subfname);
6920 f->subfname = SMB_STRDUP(n2);
6921 TALLOC_FREE(n2);
6922 return true;
6924 TALLOC_FREE(n2);
6926 f = f->next;
6928 return false;
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(),
6942 lp_unix_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);
6950 init_iconv();
6952 return true;
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')) {
6966 if (len == 4) {
6967 if (pszParmValue[3] == '8') {
6968 is_utf8 = true;
6970 } else {
6971 if (pszParmValue[3] == '-' &&
6972 pszParmValue[4] == '8') {
6973 is_utf8 = true;
6979 if (strcmp(*ptr, pszParmValue) != 0) {
6980 if (is_utf8) {
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);
6987 init_iconv();
6989 return true;
6992 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6994 bool ret = true;
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);
7001 TALLOC_FREE(realm);
7003 return ret;
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)
7020 char *fname;
7022 if (include_depth >= MAX_INCLUDE_DEPTH) {
7023 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7024 include_depth));
7025 return false;
7028 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7029 if (!bAllowIncludeRegistry) {
7030 return true;
7032 if (bInGlobalSection) {
7033 bool ret;
7034 include_depth++;
7035 ret = process_registry_globals();
7036 include_depth--;
7037 return ret;
7038 } else {
7039 DEBUG(1, ("\"include = registry\" only effective "
7040 "in %s section\n", GLOBAL_NAME));
7041 return false;
7045 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7046 current_user_info.domain,
7047 pszParmValue);
7049 add_to_file_list(pszParmValue, fname);
7051 string_set(ptr, fname);
7053 if (file_exist(fname)) {
7054 bool ret;
7055 include_depth++;
7056 ret = pm_process(fname, do_section, do_parameter, NULL);
7057 include_depth--;
7058 TALLOC_FREE(fname);
7059 return ret;
7062 DEBUG(2, ("Can't find include file %s\n", fname));
7063 TALLOC_FREE(fname);
7064 return true;
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)
7073 bool bRetval;
7074 int iTemp;
7075 struct loadparm_service serviceTemp;
7077 string_set(ptr, pszParmValue);
7079 init_service(&serviceTemp);
7081 bRetval = false;
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));
7088 } else {
7089 copy_service(ServicePtrs[iServiceIndex],
7090 &serviceTemp,
7091 ServicePtrs[iServiceIndex]->copymap);
7092 bRetval = true;
7094 } else {
7095 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7096 bRetval = false;
7099 free_service(&serviceTemp);
7100 return (bRetval);
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();
7107 return true;
7110 /***************************************************************************
7111 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7112 parameters is:
7114 [global]
7116 idmap uid = 1000-1999
7117 idmap gid = 700-899
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)
7132 return false;
7134 if (low)
7135 *low = idmap_uid_low;
7137 if (high)
7138 *high = idmap_uid_high;
7140 return true;
7143 bool lp_idmap_gid(gid_t *low, gid_t *high)
7145 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7146 return false;
7148 if (low)
7149 *low = idmap_gid_low;
7151 if (high)
7152 *high = idmap_gid_high;
7154 return true;
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);
7161 return true;
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);
7170 return true;
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);
7177 return true;
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"));
7202 return "";
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,
7245 int *ptr )
7247 int i;
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;
7252 return;
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 );
7272 if ( snum < 0 )
7273 s = &sDefault;
7274 else
7275 s = ServicePtrs[snum];
7277 init_printer_values( s );
7279 return true;
7283 /***************************************************************************
7284 Initialise a copymap.
7285 ***************************************************************************/
7287 static void init_copymap(struct loadparm_service *pservice)
7289 int i;
7291 TALLOC_FREE(pservice->copymap);
7293 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7294 if (!pservice->copymap)
7295 DEBUG(0,
7296 ("Couldn't allocate copymap!! (size %d)\n",
7297 (int)NUMPARAMETERS));
7298 else
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);
7313 else return NULL;
7314 } else {
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)
7335 int parmnum, i;
7336 void *parm_ptr = NULL; /* where we are going to store the result */
7337 struct parmlist_entry **opt_list;
7339 parmnum = map_parameter(pszParmName);
7341 if (parmnum < 0) {
7342 if (strchr(pszParmName, ':') == NULL) {
7343 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7344 pszParmName));
7345 return true;
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);
7356 return true;
7359 /* if it's already been set by the command line, then we don't
7360 override here */
7361 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7362 return true;
7365 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7366 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7367 pszParmName));
7370 /* we might point at a service, the default service or a global */
7371 if (snum < 0) {
7372 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
7373 } else {
7374 if (parm_table[parmnum].p_class == P_GLOBAL) {
7375 DEBUG(0,
7376 ("Global parameter %s found in service section!\n",
7377 pszParmName));
7378 return true;
7380 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
7383 if (snum >= 0) {
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,
7400 (char **)parm_ptr);
7403 /* now switch on the type of variable it is */
7404 switch (parm_table[parmnum].type)
7406 case P_BOOL:
7407 *(bool *)parm_ptr = lp_bool(pszParmValue);
7408 break;
7410 case P_BOOLREV:
7411 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7412 break;
7414 case P_INTEGER:
7415 *(int *)parm_ptr = lp_int(pszParmValue);
7416 break;
7418 case P_CHAR:
7419 *(char *)parm_ptr = *pszParmValue;
7420 break;
7422 case P_OCTAL:
7423 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7424 if ( i != 1 ) {
7425 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7427 break;
7429 case P_BYTES:
7431 uint64_t val;
7432 if (conv_str_size_error(pszParmValue, &val)) {
7433 if (val <= INT_MAX) {
7434 *(int *)parm_ptr = (int)val;
7435 break;
7439 DEBUG(0,("lp_do_parameter(%s): value is not "
7440 "a valid size specifier!\n", pszParmValue));
7441 return false;
7444 case P_LIST:
7445 case P_CMDLIST:
7446 TALLOC_FREE(*((char ***)parm_ptr));
7447 *(char ***)parm_ptr = str_list_make_v3(
7448 NULL, pszParmValue, NULL);
7449 break;
7451 case P_STRING:
7452 string_set((char **)parm_ptr, pszParmValue);
7453 break;
7455 case P_USTRING:
7457 char *upper_string = strupper_talloc(talloc_tos(),
7458 pszParmValue);
7459 string_set((char **)parm_ptr, upper_string);
7460 TALLOC_FREE(upper_string);
7461 break;
7463 case P_ENUM:
7464 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7465 break;
7466 case P_SEP:
7467 break;
7470 return true;
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)
7480 int parmnum, i;
7481 parmnum = map_parameter(pszParmName);
7482 if (parmnum >= 0) {
7483 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7484 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7485 return false;
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
7491 * whole table */
7492 for (i=parmnum-1;
7493 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
7494 && parm_table[i].p_class == parm_table[parmnum].p_class;
7495 i--) {
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;
7503 if (store_values) {
7504 store_lp_set_cmdline(pszParmName, pszParmValue);
7506 return true;
7509 /* it might be parametric */
7510 if (strchr(pszParmName, ':') != NULL) {
7511 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7512 if (store_values) {
7513 store_lp_set_cmdline(pszParmName, pszParmValue);
7515 return true;
7518 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7519 return true;
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,
7532 void *userdata)
7534 if (!bInGlobalSection && bGlobalOnly)
7535 return true;
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)
7548 char *p, *s;
7549 bool ret;
7551 s = talloc_strdup(NULL, option);
7552 if (!s) {
7553 return false;
7556 p = strchr(s, '=');
7557 if (!p) {
7558 talloc_free(s);
7559 return false;
7562 *p = 0;
7564 /* skip white spaces after the = sign */
7565 do {
7566 p++;
7567 } while (*p == ' ');
7569 ret = lp_set_cmdline(s, p);
7570 talloc_free(s);
7571 return ret;
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 = ", ";
7582 int i;
7583 switch (p->type)
7585 case P_ENUM:
7586 for (i = 0; p->enum_list[i].name; i++) {
7587 if (*(int *)ptr == p->enum_list[i].value) {
7588 fprintf(f, "%s",
7589 p->enum_list[i].name);
7590 break;
7593 break;
7595 case P_BOOL:
7596 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7597 break;
7599 case P_BOOLREV:
7600 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7601 break;
7603 case P_INTEGER:
7604 case P_BYTES:
7605 fprintf(f, "%d", *(int *)ptr);
7606 break;
7608 case P_CHAR:
7609 fprintf(f, "%c", *(char *)ptr);
7610 break;
7612 case P_OCTAL: {
7613 int val = *(int *)ptr;
7614 if (val == -1) {
7615 fprintf(f, "-1");
7616 } else {
7617 fprintf(f, "0%o", val);
7619 break;
7622 case P_CMDLIST:
7623 list_sep = " ";
7624 /* fall through */
7625 case P_LIST:
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 */
7632 list_sep = "";
7634 if ( strchr_m( *list, ' ' ) ) {
7635 fprintf(f, "\"%s\"%s", *list, list_sep);
7636 } else {
7637 fprintf(f, "%s%s", *list, list_sep);
7641 break;
7643 case P_STRING:
7644 case P_USTRING:
7645 if (*(char **)ptr) {
7646 fprintf(f, "%s", *(char **)ptr);
7648 break;
7649 case P_SEP:
7650 break;
7654 /***************************************************************************
7655 Check if two parameters are equal.
7656 ***************************************************************************/
7658 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7660 switch (type) {
7661 case P_BOOL:
7662 case P_BOOLREV:
7663 return (*((bool *)ptr1) == *((bool *)ptr2));
7665 case P_INTEGER:
7666 case P_ENUM:
7667 case P_OCTAL:
7668 case P_BYTES:
7669 return (*((int *)ptr1) == *((int *)ptr2));
7671 case P_CHAR:
7672 return (*((char *)ptr1) == *((char *)ptr2));
7674 case P_LIST:
7675 case P_CMDLIST:
7676 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7678 case P_STRING:
7679 case P_USTRING:
7681 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7682 if (p1 && !*p1)
7683 p1 = NULL;
7684 if (p2 && !*p2)
7685 p2 = NULL;
7686 return (p1 == p2 || strequal(p1, p2));
7688 case P_SEP:
7689 break;
7691 return false;
7694 /***************************************************************************
7695 Initialize any local varients in the sDefault table.
7696 ***************************************************************************/
7698 void init_locals(void)
7700 /* None as yet. */
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)
7711 bool bRetval;
7712 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7713 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7714 bRetval = false;
7716 /* if we were in a global section then do the local inits */
7717 if (bInGlobalSection && !isglobal)
7718 init_locals();
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));
7726 return true;
7729 if (!bInGlobalSection && bGlobalOnly)
7730 return true;
7732 /* if we have a current service, tidy it up before moving on */
7733 bRetval = true;
7735 if (iServiceIndex >= 0)
7736 bRetval = service_ok(iServiceIndex);
7738 /* if all is still well, move to the next record in the services array */
7739 if (bRetval) {
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"));
7747 return false;
7749 /* Clean all parametric options for service */
7750 /* They will be added during parsing again */
7751 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
7754 return bRetval;
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)
7765 return false;
7766 switch (parm_table[i].type) {
7767 case P_LIST:
7768 case P_CMDLIST:
7769 return str_list_equal((const char **)parm_table[i].def.lvalue,
7770 *(const char ***)lp_parm_ptr(NULL,
7771 &parm_table[i]));
7772 case P_STRING:
7773 case P_USTRING:
7774 return strequal(parm_table[i].def.svalue,
7775 *(char **)lp_parm_ptr(NULL,
7776 &parm_table[i]));
7777 case P_BOOL:
7778 case P_BOOLREV:
7779 return parm_table[i].def.bvalue ==
7780 *(bool *)lp_parm_ptr(NULL,
7781 &parm_table[i]);
7782 case P_CHAR:
7783 return parm_table[i].def.cvalue ==
7784 *(char *)lp_parm_ptr(NULL,
7785 &parm_table[i]);
7786 case P_INTEGER:
7787 case P_OCTAL:
7788 case P_ENUM:
7789 case P_BYTES:
7790 return parm_table[i].def.ivalue ==
7791 *(int *)lp_parm_ptr(NULL,
7792 &parm_table[i]);
7793 case P_SEP:
7794 break;
7796 return false;
7799 /***************************************************************************
7800 Display the contents of the global structure.
7801 ***************************************************************************/
7803 static void dump_globals(FILE *f)
7805 int i;
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))
7815 continue;
7816 fprintf(f, "\t%s = ", parm_table[i].label);
7817 print_parameter(&parm_table[i], lp_parm_ptr(NULL,
7818 &parm_table[i]),
7820 fprintf(f, "\n");
7822 if (Globals.param_opt != NULL) {
7823 data = Globals.param_opt;
7824 while(data) {
7825 fprintf(f, "\t%s = %s\n", data->key, data->value);
7826 data = data->next;
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)
7849 int i;
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))
7864 continue;
7865 } else {
7866 if (equal_parameter(parm_table[i].type,
7867 lp_parm_ptr(pService, &parm_table[i]),
7868 lp_parm_ptr(NULL, &parm_table[i])))
7869 continue;
7872 fprintf(f, "\t%s = ", parm_table[i].label);
7873 print_parameter(&parm_table[i],
7874 lp_parm_ptr(pService, &parm_table[i]),
7876 fprintf(f, "\n");
7880 if (pService->param_opt != NULL) {
7881 data = pService->param_opt;
7882 while(data) {
7883 fprintf(f, "\t%s = %s\n", data->key, data->value);
7884 data = data->next;
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)
7895 int i;
7896 bool result = false;
7897 parm_class p_class;
7898 unsigned flag = 0;
7899 fstring local_parm_name;
7900 char *parm_opt;
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, ':');
7907 if (parm_opt) {
7908 *parm_opt = '\0';
7909 parm_opt++;
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);
7915 result = true;
7918 return result;
7921 /* check for a key and print the value */
7922 if (isGlobal) {
7923 p_class = P_GLOBAL;
7924 flag = FLAG_GLOBAL;
7925 } else
7926 p_class = P_LOCAL;
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)))
7935 void *ptr;
7937 if (isGlobal) {
7938 ptr = lp_parm_ptr(NULL,
7939 &parm_table[i]);
7940 } else {
7941 ptr = lp_parm_ptr(ServicePtrs[snum],
7942 &parm_table[i]);
7945 print_parameter(&parm_table[i],
7946 ptr, f);
7947 fprintf(f, "\n");
7948 result = true;
7949 break;
7953 return result;
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);
7965 if (num < 0) {
7966 return NULL;
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)
7980 if (snum < 0) {
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 == '-'))
7987 continue;
7989 if ((*i) > 0
7990 && (parm_table[*i].offset ==
7991 parm_table[(*i) - 1].offset)
7992 && (parm_table[*i].p_class ==
7993 parm_table[(*i) - 1].p_class))
7994 continue;
7996 if (is_default(*i) && !allparameters)
7997 continue;
7999 return &parm_table[(*i)++];
8001 } else {
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 != '-') &&
8010 ((*i) == 0 ||
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,
8017 &parm_table[*i]),
8018 lp_parm_ptr(NULL,
8019 &parm_table[*i])))
8021 return &parm_table[(*i)++];
8027 return NULL;
8031 #if 0
8032 /***************************************************************************
8033 Display the contents of a single copy structure.
8034 ***************************************************************************/
8035 static void dump_copy_map(bool *pcopymap)
8037 int i;
8038 if (!pcopymap)
8039 return;
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);
8051 #endif
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)
8068 char *s;
8069 char *p;
8070 int homes;
8071 char *saveptr;
8073 if (!str)
8074 return;
8076 s = SMB_STRDUP(str);
8077 if (!s)
8078 return;
8080 homes = lp_servicenumber(HOMES_NAME);
8082 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8083 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8084 char *home;
8086 if (lp_servicenumber(p) >= 0)
8087 continue;
8089 home = get_user_home_dir(talloc_tos(), p);
8091 if (home && home[0] && homes >= 0)
8092 lp_add_home(p, homes, p, home);
8094 TALLOC_FREE(home);
8096 SAFE_FREE(s);
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);
8107 int i;
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)
8124 return (bLoaded);
8127 /***************************************************************************
8128 Unload unused services.
8129 ***************************************************************************/
8131 void lp_killunused(struct smbd_server_connection *sconn,
8132 bool (*snumused) (struct smbd_server_connection *, int))
8134 int i;
8135 for (i = 0; i < iNumServices; i++) {
8136 if (!VALID(i))
8137 continue;
8139 /* don't kill autoloaded or usershare services */
8140 if ( ServicePtrs[i]->autoloaded ||
8141 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8142 continue;
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 /***************************************************************************
8160 Unload a service.
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)
8178 int i;
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)
8182 continue;
8183 switch (parm_table[i].type) {
8184 case P_LIST:
8185 case P_CMDLIST:
8186 parm_table[i].def.lvalue = str_list_copy(
8187 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
8188 break;
8189 case P_STRING:
8190 case P_USTRING:
8191 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
8192 break;
8193 case P_BOOL:
8194 case P_BOOLREV:
8195 parm_table[i].def.bvalue =
8196 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
8197 break;
8198 case P_CHAR:
8199 parm_table[i].def.cvalue =
8200 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
8201 break;
8202 case P_INTEGER:
8203 case P_OCTAL:
8204 case P_ENUM:
8205 case P_BYTES:
8206 parm_table[i].def.ivalue =
8207 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
8208 break;
8209 case P_SEP:
8210 break;
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 /***************************************************************************
8231 JRA.
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 ));
8256 return false;
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 ));
8264 return false;
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 ));
8273 return false;
8276 return true;
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,
8286 int snum,
8287 char **lines,
8288 int numlines,
8289 char **pp_sharepath,
8290 char **pp_comment,
8291 char **pp_cp_servicename,
8292 struct security_descriptor **ppsd,
8293 bool *pallow_guest)
8295 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8296 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8297 int us_vers;
8298 DIR *dp;
8299 SMB_STRUCT_STAT sbuf;
8300 char *sharepath = NULL;
8301 char *comment = NULL;
8303 *pp_sharepath = NULL;
8304 *pp_comment = NULL;
8306 *pallow_guest = false;
8308 if (numlines < 4) {
8309 return USERSHARE_MALFORMED_FILE;
8312 if (strcmp(lines[0], "#VERSION 1") == 0) {
8313 us_vers = 1;
8314 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8315 us_vers = 2;
8316 if (numlines < 5) {
8317 return USERSHARE_MALFORMED_FILE;
8319 } else {
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]);
8328 if (!sharepath) {
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]);
8338 if (!comment) {
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;
8352 if (us_vers == 2) {
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. */
8361 if (numlines > 5) {
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) {
8399 int i;
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) {
8416 int i;
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) {
8421 break;
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);
8435 if (!dp) {
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
8442 this directory. */
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) ));
8447 closedir(dp);
8448 return USERSHARE_POSIX_ERR;
8451 closedir(dp);
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.
8477 Returns:
8478 >= 0 - snum
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;
8488 char *fname = NULL;
8489 char *sharepath = NULL;
8490 char *comment = NULL;
8491 char *cp_service_name = NULL;
8492 char **lines = NULL;
8493 int numlines = 0;
8494 int fd = -1;
8495 int iService = -1;
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;
8501 int ret = -1;
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 ));
8508 goto out;
8511 canon_name = canonicalize_servicename(ctx, file_name);
8512 if (!canon_name) {
8513 goto out;
8516 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8517 if (!fname) {
8518 goto out;
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) ));
8527 goto out;
8530 /* This must be a regular file, not a symlink, directory or
8531 other strange filetype. */
8532 if (!check_usershare_stat(fname, &lsbuf)) {
8533 goto out;
8537 TDB_DATA data;
8538 NTSTATUS status;
8540 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
8541 canon_name, &data);
8543 iService = -1;
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",
8557 canon_name ));
8558 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8559 ret = iService;
8560 goto out;
8563 /* Try and open the file read only - no symlinks allowed. */
8564 #ifdef O_NOFOLLOW
8565 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
8566 #else
8567 fd = open(fname, O_RDONLY, 0);
8568 #endif
8570 if (fd == -1) {
8571 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8572 fname, strerror(errno) ));
8573 goto out;
8576 /* Now fstat to be *SURE* it's a regular file. */
8577 if (sys_fstat(fd, &sbuf, false) != 0) {
8578 close(fd);
8579 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8580 fname, strerror(errno) ));
8581 goto out;
8584 /* Is it the same dev/inode as was lstated ? */
8585 if (!check_same_stat(&lsbuf, &sbuf)) {
8586 close(fd);
8587 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8588 "Symlink spoofing going on ?\n", fname ));
8589 goto out;
8592 /* This must be a regular file, not a symlink, directory or
8593 other strange filetype. */
8594 if (!check_usershare_stat(fname, &sbuf)) {
8595 goto out;
8598 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8600 close(fd);
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 ));
8604 goto out;
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) {
8611 goto out;
8614 /* Everything ok - add the service possibly using a template. */
8615 if (iService < 0) {
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));
8624 goto out;
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",
8637 canon_name ));
8638 goto out;
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);
8657 ret = iService;
8659 out:
8661 if (ret == -1 && iService != -1 && added_service) {
8662 lp_remove_service(iService);
8665 TALLOC_FREE(lines);
8666 TALLOC_FREE(ctx);
8667 return ret;
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;
8678 char *fname;
8680 if (asprintf(&fname, "%s/%s",
8681 usersharepath,
8682 ServicePtrs[iService]->szService) < 0) {
8683 return false;
8686 if (sys_lstat(fname, &lsbuf, false) != 0) {
8687 SAFE_FREE(fname);
8688 return false;
8691 if (!S_ISREG(lsbuf.st_ex_mode)) {
8692 SAFE_FREE(fname);
8693 return false;
8696 SAFE_FREE(fname);
8697 *last_mod = lsbuf.st_ex_mtime;
8698 return true;
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) {
8713 return -1;
8716 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8717 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8718 usersharepath, strerror(errno) ));
8719 return -1;
8722 if (!S_ISDIR(sbuf.st_ex_mode)) {
8723 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8724 usersharepath ));
8725 return -1;
8729 * This directory must be owned by root, and have the 't' bit set.
8730 * It also must not be writable by "other".
8733 #ifdef S_ISVTX
8734 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8735 #else
8736 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8737 #endif
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",
8740 usersharepath ));
8741 return -1;
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)) {
8752 break;
8756 if (snum_template == -1) {
8757 DEBUG(0,("load_usershare_service: usershare template share %s "
8758 "does not exist.\n",
8759 Globals.szUsershareTemplateShare ));
8760 return -1;
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
8771 been removed.
8772 ***************************************************************************/
8774 int load_usershare_shares(struct smbd_server_connection *sconn,
8775 bool (*snumused) (struct smbd_server_connection *, int))
8777 DIR *dp;
8778 SMB_STRUCT_STAT sbuf;
8779 struct dirent *de;
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);
8785 int iService;
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) ));
8798 return ret;
8802 * This directory must be owned by root, and have the 't' bit set.
8803 * It also must not be writable by "other".
8806 #ifdef S_ISVTX
8807 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8808 #else
8809 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8810 #endif
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",
8813 usersharepath ));
8814 return ret;
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)) {
8825 break;
8829 if (snum_template == -1) {
8830 DEBUG(0,("load_usershare_shares: usershare template share %s "
8831 "does not exist.\n",
8832 Globals.szUsershareTemplateShare ));
8833 return ret;
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);
8845 if (!dp) {
8846 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8847 usersharepath, strerror(errno) ));
8848 return ret;
8851 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8852 (de = readdir(dp));
8853 num_dir_entries++ ) {
8854 int r;
8855 const char *n = de->d_name;
8857 /* Ignore . and .. */
8858 if (*n == '.') {
8859 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8860 continue;
8864 if (n[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));
8874 break;
8877 r = process_usershare_file(usersharepath, n, snum_template);
8878 if (r == 0) {
8879 /* Update the services count. */
8880 num_usershares++;
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 ));
8885 break;
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));
8896 break;
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));
8904 break;
8908 closedir(dp);
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)) {
8915 char *servname;
8917 if (snumused && snumused(sconn, iService)) {
8918 continue;
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",
8925 servname ));
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)
8941 int i;
8943 free_file_list();
8945 /* Free resources allocated to services */
8947 for ( i = 0; i < iNumServices; i++ ) {
8948 if ( VALID(i) ) {
8949 free_service_byindex(i);
8953 SAFE_FREE( ServicePtrs );
8954 iNumServices = 0;
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)
8968 in_client = b;
8972 /***************************************************************************
8973 Determine if we're running in a client app
8974 ***************************************************************************/
8975 static bool lp_is_in_client(void)
8977 return in_client;
8980 /***************************************************************************
8981 Load the services array from the services file. Return true on success,
8982 false on failure.
8983 ***************************************************************************/
8985 static bool lp_load_ex(const char *pszFname,
8986 bool global_only,
8987 bool save_defaults,
8988 bool add_ipc,
8989 bool initialize_globals,
8990 bool allow_include_registry,
8991 bool load_all_shares)
8993 char *n2 = NULL;
8994 bool bRetval;
8996 bRetval = false;
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);
9006 free_file_list();
9008 if (save_defaults) {
9009 init_locals();
9010 lp_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 */
9021 iServiceIndex = -1;
9023 if (lp_config_backend_is_file()) {
9024 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9025 current_user_info.domain,
9026 pszFname);
9027 if (!n2) {
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);
9034 TALLOC_FREE(n2);
9036 /* finish up the last section */
9037 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9038 if (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;
9053 /* start over */
9054 DEBUG(1, ("lp_load_ex: changing to config backend "
9055 "registry\n"));
9056 init_globals(true);
9057 lp_kill_all_services();
9058 return lp_load_ex(pszFname, global_only, save_defaults,
9059 add_ipc, initialize_globals,
9060 allow_include_registry,
9061 load_all_shares);
9063 } else if (lp_config_backend_is_registry()) {
9064 bRetval = process_registry_globals();
9065 } else {
9066 DEBUG(0, ("Illegal config backend given: %d\n",
9067 lp_config_backend()));
9068 bRetval = false;
9071 if (bRetval && lp_registry_shares()) {
9072 if (load_all_shares) {
9073 bRetval = process_registry_shares();
9074 } else {
9075 bRetval = reload_registry_shares();
9080 char *serv = lp_auto_services(talloc_tos());
9081 lp_add_auto_services(serv);
9082 TALLOC_FREE(serv);
9085 if (add_ipc) {
9086 /* When 'restrict anonymous = 2' guest connections to ipc$
9087 are denied */
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()));
9101 bLoaded = true;
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");
9109 init_iconv();
9111 fault_configure(smb_panic_s3);
9113 bAllowIncludeRegistry = true;
9115 return (bRetval);
9118 bool lp_load(const char *pszFname,
9119 bool global_only,
9120 bool save_defaults,
9121 bool add_ipc,
9122 bool initialize_globals)
9124 return lp_load_ex(pszFname,
9125 global_only,
9126 save_defaults,
9127 add_ipc,
9128 initialize_globals,
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
9171 * to default values
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,
9195 bool global_only,
9196 bool save_defaults,
9197 bool add_ipc,
9198 bool initialize_globals)
9200 return lp_load_ex(pszFname,
9201 global_only,
9202 save_defaults,
9203 add_ipc,
9204 initialize_globals,
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)
9224 int iService;
9226 if (show_defaults)
9227 defaults_saved = false;
9229 dump_globals(f);
9231 dump_a_service(&sDefault, f);
9233 for (iService = 0; iService < maxtoprint; iService++) {
9234 fprintf(f,"\n");
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)
9245 if (VALID(snum)) {
9246 if (ServicePtrs[snum]->szService[0] == '\0')
9247 return;
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)
9261 int iService;
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
9272 * service names
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)) {
9279 break;
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,
9298 &last_mod) < 0) {
9299 /* Remove it from the array. */
9300 free_service_byindex(iService);
9301 /* and now reload it. */
9302 iService = load_usershare_service(pszServiceName);
9306 if (iService < 0) {
9307 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9308 return GLOBAL_SECTION_SNUM;
9311 return (iService);
9314 /*******************************************************************
9315 A useful volume label function.
9316 ********************************************************************/
9318 const char *volume_label(TALLOC_CTX *ctx, int snum)
9320 char *ret;
9321 const char *label = lp_volume(ctx, snum);
9322 if (!*label) {
9323 label = lp_servicename(ctx, snum);
9326 /* This returns a 33 byte guarenteed null terminated string. */
9327 ret = talloc_strndup(ctx, label, 32);
9328 if (!ret) {
9329 return "";
9331 return ret;
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;
9357 break;
9358 case ROLE_DOMAIN_PDC:
9359 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9360 break;
9361 case ROLE_DOMAIN_BDC:
9362 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9363 break;
9364 case ROLE_STANDALONE:
9365 default:
9366 break;
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 */
9396 return true;
9398 return false;
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 /*******************************************************************
9414 Remove a service.
9415 ********************************************************************/
9417 void lp_remove_service(int snum)
9419 ServicePtrs[snum]->valid = false;
9420 invalid_services[num_invalid_services++] = snum;
9423 /*******************************************************************
9424 Copy a service.
9425 ********************************************************************/
9427 void lp_copy_service(int snum, const char *new_name)
9429 do_section(new_name, NULL);
9430 if (snum >= 0) {
9431 snum = lp_servicenumber(new_name);
9432 if (snum >= 0) {
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);
9446 return ret;
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;
9470 return maxjobs;
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) {
9480 #ifdef HAVE_CUPS
9481 return "cups";
9482 #else
9483 return "lpstat";
9484 #endif
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) {
9525 return false;
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) &&
9532 !sign_active);
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;
9543 else
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))
9554 return;
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
9576 not much).
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;
9595 } else {
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) {
9612 return 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()) {
9647 return;
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"
9664 * turned on.
9666 if (!lp_allow_insecure_widelinks()) {
9667 return false;
9671 return lp_widelinks_internal(snum);
9674 bool lp_writeraw(void)
9676 if (lp_async_smb_echo_handler()) {
9677 return false;
9679 return lp__writeraw();
9682 bool lp_readraw(void)
9684 if (lp_async_smb_echo_handler()) {
9685 return false;
9687 return lp__readraw();
9690 int lp_server_role(void)
9692 return lp_find_server_role(lp__server_role(),
9693 lp_security(),
9694 lp_domain_logons(),
9695 lp_domain_master_true_or_auto());